Merge lp:~martin-borho/ubuntu-weather-app/reboot-worker into lp:ubuntu-weather-app

Proposed by Martin Borho
Status: Merged
Approved by: Victor Thompson
Approved revision: 21
Merged at revision: 21
Proposed branch: lp:~martin-borho/ubuntu-weather-app/reboot-worker
Merge into: lp:ubuntu-weather-app
Diff against target: 311 lines (+117/-100)
4 files modified
app/data/WeatherApi.js (+73/-67)
app/ubuntu-weather-app.qml (+25/-19)
app/ui/AddLocationPage.qml (+14/-9)
po/com.ubuntu.weather.pot (+5/-5)
To merge this branch: bzr merge lp:~martin-borho/ubuntu-weather-app/reboot-worker
Reviewer Review Type Date Requested Status
Victor Thompson Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+252972@code.launchpad.net

Commit message

To prevent a blank app at startup:

* reimplemented worker calls for data requests
* starts up the app with stored data and spins off a refresh request in a worker

Description of the change

To prevent a blank app at startup:

* reimplemented worker calls for data requests
* starts up the app with stored data and spins off a refresh request in a worker

See https://code.launchpad.net/~vthompson/ubuntu-weather-app/reboot-get-initial-data-from-storage/+merge/252962

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

LGTM! When we do empty states, we should consider displaying something useful to the user when the API calls are not working and/or there is no stored data.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/data/WeatherApi.js'
2--- app/data/WeatherApi.js 2015-03-08 17:23:12 +0000
3+++ app/data/WeatherApi.js 2015-03-14 15:20:24 +0000
4@@ -671,74 +671,80 @@
5 "geoip": GeoipApi
6 });
7
8-var sendRequest = function(message, responseCallback) {
9- // handles the response data
10- var finished = function(result) {
11- // print result to get data for test json files
12- // print(JSON.stringify(result));
13- //WorkerScript.sendMessage({
14- responseCallback({
15- action: message.action,
16- result: result
17- })
18- }
19- // handles errors
20- var onError = function(err) {
21- console.log(JSON.stringify(err, null, true));
22- //WorkerScript.sendMessage({ 'error': err})
23- responseCallback({ 'error': err})
24- }
25- // keep order of locations, sort results
26- var sortDataResults = function(locA, locB) {
27- return locA.db.id - locB.db.id;
28- }
29- // perform the api calls
30- if(message.action === "searchByName") {
31- WeatherApi.search("name", message.params, finished, onError);
32- } else if(message.action === "searchByPoint") {
33- WeatherApi.search("point", message.params, finished, onError);
34- } else if(message.action === "getGeoIp") {
35- WeatherApi.geoLookup(message.params, finished, onError);
36- } else if(message.action === "updateData") {
37- var locLength = message.params.locations.length,
38- locUpdated = 0,
39- result = [],
40- now = new Date().getTime();
41- if(locLength > 0) {
42- message.params.locations.forEach(function(loc) {
43- var updatedHnd = function (newData, cached) {
44- locUpdated += 1;
45- if(cached === true) {
46- newData["save"] = false;
47- } else {
48- newData["save"] = true;
49- newData["updated"] = new Date().getTime();
50- }
51- result.push(newData);
52- if(locUpdated === locLength) {
53- result.sort(sortDataResults);
54- finished(result);
55- }
56- },
57- params = {
58- location:loc.location,
59- db: loc.db,
60- units: 'metric',
61- service: message.params.service,
62- api_key: message.params.api_key,
63- interval: message.params.interval
64- },
65- secsFromLastFetch = (now-loc.updated)/1000;
66- if( message.params.force===true || loc.format !== RESPONSE_DATA_VERSION || secsFromLastFetch > params.interval){
67- // data older than 30min, location is new or data format is deprecated
68- WeatherApi.getLocationData(params, updatedHnd, onError);
69- } else {
70- console.log("["+loc.location.name+"] returning cached data, time from last fetch: "+secsFromLastFetch)
71- updatedHnd(loc, true);
72- }
73+/**
74+* following WorkerScript handles the data requests against the weather API.
75+* "message" requires a "params" property with the required params to perform
76+* the API call and an "action" property, which will be added also to the response.
77+*/
78+
79+if(typeof WorkerScript != "undefined") {
80+ WorkerScript.onMessage = function(message) {
81+ // handles the response data
82+ var finished = function(result) {
83+ // print result to get data for test json files
84+ // print(JSON.stringify(result));
85+ WorkerScript.sendMessage({
86+ action: message.action,
87+ result: result
88 })
89- } else {
90- finished(result);
91+ }
92+ // handles errors
93+ var onError = function(err) {
94+ console.log(JSON.stringify(err, null, true));
95+ WorkerScript.sendMessage({ 'error': err})
96+ }
97+ // keep order of locations, sort results
98+ var sortDataResults = function(locA, locB) {
99+ return locA.db.id - locB.db.id;
100+ }
101+ // perform the api calls
102+ if(message.action === "searchByName") {
103+ WeatherApi.search("name", message.params, finished, onError);
104+ } else if(message.action === "searchByPoint") {
105+ WeatherApi.search("point", message.params, finished, onError);
106+ } else if(message.action === "getGeoIp") {
107+ WeatherApi.geoLookup(message.params, finished, onError);
108+ } else if(message.action === "updateData") {
109+ var locLength = message.params.locations.length,
110+ locUpdated = 0,
111+ result = [],
112+ now = new Date().getTime();
113+ if(locLength > 0) {
114+ message.params.locations.forEach(function(loc) {
115+ var updatedHnd = function (newData, cached) {
116+ locUpdated += 1;
117+ if(cached === true) {
118+ newData["save"] = false;
119+ } else {
120+ newData["save"] = true;
121+ newData["updated"] = new Date().getTime();
122+ }
123+ result.push(newData);
124+ if(locUpdated === locLength) {
125+ result.sort(sortDataResults);
126+ finished(result);
127+ }
128+ },
129+ params = {
130+ location:loc.location,
131+ db: loc.db,
132+ units: 'metric',
133+ service: message.params.service,
134+ api_key: message.params.api_key,
135+ interval: message.params.interval
136+ },
137+ secsFromLastFetch = (now-loc.updated)/1000;
138+ if( message.params.force===true || loc.format !== RESPONSE_DATA_VERSION || secsFromLastFetch > params.interval){
139+ // data older than 30min, location is new or data format is deprecated
140+ WeatherApi.getLocationData(params, updatedHnd, onError);
141+ } else {
142+ console.log("["+loc.location.name+"] returning cached data, time from last fetch: "+secsFromLastFetch)
143+ updatedHnd(loc, true);
144+ }
145+ })
146+ } else {
147+ finished(result);
148+ }
149 }
150 }
151 }
152
153=== modified file 'app/ubuntu-weather-app.qml'
154--- app/ubuntu-weather-app.qml 2015-03-08 17:23:58 +0000
155+++ app/ubuntu-weather-app.qml 2015-03-14 15:20:24 +0000
156@@ -21,7 +21,6 @@
157 import Ubuntu.Components 1.1
158 import "components"
159 import "data" as Data
160-import "data/WeatherApi.js" as WeatherApi
161 import "data/key.js" as Key
162 import "ui"
163
164@@ -57,28 +56,35 @@
165 /*
166 (re)load the pages on completion
167 */
168- Component.onCompleted: refreshData();
169+ Component.onCompleted: {
170+ storage.getLocations(fillPages);
171+ refreshData();
172+ }
173
174 /*
175 Handle response data from data backend. Checks if a location
176 was updated and has to be stored again.
177 */
178- function responseDataHandler(messageObject) {
179- if(!messageObject.error) {
180- if(messageObject.action === "updateData") {
181- messageObject.result.forEach(function(loc) {
182- // replace location data in cache with refreshed values
183- if(loc["save"] === true) {
184- storage.updateLocation(loc.db.id, loc);
185- }
186- });
187- //print(JSON.stringify(messageObject.result));
188- fillPages(messageObject.result);
189+ WorkerScript {
190+ id: lookupWorker
191+ source: Qt.resolvedUrl("./data/WeatherApi.js")
192+ onMessage: {
193+ if(!messageObject.error) {
194+ if(messageObject.action === "updateData") {
195+ messageObject.result.forEach(function(loc) {
196+ // replace location data in cache with refreshed values
197+ if(loc["save"] === true) {
198+ storage.updateLocation(loc.db.id, loc);
199+ }
200+ });
201+ //print(JSON.stringify(messageObject.result));
202+ fillPages(messageObject.result);
203+ }
204+ } else {
205+ console.log(messageObject.error.msg+" / "+messageObject.error.request.url)
206+ // TODO error handling
207 }
208- } else {
209- console.log(messageObject.error.msg+" / "+messageObject.error.request.url)
210- // TODO error handling
211- }
212+ }
213 }
214
215 /* Fill the location pages with their data. */
216@@ -98,7 +104,7 @@
217 storage.getLocations(fillPages);
218 } else {
219 storage.getLocations(function(locations) {
220- WeatherApi.sendRequest({
221+ lookupWorker.sendMessage({
222 action: "updateData",
223 params: {
224 locations: locations,
225@@ -107,7 +113,7 @@
226 api_key: Key.twcKey,
227 interval: settings.refreshInterval
228 }
229- }, responseDataHandler)
230+ })
231 });
232 }
233 }
234
235=== modified file 'app/ui/AddLocationPage.qml'
236--- app/ui/AddLocationPage.qml 2015-03-06 14:15:29 +0000
237+++ app/ui/AddLocationPage.qml 2015-03-14 15:20:24 +0000
238@@ -122,23 +122,28 @@
239 function loadFromProvider(search) {
240 clearModelForLoading()
241
242- WeatherApi.sendRequest({
243+ lookupWorker.sendMessage({
244 action: "searchByName",
245 params: {
246 name: search,
247 units: "metric"
248 }
249- }, searchResponseHandler)
250+ });
251 }
252
253- function searchResponseHandler(msgObject) {
254- if (!msgObject.error) {
255- appendCities(msgObject.result.locations)
256- } else {
257- citiesModel.httpError = true
258+
259+ WorkerScript {
260+ id: lookupWorker
261+ source: Qt.resolvedUrl("../data/WeatherApi.js")
262+ onMessage: {
263+ if (!messageObject.error) {
264+ appendCities(messageObject.result.locations)
265+ } else {
266+ citiesModel.httpError = true
267+ }
268+
269+ citiesModel.loading = false
270 }
271-
272- citiesModel.loading = false
273 }
274
275 ListView {
276
277=== modified file 'po/com.ubuntu.weather.pot'
278--- po/com.ubuntu.weather.pot 2015-03-06 14:15:29 +0000
279+++ po/com.ubuntu.weather.pot 2015-03-14 15:20:24 +0000
280@@ -8,7 +8,7 @@
281 msgstr ""
282 "Project-Id-Version: ubuntu-weather-app\n"
283 "Report-Msgid-Bugs-To: \n"
284-"POT-Creation-Date: 2015-03-06 15:08+0100\n"
285+"POT-Creation-Date: 2015-03-14 11:54+0100\n"
286 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
287 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
288 "Language-Team: LANGUAGE <LL@li.org>\n"
289@@ -53,19 +53,19 @@
290 msgid "Search city"
291 msgstr ""
292
293-#: ../app/ui/AddLocationPage.qml:249
294+#: ../app/ui/AddLocationPage.qml:254
295 msgid "No city found"
296 msgstr ""
297
298-#: ../app/ui/AddLocationPage.qml:262
299+#: ../app/ui/AddLocationPage.qml:267
300 msgid "Couldn't load weather data, please try later again!"
301 msgstr ""
302
303-#: ../app/ui/AddLocationPage.qml:272
304+#: ../app/ui/AddLocationPage.qml:277
305 msgid "Location already added."
306 msgstr ""
307
308-#: ../app/ui/AddLocationPage.qml:275
309+#: ../app/ui/AddLocationPage.qml:280
310 msgid "OK"
311 msgstr ""
312

Subscribers

People subscribed via source and target branches

to all changes: