aboutsummaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorMartijn Kaijser <mcm.kaijser@gmail.com>2012-11-14 22:56:35 +0100
committerMartijn Kaijser <mcm.kaijser@gmail.com>2012-11-14 22:56:35 +0100
commitc09acdd7e9edb491012f3ad26c8c7fc9b89dc968 (patch)
tree15ce133c4b6dd10355c6eb05ed3cbfae6d80c390 /addons
parent363cc4ba6c3b972452f881879ccb2fef5e82ed42 (diff)
[weather] sync wunderground with repo
Diffstat (limited to 'addons')
-rw-r--r--addons/weather.wunderground/README.txt187
-rw-r--r--addons/weather.wunderground/addon.xml7
-rw-r--r--addons/weather.wunderground/changelog.txt73
-rw-r--r--addons/weather.wunderground/default.py633
-rw-r--r--addons/weather.wunderground/resources/language/Belarusian/strings.po8
-rw-r--r--addons/weather.wunderground/resources/language/English/strings.po144
-rw-r--r--addons/weather.wunderground/resources/language/Spanish (Argentina)/strings.po34
-rw-r--r--addons/weather.wunderground/resources/lib/utilities.py145
-rw-r--r--addons/weather.wunderground/resources/lib/wunderground/__init__.py1
-rw-r--r--addons/weather.wunderground/resources/lib/wunderground/wunderground.py44
-rw-r--r--addons/weather.wunderground/resources/logo/logo.jpgbin0 -> 28687 bytes
-rw-r--r--addons/weather.wunderground/resources/settings.xml24
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&#10;(http://www.wunderground.com/)</description>
+ <description lang="es_AR">Predicción meteorológica proporcionada por Weather Underground&#10;(http://www.wunderground.com/)</description>
<description lang="es_MX">Pronóstico del tiempo por Weather Underground&#10;(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
new file mode 100644
index 0000000000..cc08b54b53
--- /dev/null
+++ b/addons/weather.wunderground/resources/logo/logo.jpg
Binary files differ
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>