Merge lp:~ubuntu-weather-dev/ubuntu-weather-app/new-weather-api into lp:ubuntu-weather-app
- new-weather-api
- Merge into reboot
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Victor Thompson | ||||
Approved revision: | 237 | ||||
Merged at revision: | 242 | ||||
Proposed branch: | lp:~ubuntu-weather-dev/ubuntu-weather-app/new-weather-api | ||||
Merge into: | lp:ubuntu-weather-app | ||||
Diff against target: |
395 lines (+167/-91) 4 files modified
app/data/WeatherApi.js (+151/-87) app/ui/LocationPane.qml (+1/-1) debian/changelog (+14/-2) manifest.json.in (+1/-1) |
||||
To merge this branch: | bzr merge lp:~ubuntu-weather-dev/ubuntu-weather-app/new-weather-api | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jenkins Bot | continuous-integration | Approve | |
Victor Thompson | Approve | ||
Andrew Hayzen | Needs Information | ||
Review via email: mp+289584@code.launchpad.net |
Commit message
* Update to use new weather API
* Change the trimAPIKey function so it only trims the API Key
* Release 3.2 and bump version to 3.3
Description of the change
Move to the new weather api.
For reference, here is the commit to use the new API in the scope: http://
Andrew Hayzen (ahayzen) wrote : | # |
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:232
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Victor Thompson (vthompson) wrote : | # |
Thanks for finishing this off, Andrew!!
I ran AP and all tests pass. Code changes look fine so far, but one thing we might want to take the opportunity to do now (otherwise we may never do so) is to audit our code coverage in WeatherApi.js and remove any dead code so we don't do needless maintenance on unused code in the future. QtCreator doesn't seem to have a coverage tool, but there seem to be numerous third party tools and qml plugins that might be helpful. Maybe just a JS only coverage tool would be sufficient.
I've been testing this change out and have not hit any regressions thus far. Unless we want to look at removing any dead code, I think this is ready for QA.
TODO:
1. Update changelog
2. Bump version number?
3. Potentially look at removing any dead code
- 233. By Andrew Hayzen
-
* Release 3.2 and update changelog
- 234. By Andrew Hayzen
-
* Comment out 'dead code' for now
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:234
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Andrew Hayzen (ahayzen) wrote : | # |
1) Done
2) Done bumped the version and put the relevant stuff in the sections
3) I've commented out the 'dead code' where it uses the location code for TWC, let me know if you want me to remove
Also, I've spotted one todo on line 44 of the diff
+ var partData = dataObj["metric"] || dataObj["imperial"] || dataObj; // TODO: be more intelligent?
Do you think this is OK? or should it be more like?
if (there is metric) { use metric } else if (there is imperial) { use imperial } else { fallback }
Futhermore the lines below have things like calcFahrenheit() which convert from metric->imperial, so it assumes the data is metric, maybe we should remove the imperial option... so just
+ var partData = dataObj["metric"] || dataObj;
I think i've talked myself into changing it to that :')
- 235. By Andrew Hayzen
-
* Remove dead code
* Fix up imperial todo
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:235
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Victor Thompson (vthompson) wrote : | # |
This isn't a regression, as I've noticed it before--TWC always displays the high temp as the current temp as soon as the high has been reached. Maybe we're using the API incorrectly to determine today's high? Since it's not a regression, I'm fine leaving it as-is... but we should probably file a bug or add a comment to the code with a TODO to investigate. Bug would probably be preferred.
Victor Thompson (vthompson) wrote : | # |
Actually, maybe it's not a bug. Weather.com seems to do the same. Maybe that's their way of indicating that the temp won't rise?
- 236. By Andrew Hayzen
-
* Fix for max_temp being null in TWC causing 'high' to be 0 and therefore lower than the 'low', now show a "-"
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:236
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
- 237. By Andrew Hayzen
-
* Use "en dash"
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:237
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Victor Thompson (vthompson) wrote : | # |
Ok, this looks good now. Approve!
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:237
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'app/data/WeatherApi.js' | |||
2 | --- app/data/WeatherApi.js 2015-10-21 02:16:50 +0000 | |||
3 | +++ app/data/WeatherApi.js 2016-06-04 21:12:20 +0000 | |||
4 | @@ -100,15 +100,20 @@ | |||
5 | 100 | } | 100 | } |
6 | 101 | 101 | ||
7 | 102 | 102 | ||
9 | 103 | // Remove anything including and after APPID in the given term | 103 | // Remove just the API key |
10 | 104 | function trimAPIKey(data) { | 104 | function trimAPIKey(data) { |
13 | 105 | var owm = data.indexOf("&APPID="); | 105 | var owm = data.indexOf("APPID="); |
14 | 106 | var twc = data.indexOf("&key="); | 106 | var twc = data.indexOf("apiKey="); |
15 | 107 | |||
16 | 108 | // Key length is 32 char for both APIs | ||
17 | 109 | var keySize = 32; | ||
18 | 107 | 110 | ||
19 | 108 | if (owm > -1) { | 111 | if (owm > -1) { |
21 | 109 | data = data.substr(0, owm); | 112 | var replace = data.substr(owm+6, keySize); |
22 | 113 | data = data.replace(replace,"") | ||
23 | 110 | } else if (twc > -1) { | 114 | } else if (twc > -1) { |
25 | 111 | data = data.substr(0, twc); | 115 | var replace = data.substr(twc+7, keySize); |
26 | 116 | data = data.replace(replace,"") | ||
27 | 112 | } | 117 | } |
28 | 113 | 118 | ||
29 | 114 | return data; | 119 | return data; |
30 | @@ -400,7 +405,7 @@ | |||
31 | 400 | /** | 405 | /** |
32 | 401 | provides neccessary methods for requesting and preparing data from OpenWeatherMap.org | 406 | provides neccessary methods for requesting and preparing data from OpenWeatherMap.org |
33 | 402 | */ | 407 | */ |
35 | 403 | var _baseUrl = "http://wxdata.weather.com/wxdata/"; | 408 | var _baseUrl = "https://api.weather.com/"; |
36 | 404 | // | 409 | // |
37 | 405 | var _serviceName = "weatherchannel"; | 410 | var _serviceName = "weatherchannel"; |
38 | 406 | // | 411 | // |
39 | @@ -457,65 +462,70 @@ | |||
40 | 457 | }; | 462 | }; |
41 | 458 | // | 463 | // |
42 | 459 | function _buildDataPoint(date, dataObj) { | 464 | function _buildDataPoint(date, dataObj) { |
44 | 460 | var data = dataObj["Observation"] || dataObj, | 465 | var partData = dataObj["metric"] || dataObj; |
45 | 466 | var data = dataObj["observation"] || dataObj, | ||
46 | 461 | result = { | 467 | result = { |
48 | 462 | timestamp: data.date || data.dateTime, | 468 | timestamp: data.fcst_valid, |
49 | 463 | date: date, | 469 | date: date, |
50 | 464 | metric: { | 470 | metric: { |
54 | 465 | temp: data.temp, | 471 | temp: partData.temp, |
55 | 466 | tempFeels: data.feelsLike, | 472 | tempFeels: partData.feels_like, |
56 | 467 | windSpeed: data.wSpeed | 473 | windSpeed: partData.wspd |
57 | 468 | }, | 474 | }, |
58 | 469 | imperial: { | 475 | imperial: { |
62 | 470 | temp: calcFahrenheit(data.temp), | 476 | temp: calcFahrenheit(partData.temp), |
63 | 471 | tempFeels: calcFahrenheit(data.feelsLike), | 477 | tempFeels: calcFahrenheit(partData.feels_like), |
64 | 472 | windSpeed: convertKphToMph(data.wSpeed) | 478 | windSpeed: convertKphToMph(partData.wspd) |
65 | 473 | }, | 479 | }, |
66 | 474 | precipType: (data.precip_type !== undefined) ? data.precip_type : null, | 480 | precipType: (data.precip_type !== undefined) ? data.precip_type : null, |
67 | 475 | propPrecip: (data.pop !== undefined) ? data.pop : null, | 481 | propPrecip: (data.pop !== undefined) ? data.pop : null, |
75 | 476 | humidity: data.humid, | 482 | humidity: partData.rh, |
76 | 477 | pressure: data.pressure, | 483 | pressure: partData.mslp, |
77 | 478 | windDeg: data.wDir, | 484 | windDeg: data.wdir, |
78 | 479 | windDir: data.wDirText, | 485 | windDir: data.wdir_cardinal, |
79 | 480 | icon: _iconMap[(data.wxIcon||data.icon)], | 486 | icon: _iconMap[data.icon_code], |
80 | 481 | condition: data.text || data.wDesc, | 487 | condition: data.phrase_32char, |
81 | 482 | uv: data.uv | 488 | uv: data.uv_index |
82 | 483 | }; | 489 | }; |
85 | 484 | if(_iconMap[data.wxIcon||data.icon] === undefined) { | 490 | |
86 | 485 | print("ICON MISSING POINT: "+(data.wxIcon||data.icon)+" "+result.condition) | 491 | if (_iconMap[data.icon_code] === undefined) { |
87 | 492 | print("ICON MISSING POINT: " + data.icon_code + " " + result.condition) | ||
88 | 486 | } | 493 | } |
89 | 494 | |||
90 | 487 | return result; | 495 | return result; |
91 | 488 | } | 496 | } |
92 | 489 | // | 497 | // |
93 | 490 | function _buildDayFormat(date, data, now) { | 498 | function _buildDayFormat(date, data, now) { |
95 | 491 | var partData = (now > data.validDate || data.day === undefined) ? data.night : data.day, | 499 | var partData = (now > data.fcst_valid || data.day === undefined) ? data.night : data.day, |
96 | 492 | result = { | 500 | result = { |
97 | 493 | date: date, | 501 | date: date, |
99 | 494 | timestamp: data.validDate, | 502 | timestamp: data.fcst_valid, |
100 | 495 | metric: { | 503 | metric: { |
104 | 496 | tempMin: data.minTemp, | 504 | tempMin: data.min_temp, |
105 | 497 | tempMax: data.maxTemp, | 505 | tempMax: data.max_temp !== null ? data.max_temp : undefined, |
106 | 498 | windSpeed: partData.wSpeed | 506 | windSpeed: partData.wspd |
107 | 499 | }, | 507 | }, |
108 | 500 | imperial: { | 508 | imperial: { |
112 | 501 | tempMin: calcFahrenheit(data.minTemp), | 509 | tempMin: calcFahrenheit(data.min_temp), |
113 | 502 | tempMax: calcFahrenheit(data.maxTemp !== undefined ? data.maxTemp : data.minTemp), | 510 | tempMax: data.max_temp !== null && data.max_temp !== undefined ? calcFahrenheit(data.max_temp) : undefined, |
114 | 503 | windSpeed: convertKphToMph(partData.wSpeed) | 511 | windSpeed: convertKphToMph(partData.wspd) |
115 | 504 | }, | 512 | }, |
116 | 505 | precipType: partData.precip_type, | 513 | precipType: partData.precip_type, |
117 | 506 | propPrecip: partData.pop, | 514 | propPrecip: partData.pop, |
118 | 507 | pressure: null, | 515 | pressure: null, |
125 | 508 | humidity: partData.humid, | 516 | humidity: partData.rh, |
126 | 509 | icon: _iconMap[partData.icon], | 517 | icon: _iconMap[partData.icon_code], |
127 | 510 | condition: partData.phrase, | 518 | condition: partData.phrase_32char, |
128 | 511 | windDeg: partData.wDir, | 519 | windDeg: partData.wdir, |
129 | 512 | windDir: partData.wDirText, | 520 | windDir: partData.wdir_cardinal, |
130 | 513 | uv: partData.uv, | 521 | uv: partData.uv_index, |
131 | 514 | hourly: [] | 522 | hourly: [] |
132 | 515 | } | 523 | } |
135 | 516 | if(_iconMap[partData.icon] === undefined) { | 524 | |
136 | 517 | print("ICON MISSING DAY: "+partData.icon+" "+result.condition) | 525 | if (_iconMap[partData.icon_code] === undefined) { |
137 | 526 | print("ICON MISSING DAY: " + partData.icon_code + " " + result.condition) | ||
138 | 518 | } | 527 | } |
139 | 528 | |||
140 | 519 | return result; | 529 | return result; |
141 | 520 | } | 530 | } |
142 | 521 | // | 531 | // |
143 | @@ -527,35 +537,43 @@ | |||
144 | 527 | nowMs = parseInt(now/1000), | 537 | nowMs = parseInt(now/1000), |
145 | 528 | localNow = getLocationTime(now+offset), | 538 | localNow = getLocationTime(now+offset), |
146 | 529 | data = { | 539 | data = { |
152 | 530 | "location": combinedData[0]["Location"], | 540 | "location": combinedData["current"]["metadata"], |
153 | 531 | "daily": combinedData[0]["DailyForecasts"], | 541 | "daily": combinedData["daily"]["forecasts"], |
154 | 532 | "forecast": combinedData[0]["HourlyForecasts"], | 542 | "forecast": combinedData["forecast"]["forecasts"], |
155 | 533 | "current": combinedData[0]["StandardObservation"], | 543 | "current": combinedData["current"]["observation"], |
151 | 534 | "sunRiseSet": combinedData[0]["SunRiseSet"], | ||
156 | 535 | }; | 544 | }; |
157 | 536 | print("["+location.name+"] "+JSON.stringify(localNow)); | 545 | print("["+location.name+"] "+JSON.stringify(localNow)); |
158 | 537 | // add openweathermap id for faster responses | 546 | // add openweathermap id for faster responses |
159 | 538 | if(location.services && !location.services[_serviceName] && data["location"].key) { | 547 | if(location.services && !location.services[_serviceName] && data["location"].key) { |
160 | 539 | location.services[_serviceName] = data["location"].key | 548 | location.services[_serviceName] = data["location"].key |
162 | 540 | } | 549 | } |
163 | 541 | // only 5 days of forecast for TWC | 550 | // only 5 days of forecast for TWC |
165 | 542 | for(var x=0;x<5;x++) { | 551 | for(var x=0; x<5; x++) { |
166 | 543 | var dayData = data["daily"][x], | 552 | var dayData = data["daily"][x], |
169 | 544 | date = getLocationTime(((dayData.validDate*1000)-1000)+offset); // minus 1 sec to handle +/-12 TZ | 553 | date = getLocationTime(((dayData.fcst_valid * 1000) - 1000) + offset); // minus 1 sec to handle +/-12 TZ |
170 | 545 | var sunRiseSet = data["sunRiseSet"][x]; | 554 | |
171 | 555 | // Sun{rise,set} is in ISOString format so use getTime() to convert | ||
172 | 556 | var sunrise = new Date(dayData.sunrise).getTime(), | ||
173 | 557 | sunset = new Date(dayData.sunset).getTime(); | ||
174 | 546 | day = date.year+"-"+date.month+"-"+date.date; | 558 | day = date.year+"-"+date.month+"-"+date.date; |
177 | 547 | if(!todayDate) { | 559 | |
178 | 548 | if(localNow.year+"-"+localNow.month+"-"+localNow.date > day) { | 560 | if (!todayDate) { |
179 | 561 | if (localNow.year + "-" + localNow.month + "-" + localNow.date > day) { | ||
180 | 549 | // skip "yesterday" | 562 | // skip "yesterday" |
181 | 550 | continue; | 563 | continue; |
182 | 551 | } | 564 | } |
183 | 565 | |||
184 | 552 | todayDate = date; | 566 | todayDate = date; |
185 | 553 | } | 567 | } |
186 | 568 | |||
187 | 554 | tmpResult[day] = _buildDayFormat(date, dayData, nowMs); | 569 | tmpResult[day] = _buildDayFormat(date, dayData, nowMs); |
188 | 570 | |||
189 | 555 | var timezoneOffset = new Date().getTimezoneOffset(); | 571 | var timezoneOffset = new Date().getTimezoneOffset(); |
190 | 556 | var timesOffset = (location.timezone && location.timezone.dstOffset !== undefined) ? (location.timezone.dstOffset*60 + timezoneOffset)*60*1000: 0 | 572 | var timesOffset = (location.timezone && location.timezone.dstOffset !== undefined) ? (location.timezone.dstOffset*60 + timezoneOffset)*60*1000: 0 |
193 | 557 | var sunrise = new Date(sunRiseSet.rise*1000 + timesOffset); | 573 | |
194 | 558 | var sunset = new Date(sunRiseSet.set*1000 + timesOffset); | 574 | sunrise = new Date(sunrise + timesOffset); |
195 | 575 | sunset = new Date(sunset + timesOffset); | ||
196 | 576 | |||
197 | 559 | var options = { timeZone: location.timezone.timeZoneId, timeZoneName: 'long' }; | 577 | var options = { timeZone: location.timezone.timeZoneId, timeZoneName: 'long' }; |
198 | 560 | tmpResult[day].sunrise = sunrise.toLocaleTimeString(Qt.locale().name, options); | 578 | tmpResult[day].sunrise = sunrise.toLocaleTimeString(Qt.locale().name, options); |
199 | 561 | tmpResult[day].sunset = sunset.toLocaleTimeString(Qt.locale().name, options); | 579 | tmpResult[day].sunset = sunset.toLocaleTimeString(Qt.locale().name, options); |
200 | @@ -563,8 +581,9 @@ | |||
201 | 563 | // | 581 | // |
202 | 564 | if(data["forecast"] !== undefined) { | 582 | if(data["forecast"] !== undefined) { |
203 | 565 | data["forecast"].forEach(function(hourData) { | 583 | data["forecast"].forEach(function(hourData) { |
205 | 566 | var dateData = getLocationTime((hourData.dateTime*1000)+offset), | 584 | var dateData = getLocationTime((hourData.fcst_valid * 1000) + offset), |
206 | 567 | day = dateData.year+"-"+dateData.month+"-"+dateData.date; | 585 | day = dateData.year+"-"+dateData.month+"-"+dateData.date; |
207 | 586 | |||
208 | 568 | if(tmpResult[day]) { | 587 | if(tmpResult[day]) { |
209 | 569 | tmpResult[day]["hourly"].push(_buildDataPoint(dateData, hourData)); | 588 | tmpResult[day]["hourly"].push(_buildDataPoint(dateData, hourData)); |
210 | 570 | } | 589 | } |
211 | @@ -591,48 +610,93 @@ | |||
212 | 591 | return result; | 610 | return result; |
213 | 592 | } | 611 | } |
214 | 593 | // | 612 | // |
225 | 594 | function _getUrl(params) { | 613 | function _getUrls(params) { |
226 | 595 | var url, serviceId, | 614 | var baseParams = { |
227 | 596 | baseParams = { | 615 | units: (params.units === "metric") ? "m" : "e", |
228 | 597 | key: params.twc_api_key, | 616 | language: Qt.locale().name.replace("_","-"), |
229 | 598 | units: (params.units === "metric") ? "m" : "e", | 617 | apiKey: params.twc_api_key, |
230 | 599 | locale: Qt.locale().name, | 618 | }; |
231 | 600 | hours: "48", | 619 | var commands = { |
232 | 601 | }, | 620 | "geocode": "v1/geocode/", |
233 | 602 | commands = { | 621 | }; |
234 | 603 | "mobileaggregation": "mobile/mobagg/", | 622 | var urls = { |
235 | 623 | current: "", | ||
236 | 624 | daily: "", | ||
237 | 625 | hourly: "", | ||
238 | 626 | }; | ||
239 | 627 | |||
240 | 628 | // FIXME: only use coords for now and not location codes (UKXX0085) | ||
241 | 629 | if (params.location.coord) { | ||
242 | 630 | var coord = { | ||
243 | 631 | lat: params.location.coord.lat, | ||
244 | 632 | lng: params.location.coord.lon | ||
245 | 604 | }; | 633 | }; |
253 | 605 | if(params.location.services && params.location.services[_serviceName]) { | 634 | |
254 | 606 | serviceId = encodeURIComponent(params.location.services[_serviceName]); | 635 | urls.current = _baseUrl + commands["geocode"] + |
255 | 607 | url = _baseUrl+commands["mobileaggregation"]+serviceId+".js?"+parameterize(baseParams); | 636 | coord.lat + "/" + coord.lng + |
256 | 608 | } else if (params.location.coord) { | 637 | "/observations/current.json?" + |
257 | 609 | var coord = {lat: params.location.coord.lat, lng: params.location.coord.lon}; | 638 | parameterize(baseParams); |
258 | 610 | url = _baseUrl+commands["mobileaggregation"]+"get.js?"+parameterize(baseParams)+"&"+ | 639 | urls.daily = _baseUrl + commands["geocode"] + |
259 | 611 | parameterize(coord); | 640 | coord.lat + "/" + coord.lng + |
260 | 641 | "/forecast/daily/5day.json?" + | ||
261 | 642 | parameterize(baseParams); | ||
262 | 643 | urls.hourly = _baseUrl + commands["geocode"] + | ||
263 | 644 | coord.lat + "/" + coord.lng + | ||
264 | 645 | "/forecast/hourly/48hour.json?" + | ||
265 | 646 | parameterize(baseParams); | ||
266 | 612 | } | 647 | } |
268 | 613 | return url; | 648 | |
269 | 649 | return urls; | ||
270 | 614 | } | 650 | } |
271 | 615 | // | 651 | // |
272 | 616 | return { | 652 | return { |
273 | 617 | getData: function(params, apiCaller, onSuccess, onError) { | 653 | getData: function(params, apiCaller, onSuccess, onError) { |
275 | 618 | var url = _getUrl(params), | 654 | var urls = _getUrls(params), |
276 | 619 | handlerMap = { | 655 | handlerMap = { |
287 | 620 | all: { type: "all", url: url} | 656 | current: { |
288 | 621 | }, | 657 | type: "current", |
289 | 622 | response = { | 658 | url: urls.current |
290 | 623 | location: params.location, | 659 | }, |
291 | 624 | db: (params.db) ? params.db : null, | 660 | daily: { |
292 | 625 | format: RESPONSE_DATA_VERSION | 661 | type: "daily", |
293 | 626 | }, | 662 | url: urls.daily |
294 | 627 | addDataToResponse = (function(request, data) { | 663 | }, |
295 | 628 | var formattedResult; | 664 | forecast: { |
296 | 629 | response["data"] = formatResult(data, params.location); | 665 | type: "forecast", |
297 | 666 | url: urls.hourly | ||
298 | 667 | } | ||
299 | 668 | }, | ||
300 | 669 | response = { | ||
301 | 670 | location: params.location, | ||
302 | 671 | db: (params.db) ? params.db : null, | ||
303 | 672 | format: RESPONSE_DATA_VERSION | ||
304 | 673 | }, | ||
305 | 674 | respData = {}, | ||
306 | 675 | addDataToResponse = (function(request, data) { | ||
307 | 676 | var formattedResult; | ||
308 | 677 | respData[request.type] = data; | ||
309 | 678 | |||
310 | 679 | if (respData["current"] !== undefined && | ||
311 | 680 | respData["forecast"] !== undefined && | ||
312 | 681 | respData["daily"] !== undefined) { | ||
313 | 682 | |||
314 | 683 | response["data"] = formatResult(respData, params.location); | ||
315 | 630 | onSuccess(response); | 684 | onSuccess(response); |
321 | 631 | }), | 685 | } |
322 | 632 | onErrorHandler = (function(err) { | 686 | }), |
323 | 633 | onError(err); | 687 | onErrorHandler = (function(err) { |
324 | 634 | }); | 688 | onError(err); |
325 | 635 | apiCaller(handlerMap.all, addDataToResponse, onErrorHandler); | 689 | }), |
326 | 690 | retryHandler = (function(err) { | ||
327 | 691 | console.log("retry of " + trimAPIKey(err.request.url)); | ||
328 | 692 | var retryFunc = handlerMap[err.request.type]; | ||
329 | 693 | |||
330 | 694 | apiCaller(retryFunc, addDataToResponse, onErrorHandler); | ||
331 | 695 | }); | ||
332 | 696 | |||
333 | 697 | apiCaller(handlerMap.current, addDataToResponse, retryHandler); | ||
334 | 698 | apiCaller(handlerMap.forecast, addDataToResponse, retryHandler); | ||
335 | 699 | apiCaller(handlerMap.daily, addDataToResponse, retryHandler); | ||
336 | 636 | } | 700 | } |
337 | 637 | } | 701 | } |
338 | 638 | })(); | 702 | })(); |
339 | 639 | 703 | ||
340 | === modified file 'app/ui/LocationPane.qml' | |||
341 | --- app/ui/LocationPane.qml 2016-02-06 01:17:07 +0000 | |||
342 | +++ app/ui/LocationPane.qml 2016-06-04 21:12:20 +0000 | |||
343 | @@ -150,7 +150,7 @@ | |||
344 | 150 | return { | 150 | return { |
345 | 151 | day: formatTimestamp(data.date, 'dddd'), | 151 | day: formatTimestamp(data.date, 'dddd'), |
346 | 152 | low: Math.round(data[tempUnits].tempMin).toString() + settings.tempScale, | 152 | low: Math.round(data[tempUnits].tempMin).toString() + settings.tempScale, |
348 | 153 | high: (data[tempUnits].tempMax !== undefined) ? Math.round(data[tempUnits].tempMax).toString() + settings.tempScale : "", | 153 | high: (data[tempUnits].tempMax !== undefined) ? Math.round(data[tempUnits].tempMax).toString() + settings.tempScale : "–", |
349 | 154 | image: (data.icon !== undefined && iconMap[data.icon] !== undefined) ? iconMap[data.icon] : "", | 154 | image: (data.icon !== undefined && iconMap[data.icon] !== undefined) ? iconMap[data.icon] : "", |
350 | 155 | condition: emptyIfUndefined(data.condition), | 155 | condition: emptyIfUndefined(data.condition), |
351 | 156 | chanceOfPrecip: emptyIfUndefined(data.propPrecip, "%"), | 156 | chanceOfPrecip: emptyIfUndefined(data.propPrecip, "%"), |
352 | 157 | 157 | ||
353 | === modified file 'debian/changelog' | |||
354 | --- debian/changelog 2016-03-26 16:38:54 +0000 | |||
355 | +++ debian/changelog 2016-06-04 21:12:20 +0000 | |||
356 | @@ -1,4 +1,16 @@ | |||
358 | 1 | ubuntu-weather-app (3.2) UNRELEASED; urgency=medium | 1 | ubuntu-weather-app (3.3ubuntu1) UNRELEASED; urgency=medium |
359 | 2 | |||
360 | 3 | [ Andrew Hayzen ] | ||
361 | 4 | * Release 3.2 and bump version to 3.3 | ||
362 | 5 | * Update to use new weather API | ||
363 | 6 | |||
364 | 7 | [ Victor Thompson ] | ||
365 | 8 | * Update to use new weather API | ||
366 | 9 | * Change the trimAPIKey function so it only trims the API Key | ||
367 | 10 | |||
368 | 11 | -- Andrew Hayzen <ahayzen@gmail.com> Sat, 04 Jun 2016 18:31:29 +0100 | ||
369 | 12 | |||
370 | 13 | ubuntu-weather-app (3.2ubuntu1) vivid; urgency=medium | ||
371 | 2 | 14 | ||
372 | 3 | [ Andrew Hayzen ] | 15 | [ Andrew Hayzen ] |
373 | 4 | * Release 3.1 and bump version to 3.2 | 16 | * Release 3.1 and bump version to 3.2 |
374 | @@ -20,7 +32,7 @@ | |||
375 | 20 | [ Vamshi Balanaga ] | 32 | [ Vamshi Balanaga ] |
376 | 21 | * Added test to swipe between location tabs on home page (LP: #1452492) | 33 | * Added test to swipe between location tabs on home page (LP: #1452492) |
377 | 22 | 34 | ||
379 | 23 | -- Andrew Hayzen <ahayzen@gmail.com> Thu, 03 Dec 2015 15:20:49 +0000 | 35 | -- Andrew Hayzen <ahayzen@gmail.com> Sat, 04 Jun 2016 18:30:00 +0100 |
380 | 24 | 36 | ||
381 | 25 | ubuntu-weather-app (3.1ubuntu1) vivid; urgency=medium | 37 | ubuntu-weather-app (3.1ubuntu1) vivid; urgency=medium |
382 | 26 | 38 | ||
383 | 27 | 39 | ||
384 | === modified file 'manifest.json.in' | |||
385 | --- manifest.json.in 2016-02-28 22:15:28 +0000 | |||
386 | +++ manifest.json.in 2016-06-04 21:12:20 +0000 | |||
387 | @@ -12,7 +12,7 @@ | |||
388 | 12 | "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>", | 12 | "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>", |
389 | 13 | "name": "@PROJECT_NAME@", | 13 | "name": "@PROJECT_NAME@", |
390 | 14 | "title": "Weather", | 14 | "title": "Weather", |
392 | 15 | "version": "3.2.@BZR_REVNO@", | 15 | "version": "3.3.@BZR_REVNO@", |
393 | 16 | "x-source": { | 16 | "x-source": { |
394 | 17 | "vcs-bzr": "@BZR_SOURCE@", | 17 | "vcs-bzr": "@BZR_SOURCE@", |
395 | 18 | "vcs-bzr-revno": "@BZR_REVNO@" | 18 | "vcs-bzr-revno": "@BZR_REVNO@" |
OK, this is the first iteration of a 'working' solution, still needs lots of testing :-) Basically as TWC now, from what I understand, requires us to do multiple url calls to get the current, daily and hourly data. I've copied the OWM code and modified it to match the TWC api (as OWM is similar in the fact that it requires multiple url calls).
Main inline comment so far is:
Not sure what todo here? This is for "weather codes" such as, UKXX0085, which we were using, but I cannot see that in the new API? Currently the 1==2 is forcing it to use coordinate based lookups.
Also was the search using TWC? I need to check if that needs to be updated?