diff options
author | Martijn Kaijser <mcm.kaijser@gmail.com> | 2012-11-14 22:56:35 +0100 |
---|---|---|
committer | Martijn Kaijser <mcm.kaijser@gmail.com> | 2012-11-14 22:56:35 +0100 |
commit | c09acdd7e9edb491012f3ad26c8c7fc9b89dc968 (patch) | |
tree | 15ce133c4b6dd10355c6eb05ed3cbfae6d80c390 /addons | |
parent | 363cc4ba6c3b972452f881879ccb2fef5e82ed42 (diff) |
[weather] sync wunderground with repo
Diffstat (limited to 'addons')
-rw-r--r-- | addons/weather.wunderground/README.txt | 187 | ||||
-rw-r--r-- | addons/weather.wunderground/addon.xml | 7 | ||||
-rw-r--r-- | addons/weather.wunderground/changelog.txt | 73 | ||||
-rw-r--r-- | addons/weather.wunderground/default.py | 633 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/language/Belarusian/strings.po | 8 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/language/English/strings.po | 144 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/language/Spanish (Argentina)/strings.po | 34 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/lib/utilities.py | 145 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/lib/wunderground/__init__.py | 1 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/lib/wunderground/wunderground.py | 44 | ||||
-rw-r--r-- | addons/weather.wunderground/resources/logo/logo.jpg | bin | 0 -> 28687 bytes | |||
-rw-r--r-- | addons/weather.wunderground/resources/settings.xml | 24 |
12 files changed, 1169 insertions, 131 deletions
diff --git a/addons/weather.wunderground/README.txt b/addons/weather.wunderground/README.txt new file mode 100644 index 0000000000..39834e5754 --- /dev/null +++ b/addons/weather.wunderground/README.txt @@ -0,0 +1,187 @@ +--------------------------- +DEFAULT XBMC WEATHER LABELS +--------------------------- + + +CURRENT +------- +Current.Location +Current.Condition +Current.Temperature +Current.Wind +Current.WindDirection +Current.Humidity +Current.FeelsLike +Current.UVIndex +Current.DewPoint +Current.OutlookIcon +Current.FanartCode + + +DAY [0-6] +--------- +Day%i.Title +Day%i.HighTemp +Day%i.LowTemp +Day%i.Outlook +Day%i.OutlookIcon +Day%i.FanartCode + + +WEATHERPROVIDER +---------------- +WeatherProvider + + + + +------------------------- +ADDITIONAL WEATHER LABELS +------------------------- + + +FORECAST +-------- +Forecast.IsFetched +Forecast.City +Forecast.State +Forecast.Country +Forecast.Updated + + +CURRENT +------- +Current.IsFetched +Current.WindDegree +Current.SolarRadiation +Current.Pressure +Current.Precipitation +Current.HeatIndex +Current.WindChill +Current.Visibility +Current.WindGust + + +TODAY +----- +Today.IsFetched +Today.Sunrise +Today.Sunset +Today.MoonPhase +Today.AvgHighTemperature +Today.AvgLowTemperature +Today.RecordHighTemperature +Today.RecordLowTemperature +Today.RecordHighYear +Today.RecordLowYear + + +DAILY [1-10] +------------ +Daily.IsFetched +Daily.%i.LongDay +Daily.%i.ShortDay +Daily.%i.LongDate +Daily.%i.ShortDate +Daily.%i.Outlook +Daily.%i.OutlookIcon +Daily.%i.FanartCode +Daily.%i.WindSpeed +Daily.%i.MaxWind +Daily.%i.WindDirection +Daily.%i.ShortWindDirection +Daily.%i.WindDegree +Daily.%i.Humidity +Daily.%i.MinHumidity +Daily.%i.MaxHumidity +Daily.%i.HighTemperature +Daily.%i.LowTemperature +Daily.%i.LongOutlookDay +Daily.%i.LongOutlookNight +Daily.%i.Precipitation +Daily.%i.Snow +Daily.%i.ChancePrecipitation + + +WEEKEND [1-3] +------------- +Weekend.IsFetched +Weekend.%i.LongDay +Weekend.%i.ShortDay +Weekend.%i.LongDate +Weekend.%i.ShortDate +Weekend.%i.Outlook +Weekend.%i.OutlookIcon +Weekend.%i.FanartCode +Weekend.%i.WindSpeed +Weekend.%i.MaxWind +Weekend.%i.WindDirection +Weekend.%i.ShortWindDirection +Weekend.%i.WindDegree +Weekend.%i.Humidity +Weekend.%i.MinHumidity +Weekend.%i.MaxHumidity +Weekend.%i.HighTemperature +Weekend.%i.LowTemperature +Weekend.%i.LongOutlookDay +Weekend.%i.LongOutlookNight +Weekend.%i.Precipitation +Weekend.%i.Snow +Weekend.%i.ChancePrecipitation + + +36HOUR [1-3] +------------ +36Hour.IsFetched +36Hour.%i.Forecast +36Hour.%i.TemperatureHeading +36Hour.%i.Temperature +36Hour.%i.Heading +36Hour.%i.ChancePrecipitation +36Hour.%i.OutlookIcon +36Hour.%i.FanartCode + + +HOURLY [1-36] +------------- +Hourly.IsFetched +Hourly.%i.Time +Hourly.%i.ShortDate +Hourly.%i.LongDate +Hourly.%i.Temperature +Hourly.%i.DewPoint +Hourly.%i.FeelsLike +Hourly.%i.Precipitation +Hourly.%i.Snow +Hourly.%i.HeatIndex +Hourly.%i.WindChill +Hourly.%i.Mslp +Hourly.%i.WindSpeed +Hourly.%i.WindDirection +Hourly.%i.ShortWindDirection +Hourly.%i.WindDegree +Hourly.%i.Humidity +Hourly.%i.UVIndex +Hourly.%i.ChancePrecipitation +Hourly.%i.Outlook +Hourly.%i.OutlookIcon +Hourly.%i.FanartCode + + +ALERTS [1-<number of alerts>] +----------------------------- +Alerts.IsFetched +Alerts.%i.Description +Alerts.%i.Message +Alerts.%i.StartDate +Alerts.%i.EndDate +Alerts.%i.Significance +Alerts.RSS +Alerts +Alerts.Count + + +[MAP] +Map.IsFetched +MapPath + diff --git a/addons/weather.wunderground/addon.xml b/addons/weather.wunderground/addon.xml index 8adb2cc2e8..61e2bd922c 100644 --- a/addons/weather.wunderground/addon.xml +++ b/addons/weather.wunderground/addon.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<addon id="weather.wunderground" name="Weather Underground" version="0.0.9" provider-name="Team XBMC"> +<addon id="weather.wunderground" name="Weather Underground" version="1.0.1" provider-name="Team XBMC"> <requires> <import addon="xbmc.python" version="2.0"/> <import addon="script.module.simplejson" version="2.0.10"/> </requires> <extension point="xbmc.python.weather" library="default.py"/> + <extension point="xbmc.python.module" library="resources/lib/wunderground"/> <extension point="xbmc.addon.metadata"> <summary lang="af">Weer voorspelling vanaf wonderground.com</summary> <summary lang="ar">توقعات الطقس من wunderground.com</summary> @@ -17,6 +18,7 @@ <summary lang="el">Πρόγνωση καιρού από το wunderground.com</summary> <summary lang="en">Weather forecast from wunderground.com</summary> <summary lang="es">Predicción meteorológica de wunderground.com</summary> + <summary lang="es_AR">Predicción meteorológica de wunderground.com</summary> <summary lang="es_MX">Pronóstico de wunderground.com</summary> <summary lang="et">Ilmaennustus portaalist wunderground.com</summary> <summary lang="fi">Sääennusteet wunderground.com-sivustolta</summary> @@ -55,6 +57,7 @@ <description lang="el">Η πρόγνωση καιρού παρέχεται από το Weather Underground (http://www.wunderground.com/)</description> <description lang="en">Weather forecast provided by Weather Underground (http://www.wunderground.com/)</description> <description lang="es">Predicción meteorológica proporcionada por Weather Underground (http://www.wunderground.com/)</description> + <description lang="es_AR">Predicción meteorológica proporcionada por Weather Underground (http://www.wunderground.com/)</description> <description lang="es_MX">Pronóstico del tiempo por Weather Underground (http://www.wunderground.com/)</description> <description lang="et">Ilma ennustab Weather Underground (http://www.wunderground.com/)</description> <description lang="fi">Sääennusteet Weather Underground -sivuston tarjoamina (http://www.wunderground.com/)</description> @@ -93,6 +96,7 @@ <disclaimer lang="el">Χρήση αυτού του πρόσθετου συνεπάγεται την αποδοχή των Όρων Χρήσης της Υπηρεσίας (Terms of Service) οι οποίοι βρίσκονται στο http://www.wunderground.com/weather/api/d/terms.html</disclaimer> <disclaimer lang="en">Use of this add-on implies that you have agreed to the Terms of Service located at http://www.wunderground.com/weather/api/d/terms.html</disclaimer> <disclaimer lang="es">Al usar este complemento, aceptas los términos de uso de http://www.wunderground.com/weather/api/d/terms.html</disclaimer> + <disclaimer lang="es_AR">Al usar este complemento, aceptas los términos de uso de http://www.wunderground.com/weather/api/d/terms.html</disclaimer> <disclaimer lang="es_MX">El uso de este add-on implica que usted esta de acuerdo con los Términos de Servicio localizados en http://www.wunderground.com/weather/api/d/terms.html</disclaimer> <disclaimer lang="et">Selle lisamooduli kasutamine viitab sellele, et te olete nõustunud kasutajatingimustega aadressil http://www.wunderground.com/weather/api/d/terms.html</disclaimer> <disclaimer lang="fi">Tämän lisäosan käyttäminen tarkoittaa, että olet hyväksynyt osoitteessa http://www.wunderground.com/weather/api/d/terms.html sijaitsevat käyttöehdot</disclaimer> @@ -123,4 +127,3 @@ <platform>all</platform> </extension> </addon> - diff --git a/addons/weather.wunderground/changelog.txt b/addons/weather.wunderground/changelog.txt index f9c0fe010c..0776546b44 100644 --- a/addons/weather.wunderground/changelog.txt +++ b/addons/weather.wunderground/changelog.txt @@ -1,9 +1,76 @@ +v1.0.1 +- fix encoding issues + +v1.0.0 +- bump version for frodo +- added .po language files + +v0.1.12 +- updated wunderground api module + +v0.1.11 +- added spanish translation +- avoid crashes on api error responses +- fix invalid humidity value + +v0.1.10 +- add 'L' weather alert severity +- filter invalid response code +- don't add beaufort unit to windspeeds +- fix default zoom level +- fixed windspeed for uk based locations in 36 hour and weekend forecast +- localize AM/PM strings +- made animated maps optional + +v0.1.9 +- fixed json error when no files are found +- fix 36 hour heading and temp (again) +- better detection of systems that use AM/PM time format +- provide windspeeds in beaufort for systems that use it + +v0.1.8 +- fixed escape slashes in path + +v0.1.7 +- clear alert properties when there are no alerts +- delete chached images when weather location is changed + +v0.1.6 +- fix 36 hour heading and temp for certain languages +- provide 3 day weekend forecast +- keep 4 hours worth of satellite images to create an animation + +v0.1.5 +- fixed weather icon location +- fixed temp unit for hourly feels like + +v0.1.4 +- fetch satellite image instead of radar + +v0.1.3 +- disabled yesterdays weather and animated radar images (we don't have free access to that data) +- added static radar image + +v0.1.2 +- bug fixes + +v0.1.1 +- beta release + +v0.1.0 +- wait for thread to finish before setting properties + v0.0.9 -- clear 7 day labels not 6 -- save only the actual location code +- implement threading +- added wundermap support v0.0.8 -- fix error if no internet connection is available when searching for a location +- use ascii strings for location search +- added advanced configuration +- added debug logging +- added Current.Location window property +- moved api code to a separate module (other weather addons can use it fetch wunderground data) +- localize weather data v0.0.7 - fix: import error on Windows with non/extended-ascii profile paths diff --git a/addons/weather.wunderground/default.py b/addons/weather.wunderground/default.py index 3c366885b8..7b8f437f1c 100644 --- a/addons/weather.wunderground/default.py +++ b/addons/weather.wunderground/default.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # * This Program is free software; you can redistribute it and/or modify # * it under the terms of the GNU General Public License as published by # * the Free Software Foundation; either version 2, or (at your option) @@ -9,113 +11,189 @@ # * GNU General Public License for more details. # * # * You should have received a copy of the GNU General Public License -# * along with XBMC; see the file COPYING. If not, see -# * <http://www.gnu.org/licenses/>. -# * +# * along with XBMC; see the file COPYING. If not, write to +# * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# * http://www.gnu.org/copyleft/gpl.html -import os, sys, urllib2, base64, socket, simplejson -import xbmcgui, xbmcaddon + +import os, sys, socket, unicodedata, urllib2, time, base64 +from datetime import date +import xbmc, xbmcgui, xbmcaddon, xbmcvfs +if sys.version_info < (2, 7): + import simplejson +else: + import json as simplejson __addon__ = xbmcaddon.Addon() -__provider__ = __addon__.getAddonInfo('name') -__cwd__ = __addon__.getAddonInfo('path') -__resource__ = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'lib')).decode("utf-8") +__addonname__ = __addon__.getAddonInfo('name') +__addonid__ = __addon__.getAddonInfo('id') +__cwd__ = __addon__.getAddonInfo('path').decode("utf-8") +__version__ = __addon__.getAddonInfo('version') +__language__ = __addon__.getLocalizedString +__resource__ = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'lib')) sys.path.append (__resource__) from utilities import * +from wunderground import wundergroundapi -LOCATION_URL = 'http://autocomplete.wunderground.com/aq?query=%s&format=JSON' -WEATHER_URL = 'http://api.wunderground.com/api/%s/conditions/forecast7day/hourly/q/%s.json' -GEOIP_URL = 'http://api.wunderground.com/api/%s/geolookup/q/autoip.json' -A_I_K = 'NDEzNjBkMjFkZjFhMzczNg==' -WEATHER_WINDOW = xbmcgui.Window(12600) -MAXDAYS = 6 +WUNDERGROUND_LOC = 'http://autocomplete.wunderground.com/aq?query=%s&format=JSON' +WEATHER_FEATURES = 'hourly/conditions/forecast10day/astronomy/almanac/alerts/satellite' +FORMAT = 'json' +DEBUG = __addon__.getSetting('Debug') +WEATHER_ICON = xbmc.translatePath('special://temp/weather/%s.png').decode("utf-8") +WEATHER_WINDOW = xbmcgui.Window(12600) +LANGUAGE = xbmc.getLanguage().lower() +SPEEDUNIT = xbmc.getRegion('speedunit') +TEMPUNIT = unicode(xbmc.getRegion('tempunit'),encoding='utf-8') +TIMEFORMAT = xbmc.getRegion('meridiem') +DATEFORMAT = xbmc.getRegion('dateshort') +MAXDAYS = 6 socket.setdefaulttimeout(10) +def log(txt): + if DEBUG == 'true': + if isinstance (txt,str): + txt = txt.decode("utf-8") + message = u'%s: %s' % (__addonid__, txt) + xbmc.log(msg=message.encode("utf-8"), level=xbmc.LOGDEBUG) + def set_property(name, value): WEATHER_WINDOW.setProperty(name, value) def refresh_locations(): - location_set1 = __addon__.getSetting('Location1') - location_set2 = __addon__.getSetting('Location2') - location_set3 = __addon__.getSetting('Location3') locations = 0 - if location_set1 != '': - locations += 1 - set_property('Location1', location_set1) - else: - set_property('Location1', '') - if location_set2 != '': - locations += 1 - set_property('Location2', location_set2) - else: - set_property('Location2', '') - if location_set3 != '': - locations += 1 - set_property('Location3', location_set3) - else: - set_property('Location3', '') + for count in range(1, 4): + loc_name = __addon__.getSetting('Location%s' % count) + if loc_name != '': + locations += 1 + else: + __addon__.setSetting('Location%sid' % count, '') + set_property('Location%s' % count, loc_name) set_property('Locations', str(locations)) + log('available locations: %s' % str(locations)) -def fetch(url): +def find_location(loc): + url = WUNDERGROUND_LOC % urllib2.quote(loc) try: req = urllib2.urlopen(url) - json_string = req.read() + response = req.read() req.close() except: - json_string = '' - try: - json_clean = json_string.replace('"-9999.00"','""').replace('"-9998"','""').replace('"NA"','""') - parsed_json = simplejson.loads(json_clean) - except: - parsed_json = '' - return parsed_json + response = '' + return response def location(string): - loc = [] - locid = [] - query = fetch(LOCATION_URL % (urllib2.quote(string))) - if query != '': - for item in query['RESULTS']: + locs = [] + locids = [] + log('location: %s' % string) + loc = unicodedata.normalize('NFKD', unicode(string, 'utf-8')).encode('ascii','ignore') + log('searching for location: %s' % loc) + query = find_location(loc) + log('location data: %s' % query) + data = parse_data(query) + if data != '' and data.has_key('RESULTS'): + for item in data['RESULTS']: location = item['name'] locationid = item['l'][3:] - loc.append(location) - locid.append(locationid) - return loc, locid + locs.append(location) + locids.append(locationid) + return locs, locids def geoip(): - data = fetch(GEOIP_URL % aik[::-1]) + retry = 0 + while (retry < 6) and (not xbmc.abortRequested): + query = wundergroundapi('geolookup', None, 'autoip', FORMAT) + if query != '': + retry = 6 + else: + retry += 1 + xbmc.sleep(10000) + log('geoip download failed') + log('geoip data: %s' % query) + data = parse_data(query) if data != '' and data.has_key('location'): - location = data['location']['l'][3:] - __addon__.setSetting('Location1', data['location']['city']) - __addon__.setSetting('Location1id', location) + location = data['location']['city'] + locationid = data['location']['l'][3:] + __addon__.setSetting('Location1', location) + __addon__.setSetting('Location1id', locationid) + log('geoip location: %s' % location) + else: + locationid = '' + return locationid + +def forecast(loc): + try: + lang = LANG[LANGUAGE] + except: + lang = 'EN' + opt = 'lang:' + lang + log('weather location: %s' % loc) + retry = 0 + while (retry < 6) and (not xbmc.abortRequested): + query = wundergroundapi(WEATHER_FEATURES, opt, loc, FORMAT) + if query != '': + retry = 6 + else: + retry += 1 + xbmc.sleep(10000) + log('weather download failed') + log('forecast data: %s' % query) + data = parse_data(query) + if data != '' and not data.has_key('error'): + properties(data,loc) else: - location = '' - return location - -def forecast(city): - data = fetch(WEATHER_URL % (aik[::-1], city)) - if data != '': - properties(data) - -def properties(query): - weathercode = WEATHER_CODES[query['current_observation']['icon_url'][31:-4]] - set_property('Current.Condition' , query['current_observation']['weather']) - set_property('Current.Temperature' , str(query['current_observation']['temp_c'])) - set_property('Current.Wind' , str(query['current_observation']['wind_kph'])) - set_property('Current.WindDirection' , query['current_observation']['wind_dir']) - set_property('Current.Humidity' , query['current_observation']['relative_humidity'].rstrip('%')) - set_property('Current.FeelsLike' , str((int(query['hourly_forecast'][0]['feelslike']['english'])-32)*5/9)) - set_property('Current.UVIndex' , query['hourly_forecast'][0]['uvi']) - set_property('Current.DewPoint' , str(query['current_observation']['dewpoint_c'])) + clear() + +def clear(): + set_property('Current.Condition' , 'N/A') + set_property('Current.Temperature' , '0') + set_property('Current.Wind' , '0') + set_property('Current.WindDirection' , 'N/A') + set_property('Current.Humidity' , '0') + set_property('Current.FeelsLike' , '0') + set_property('Current.UVIndex' , '0') + set_property('Current.DewPoint' , '0') + set_property('Current.OutlookIcon' , 'na.png') + set_property('Current.FanartCode' , 'na') + for count in range (0, MAXDAYS+1): + set_property('Day%i.Title' % count, 'N/A') + set_property('Day%i.HighTemp' % count, '0') + set_property('Day%i.LowTemp' % count, '0') + set_property('Day%i.Outlook' % count, 'N/A') + set_property('Day%i.OutlookIcon' % count, 'na.png') + set_property('Day%i.FanartCode' % count, 'na') + +def parse_data(json): + try: + reply = json.replace('"-999%"','""').replace('"-9999.00"','""').replace('"-9998"','""').replace('"NA"','""').replace(' <? END CHANCE OF PRECIP\n\n?>','') # wu api bug + data = simplejson.loads(reply) + except: + log('failed to parse weather data') + data = '' + return data + +def properties(data,loc): +# standard properties + weathercode = WEATHER_CODES[data['current_observation']['icon_url'][31:-4]] + location = __addon__.getSetting('Location%s' % sys.argv[1]) + if (location == '') and (sys.argv[1] != '1'): + location = __addon__.getSetting('Location1') + set_property('Current.Location' , location) + set_property('Current.Condition' , data['current_observation']['weather']) + set_property('Current.Temperature' , str(data['current_observation']['temp_c'])) + set_property('Current.Wind' , str(data['current_observation']['wind_kph'])) + set_property('Current.WindDirection' , data['current_observation']['wind_dir']) + set_property('Current.Humidity' , data['current_observation']['relative_humidity'].rstrip('%')) + set_property('Current.FeelsLike' , data['current_observation']['feelslike_c']) + set_property('Current.UVIndex' , data['current_observation']['UV']) + set_property('Current.DewPoint' , str(data['current_observation']['dewpoint_c'])) set_property('Current.OutlookIcon' , '%s.png' % weathercode) set_property('Current.FanartCode' , weathercode) - for count, item in enumerate(query['forecast']['simpleforecast']['forecastday']): + for count, item in enumerate(data['forecast']['simpleforecast']['forecastday']): weathercode = WEATHER_CODES[item['icon_url'][31:-4]] - day = DAYS[item['date']['weekday_short']] - set_property('Day%i.Title' % count, day) + set_property('Day%i.Title' % count, item['date']['weekday']) set_property('Day%i.HighTemp' % count, str(item['high']['celsius'])) set_property('Day%i.LowTemp' % count, str(item['low']['celsius'])) set_property('Day%i.Outlook' % count, item['conditions']) @@ -123,6 +201,378 @@ def properties(query): set_property('Day%i.FanartCode' % count, weathercode) if count == MAXDAYS: break +# forecast properties + set_property('Forecast.IsFetched' , 'true') + set_property('Forecast.City' , data['current_observation']['display_location']['city']) + set_property('Forecast.State' , data['current_observation']['display_location']['state_name']) + set_property('Forecast.Country' , data['current_observation']['display_location']['country']) + update = time.localtime(float(data['current_observation']['observation_epoch'])) + if DATEFORMAT[1] == 'm': + localdate = WEEKDAY[update[6]] + ' ' + MONTH[update[1]] + ' ' + str(update[2]) + ', ' + str(update[0]) + else: + localdate = WEEKDAY[update[6]] + ' ' + str(update[2]) + ' ' + MONTH[update[1]] + ' ' + str(update[0]) + if TIMEFORMAT != '/': + localtime = time.strftime('%I:%M%p', update) + else: + localtime = time.strftime('%H:%M', update) + set_property('Forecast.Updated' , localdate + ' - ' + localtime) +# current properties + set_property('Current.IsFetched' , 'true') + set_property('Current.WindDegree' , str(data['current_observation']['wind_degrees']) + u'°') + set_property('Current.SolarRadiation' , str(data['current_observation']['solarradiation'])) + if 'F' in TEMPUNIT: + set_property('Current.Pressure' , data['current_observation']['pressure_in'] + ' inHg') + set_property('Current.Precipitation' , data['current_observation']['precip_1hr_in'] + ' in') + set_property('Current.HeatIndex' , str(data['current_observation']['heat_index_f']) + TEMPUNIT) + set_property('Current.WindChill' , str(data['current_observation']['windchill_f']) + TEMPUNIT) + else: + set_property('Current.Pressure' , data['current_observation']['pressure_mb'] + ' mb') + set_property('Current.Precipitation' , data['current_observation']['precip_1hr_metric'] + ' mm') + set_property('Current.HeatIndex' , str(data['current_observation']['heat_index_c']) + TEMPUNIT) + set_property('Current.WindChill' , str(data['current_observation']['windchill_c']) + TEMPUNIT) + if SPEEDUNIT == 'mph': + set_property('Current.Visibility' , data['current_observation']['visibility_mi'] + ' mi') + set_property('Current.WindGust' , str(data['current_observation']['wind_gust_mph']) + ' ' + SPEEDUNIT) + elif SPEEDUNIT == 'Beaufort': + set_property('Current.Visibility' , data['current_observation']['visibility_km'] + ' km') + set_property('Current.WindGust' , KPHTOBFT(data['current_observation']['wind_gust_kph'])) + else: + set_property('Current.Visibility' , data['current_observation']['visibility_km'] + ' km') + set_property('Current.WindGust' , str(data['current_observation']['wind_gust_kph']) + ' ' + SPEEDUNIT) +# today properties + set_property('Today.IsFetched' , 'true') + if TIMEFORMAT != '/': + AM = unicode(TIMEFORMAT.split('/')[0],encoding='utf-8') + PM = unicode(TIMEFORMAT.split('/')[1],encoding='utf-8') + hour = int(data['moon_phase']['sunrise']['hour']) % 24 + isam = (hour >= 0) and (hour < 12) + if isam: + hour = ('12' if (hour == 0) else '%02d' % (hour)) + set_property('Today.Sunrise' , hour.lstrip('0') + ':' + data['moon_phase']['sunrise']['minute'] + ' ' + AM) + else: + hour = ('12' if (hour == 12) else '%02d' % (hour-12)) + set_property('Today.Sunrise' , hour.lstrip('0') + ':' + data['moon_phase']['sunrise']['minute'] + ' ' + PM) + hour = int(data['moon_phase']['sunset']['hour']) % 24 + isam = (hour >= 0) and (hour < 12) + if isam: + hour = ('12' if (hour == 0) else '%02d' % (hour)) + set_property('Today.Sunset' , hour.lstrip('0') + ':' + data['moon_phase']['sunset']['minute'] + ' ' + AM) + else: + hour = ('12' if (hour == 12) else '%02d' % (hour-12)) + set_property('Today.Sunset' , hour.lstrip('0') + ':' + data['moon_phase']['sunset']['minute'] + ' ' + PM) + else: + set_property('Today.Sunrise' , data['moon_phase']['sunrise']['hour'] + ':' + data['moon_phase']['sunrise']['minute']) + set_property('Today.Sunset' , data['moon_phase']['sunset']['hour'] + ':' + data['moon_phase']['sunset']['minute']) + set_property('Today.moonphase' , MOONPHASE(int(data['moon_phase']['ageOfMoon']), int(data['moon_phase']['percentIlluminated']))) + if 'F' in TEMPUNIT: + set_property('Today.AvgHighTemperature' , data['almanac']['temp_high']['normal']['F'] + TEMPUNIT) + set_property('Today.AvgLowTemperature' , data['almanac']['temp_low']['normal']['F'] + TEMPUNIT) + try: + set_property('Today.RecordHighTemperature' , data['almanac']['temp_high']['record']['F'] + TEMPUNIT) + set_property('Today.RecordLowTemperature' , data['almanac']['temp_low']['record']['F'] + TEMPUNIT) + except: + set_property('Today.RecordHighTemperature' , '') + set_property('Today.RecordLowTemperature' , '') + else: + set_property('Today.AvgHighTemperature' , data['almanac']['temp_high']['normal']['C'] + TEMPUNIT) + set_property('Today.AvgLowTemperature' , data['almanac']['temp_low']['normal']['C'] + TEMPUNIT) + try: + set_property('Today.RecordHighTemperature' , data['almanac']['temp_high']['record']['C'] + TEMPUNIT) + set_property('Today.RecordLowTemperature' , data['almanac']['temp_low']['record']['C'] + TEMPUNIT) + except: + set_property('Today.RecordHighTemperature' , '') + set_property('Today.RecordLowTemperature' , '') + try: + set_property('Today.RecordHighYear' , data['almanac']['temp_high']['recordyear']) + set_property('Today.RecordLowYear' , data['almanac']['temp_low']['recordyear']) + except: + set_property('Today.RecordHighYear' , '') + set_property('Today.RecordLowYear' , '') +# daily properties + set_property('Daily.IsFetched', 'true') + for count, item in enumerate(data['forecast']['simpleforecast']['forecastday']): + weathercode = WEATHER_CODES[item['icon_url'][31:-4]] + set_property('Daily.%i.LongDay' % (count+1), item['date']['weekday']) + set_property('Daily.%i.ShortDay' % (count+1), item['date']['weekday_short']) + if DATEFORMAT[1] == 'm': + set_property('Daily.%i.LongDate' % (count+1), item['date']['monthname'] + ' ' + str(item['date']['day'])) + set_property('Daily.%i.ShortDate' % (count+1), MONTH[item['date']['month']] + ' ' + str(item['date']['day'])) + else: + set_property('Daily.%i.LongDate' % (count+1), str(item['date']['day']) + ' ' + item['date']['monthname']) + set_property('Daily.%i.ShortDate' % (count+1), str(item['date']['day']) + ' ' + MONTH[item['date']['month']]) + set_property('Daily.%i.Outlook' % (count+1), item['conditions']) + set_property('Daily.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) + set_property('Daily.%i.FanartCode' % (count+1), weathercode) + if SPEEDUNIT == 'mph': + set_property('Daily.%i.WindSpeed' % (count+1), str(item['avewind']['mph']) + ' ' + SPEEDUNIT) + set_property('Daily.%i.MaxWind' % (count+1), str(item['maxwind']['mph']) + ' ' + SPEEDUNIT) + elif SPEEDUNIT == 'Beaufort': + set_property('Daily.%i.WindSpeed' % (count+1), KPHTOBFT(item['avewind']['kph'])) + set_property('Daily.%i.MaxWind' % (count+1), KPHTOBFT(item['maxwind']['kph'])) + else: + set_property('Daily.%i.WindSpeed' % (count+1), str(item['avewind']['kph']) + ' ' + SPEEDUNIT) + set_property('Daily.%i.MaxWind' % (count+1), str(item['maxwind']['kph']) + ' ' + SPEEDUNIT) + set_property('Daily.%i.WindDirection' % (count+1), item['avewind']['dir']) + set_property('Daily.%i.ShortWindDirection' % (count+1), item['avewind']['dir']) + set_property('Daily.%i.WindDegree' % (count+1), str(item['avewind']['degrees']) + u'°') + set_property('Daily.%i.Humidity' % (count+1), str(item['avehumidity']) + '%') + set_property('Daily.%i.MinHumidity' % (count+1), str(item['minhumidity']) + '%') + set_property('Daily.%i.MaxHumidity' % (count+1), str(item['maxhumidity']) + '%') + if 'F' in TEMPUNIT: + set_property('Daily.%i.HighTemperature' % (count+1), str(item['high']['fahrenheit']) + TEMPUNIT) + set_property('Daily.%i.LowTemperature' % (count+1), str(item['low']['fahrenheit']) + TEMPUNIT) + set_property('Daily.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext']) + set_property('Daily.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext']) + set_property('Daily.%i.Precipitation' % (count+1), str(item['qpf_day']['in']) + ' in') + set_property('Daily.%i.Snow' % (count+1), str(item['snow_day']['in']) + ' in') + else: + set_property('Daily.%i.HighTemperature' % (count+1), str(item['high']['celsius']) + TEMPUNIT) + set_property('Daily.%i.LowTemperature' % (count+1), str(item['low']['celsius']) + TEMPUNIT) + set_property('Daily.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric']) + set_property('Daily.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric']) + set_property('Daily.%i.Precipitation' % (count+1), str(item['qpf_day']['mm']) + ' mm') + set_property('Daily.%i.Snow' % (count+1), str(item['snow_day']['cm']) + ' mm') + set_property('Daily.%i.ChancePrecipitation' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['pop'] + '%') +# weekend properties + set_property('Weekend.IsFetched', 'true') + if __addon__.getSetting('Weekend') == '2': + weekend = (3,4,5) + elif __addon__.getSetting('Weekend') == '1': + weekend = (4,5,6) + else: + weekend = (5,6,7) + count = 0 + for item in data['forecast']['simpleforecast']['forecastday']: + if date(item['date']['year'], item['date']['month'], item['date']['day']).isoweekday() in weekend: + weathercode = WEATHER_CODES[item['icon_url'][31:-4]] + set_property('Weekend.%i.LongDay' % (count+1), item['date']['weekday']) + set_property('Weekend.%i.ShortDay' % (count+1), item['date']['weekday_short']) + if DATEFORMAT[1] == 'm': + set_property('Weekend.%i.LongDate' % (count+1), item['date']['monthname'] + ' ' + str(item['date']['day'])) + set_property('Weekend.%i.ShortDate' % (count+1), MONTH[item['date']['month']] + ' ' + str(item['date']['day'])) + else: + set_property('Weekend.%i.LongDate' % (count+1), str(item['date']['day']) + ' ' + item['date']['monthname']) + set_property('Weekend.%i.ShortDate' % (count+1), str(item['date']['day']) + ' ' + MONTH[item['date']['month']]) + set_property('Weekend.%i.Outlook' % (count+1), item['conditions']) + set_property('Weekend.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) + set_property('Weekend.%i.FanartCode' % (count+1), weathercode) + if SPEEDUNIT == 'mph': + set_property('Weekend.%i.WindSpeed' % (count+1), str(item['avewind']['mph']) + ' ' + SPEEDUNIT) + set_property('Weekend.%i.MaxWind' % (count+1), str(item['maxwind']['mph']) + ' ' + SPEEDUNIT) + elif SPEEDUNIT == 'Beaufort': + set_property('Weekend.%i.WindSpeed' % (count+1), KPHTOBFT(item['avewind']['kph'])) + set_property('Weekend.%i.MaxWind' % (count+1), KPHTOBFT(item['maxwind']['kph'])) + else: + set_property('Weekend.%i.WindSpeed' % (count+1), str(item['avewind']['kph']) + ' ' + SPEEDUNIT) + set_property('Weekend.%i.MaxWind' % (count+1), str(item['maxwind']['kph']) + ' ' + SPEEDUNIT) + set_property('Weekend.%i.WindDirection' % (count+1), item['avewind']['dir']) + set_property('Weekend.%i.ShortWindDirection' % (count+1), item['avewind']['dir']) + set_property('Weekend.%i.WindDegree' % (count+1), str(item['avewind']['degrees']) + u'°') + set_property('Weekend.%i.Humidity' % (count+1), str(item['avehumidity']) + '%') + set_property('Weekend.%i.MinHumidity' % (count+1), str(item['minhumidity']) + '%') + set_property('Weekend.%i.MaxHumidity' % (count+1), str(item['maxhumidity']) + '%') + set_property('Weekend.%i.ChancePrecipitation' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['pop'] + '%') + if 'F' in TEMPUNIT: + set_property('Weekend.%i.HighTemperature' % (count+1), str(item['high']['fahrenheit']) + TEMPUNIT) + set_property('Weekend.%i.LowTemperature' % (count+1), str(item['low']['fahrenheit']) + TEMPUNIT) + set_property('Weekend.%i.Precipitation' % (count+1), str(item['qpf_day']['in']) + ' in') + set_property('Weekend.%i.Snow' % (count+1), str(item['snow_day']['in']) + ' in') + set_property('Weekend.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext']) + set_property('Weekend.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext']) + else: + set_property('Weekend.%i.HighTemperature' % (count+1), str(item['high']['celsius']) + TEMPUNIT) + set_property('Weekend.%i.LowTemperature' % (count+1), str(item['low']['celsius']) + TEMPUNIT) + set_property('Weekend.%i.Precipitation' % (count+1), str(item['qpf_day']['mm']) + ' mm') + set_property('Weekend.%i.Snow' % (count+1), str(item['snow_day']['cm']) + ' mm') + if data['current_observation']['display_location']['country'] == 'UK': # for the brits + dfcast_e = data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext'].split('.') + dfcast_m = data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric'].split('.') + nfcast_e = data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext'].split('.') + nfcast_m = data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric'].split('.') + for field in dfcast_e: + if field.endswith('mph'): # find windspeed in mph + wind = field + break + for field in dfcast_m: + if field.endswith('km/h'): # find windspeed in km/h + dfcast_m[dfcast_m.index(field)] = wind # replace windspeed in km/h with windspeed in mph + break + for field in nfcast_e: + if field.endswith('mph'): # find windspeed in mph + wind = field + break + for field in nfcast_m: + if field.endswith('km/h'): # find windspeed in km/h + nfcast_m[nfcast_m.index(field)] = wind # replace windspeed in km/h with windspeed in mph + break + set_property('Weekend.%i.LongOutlookDay' % (count+1), '. '.join(dfcast_m)) + set_property('Weekend.%i.LongOutlookNight' % (count+1), '. '.join(nfcast_m)) + else: + set_property('Weekend.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric']) + set_property('Weekend.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric']) + count += 1 + if count == 3: + break +# 36 hour properties + set_property('36Hour.IsFetched', 'true') + for count, item in enumerate(data['forecast']['txt_forecast']['forecastday']): + weathercode = WEATHER_CODES[item['icon_url'][31:-4]] + if 'F' in TEMPUNIT: + try: + fcast = item['fcttext'].split('.') + for line in fcast: + if line.endswith('F'): + set_property('36Hour.%i.TemperatureHeading' % (count+1), line.rsplit(' ',1)[0]) + set_property('36Hour.%i.Temperature' % (count+1), line.rsplit(' ',1)[1].rstrip('F').strip() + TEMPUNIT) + break + except: + set_property('36Hour.%i.TemperatureHeading' % (count+1), '') + set_property('36Hour.%i.Temperature' % (count+1), '') + set_property('36Hour.%i.Forecast' % (count+1), item['fcttext']) + else: + try: + fcast = item['fcttext_metric'].split('.') + for line in fcast: + if line.endswith('C'): + set_property('36Hour.%i.TemperatureHeading' % (count+1), line.rsplit(' ',1)[0]) + set_property('36Hour.%i.Temperature' % (count+1), line.rsplit(' ',1)[1].rstrip('C').strip() + TEMPUNIT) + break + except: + set_property('36Hour.%i.TemperatureHeading' % (count+1), '') + set_property('36Hour.%i.Temperature' % (count+1), '') + if data['current_observation']['display_location']['country'] == 'UK': # for the brits + fcast_e = item['fcttext'].split('.') + for field in fcast_e: + if field.endswith('mph'): # find windspeed in mph + wind = field + break + for field in fcast: + if field.endswith('km/h'): # find windspeed in km/h + fcast[fcast.index(field)] = wind # replace windspeed in km/h with windspeed in mph + break + set_property('36Hour.%i.Forecast' % (count+1), '. '.join(fcast)) + else: + set_property('36Hour.%i.Forecast' % (count+1), item['fcttext_metric']) + set_property('36Hour.%i.Heading' % (count+1), item['title']) + set_property('36Hour.%i.ChancePrecipitation' % (count+1), item['pop'] + '%') + set_property('36Hour.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) + set_property('36Hour.%i.FanartCode' % (count+1), weathercode) + if count == 2: + break +# hourly properties + set_property('Hourly.IsFetched', 'true') + for count, item in enumerate(data['hourly_forecast']): + weathercode = WEATHER_CODES[item['icon_url'][31:-4]] + if TIMEFORMAT != '/': + set_property('Hourly.%i.Time' % (count+1), item['FCTTIME']['civil']) + else: + set_property('Hourly.%i.Time' % (count+1), item['FCTTIME']['hour_padded'] + ':' + item['FCTTIME']['min']) + if DATEFORMAT[1] == 'm': + set_property('Hourly.%i.ShortDate' % (count+1), item['FCTTIME']['month_name_abbrev'] + ' ' + item['FCTTIME']['mday_padded']) + set_property('Hourly.%i.LongDate' % (count+1), item['FCTTIME']['month_name'] + ' ' + item['FCTTIME']['mday_padded']) + else: + set_property('Hourly.%i.ShortDate' % (count+1), item['FCTTIME']['mday_padded'] + ' ' + item['FCTTIME']['month_name_abbrev']) + set_property('Hourly.%i.LongDate' % (count+1), item['FCTTIME']['mday_padded'] + ' ' + item['FCTTIME']['month_name']) + if 'F' in TEMPUNIT: + set_property('Hourly.%i.Temperature' % (count+1), item['temp']['english'] + TEMPUNIT) + set_property('Hourly.%i.DewPoint' % (count+1), item['dewpoint']['english'] + TEMPUNIT) + set_property('Hourly.%i.FeelsLike' % (count+1), item['feelslike']['english'] + TEMPUNIT) + set_property('Hourly.%i.Precipitation' % (count+1), item['qpf']['english'] + ' in') + set_property('Hourly.%i.Snow' % (count+1), item['snow']['english'] + ' in') + set_property('Hourly.%i.HeatIndex' % (count+1), item['heatindex']['english'] + TEMPUNIT) + set_property('Hourly.%i.WindChill' % (count+1), item['windchill']['english'] + TEMPUNIT) + set_property('Hourly.%i.Mslp' % (count+1), item['mslp']['english'] + ' inHg') + else: + set_property('Hourly.%i.Temperature' % (count+1), item['temp']['metric'] + TEMPUNIT) + set_property('Hourly.%i.DewPoint' % (count+1), item['dewpoint']['metric'] + TEMPUNIT) + set_property('Hourly.%i.FeelsLike' % (count+1), item['feelslike']['metric'] + TEMPUNIT) + set_property('Hourly.%i.Precipitation' % (count+1), item['qpf']['metric'] + ' mm') + set_property('Hourly.%i.Snow' % (count+1), item['snow']['metric'] + ' mm') + set_property('Hourly.%i.HeatIndex' % (count+1), item['heatindex']['metric'] + TEMPUNIT) + set_property('Hourly.%i.WindChill' % (count+1), item['windchill']['metric'] + TEMPUNIT) + set_property('Hourly.%i.Mslp' % (count+1), item['mslp']['metric'] + ' inHg') + if SPEEDUNIT == 'mph': + set_property('Hourly.%i.WindSpeed' % (count+1), item['wspd']['english'] + ' ' + SPEEDUNIT) + elif SPEEDUNIT == 'Beaufort': + set_property('Hourly.%i.WindSpeed' % (count+1), KPHTOBFT(int(item['wspd']['metric']))) + else: + set_property('Hourly.%i.WindSpeed' % (count+1), item['wspd']['metric'] + ' ' + SPEEDUNIT) + set_property('Hourly.%i.WindDirection' % (count+1), item['wdir']['dir']) + set_property('Hourly.%i.ShortWindDirection' % (count+1), item['wdir']['dir']) + set_property('Hourly.%i.WindDegree' % (count+1), item['wdir']['degrees'] + u'°') + set_property('Hourly.%i.Humidity' % (count+1), item['humidity'] + '%') + set_property('Hourly.%i.UVIndex' % (count+1), item['uvi']) + set_property('Hourly.%i.ChancePrecipitation' % (count+1), item['pop'] + '%') + set_property('Hourly.%i.Outlook' % (count+1), item['condition']) + set_property('Hourly.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) + set_property('Hourly.%i.FanartCode' % (count+1), weathercode) + if count == 35: # workaround: wunderground provides a 10day hourly forecast + break +# alert properties + set_property('Alerts.IsFetched', 'true') + if str(data['alerts']) != '[]': + rss = '' + alerts = '' + for count, item in enumerate(data['alerts']): + set_property('Alerts.%i.Description' % (count+1), item['description']) + set_property('Alerts.%i.Message' % (count+1), item['message']) + set_property('Alerts.%i.StartDate' % (count+1), item['date']) + set_property('Alerts.%i.EndDate' % (count+1), item['expires']) + set_property('Alerts.%i.Significance' % (count+1), SEVERITY[item['significance']]) + rss = rss + item['description'] + ' - ' + alerts = alerts + item['message'] + set_property('Alerts.RSS' , rss.rstrip(' - ')) + set_property('Alerts' , alerts) + set_property('Alerts.Count' , str(count+1)) + else: + set_property('Alerts.RSS' , '') + set_property('Alerts' , '') + set_property('Alerts.Count' , '0') +# map properties + set_property('Map.IsFetched', 'true') + filelist = [] + locid = base64.b16encode(loc) + addondir = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'logo')) + mapdir = xbmc.translatePath('special://profile/addon_data/%s/map' % __addonid__) + set_property('MapPath', addondir) + if not xbmcvfs.exists(mapdir): + xbmcvfs.mkdir(mapdir) + json_query = xbmc.executeJSONRPC('{ "jsonrpc" : "2.0" , "method" : "Files.GetDirectory" , "params" : { "directory" : "%s" , "sort" : { "method" : "file" } } , "id" : 1 }' % mapdir.replace('\\', '\\\\')) + json_query = unicode(json_query, 'utf-8', errors='ignore') + json_response = simplejson.loads(json_query) + if (json_response['result'] != None) and (json_response['result'].has_key('files')) and (json_response['result']['files'] != None): + for item in json_response['result']['files']: + if item['filetype'] == 'file': + filelist.append(item['file']) + animate = __addon__.getSetting('Animate') + for item in filelist: + if animate == 'true': + if (time.time() - os.path.getmtime(item) > 14400) or (not locid in item): + xbmcvfs.delete(item) + else: + xbmcvfs.delete(item) + zoom = __addon__.getSetting('Zoom') + if zoom == '10': # default setting does not return decimals, changed setting will + zoom = '10.0' + url = data['satellite']['image_url_ir4'].replace('width=300&height=300','width=640&height=360').replace('radius=75','radius=%i' % int(1000/int(zoom.rstrip('0').rstrip('.,')))) + log('map url: %s' % url) + req = urllib2.urlopen(url) + response = req.read() + req.close() + timestamp = time.strftime('%Y%m%d%H%M%S') + mapfile = xbmc.translatePath('special://profile/addon_data/%s/map/%s-%s.png' % (__addonid__,locid,timestamp)) + tmpmap = open(mapfile, 'wb') + tmpmap.write(response) + tmpmap.close() + log('satellite image downloaded') + set_property('MapPath', mapdir) + +log('version %s started: %s' % (__version__, sys.argv)) +log('lang: %s' % LANGUAGE) +log('speed: %s' % SPEEDUNIT) +log('temp: %s' % TEMPUNIT[1]) +log('time: %s' % TIMEFORMAT) +log('date: %s' % DATEFORMAT) if sys.argv[1].startswith('Location'): keyboard = xbmc.Keyboard('', xbmc.getLocalizedString(14024), False) @@ -133,41 +583,30 @@ if sys.argv[1].startswith('Location'): dialog = xbmcgui.Dialog() if locations != []: selected = dialog.select(xbmc.getLocalizedString(396), locations) - if selected != -1: + if selected != -1: __addon__.setSetting(sys.argv[1], locations[selected]) __addon__.setSetting(sys.argv[1] + 'id', locationids[selected]) + log('selected location: %s' % locations[selected]) + log('selected location id: %s' % locationids[selected]) else: - dialog.ok(__provider__, xbmc.getLocalizedString(284)) + dialog.ok(__addonname__, xbmc.getLocalizedString(284)) else: location = __addon__.getSetting('Location%sid' % sys.argv[1]) - aik = base64.b64decode(A_I_K) if (location == '') and (sys.argv[1] != '1'): location = __addon__.getSetting('Location1id') + log('trying location 1 instead') if location == '': + log('fallback to geoip') location = geoip() if not location == '': if location.startswith('/q/'): # backwards compatibility location = location[3:] forecast(location) else: - set_property('Current.Condition' , 'N/A') - set_property('Current.Temperature' , '0') - set_property('Current.Wind' , '0') - set_property('Current.WindDirection' , 'N/A') - set_property('Current.Humidity' , '0') - set_property('Current.FeelsLike' , '0') - set_property('Current.UVIndex' , '0') - set_property('Current.DewPoint' , '0') - set_property('Current.OutlookIcon' , 'na.png') - set_property('Current.FanartCode' , 'na') - for count in range (0, MAXDAYS+1): - set_property('Day%i.Title' % count, 'N/A') - set_property('Day%i.HighTemp' % count, '0') - set_property('Day%i.LowTemp' % count, '0') - set_property('Day%i.Outlook' % count, 'N/A') - set_property('Day%i.OutlookIcon' % count, 'na.png') - set_property('Day%i.FanartCode' % count, 'na') - -refresh_locations() -set_property('WeatherProvider', 'Weather Underground') + log('no location found') + clear() + refresh_locations() + +set_property('WeatherProvider', __addonname__) +log('finished') diff --git a/addons/weather.wunderground/resources/language/Belarusian/strings.po b/addons/weather.wunderground/resources/language/Belarusian/strings.po index 13c82e1e3c..671ffc37c3 100644 --- a/addons/weather.wunderground/resources/language/Belarusian/strings.po +++ b/addons/weather.wunderground/resources/language/Belarusian/strings.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: XBMC Main Translation Project (Frodo)\n" "Report-Msgid-Bugs-To: http://trac.xbmc.org/\n" "POT-Creation-Date: 2012-05-28 15:38+0000\n" -"PO-Revision-Date: 2012-11-07 03:01+0000\n" +"PO-Revision-Date: 2012-11-11 10:18+0000\n" "Last-Translator: XBMC Translation Team\n" "Language-Team: Belarusian (http://www.transifex.com/projects/p/XBMC-Main-Frodo/language/be/)\n" "MIME-Version: 1.0\n" @@ -23,12 +23,12 @@ msgstr "Location Setup" msgctxt "#30111" msgid "Change location 1" -msgstr "Change location 1" +msgstr "Зьмяніць месца 1" msgctxt "#30112" msgid "Change location 2" -msgstr "Change location 2" +msgstr "Зьмяніць месца 2" msgctxt "#30113" msgid "Change location 3" -msgstr "Change location 3" +msgstr "Зьмяніць месца 3" diff --git a/addons/weather.wunderground/resources/language/English/strings.po b/addons/weather.wunderground/resources/language/English/strings.po index b741f48da0..480791ef0c 100644 --- a/addons/weather.wunderground/resources/language/English/strings.po +++ b/addons/weather.wunderground/resources/language/English/strings.po @@ -1,15 +1,15 @@ # XBMC Media Center language file # Addon Name: Weather Underground # Addon id: weather.wunderground -# Addon version: 0.0.9 +# Addon version: 1.0.0 # Addon Provider: Team XBMC msgid "" msgstr "" "Project-Id-Version: XBMC-Addons\n" "Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" -"POT-Creation-Date: 2012-05-28 15:38+0000\n" +"POT-Creation-Date: 2012-09-23 21:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: XBMC Translation Team\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,20 +17,140 @@ msgstr "" "Language: en\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -msgctxt "#30101" -msgid "Location Setup" +msgctxt "#32101" +msgid "Location setup" msgstr "" -#empty strings from id 30102 to 30110 +msgctxt "#32102" +msgid "Advanced options" +msgstr "" + +#empty strings from id 32103 to 32110 + +msgctxt "#32111" +msgid "Location 1" +msgstr "" + +msgctxt "#32112" +msgid "Location 2" +msgstr "" + +msgctxt "#32113" +msgid "Location 3" +msgstr "" + +msgctxt "#32114" +msgid "Location 1 display name" +msgstr "" + +msgctxt "#32115" +msgid "Location 2 display name" +msgstr "" + +msgctxt "#32116" +msgid "Location 3 display name" +msgstr "" + +msgctxt "#32117" +msgid "Location 1 id" +msgstr "" + +msgctxt "#32118" +msgid "Location 2 id" +msgstr "" + +msgctxt "#32119" +msgid "Location 3 id" +msgstr "" + +msgctxt "#32120" +msgid "Enable logging" +msgstr "" + +msgctxt "#32121" +msgid "Weekend" +msgstr "" + +msgctxt "#32122" +msgid "Saturday/Sunday" +msgstr "" + +msgctxt "#32123" +msgid "Friday/Saturday" +msgstr "" + +msgctxt "#32124" +msgid "Thursday/Friday" +msgstr "" + +msgctxt "#32125" +msgid "Map zoom level" +msgstr "" + +msgctxt "#32126" +msgid "Animated map" +msgstr "" + +#empty strings from id 32127 to 32500 + +msgctxt "#32501" +msgid "New Moon" +msgstr "" + +msgctxt "#32502" +msgid "Waxing Crescent" +msgstr "" + +msgctxt "#32503" +msgid "First Quarter" +msgstr "" + +msgctxt "#32504" +msgid "Waxing Gibbous" +msgstr "" + +msgctxt "#32505" +msgid "Full Moon" +msgstr "" + +msgctxt "#32506" +msgid "Waning Gibbous" +msgstr "" + +msgctxt "#32507" +msgid "Last Quarter" +msgstr "" + +msgctxt "#32508" +msgid "Waning Crescent" +msgstr "" + +#empty string with id 32509 + +msgctxt "#32510" +msgid "Warning" +msgstr "" + +msgctxt "#32511" +msgid "Watch" +msgstr "" + +msgctxt "#32512" +msgid "Advisory" +msgstr "" + +msgctxt "#32513" +msgid "Statement" +msgstr "" -msgctxt "#30111" -msgid "Change location 1" +msgctxt "#32514" +msgid "Outlook" msgstr "" -msgctxt "#30112" -msgid "Change location 2" +msgctxt "#32515" +msgid "Forecast" msgstr "" -msgctxt "#30113" -msgid "Change location 3" +msgctxt "#32516" +msgid "Synopsis" msgstr "" diff --git a/addons/weather.wunderground/resources/language/Spanish (Argentina)/strings.po b/addons/weather.wunderground/resources/language/Spanish (Argentina)/strings.po new file mode 100644 index 0000000000..a25163adb5 --- /dev/null +++ b/addons/weather.wunderground/resources/language/Spanish (Argentina)/strings.po @@ -0,0 +1,34 @@ +# XBMC Media Center language file +# Addon Name: Weather Underground +# Addon id: weather.wunderground +# Addon version: 0.0.9 +# Addon Provider: Team XBMC +msgid "" +msgstr "" +"Project-Id-Version: XBMC Main Translation Project (Frodo)\n" +"Report-Msgid-Bugs-To: http://trac.xbmc.org/\n" +"POT-Creation-Date: 2012-05-28 15:38+0000\n" +"PO-Revision-Date: 2012-11-11 15:02+0000\n" +"Last-Translator: XBMC Translation Team\n" +"Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/XBMC-Main-Frodo/language/es_AR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es_AR\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30101" +msgid "Location Setup" +msgstr "Configurar ubicación" + +msgctxt "#30111" +msgid "Change location 1" +msgstr "Cambiar ubicación 1" + +msgctxt "#30112" +msgid "Change location 2" +msgstr "Cambiar ubicación 2" + +msgctxt "#30113" +msgid "Change location 3" +msgstr "Cambiar ubicación 3" diff --git a/addons/weather.wunderground/resources/lib/utilities.py b/addons/weather.wunderground/resources/lib/utilities.py index b31f732ab3..ce9eed833b 100644 --- a/addons/weather.wunderground/resources/lib/utilities.py +++ b/addons/weather.wunderground/resources/lib/utilities.py @@ -1,13 +1,55 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- + +import sys import xbmc -DAYS = { "Mon": xbmc.getLocalizedString( 11 ), - "Tue": xbmc.getLocalizedString( 12 ), - "Wed": xbmc.getLocalizedString( 13 ), - "Thu": xbmc.getLocalizedString( 14 ), - "Fri": xbmc.getLocalizedString( 15 ), - "Sat": xbmc.getLocalizedString( 16 ), - "Sun": xbmc.getLocalizedString( 17 )} +__language__ = sys.modules[ "__main__" ].__language__ + +LANG = { 'afrikaans' : 'AF', + 'arabic' : 'AR', + 'basque' : 'EU', + 'bosnian' : 'SR', # n/a + 'bulgarian' : 'BU', + 'catalan' : 'CA', + 'chinese (simple)' : 'CN', + 'chinese (traditional)' : 'TW', + 'croatian' : 'CR', + 'czech' : 'CZ', + 'danish' : 'DK', + 'dutch' : 'NL', + 'english' : 'LI', + 'english (us)' : 'EN', + 'esperanto' : 'EO', + 'finnish' : 'FI', + 'french' : 'FR', + 'german' : 'DL', + 'greek' : 'GR', + 'hebrew' : 'IL', + 'hindi (devanagiri)' : 'HI', + 'hungarian' : 'HU', + 'icelandic' : 'IS', + 'indonesian' : 'ID', + 'italian' : 'IT', + 'japanese' : 'JP', + 'korean' : 'KR', + 'lithuanian' : 'LT', + 'maltese' : 'MT', + 'norwegian' : 'NO', + 'polish' : 'PL', + 'portuguese' : 'BR', + 'portuguese (brazil)' : 'BR', + 'romanian' : 'RO', + 'russian' : 'RU', + 'serbian' : 'SR', + 'serbian (cyrillic)' : 'SR', + 'slovak' : 'SK', + 'slovenian' : 'SL', + 'spanish' : 'SP', + 'spanish (mexico)' : 'SP', + 'swedish' : 'SW', + 'thai' : 'TH', + 'turkish' : 'TU', + 'ukrainian' : 'UA'} WEATHER_CODES = { 'chanceflurries' : '41', 'chancerain' : '39', @@ -29,6 +71,7 @@ WEATHER_CODES = { 'chanceflurries' : '41', 'sunny' : '32', 'tstorms' : '35', 'unknown' : 'na', + '' : 'na', 'nt_chanceflurries' : '46', 'nt_chancerain' : '45', 'nt_chancesleet' : '45', @@ -48,4 +91,88 @@ WEATHER_CODES = { 'chanceflurries' : '41', 'nt_snow' : '46', 'nt_sunny' : '31', 'nt_tstorms' : '47', - 'nt_unknown' : 'na'} + 'nt_unknown' : 'na', + 'nt_' : 'na'} + +MONTH = { 1 : xbmc.getLocalizedString(51), + 2 : xbmc.getLocalizedString(52), + 3 : xbmc.getLocalizedString(53), + 4 : xbmc.getLocalizedString(54), + 5 : xbmc.getLocalizedString(55), + 6 : xbmc.getLocalizedString(56), + 7 : xbmc.getLocalizedString(57), + 8 : xbmc.getLocalizedString(58), + 9 : xbmc.getLocalizedString(59), + 10 : xbmc.getLocalizedString(60), + 11 : xbmc.getLocalizedString(61), + 12 : xbmc.getLocalizedString(62)} + +WEEKDAY = { 0 : xbmc.getLocalizedString(41), + 1 : xbmc.getLocalizedString(42), + 2 : xbmc.getLocalizedString(43), + 3 : xbmc.getLocalizedString(44), + 4 : xbmc.getLocalizedString(45), + 5 : xbmc.getLocalizedString(46), + 6 : xbmc.getLocalizedString(47)} + +SEVERITY = { 'W' : __language__(32510), + 'A' : __language__(32511), + 'Y' : __language__(32512), + 'S' : __language__(32513), + 'O' : __language__(32514), + 'F' : __language__(32515), + 'N' : __language__(32516), + 'L' :'', # no idea + '' : ''} + +def MOONPHASE(age, percent): + if (percent == 0) and (age == 0): + phase = __language__(32501) + elif (age < 17) and (age > 0) and (percent > 0) and (percent < 50): + phase = __language__(32502) + elif (age < 17) and (age > 0) and (percent == 50): + phase = __language__(32503) + elif (age < 17) and (age > 0) and (percent > 50) and (percent < 100): + phase = __language__(32504) + elif (age > 0) and (percent == 100): + phase = __language__(32505) + elif (age > 15) and (percent < 100) and (percent > 50): + phase = __language__(32506) + elif (age > 15) and (percent == 50): + phase = __language__(32507) + elif (age > 15) and (percent < 50) and (percent > 0): + phase = __language__(32508) + else: + phase = '' + return phase + +def KPHTOBFT(spd): + if (spd < 1.0): + bft = '0' + elif (spd >= 1.0) and (spd < 5.6): + bft = '1' + elif (spd >= 5.6) and (spd < 12.0): + bft = '2' + elif (spd >= 12.0) and (spd < 20.0): + bft = '3' + elif (spd >= 20.0) and (spd < 29.0): + bft = '4' + elif (spd >= 29.0) and (spd < 39.0): + bft = '5' + elif (spd >= 39.0) and (spd < 50.0): + bft = '6' + elif (spd >= 50.0) and (spd < 62.0): + bft = '7' + elif (spd >= 62.0) and (spd < 75.0): + bft = '8' + elif (spd >= 75.0) and (spd < 89.0): + bft = '9' + elif (spd >= 89.0) and (spd < 103.0): + bft = '10' + elif (spd >= 103.0) and (spd < 118.0): + bft = '11' + elif (spd >= 118.0): + bft = '12' + else: + bft = '' + return bft diff --git a/addons/weather.wunderground/resources/lib/wunderground/__init__.py b/addons/weather.wunderground/resources/lib/wunderground/__init__.py new file mode 100644 index 0000000000..b93054b3ec --- /dev/null +++ b/addons/weather.wunderground/resources/lib/wunderground/__init__.py @@ -0,0 +1 @@ +# Dummy file to make this directory a package. diff --git a/addons/weather.wunderground/resources/lib/wunderground/wunderground.py b/addons/weather.wunderground/resources/lib/wunderground/wunderground.py new file mode 100644 index 0000000000..809b583f09 --- /dev/null +++ b/addons/weather.wunderground/resources/lib/wunderground/wunderground.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +import urllib2, base64 + +WAIK = 'NDEzNjBkMjFkZjFhMzczNg==' +WUNDERGROUND_URL = 'http://api.wunderground.com/api/KEY/%s/%s/q/%s.%s' +API_EXCLUDE = ['hourly10day', 'yesterday', 'planner', 'webcams', 'animatedradar', 'animatedsatellite', 'currenthurricane'] + +def wundergroundapi(features, settings, query, format): + + """ + wunderground api module + + How to use: + + 1) import the wunderground addon in your addon.xml: + <requires> + <import addon="weather.wunderground" version="0.1.12"/> + </requires> + + 2) import the wunderground api module in your script: + from wunderground import wundergroundapi + + 3) to fetch weather data: + weatherdata = wundergroundapi(features, settings, query, format) + + see http://www.wunderground.com/weather/api/d/docs?d=data/index + for api features, optional settings, query examples and response formats. + """ + + for item in API_EXCLUDE: + if item in features: + return 'api access to %s restricted' % item + if not settings: + settings = 'lang:EN' + query = WUNDERGROUND_URL % (features, settings, query, format) + url = query.replace('KEY',(base64.b64decode(WAIK)[::-1]),1) + try: + req = urllib2.urlopen(url) + response = req.read() + req.close() + except: + response = '' + return response diff --git a/addons/weather.wunderground/resources/logo/logo.jpg b/addons/weather.wunderground/resources/logo/logo.jpg Binary files differnew file mode 100644 index 0000000000..cc08b54b53 --- /dev/null +++ b/addons/weather.wunderground/resources/logo/logo.jpg diff --git a/addons/weather.wunderground/resources/settings.xml b/addons/weather.wunderground/resources/settings.xml index 38fc86e120..33dfdd55ab 100644 --- a/addons/weather.wunderground/resources/settings.xml +++ b/addons/weather.wunderground/resources/settings.xml @@ -1,11 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <settings> - <category label="30101"> - <setting id="Location1" label="30111" type="action" action="RunScript($ID,Location1)" default=""/> - <setting id="Location2" label="30112" type="action" action="RunScript($ID,Location2)" enable="!eq( -1,)" default=""/> - <setting id="Location3" label="30113" type="action" action="RunScript($ID,Location3)" enable="!eq( -1,)" default=""/> + <category label="32101"> + <setting id="Location1" label="32111" type="action" action="RunScript($ID,Location1)" default=""/> + <setting id="Location2" label="32112" type="action" action="RunScript($ID,Location2)" enable="!eq(-1,)" default=""/> + <setting id="Location3" label="32113" type="action" action="RunScript($ID,Location3)" enable="!eq(-1,)" default=""/> <setting id="Location1id" type="text" visible="false" default=""/> <setting id="Location2id" type="text" visible="false" default=""/> <setting id="Location3id" type="text" visible="false" default=""/> </category> + <category label="32102"> + <setting id="Location1" label="32114" type="text" default=""/> + <setting id="Location1id" label="32117" type="text" subsetting="true" default=""/> + <setting type="sep"/> + <setting id="Location2" label="32115" type="text" enable="!eq(-3,)" default=""/> + <setting id="Location2id" label="32118" type="text" subsetting="true" enable="!eq(-3,)" default=""/> + <setting type="sep"/> + <setting id="Location3" label="32116" type="text" enable="!eq(-3,)" default=""/> + <setting id="Location3id" label="32119" type="text" subsetting="true" enable="!eq(-3,)" default=""/> + <setting type="sep"/> + <setting id="Zoom" label="32125" type="slider" option="int" range="1,100" default="10"/> + <setting id="Animate" label="32126" type="bool" default="false"/> + <setting id="Weekend" label="32121" type="enum" lvalues="32122|32123|32124" default="0"/> + <setting type="sep"/> + <setting id="Debug" label="32120" type="bool" default="false"/> + </category> </settings> |