Cache weatherdata between two updates, only change of location or explicit click on reload-button triggers a reload of weatherdata. Reduces server load on openweathermap.org .

openweathermap_3.6
Jens Lody 11 years ago
parent bc65d7e44f
commit 142ca04700
  1. 615
      src/extension.js

@ -284,8 +284,12 @@ const WeatherMenuButton = new Lang.Class({
this._settings = Convenience.getSettings(WEATHER_SETTINGS_SCHEMA); this._settings = Convenience.getSettings(WEATHER_SETTINGS_SCHEMA);
this._settingsC = this._settings.connect("changed", function() { this._settingsC = this._settings.connect("changed", function() {
that.rebuildFutureWeatherUi(); that.rebuildFutureWeatherUi();
that.refreshWeatherCurrent(false); if (that.locationChanged()) {
that.refreshWeatherForecast(false); that.currentWeatherCache = 'undefined';
that.forecastWeatherCache = 'undefined';
}
that.parseWeatherCurrent();
that.parseWeatherForecast();
}); });
}, },
@ -298,11 +302,23 @@ const WeatherMenuButton = new Lang.Class({
schema: schemaInterface schema: schemaInterface
}); });
this._settingsInterfaceC = this._settingsInterface.connect("changed", function() { this._settingsInterfaceC = this._settingsInterface.connect("changed", function() {
that.refreshWeatherCurrent(false); if (that.locationChanged()) {
that.refreshWeatherForecast(false); that.currentWeatherCache = 'undefined';
that.forecastWeatherCache = 'undefined';
}
that.parseWeatherCurrent();
that.parseWeatherForecast();
}); });
}, },
locationChanged: function() {
let location = this.extractCity(this._city);
if (this.oldLocation != location) {
return true;
}
return false;
},
get _clockFormat() { get _clockFormat() {
if (!this._settingsInterface) if (!this._settingsInterface)
this.loadConfigInterface(); this.loadConfigInterface();
@ -1088,253 +1104,268 @@ weather-storm.png = weather-storm-symbolic.svg
return 0; return 0;
}, },
refreshWeatherCurrent: function(recurse) { parseWeatherCurrent: function() {
if (!this.extractId(this._city)) { if (this.currentWeatherCache == 'undefined') {
this.updateCities(); this.refreshWeatherCurrent();
return 0; return;
} }
let params = {
q: this.extractCity(this._city),
units: 'metric'
};
if(this._appid)
params['APPID'] = this._appid;
this.load_json_async(WEATHER_URL_CURRENT, params, function(json) { if (this._old_position_in_panel != this._position_in_panel) {
if (!json) switch (this._old_position_in_panel) {
return 0; case WeatherPosition.LEFT:
Main.panel._leftBox.remove_actor(this.actor);
break;
case WeatherPosition.CENTER:
Main.panel._centerBox.remove_actor(this.actor);
break;
case WeatherPosition.RIGHT:
Main.panel._rightBox.remove_actor(this.actor);
break;
}
if (Number(json.cod) != 200) let children = null;
return 0; switch (this._position_in_panel) {
case WeatherPosition.LEFT:
children = Main.panel._leftBox.get_children();
Main.panel._leftBox.insert_child_at_index(this.actor, children.length);
break;
case WeatherPosition.CENTER:
children = Main.panel._centerBox.get_children();
Main.panel._centerBox.insert_child_at_index(this.actor, children.length);
break;
case WeatherPosition.RIGHT:
children = Main.panel._rightBox.get_children();
Main.panel._rightBox.insert_child_at_index(this.actor, 0);
break;
}
this._old_position_in_panel = this._position_in_panel;
}
this.rebuildSelectCityItem(); let json = this.currentWeatherCache;
// Refresh current weather
let location = this.extractLocation(this._city);
let comment = json.weather[0].description;
if (this._translate_condition)
comment = this.get_weather_condition(json.weather[0].id);
if (this._old_position_in_panel != this._position_in_panel) { let temperature = json.main.temp;
switch (this._old_position_in_panel) { let cloudiness = json.clouds.all;
case WeatherPosition.LEFT: let humidity = json.main.humidity + ' %';
Main.panel._leftBox.remove_actor(this.actor); let pressure = json.main.pressure;
break; let pressure_unit = 'hPa';
case WeatherPosition.CENTER:
Main.panel._centerBox.remove_actor(this.actor);
break;
case WeatherPosition.RIGHT:
Main.panel._rightBox.remove_actor(this.actor);
break;
}
let children = null;
switch (this._position_in_panel) {
case WeatherPosition.LEFT:
children = Main.panel._leftBox.get_children();
Main.panel._leftBox.insert_child_at_index(this.actor, children.length);
break;
case WeatherPosition.CENTER:
children = Main.panel._centerBox.get_children();
Main.panel._centerBox.insert_child_at_index(this.actor, children.length);
break;
case WeatherPosition.RIGHT:
children = Main.panel._rightBox.get_children();
Main.panel._rightBox.insert_child_at_index(this.actor, 0);
break;
}
this._old_position_in_panel = this._position_in_panel;
}
let location = this.extractLocation(this._city); let wind_direction = this.get_wind_direction(json.wind.deg);
let wind = json.wind.speed;
let wind_unit = 'm/s';
let iconname = this.get_weather_icon_safely(json.weather[0].id);
// Refresh current weather let sunrise = json.sys.sunrise;
let comment = json.weather[0].description; let sunset = json.sys.sunset;
if (this._translate_condition)
comment = this.get_weather_condition(json.weather[0].id);
let temperature = json.main.temp; if (typeof this.lastBuildId == 'undefined')
let cloudiness = json.clouds.all; this.lastBuildId = 0;
let humidity = json.main.humidity + ' %';
let pressure = json.main.pressure;
let pressure_unit = 'hPa';
let wind_direction = this.get_wind_direction(json.wind.deg); if (typeof this.lastBuildDate == 'undefined')
let wind = json.wind.speed; this.lastBuildDate = 0;
let wind_unit = 'm/s';
let iconname = this.get_weather_icon_safely(json.weather[0].id);
let sunrise = json.sys.sunrise; if (this.lastBuildId != json.dt || !this.lastBuildDate) {
let sunset = json.sys.sunset; this.lastBuildId = json.dt;
this.lastBuildDate = new Date(this.lastBuildId * 1000);
}
if (typeof this.lastBuildId == "undefined") switch (this._pressure_units) {
this.lastBuildId = 0; case WeatherPressureUnits.inHg:
pressure = this.toInHg(pressure);
pressure_unit = "inHg";
break;
if (typeof this.lastBuildDate == "undefined") case WeatherPressureUnits.hPa:
this.lastBuildDate = 0; pressure = Math.round(pressure * 10) / 10;
pressure_unit = "hPa";
break;
if (this.lastBuildId != json.dt || !this.lastBuildDate) { case WeatherPressureUnits.bar:
this.lastBuildId = json.dt; pressure = Math.round((pressure / 1000) * 10) / 10;
this.lastBuildDate = new Date(); pressure_unit = "bar";
} break;
let actualDate = new Date();
let d = Math.floor((actualDate.getTime() - this.lastBuildDate.getTime()) / 86400000);
switch (this._pressure_units) { case WeatherPressureUnits.Pa:
case WeatherPressureUnits.inHg: pressure = Math.round((pressure * 100) * 10) / 10;
pressure = this.toInHg(pressure); pressure_unit = "Pa";
pressure_unit = "inHg"; break;
break;
case WeatherPressureUnits.hPa: case WeatherPressureUnits.kPa:
pressure = Math.round(pressure * 10) / 10; pressure = Math.round((pressure / 10) * 10) / 10;
pressure_unit = "hPa"; pressure_unit = "kPa";
break; break;
case WeatherPressureUnits.bar: case WeatherPressureUnits.atm:
pressure = Math.round((pressure / 1000) * 10) / 10; pressure = Math.round((pressure * 0.000986923267) * 10) / 10;
pressure_unit = "bar"; pressure_unit = "atm";
break; break;
case WeatherPressureUnits.Pa: case WeatherPressureUnits.at:
pressure = Math.round((pressure * 100) * 10) / 10; pressure = Math.round((pressure * 0.00101971621298) * 10) / 10;
pressure_unit = "Pa"; pressure_unit = "at";
break; break;
case WeatherPressureUnits.kPa: case WeatherPressureUnits.Torr:
pressure = Math.round((pressure / 10) * 10) / 10; pressure = Math.round((pressure * 0.750061683) * 10) / 10;
pressure_unit = "kPa"; pressure_unit = "Torr";
break; break;
case WeatherPressureUnits.atm: case WeatherPressureUnits.psi:
pressure = Math.round((pressure * 0.000986923267) * 10) / 10; pressure = Math.round((pressure * 0.0145037738) * 10) / 10;
pressure_unit = "atm"; pressure_unit = "psi";
break; break;
}
case WeatherPressureUnits.at: switch (this._units) {
pressure = Math.round((pressure * 0.00101971621298) * 10) / 10; case WeatherUnits.FAHRENHEIT:
pressure_unit = "at"; temperature = this.toFahrenheit(temperature);
break; break;
case WeatherPressureUnits.Torr: case WeatherUnits.CELSIUS:
pressure = Math.round((pressure * 0.750061683) * 10) / 10; temperature = Math.round(temperature * 10) / 10;
pressure_unit = "Torr"; break;
break;
case WeatherPressureUnits.psi: case WeatherUnits.KELVIN:
pressure = Math.round((pressure * 0.0145037738) * 10) / 10; temperature = this.toKelvin(temperature);
pressure_unit = "psi"; break;
break;
}
switch (this._units) { case WeatherUnits.RANKINE:
case WeatherUnits.FAHRENHEIT: temperature = this.toRankine(temperature);
temperature = this.toFahrenheit(temperature); break;
break;
case WeatherUnits.CELSIUS: case WeatherUnits.REAUMUR:
temperature = Math.round(temperature * 10) / 10; temperature = this.toReaumur(temperature);
break; break;
case WeatherUnits.KELVIN: case WeatherUnits.ROEMER:
temperature = this.toKelvin(temperature); temperature = this.toRoemer(temperature);
break; break;
case WeatherUnits.RANKINE: case WeatherUnits.DELISLE:
temperature = this.toRankine(temperature); temperature = this.toDelisle(temperature);
break; break;
case WeatherUnits.REAUMUR: case WeatherUnits.NEWTON:
temperature = this.toReaumur(temperature); temperature = this.toNewton(temperature);
break; break;
}
case WeatherUnits.ROEMER: let lastBuild = '-';
temperature = this.toRoemer(temperature);
break;
case WeatherUnits.DELISLE: if (this._clockFormat == "24h") {
temperature = this.toDelisle(temperature); sunrise = new Date(sunrise * 1000).toLocaleFormat("%R");
break; sunset = new Date(sunset * 1000).toLocaleFormat("%R");
lastBuild = this.lastBuildDate.toLocaleFormat("%R");
} else {
sunrise = new Date(sunrise * 1000).toLocaleFormat("%I:%M %p");
sunset = new Date(sunset * 1000).toLocaleFormat("%I:%M %p");
lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p");
}
case WeatherUnits.NEWTON: let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
temperature = this.toNewton(temperature); let d = Math.floor((beginOfDay.getTime() - this.lastBuildDate.getTime()) / 86400000);
break; if (d < 0) {
} lastBuild = _("Yesterday");
if (d < -1)
lastBuild = _("%s days ago").replace("%s", -1 * d);
}
let lastBuild = '-'; this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname;
if (this._clockFormat == "24h") { let weatherInfoC = "";
sunrise = new Date(sunrise * 1000).toLocaleFormat("%R"); let weatherInfoT = "";
sunset = new Date(sunset * 1000).toLocaleFormat("%R");
lastBuild = this.lastBuildDate.toLocaleFormat("%R");
} else {
sunrise = new Date(sunrise * 1000).toLocaleFormat("%I:%M %p");
sunset = new Date(sunset * 1000).toLocaleFormat("%I:%M %p");
lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p");
}
if (d >= 1) { if (this._comment_in_panel)
lastBuild = _("Yesterday"); weatherInfoC = comment;
if (d > 1)
lastBuild = _("%s days ago").replace("%s", d);
}
this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname; if (this._text_in_panel)
weatherInfoT = parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode();
let weatherInfoC = ""; this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT;
let weatherInfoT = "";
if (this._comment_in_panel) this._currentWeatherSummary.text = comment + ", " + parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode();
weatherInfoC = comment; this._currentWeatherLocation.text = location;
this._currentWeatherTemperature.text = cloudiness + ' %';
this._currentWeatherHumidity.text = parseFloat(humidity).toLocaleString() + ' %';
this._currentWeatherPressure.text = parseFloat(pressure).toLocaleString() + ' ' + pressure_unit;
this._currentWeatherSunrise.text = sunrise;
this._currentWeatherSunset.text = sunset;
this._currentWeatherBuild.text = lastBuild;
if (this._text_in_panel) // Override wind units with our preference
weatherInfoT = parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode(); switch (this._wind_speed_units) {
case WeatherWindSpeedUnits.MPH:
wind = Math.round((wind * WEATHER_CONV_MPS_IN_MPH) * 10) / 10;
wind_unit = 'mph';
break;
this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT; case WeatherWindSpeedUnits.KPH:
wind = Math.round((wind * WEATHER_CONV_MPS_IN_KPH) * 10) / 10;
wind_unit = 'km/h';
break;
this._currentWeatherSummary.text = comment + ", " + parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode(); case WeatherWindSpeedUnits.MPS:
this._currentWeatherLocation.text = location; wind = Math.round(wind * 10) / 10;
this._currentWeatherTemperature.text = cloudiness + ' %'; break;
this._currentWeatherHumidity.text = parseFloat(humidity).toLocaleString() + ' %';
this._currentWeatherPressure.text = parseFloat(pressure).toLocaleString() + ' ' + pressure_unit;
this._currentWeatherSunrise.text = sunrise;
this._currentWeatherSunset.text = sunset;
this._currentWeatherBuild.text = lastBuild;
// Override wind units with our preference case WeatherWindSpeedUnits.KNOTS:
switch (this._wind_speed_units) { wind = Math.round((wind * WEATHER_CONV_MPS_IN_KNOTS) * 10) / 10;
case WeatherWindSpeedUnits.MPH: wind_unit = 'kn';
wind = Math.round((wind * WEATHER_CONV_MPS_IN_MPH) * 10) / 10; break;
wind_unit = 'mph';
break;
case WeatherWindSpeedUnits.KPH: case WeatherWindSpeedUnits.FPS:
wind = Math.round((wind * WEATHER_CONV_MPS_IN_KPH) * 10) / 10; wind = Math.round((wind * WEATHER_CONV_MPS_IN_FPS) * 10) / 10;
wind_unit = 'km/h'; wind_unit = 'ft/s';
break; break;
case WeatherWindSpeedUnits.MPS: case WeatherWindSpeedUnits.BEAUFORT:
wind = Math.round(wind * 10) / 10; wind_unit = this.toBeaufort(wind, true);
break; wind = this.toBeaufort(wind);
}
case WeatherWindSpeedUnits.KNOTS: if (!wind)
wind = Math.round((wind * WEATHER_CONV_MPS_IN_KNOTS) * 10) / 10; this._currentWeatherWind.text = '\u2013';
wind_unit = 'kn'; else if (wind == 0 || !wind_direction)
break; this._currentWeatherWind.text = parseFloat(wind).toLocaleString() + ' ' + wind_unit;
else // i.e. wind > 0 && wind_direction
this._currentWeatherWind.text = wind_direction + ' ' + parseFloat(wind).toLocaleString() + ' ' + wind_unit;
case WeatherWindSpeedUnits.FPS: },
wind = Math.round((wind * WEATHER_CONV_MPS_IN_FPS) * 10) / 10;
wind_unit = 'ft/s';
break;
case WeatherWindSpeedUnits.BEAUFORT: refreshWeatherCurrent: function(recurse) {
wind_unit = this.toBeaufort(wind, true); if (!this.extractId(this._city)) {
wind = this.toBeaufort(wind); this.updateCities();
} return;
}
this.oldLocation = this.extractCity(this._city);
if (!wind) let params = {
this._currentWeatherWind.text = '\u2013'; q: this.oldLocation,
else if (wind == 0 || !wind_direction) units: 'metric'
this._currentWeatherWind.text = parseFloat(wind).toLocaleString() + ' ' + wind_unit; };
else // i.e. wind > 0 && wind_direction if (this._appid)
this._currentWeatherWind.text = wind_direction + ' ' + parseFloat(wind).toLocaleString() + ' ' + wind_unit; params['APPID'] = this._appid;
this.load_json_async(WEATHER_URL_CURRENT, params, function(json) {
if (!json)
return;
if (Number(json.cod) != 200)
return;
if (this.currentWeatherCache != json)
this.currentWeatherCache = json;
this.rebuildSelectCityItem();
this.parseWeatherCurrent();
this.parseWeatherForecast();
return 0;
}); });
// Repeatedly refresh weather if recurse is set // Repeatedly refresh weather if recurse is set
@ -1343,7 +1374,91 @@ weather-storm.png = weather-storm-symbolic.svg
this.refreshWeatherCurrent(true); this.refreshWeatherCurrent(true);
})); }));
} }
return 0; },
parseWeatherForecast: function() {
if (this.forecastWeatherCache == 'undefined') {
this.refreshWeatherForecast();
return;
}
let forecast = this.forecastWeatherCache;
let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
// Refresh forecast
for (let i = 0; i < this._days_forecast; i++) {
let forecastUi = this._forecast[i];
let forecastData = forecast[i];
if (forecastData == 'undefined')
continue;
let t_low = forecastData.temp.min;
let t_high = forecastData.temp.max;
switch (this._units) {
case WeatherUnits.FAHRENHEIT:
t_low = this.toFahrenheit(t_low);
t_high = this.toFahrenheit(t_high);
break;
case WeatherUnits.CELSIUS:
t_low = Math.round(t_low * 10) / 10;
t_high = Math.round(t_high * 10) / 10;
break;
case WeatherUnits.KELVIN:
t_low = this.toKelvin(t_low);
t_high = this.toKelvin(t_high);
break;
case WeatherUnits.RANKINE:
t_low = this.toRankine(t_low);
t_high = this.toRankine(t_high);
break;
case WeatherUnits.REAUMUR:
t_low = this.toReaumur(t_low);
t_high = this.toReaumur(t_high);
break;
case WeatherUnits.ROEMER:
t_low = this.toRoemer(t_low);
t_high = this.toRoemer(t_high);
break;
case WeatherUnits.DELISLE:
t_low = this.toDelisle(t_low);
t_high = this.toDelisle(t_high);
break;
case WeatherUnits.NEWTON:
t_low = this.toNewton(t_low);
t_high = this.toNewton(t_high);
break;
}
let comment = forecastData.weather[0].description;
if (this._translate_condition)
comment = this.get_weather_condition(forecastData.weather[0].id);
let forecastDate = new Date(forecastData.dt * 1000);
let dayLeft = Math.floor((forecastDate.getTime() - beginOfDay.getTime()) / 86400000);
let date_string = _("Today");
if (dayLeft == 1)
date_string = _("Tomorrow");
else if (dayLeft > 1)
date_string = _("In %s days").replace("%s", dayLeft);
else if (dayLeft == -1)
date_string = _("Yesterday");
else if (dayLeft < -1)
date_string = _("%s days ago").replace("%s", -1 * dayLeft);
forecastUi.Day.text = date_string + ' (' + this.get_locale_day(forecastDate.getDay()) + ')';
forecastUi.Temperature.text = '\u2193 ' + parseFloat(t_low).toLocaleString() + ' ' + this.unit_to_unicode() + ' \u2191 ' + parseFloat(t_high).toLocaleString() + ' ' + this.unit_to_unicode();
forecastUi.Summary.text = comment;
forecastUi.Icon.icon_name = this.get_weather_icon_safely(forecastData.weather[0].id);
}
}, },
refreshWeatherForecast: function(recurse) { refreshWeatherForecast: function(recurse) {
@ -1352,97 +1467,27 @@ weather-storm.png = weather-storm-symbolic.svg
return 0; return 0;
} }
this.oldLocation = this.extractCity(this._city);
let params = { let params = {
q: this.extractCity(this._city), q: this.oldLocation,
units: 'metric', units: 'metric',
cnt : '10' cnt: '13'
}; };
if(this._appid) if(this._appid)
params['APPID'] = this._appid; params['APPID'] = this._appid;
this.load_json_async(WEATHER_URL_FORECAST, params, function(json) { this.load_json_async(WEATHER_URL_FORECAST, params, function(json) {
if (!json) if (!json)
return 0; return;
if (Number(json.cod) != 200) if (Number(json.cod) != 200)
return 0; return;
let forecast = json.list; if (this.forecastWeatherCache != json.list)
this.forecastWeatherCache = json.list;
// Refresh forecast
for (let i = 0; i < this._days_forecast; i++) { this.parseWeatherForecast();
let forecastUi = this._forecast[i];
let forecastData = forecast[i];
let t_low = forecastData.temp.min;
let t_high = forecastData.temp.max;
switch (this._units) {
case WeatherUnits.FAHRENHEIT:
t_low = this.toFahrenheit(t_low);
t_high = this.toFahrenheit(t_high);
break;
case WeatherUnits.CELSIUS:
t_low = Math.round(t_low * 10) / 10;
t_high = Math.round(t_high * 10) / 10;
break;
case WeatherUnits.KELVIN:
t_low = this.toKelvin(t_low);
t_high = this.toKelvin(t_high);
break;
case WeatherUnits.RANKINE:
t_low = this.toRankine(t_low);
t_high = this.toRankine(t_high);
break;
case WeatherUnits.REAUMUR:
t_low = this.toReaumur(t_low);
t_high = this.toReaumur(t_high);
break;
case WeatherUnits.ROEMER:
t_low = this.toRoemer(t_low);
t_high = this.toRoemer(t_high);
break;
case WeatherUnits.DELISLE:
t_low = this.toDelisle(t_low);
t_high = this.toDelisle(t_high);
break;
case WeatherUnits.NEWTON:
t_low = this.toNewton(t_low);
t_high = this.toNewton(t_high);
break;
}
let comment = forecastData.weather[0].description;
if (this._translate_condition)
comment = this.get_weather_condition(forecastData.weather[0].id);
let forecastDate = new Date(forecastData.dt * 1000);
let actualDate = new Date();
let dayLeft = Math.floor((actualDate.getTime() - forecastDate.getTime()) / 1000 / 60 / 60 / 24);
let date_string = _("Today");
if (dayLeft == -1)
date_string = _("Tomorrow");
else if (dayLeft < -1)
date_string = _("In %s days").replace("%s", -1 * dayLeft);
else if (dayLeft == 1)
date_string = _("Yesterday");
else if (dayLeft > 1)
date_string = _("%s days ago").replace("%s", dayLeft);
forecastUi.Day.text = date_string + ' (' + this.get_locale_day(forecastDate.getDay()) + ')';
forecastUi.Temperature.text = '\u2193 ' + parseFloat(t_low).toLocaleString() + ' ' + this.unit_to_unicode() + ' \u2191 ' + parseFloat(t_high).toLocaleString() + ' ' + this.unit_to_unicode();
forecastUi.Summary.text = comment;
forecastUi.Icon.icon_name = this.get_weather_icon_safely(forecastData.weather[0].id);
}
return 0;
}); });
// Repeatedly refresh weather if recurse is set // Repeatedly refresh weather if recurse is set

Loading…
Cancel
Save