Merge lp:~martin-borho/ubuntu-weather-app/backend-upgrade into lp:ubuntu-weather-app/obsolete.trunk

Proposed by Martin Borho on 2013-06-14
Status: Merged
Approved by: Raúl Yeguas on 2013-06-17
Approved revision: 40
Merged at revision: 41
Proposed branch: lp:~martin-borho/ubuntu-weather-app/backend-upgrade
Merge into: lp:ubuntu-weather-app/obsolete.trunk
Diff against target: 275 lines (+93/-43)
5 files modified
components/LocationTab.qml (+8/-7)
components/SettingsDialog.qml (+1/-1)
components/Storage.qml (+1/-0)
components/WeatherApi.js (+66/-26)
ubuntu-weather-app.qml (+17/-9)
To merge this branch: bzr merge lp:~martin-borho/ubuntu-weather-app/backend-upgrade
Reviewer Review Type Date Requested Status
Raúl Yeguas 2013-06-14 Approve on 2013-06-17
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve on 2013-06-14
Review via email: mp+169423@code.launchpad.net

Commit message

Improvements to API-Worker to reduce HTTP calls against weather api.

Description of the change

- Weather data will not get refreshed unless stored data is older than 30min or an refresh is forced.
- Metric and imperial values are getting precalculated in API-Worker now. Refresh of weather data isn't neccessary anymore after changing scale in settings.

To post a comment you must log in.
Raúl Yeguas (neokore) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components/LocationTab.qml'
2--- components/LocationTab.qml 2013-06-12 17:44:34 +0000
3+++ components/LocationTab.qml 2013-06-14 13:37:21 +0000
4@@ -19,7 +19,8 @@
5
6 Component.onCompleted: {
7 var locData = mainView.locationsList[locationIndex],
8- currentData = locData.current.results;
9+ currentData = locData.current.results,
10+ units = (mainView.settings.units === 'imperial') ? 'imperial' : 'metric';
11
12 // set location data as property
13 locationData = locData;
14@@ -32,9 +33,9 @@
15 // set current Condition
16 currentCondition.condition = currentData.condition.id;
17 currentCondition.icon = currentData.condition.icon;
18- currentCondition.currentTemp = currentData.temp;
19- currentCondition.minTemp = currentData.temp_min;
20- currentCondition.maxTemp = currentData.temp_max;
21+ currentCondition.currentTemp = currentData[units].temp;
22+ currentCondition.minTemp = currentData[units].temp_min;
23+ currentCondition.maxTemp = currentData[units].temp_max;
24
25 // set daily forecasts
26 var dailyForecasts = locationData.daily.results,
27@@ -43,8 +44,8 @@
28 dayForecastModel.append({
29 dateRel: "",//Tomorrow",
30 date: formatTimestamp(dailyForecasts[x].timestamp, 'dddd, dd MMMM yyyy'),
31- temp: dailyForecasts[x].max,
32- tempMin: dailyForecasts[x].min,
33+ temp: dailyForecasts[x][units].max,
34+ tempMin: dailyForecasts[x][units].min,
35 cond: dailyForecasts[x].condition.id,
36 condIcon: dailyForecasts[x].condition.icon
37 });
38@@ -61,7 +62,7 @@
39 text: i18n.tr("Refresh")
40
41 onTriggered: {
42- mainView.refreshData();
43+ mainView.refreshData(false, true);
44 }
45 }
46 Action {
47
48=== modified file 'components/SettingsDialog.qml'
49--- components/SettingsDialog.qml 2013-06-12 17:13:32 +0000
50+++ components/SettingsDialog.qml 2013-06-14 13:37:21 +0000
51@@ -52,7 +52,7 @@
52 for(var settingName in storedSettings) {
53 settings[settingName] = storedSettings[settingName];
54 }
55- refreshData();
56+ refreshData(true);
57 });
58 }
59 }
60
61=== modified file 'components/Storage.qml'
62--- components/Storage.qml 2013-06-09 15:42:41 +0000
63+++ components/Storage.qml 2013-06-14 13:37:21 +0000
64@@ -83,6 +83,7 @@
65 for(var i = 0; i < rs.rows.length; i++) {
66 var row = rs.rows.item(i),
67 locData = JSON.parse(row.data);
68+ locData["updated"] = parseInt(row.date, 10);
69 locData["db"] = {id: row.id, updated: new Date(parseInt(row.date, 10))};
70 locations.push(locData);
71 }
72
73=== modified file 'components/WeatherApi.js'
74--- components/WeatherApi.js 2013-06-12 16:41:07 +0000
75+++ components/WeatherApi.js 2013-06-14 13:37:21 +0000
76@@ -1,11 +1,25 @@
77 .pragma library
78+/**
79+* Version of the response data format.
80+* Increase this number to force a refresh.
81+*/
82+var RESPONSE_DATA_VERSION = 1;
83+
84+/**
85+* Helper functions
86+*/
87+function calcFahrenheit(celsius) {
88+ return celsius * 1.8 + 32;
89+}
90+function calcMph(kmh) {
91+ return kmh*0.62137;
92+}
93
94 var OpenWeatherMapApi = (function() {
95 /**
96 provides neccessary methods for requesting and preparing data from OpenWeatherMap.org
97 */
98 var _baseUrl = "http://api.openweathermap.org/data/2.5/";
99-
100 //
101 function _buildSearchResult(request, data) {
102 var searchResult = {
103@@ -31,12 +45,20 @@
104 var result = {
105 timestamp: data.dt,
106 date: (data.date !== undefined) ? data.date : ((data.dt_txt !== undefined) ? data.dt_txt: null),
107- temp: data.main.temp,
108- temp_min: data.main.temp_min,
109- temp_max: data.main.temp_max,
110+ metric: {
111+ temp:data.main.temp,
112+ temp_min: data.main.temp_min,
113+ temp_max: data.main.temp_max
114+ },
115+ imperial: {
116+ temp: calcFahrenheit(data.main.temp),
117+ temp_min: calcFahrenheit(data.main.temp_min),
118+ temp_max: calcFahrenheit(data.main.temp_max)
119+ },
120 humidity: data.main.humidity,
121 pressure: data.main.pressure,
122- wind_speed: data.wind.speed,
123+ wind_speed_kmh: data.wind.speed,
124+ wind_speed_mph: calcMph(data.wind.speed),
125 wind_deg: data.wind.deg,
126 condition: data.weather[0]
127 };
128@@ -76,12 +98,22 @@
129 // TODO date_txt
130 forecastResult.results.push({
131 timestamp: f.dt,
132- day: f.temp.day,
133- min: f.temp.min,
134- max: f.temp.max,
135- night: f.temp.night,
136- eve: f.temp.eve,
137- morn: f.temp.morn,
138+ metric: {
139+ day: f.temp.day,
140+ min: f.temp.min,
141+ max: f.temp.max,
142+ night: f.temp.night,
143+ eve: f.temp.eve,
144+ morn: f.temp.morn
145+ },
146+ imperial: {
147+ day: calcFahrenheit(f.temp.day),
148+ min: calcFahrenheit(f.temp.min),
149+ max: calcFahrenheit(f.temp.max),
150+ night: calcFahrenheit(f.temp.night),
151+ eve: calcFahrenheit(f.temp.eve),
152+ morn: calcFahrenheit(f.temp.morn)
153+ },
154 pressure: f.pressure,
155 humidity: f.humidity,
156 condition: f.weather[0],
157@@ -228,7 +260,8 @@
158 },
159 response = {
160 location: params.location,
161- db: (params.db) ? params.db : null
162+ db: (params.db) ? params.db : null,
163+ format: RESPONSE_DATA_VERSION
164 },
165 addDataToResponse = (function(data) {
166 response[data.request.type] = data;
167@@ -256,16 +289,15 @@
168 "openweathermap": OpenWeatherMapApi
169 });
170
171-
172-/*
173- following WorkerScript handles the data requests against the weather API.
174- "message" requires a "params" property with the required params to perform
175- the API call and an "action" property, which will be added also to the response.
176+/**
177+* following WorkerScript handles the data requests against the weather API.
178+* "message" requires a "params" property with the required params to perform
179+* the API call and an "action" property, which will be added also to the response.
180 */
181 if(typeof WorkerScript != "undefined") {
182 WorkerScript.onMessage = function(message) {
183 // handles the response data
184- var finished = function(result) {
185+ var finished = function(result) {
186 WorkerScript.sendMessage({
187 action: message.action,
188 result: result
189@@ -288,25 +320,33 @@
190 } else if(message.action === "updateData") {
191 var locLength = message.params.locations.length,
192 locUpdated = 0,
193- result = [];
194+ result = [],
195+ now = new Date().getTime();
196 if(locLength > 0) {
197 message.params.locations.forEach(function(loc) {
198- var updatedHnd = function (newData) {
199- locUpdated += 1;
200+ var updatedHnd = function (newData, cached) {
201+ locUpdated += 1;
202+ newData["save"] = (cached === true) ? false : true;
203 result.push(newData);
204 if(locUpdated === locLength) {
205 result.sort(sortDataResults);
206 finished(result);
207 }
208 },
209- units = (message.params.units === "metric" || message.params.units === "imperial")
210- ? message.params.units : "metric",
211 params = {
212 location:loc.location,
213 db: loc.db,
214- units: units
215- };
216- WeatherApi.getLocationData(params, updatedHnd, onError);
217+ units: 'metric'
218+ },
219+ secsFromLastFetch = (now-loc.updated)/1000;
220+ //
221+ if( message.params.force===true || loc.format !== RESPONSE_DATA_VERSION || secsFromLastFetch > 1800){
222+ // data older than 30min, location is new or data format is deprecated
223+ WeatherApi.getLocationData(params, updatedHnd, onError);
224+ } else {
225+ console.log("["+loc.location.name+"] returning cached data, time from last fetch: "+secsFromLastFetch)
226+ updatedHnd(loc, true);
227+ }
228 })
229 } else {
230 finished(result);
231
232=== modified file 'ubuntu-weather-app.qml'
233--- ubuntu-weather-app.qml 2013-06-12 17:44:34 +0000
234+++ ubuntu-weather-app.qml 2013-06-14 13:37:21 +0000
235@@ -25,7 +25,9 @@
236 if(!messageObject.error) {
237 if(messageObject.action === "updateData") {
238 messageObject.result.forEach(function(loc) {
239- storage.updateLocation(loc.db.id, loc);
240+ if(loc["save"] === true) {
241+ storage.updateLocation(loc.db.id, loc);
242+ }
243 });
244 buildTabs(messageObject.result);
245 }
246@@ -67,15 +69,21 @@
247 tabsObject.selectedTabIndex = locLength -1;
248 }
249
250- function refreshData() {
251- if(bigLoading === null)
252+ function refreshData(from_storage, force_refresh) {
253+ if(bigLoading === null) {
254 loading.running = true;
255- storage.getLocations(function(locations) {
256- locationDataWorker.sendMessage({
257- action: "updateData",
258- params: {locations:locations, units:settings["units"]}
259- })
260- });
261+ }
262+ //
263+ if(from_storage === true && force_refresh !== true) {
264+ storage.getLocations(buildTabs);
265+ } else {
266+ storage.getLocations(function(locations) {
267+ locationDataWorker.sendMessage({
268+ action: "updateData",
269+ params: {locations:locations, force: force_refresh}
270+ })
271+ });
272+ }
273 }
274
275 function showLocationManager() {

Subscribers

People subscribed via source and target branches