weather-indicator-team team mailing list archive
-
weather-indicator-team team
-
Mailing list archive
-
Message #00133
[Merge] lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0
Joshua has proposed merging lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0.
Requested reviews:
Weather Indicator Team (weather-indicator-team)
For more details, see:
https://code.launchpad.net/~jtasker/weather-indicator/cloudy/+merge/164598
This fixes all the "SIGSEGV" bugs related to glib/dbus; (libdbus is not thread-safe - I re-wrote some of the threading code to deal with this)
I also updated it to use Gtk3 and GObject, instead of the now-deprecated PyGtk.
Finally, I added code to calculate humidex/wind chill, and added a related tab to the Preferences Dialog.
Note that this version requires pywapi 0.3.1, which is available here:
http://code.google.com/p/python-weather-api/downloads/detail?name=pywapi-0.3.1.tar.gz
deb packages for pywapi 0.3.1 are available here:
https://launchpad.net/~pywapi-devel
>From the changelog:
* Ported to GTK3 and GObject from PyGTK
* Rewrite threading code to avoid dbus-related crashes (LP: #743541)
* Added "feels like" temperature (humidex/heat index/wind chill)
* New "Conditions" tab in Preferences dialog to choose temperature
formulas and toggle display of some condition information
* Bumped version number to reflect massive changes
Note that it still sometimes gives LIBDBUSMENU-GLIB warnings to .xsession-errors, but they can be safely ignored - I have left it running for a week straight with no crashes.
--
https://code.launchpad.net/~jtasker/weather-indicator/cloudy/+merge/164598
Your team Weather Indicator Team is requested to review the proposed merge of lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0.
=== modified file 'AUTHORS'
--- AUTHORS 2011-03-19 09:27:37 +0000
+++ AUTHORS 2013-05-18 18:24:25 +0000
@@ -1,3 +1,4 @@
Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
Copyright (C) 2010 Vadim Rutkovsky roignac@xxxxxxxxx
+Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx
=== modified file 'bin/indicator-weather'
--- bin/indicator-weather 2012-07-30 04:02:24 +0000
+++ bin/indicator-weather 2013-05-18 18:24:25 +0000
@@ -4,6 +4,7 @@
# Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
# Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
# Copyright (C) 2011 Vadim Rutkovsky roignac@xxxxxxxxx
+# Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
@@ -17,29 +18,26 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
### END LICENSE
-try:
- from gi.repository import Gio
-except ImportError:
- pass
+from gi.repository import Gio, GLib, Gtk, Gdk, Notify, GObject, GdkPixbuf
+from gi.repository import AppIndicator3 as AppIndicator
+
import sys, os, shutil, tempfile
-import gtk, pygtk, gobject, pynotify
-pygtk.require('2.0')
-import appindicator
+
import urllib2, urllib
from urllib import urlencode
import re
import locale
from xml.dom.minidom import parseString
import datetime
-import dbus
+#import dbus
import time
import traceback
import types
-# Will be used for humidex
-#import math
+from math import exp
import commands, threading
import logging, logging.handlers
import pywapi
+import Queue
import gettext
from gettext import gettext as _
@@ -55,7 +53,7 @@
sys.path.insert(0, PROJECT_ROOT_DIRECTORY)
os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses
-VERSION = "12.07.30 'Cloudy 10'"
+VERSION = "13.05.17 'Cloudy 11'"
from indicator_weather.helpers import *
@@ -69,11 +67,16 @@
WEATHER_KEY = 'weather'
LOCATIONS_KEY = 'locations'
INDICATOR_DISPLAY = 'show_label'
+ RELATIVE_DISPLAY = 'show_relative'
+ WIND_DISPLAY = 'show_wind'
+ SUNTIMES_DISPLAY = 'show_suntimes'
NOTIFICATIONS = 'notif'
WEATHER_SOURCE = 'data_source'
REFRESH_RATE = 'refresh_rate'
METRIC_SYSTEM = 'unit'
WIND_UNIT = 'wind'
+ HEAT_ESTIMATE = 'heat'
+ CHILL_ESTIMATE = 'chill'
PLACECHOSEN = 'placechosen'
PLACES = 'places'
@@ -84,47 +87,67 @@
INDICATOR_DISPLAY : {
INFO_TYPE : types.IntType,
INFO_SETTING : 'indicator-display'
- },
+ },
+ RELATIVE_DISPLAY : {
+ INFO_TYPE : types.BooleanType,
+ INFO_SETTING : 'relative-display'
+ },
+ WIND_DISPLAY : {
+ INFO_TYPE : types.BooleanType,
+ INFO_SETTING : 'wind-display'
+ },
+ SUNTIMES_DISPLAY : {
+ INFO_TYPE : types.BooleanType,
+ INFO_SETTING : 'suntimes-display'
+ },
NOTIFICATIONS : {
INFO_TYPE : types.StringType,
INFO_SETTING : 'notifications'
- },
+ },
WEATHER_SOURCE : {
INFO_TYPE : types.StringType,
INFO_SETTING : 'weather-source'
- },
+ },
REFRESH_RATE : {
INFO_TYPE : types.IntType,
INFO_SETTING : 'refresh-rate'
- },
+ },
METRIC_SYSTEM : {
INFO_TYPE : types.StringType,
INFO_SETTING : 'metric-system'
- },
+ },
WIND_UNIT : {
INFO_TYPE : types.StringType,
INFO_SETTING : 'wind-unit'
- },
+ },
+ HEAT_ESTIMATE: {
+ INFO_TYPE : types.StringType,
+ INFO_SETTING : 'heat-estimate'
+ },
+ CHILL_ESTIMATE: {
+ INFO_TYPE : types.StringType,
+ INFO_SETTING : 'chill-estimate'
+ },
PLACECHOSEN : {
INFO_TYPE : types.IntType,
INFO_SETTING: 'placechosen'
- },
+ },
PLACES : {
INFO_TYPE : types.ListType,
INFO_SETTING: 'places'
- },
+ },
}
- # Open the DB
def prepare_settings_store(self):
+ """ Open the DB """
log.debug("Settings: preparing settings store")
try:
self.db = Gio.Settings.new(self.BASE_KEY)
except Exception as e:
log.debug("Settings: exception occurred while opening settings:\n %s" % str(e))
- # Make sure autostart file is installed. Inspired by GTG.
def check_autostart(self):
+ """ Make sure autostart file is installed. Inspired by GTG. """
autostart_dir = os.path.join(os.path.expanduser("~"),".config/autostart/")
autostart_file = "indicator-weather.desktop"
autostart_path = os.path.join(autostart_dir, autostart_file)
@@ -136,11 +159,11 @@
this_directory = os.path.dirname(os.path.abspath(__file__))
for path in desktop_file_directories:
fullpath = os.path.normpath(os.path.join(this_directory, path, \
- autostart_file))
+ autostart_file))
if os.path.isfile(fullpath):
desktop_file_path = fullpath
break
- #If we have found the desktop file, we make a link to in in
+ # If we have found the desktop file, we make a link to in in
# autostart_path.
if desktop_file_path:
if not os.path.exists(autostart_dir):
@@ -149,8 +172,8 @@
log.debug("Installing autostart file.")
os.symlink(desktop_file_path, autostart_path)
- # Get a value of the setting
def get_value(self, setting, return_id = False):
+ """ Get a value of the specified setting """
log.debug("Settings: getting value for %s" % setting)
setting_name = Settings.INFO[setting][INFO_SETTING]
try:
@@ -162,15 +185,15 @@
types.ListType: self.db.get_string,
types.DictType: self.db.get_string,
types.NoneType: self.db.get_value,
- }[setting_type]
+ }[setting_type]
return get_func(setting_name)
except:
- self.log.debug("Settings: can't find value for %s" % setting)
+ log.debug("Settings: can't find value for %s" % setting)
return None
- # Set a setting value
+
def set_value(self, setting, value):
-
+ """ Set a value for the specified setting """
value = '' if value is None else value
value = str(value) if type(value) is types.ListType else value
log.debug("Settings: setting '%s'='%s'" % (setting, value))
@@ -185,17 +208,19 @@
types.ListType: self.db.set_string,
types.DictType: self.db.set_string,
types.NoneType: self.db.set_value,
- }[setting_type]
+ }[setting_type]
set_func(setting_name, value)
except:
log.debug( \
"Settings: schema for '%s' not found, aborting" % setting)
- # Get cached weather by location code.
- # If return_id is True, only document id is returned, otherwise - full weather data
def get_weather(self, location_code, return_id = False):
+ """Get cached weather by location code.
+ If return_id is True, only document id is returned, otherwise - full weather data
+
+ """
log.debug("Settings: getting cached weather for %s" % \
- location_code)
+ location_code)
try:
cached_weather_string = self.db.get_string(self.WEATHER_KEY)
cached_weather = {} if cached_weather_string == ''\
@@ -207,22 +232,22 @@
"Settings: can't find value for %s" % location_code)
return None
except:
- log.debug("Settings: can't find %s setting" % WEATHER_KEY)
+ log.debug("Settings: can't find %s setting" % self.WEATHER_KEY)
return None
- # Save weather info in cache for specific location
def save_weather(self, weather, location_code):
-
+ """ Save weather info in cache for specific location """
record = {
- "label" : weather.get_temperature(needs_rounding=True),
- "condition": weather.get_condition_label(),
- "icon" : weather.get_icon_name(),
- "temper" : weather.get_temperature_label(),
- "humidex" : weather.get_humidex_label(),
- "humidity" : weather.get_humidity_label(),
- "wind" : weather.get_wind_label(),
- "sunrise" : weather.get_sunrise_label(),
- "sunset" : weather.get_sunset_label()
+## "label" : weather.get_temperature(needs_rounding=True),
+ "label" : weather.get_temperature_string(),
+ "condition" : weather.get_condition_label(),
+ "icon" : weather.get_icon_name(),
+ "temper" : weather.get_temperature_label(),
+ "feelslike" : weather.get_relative_label(),
+ "humidity" : weather.get_humidity_label(),
+ "wind" : weather.get_wind_label(),
+ "sunrise" : weather.get_sunrise_label(),
+ "sunset" : weather.get_sunset_label()
}
log.debug("Settings: setting '%s'='%s'" % (location_code, record))
@@ -235,11 +260,14 @@
self.db.set_string(self.WEATHER_KEY, cached_weather_string)
except:
log.debug(\
- "Settings: schema for '%s' not found, aborting" % setting)
+ "Settings: schema for '%s' not found, aborting" % self.WEATHER_KEY)
- # Get location details by location code
- # If return_id is True, only document id is returned, otherwise - full location data
def get_location_details(self, location_code, return_id = False):
+ """ Get location details by location code
+ If return_id is True, only document id is returned,
+ otherwise - full location data is returned
+
+ """
try:
locations_string = self.db.get_string(self.LOCATIONS_KEY)
locations = {} if locations_string == ''\
@@ -252,14 +280,13 @@
return None
except:
log.debug("Settings: can't find location details for %s" % \
- location_code)
+ location_code)
return None
- # Save location details
def save_location_details(self, location_details, location_code):
+ """ Save location details """
log.debug("Settings: setting '%s'='%s'" %\
- (location_code, location_details))
-
+ (location_code, location_details))
try:
locations_string = self.db.get_string(self.LOCATIONS_KEY)
locations = {} if locations_string == ''\
@@ -270,8 +297,8 @@
except:
pass
-class MetricSystem:
- """ Class with available metric systems units """
+class UnitSystem:
+ """ Class with available measurement unit systems """
SI = 1
IMPERIAL = 2
@@ -285,52 +312,65 @@
class WeatherDataSource:
""" Class for available weather data sources """
- GOOGLE = 1
- YAHOO = 2
+ YAHOO = 1
+ WEATHER_COM = 2
+class RelativeFormula:
+ """ Class for relative temperature formulas """
+ HEATINDEX = 1
+ HUMIDEX = 2
+ WINDCHILL = 3
+ APPARENT = 4
+
class Location:
""" Data object to store location details """
- # Initialize an object with a label
- def __init__(self, metric_system, wind_unit, location_details = None):
+ def __init__(self, metric_system, wind_unit, heat_index, chill_index, location_details = None):
+ """ Initialize an object with a label """
self.metric_system = metric_system
self.wind_unit = wind_unit
+ self.heat_index = heat_index
+ self.chill_index = chill_index
self.location_details = location_details
- # Convert coordinate for google
def convert_coordinate_for_google(self, value):
- value = float(value) * 1e6
- return int(round(value))
+ """ Convert coordinate for google """
+ value = float(value) * 1e6
+ return int(round(value))
- # Get necessary location details by its GeoNames details
def prepare_location(self, geonames_details):
+ """ Get necessary location details by its GeoNames details """
self.location_details = {}
self.location_details['full name'] = geonames_details[0]
self.location_details['latitude'] = geonames_details[2]
self.location_details['longitude'] = geonames_details[3]
self.prepare_location_for_google(geonames_details)
self.prepare_location_for_yahoo(geonames_details)
+ #TODO: Get weather.com id
+ #HACK, make a real routine to do this (pretty sure id is correct though)
+ self.location_details['weather-com id'] = self.location_details['yahoo id']
#TODO: Get noaa id from geonames service
self.location_details['noaa id'] = "woot"
# check mandatory attributes
if not hasattr(self, 'location_code') or \
- 'latitude' not in self.location_details or \
- 'longitude' not in self.location_details:
+ 'latitude' not in self.location_details or \
+ 'longitude' not in self.location_details:
return False
# check that we have at least one supported data source
if 'google id' not in self.location_details and \
- 'yahoo id' not in self.location_details:
+ 'yahoo id' not in self.location_details and \
+ 'weather-com id' not in self.location_details:
log.error(("Location '%s'" %
- self.location_details['full name'])) + \
+ self.location_details['full name'])) + \
"is not supported by current data sources"
return False
return True
def prepare_location_for_google(self, geonames_details):
- # Format latitude and longitude for Google needs
+ """ Format latitude and longitude for Google needs """
try:
lat = self.convert_coordinate_for_google(geonames_details[2])
lon = self.convert_coordinate_for_google(geonames_details[3])
@@ -340,7 +380,7 @@
log.error(e)
def prepare_location_for_yahoo(self, geonames_details):
- # Get location details in english for Yahoo
+ """ Get location details in english for Yahoo """
baseurl = 'http://api.geonames.org/getJSON'
params = {'geonameId': geonames_details[1], 'username': 'indicatorweather'}
url = '?'.join((baseurl, urlencode(params)))
@@ -356,19 +396,13 @@
return
# Get YAHOO WOEID by english name of location
- baseurl = 'http://where.yahooapis.com/geocode'
- params = {'location': displayed_city_name, 'appid': 'mOawLd4s', 'flags': 'J'}
- url = '?'.join((baseurl, urlencode(params)))
- log.debug("Location: Get Yahoo WOEID, url %s" % url)
- f = urllib2.urlopen(url)
- s=f.read()
- null = None
- yahoo_woeid_result = eval(s)
- if (yahoo_woeid_result['ResultSet']['Error'] != 0) and (yahoo_woeid_result['ResultSet']['Results'] != None):
- log.error("Location: Yahoo woeid return error. Full response:\n %s" % str(yahoo_woeid_result))
+ woeid_result = pywapi.get_woeid_from_yahoo(displayed_city_name)
+ if woeid_result.has_key('error'):
+ log.error("Location: Yahoo woeid return error. Full response:\n %s" % woeid_result['error'])
return
else:
- woeid = yahoo_woeid_result['ResultSet']['Results'][0]['woeid']
+ # only look at the the first woeid result
+ woeid = woeid_result[0][0]
self.location_code = woeid
log.debug("Location: woeid is %s" % woeid)
@@ -400,21 +434,24 @@
except Exception, e:
log.error(e)
- # Return lcoation code and location details
def export_location_details(self):
+ """ Return location code and location details """
return (self.location_code, self.location_details)
- # Get fresh weather data and store it to weather object
def update_weather_data(self, source):
- # gather existing source keys
+ """ Get fresh weather data and store it to weather object """
valid_source = None
loc_ids = {}
SOURCES = {
- WeatherDataSource.GOOGLE : ("google id", "Google"),
- WeatherDataSource.YAHOO : ("yahoo id", "Yahoo"),
+ WeatherDataSource.WEATHER_COM : ("weather-com id", "Weather.com"),
+ WeatherDataSource.YAHOO : ("yahoo id", "Yahoo")
}
+ log.debug("Location: update_weather_data: source=%s" % source) #DEBUG
+ log.debug("SOURCES=%s" % SOURCES) #DEBUG
+ log.debug("self.location_details=%s" % self.location_details) #DEBUG
+ # gather existing source keys
for source_id in SOURCES.keys():
if SOURCES[source_id][0] in self.location_details:
loc_ids[source_id] = SOURCES[source_id][0]
@@ -423,158 +460,156 @@
if source in loc_ids:
valid_source = source
log.debug(("Location: default weather source '%s' " +
- "chosen for '%s'") % (SOURCES[valid_source][1],
- self.location_details['label']))
+ "chosen for '%s'") % (SOURCES[valid_source][1],
+ self.location_details['label']))
# try with the first alternative
elif len(loc_ids.keys()):
valid_source = loc_ids.keys()[0]
- log.debug(("Location: non default weather source '%s' " +
- "chosen for '%s'") % (SOURCES[valid_source][1],
- self.location_details['label']))
if valid_source is None:
log.error(("Location: no valid weather source can be " +
- "chosen for '%s'") % (
- self.location_details['label']))
+ "chosen for '%s'") % (
+ self.location_details['label']))
self.weather = None
else:
+ log.debug(("Location: non default weather source '%s' " +
+ "chosen for '%s'") % (SOURCES[valid_source][1],
+ self.location_details['label']))
+ log.debug(("Location: update_weather_data: creating object: "
+ "Weather(location_id=%s, weather_datasource=%s, "
+ "metric_system=%s, wind_unit=%s, heat_index=%s, "
+ "chill_index=%s, lat=%s, lon=%s)") % (
+ self.location_details[loc_ids[valid_source]],
+ valid_source, self.metric_system, self.wind_unit,
+ self.heat_index, self.chill_index,
+ self.location_details['latitude'],
+ self.location_details['longitude'])) #DEBUG
self.weather = Weather(
self.location_details[loc_ids[valid_source]],
valid_source, self.metric_system, self.wind_unit,
+ self.heat_index, self.chill_index,
self.location_details['latitude'],
self.location_details['longitude'])
+ log.debug("Location: update_weather_data: self.weather object created") #DEBUG
class Forecast:
""" Class to get forecast information """
- # Initialize a class with metric system, wind units, location and current user locale
- def __init__ (self, units, lat, lon, locale):
+ def __init__ (self, units, location_id, locale):
+ """Initialize a class with metric system, wind units,
+ location code and current user locale
+
+ """
self.metric_system = units
- self.lat = self.convert_coordinate_for_google(lat)
- self.lon = self.convert_coordinate_for_google(lon)
+ self.location_id = location_id
self.locale = locale
- # Convert coordinate for google
- def convert_coordinate_for_google(self, value):
- value = float(value) * 1e6
- return int(round(value))
-
- # Get and store forecast data. For now using Google only
def prepare_forecast_data(self):
+ """ Get and store forecast data. For now using Yahoo only. """
+ # TODO: Implement Weather.com
self.daysofweek = []
self.icons = []
self.conditions = []
self.error_message = None
try:
- # Generate a fake location by current coordinates
- location_name = ",,,%s,%s" % (self.lat, self.lon)
- self.forecast = pywapi.get_weather_from_google (location_name, hl = self.locale)
- self.unitsystem = self.forecast['forecast_information']['unit_system']
-
+ log.debug("Forecast: units set to %s" % self.metric_system)
+ # Check units, default to imperial
+ if self.metric_system == UnitSystem.SI:
+ self.unitsystem = 'metric'
+ elif self.metric_system == UnitSystem.IMPERIAL:
+ self.unitsystem = 'imperial'
+ else:
+ self.unitsystem = 'imperial'
+
+ log.debug("calling pywapi.get_weather_from_yahoo(%s, %s)" % (self.location_id, self.unitsystem)) #DEBUG
+ self.forecast = pywapi.get_weather_from_yahoo(self.location_id, self.unitsystem)
+
+ log.debug("get_weather_from_yahoo returned %s" % self.forecast) #DEBUG
for forecast in self.forecast['forecasts']:
- self.daysofweek.append(forecast["day_of_week"])
- forecast_icon = str(forecast["icon"])
- if "/ig/images/weather/" in forecast_icon:
- self.icons.append(forecast_icon.split("/ig/images/weather/")[-1].split(".gif")[0])
- elif "http://g0.gstatic.com/images/icons/onebox" in forecast_icon:
- self.icons.append(forecast_icon.split("http://g0.gstatic.com/images/icons/onebox/weather_")[-1].split("-40.gif")[0])
- self.conditions.append(forecast["condition"])
+ self.daysofweek.append(forecast["day"])
+
+ # Yahoo forecast icon URL is "http://l.yimg.com/a/i/us/we/52/<code>.gif"
+ self.icons.append(forecast["code"])
+ self.conditions.append(forecast["text"])
+
self.error_message = None
except urllib2.URLError:
- log.error("Forecast: error reading forecast for %s" % location_name)
+ log.error("Forecast: error reading forecast for %s" % self.location_id)
except KeyError:
- log.error("Forecast: returned empty forecast %s" % location_name)
+ log.error("Forecast: returned empty forecast %s" % self.location_id)
self.error_message = _('Unknown error occurred while picking up weather data')
- # Parse high values for forecast data
def get_forecast_data(self):
+ """ Parse high and low values for forecast data """
self.highdata = []
self.lowdata = []
- if not hasattr(self, 'unitsystem'):
- return None
-
- if ((self.unitsystem == 'SI') and (self.metric_system == MetricSystem.SI)) or ((self.unitsystem == 'US') and (self.metric_system == MetricSystem.IMPERIAL)):
- #correct scale selected
- for forecast in self.forecast['forecasts']:
- self.highdata.append(forecast["high"])
- self.lowdata.append(forecast["low"])
-
- elif ((self.unitsystem == 'SI') and (self.metric_system == MetricSystem.IMPERIAL)):
- #convert from SI to imperial
- for forecast in self.forecast['forecasts']:
- self.highdata.append(int(((int(forecast["high"])*9)/5)+32))
- self.lowdata.append(int(((int(forecast["low"])*9)/5)+32))
-
- elif ((self.unitsystem == 'US') and (self.metric_system == MetricSystem.SI)):
- #convert from imperial to SI
- for forecast in self.forecast['forecasts']:
- self.highdata.append(int((((int(forecast["high"]))-32)*5)/9))
- self.lowdata.append(int((((int(forecast["low"]))-32)*5)/9))
+ # Since we are now using Yahoo, forecast will always be in correct units
+ for forecast in self.forecast['forecasts']:
+ self.highdata.append(forecast["high"])
+ self.lowdata.append(forecast["low"])
return (self.highdata, self.lowdata)
- # Parse a list of days of week with forecast data
def get_forecast_daysofweek(self):
+ """ Parse a list of days of week with forecast data """
return self.daysofweek
- # Parse icons for forecast data
def get_forecast_icons(self):
+ """ Parse icons for forecast data """
return self.icons
- # Parse conditions for forecast data
def get_forecast_conditions(self):
+ """ Parse conditions for forecast data """
return self.conditions
class Weather:
- """
- Data object to parse weather data with unit convertion
- """
-
- #Available conditions by google icon
- #Format: Google icon name: (day icon, night icon, is a severe weather condition)
- #Reference: http://www.blindmotion.com/2009/03/google-weather-api-images/
- _GoogleConditions = {
- "sunny" : ( "weather-clear", "weather-clear-night", False),
- "mostly_sunny" : ( "weather-clear", "weather-clear-night", False),
- "partlycloudy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
- "partly_cloudy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
- "windy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
- "cloudy" : ( "weather-clouds", "weather-clouds-night", False),
- "mostlycloudy" : ( "weather-overcast", "weather-overcast", False),
- "mostly_cloudy" : ( "weather-overcast", "weather-overcast", False),
- "overcast" : ( "weather-overcast", "weather-overcast", False),
- "rain" : ( "weather-showers", "weather-showers", False),
- "chanceofrain" : ( "weather-showers", "weather-showers", False),
- "chance_of_rain" : ( "weather-showers", "weather-showers", False),
- "heavyrain" : ( "weather-showers", "weather-showers", False),
- "drizzle" : ( "weather-showers", "weather-showers", False),
- "sleet" : ( "weather-snow", "weather-snow", False),
- "rain_snow" : ( "weather-snow", "weather-snow", False),
- "rainsnow" : ( "weather-snow", "weather-snow", False),
- "snow" : ( "weather-snow", "weather-snow", False),
- "chanceofsnow" : ( "weather-snow", "weather-snow", False),
- "chance_of_snow" : ( "weather-snow", "weather-snow", False),
- "heavysnow" : ( "weather-snow", "weather-snow", False),
- "icy" : ( "weather-snow", "weather-snow", False),
- "snowflurries" : ( "weather-snow", "weather-snow", False),
- "flurries" : ( "weather-snow", "weather-snow", False),
- "dust" : ( "weather-fog", "weather-fog", False),
- "fog" : ( "weather-fog", "weather-fog", False),
- "smoke" : ( "weather-fog", "weather-fog", False),
- "haze" : ( "weather-fog", "weather-fog", False),
- "mist" : ( "weather-fog", "weather-fog", False),
- "thunderstorm" : ( "weather-storm", "weather-storm", True),
- "chance_of_storm" : ( "weather-storm", "weather-storm", True),
- "thunderstorms" : ( "weather-storm", "weather-storm", True),
- "scatteredshowers" : ( "weather-showers-scattered", "weather-showers-scattered", True),
- "scatteredthunderstorms" : ( "weather-storm", "weather-storm", True),
- }
-
- #Available conditions by yahoo condition code
- #Format: condition code: (day icon, night icon, is a severe weather condition, localized condition name)
+ """Data object to parse weather data with unit conversion """
+
+## #Available conditions by google icon
+## #Format: Google icon name: (day icon, night icon, is a severe weather condition)
+## #Reference: http://www.blindmotion.com/2009/03/google-weather-api-images/
+## _GoogleConditions = {
+## "sunny" : ( "weather-clear", "weather-clear-night", False),
+## "mostly_sunny" : ( "weather-clear", "weather-clear-night", False),
+## "partlycloudy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
+## "partly_cloudy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
+## "windy" : ( "weather-few-clouds", "weather-few-clouds-night", False),
+## "cloudy" : ( "weather-clouds", "weather-clouds-night", False),
+## "mostlycloudy" : ( "weather-overcast", "weather-overcast", False),
+## "mostly_cloudy" : ( "weather-overcast", "weather-overcast", False),
+## "overcast" : ( "weather-overcast", "weather-overcast", False),
+## "rain" : ( "weather-showers", "weather-showers", False),
+## "chanceofrain" : ( "weather-showers", "weather-showers", False),
+## "chance_of_rain" : ( "weather-showers", "weather-showers", False),
+## "heavyrain" : ( "weather-showers", "weather-showers", False),
+## "drizzle" : ( "weather-showers", "weather-showers", False),
+## "sleet" : ( "weather-snow", "weather-snow", False),
+## "rain_snow" : ( "weather-snow", "weather-snow", False),
+## "rainsnow" : ( "weather-snow", "weather-snow", False),
+## "snow" : ( "weather-snow", "weather-snow", False),
+## "chanceofsnow" : ( "weather-snow", "weather-snow", False),
+## "chance_of_snow" : ( "weather-snow", "weather-snow", False),
+## "heavysnow" : ( "weather-snow", "weather-snow", False),
+## "icy" : ( "weather-snow", "weather-snow", False),
+## "snowflurries" : ( "weather-snow", "weather-snow", False),
+## "flurries" : ( "weather-snow", "weather-snow", False),
+## "dust" : ( "weather-fog", "weather-fog", False),
+## "fog" : ( "weather-fog", "weather-fog", False),
+## "smoke" : ( "weather-fog", "weather-fog", False),
+## "haze" : ( "weather-fog", "weather-fog", False),
+## "mist" : ( "weather-fog", "weather-fog", False),
+## "thunderstorm" : ( "weather-storm", "weather-storm", True),
+## "chance_of_storm" : ( "weather-storm", "weather-storm", True),
+## "thunderstorms" : ( "weather-storm", "weather-storm", True),
+## "scatteredshowers" : ( "weather-showers-scattered", "weather-showers-scattered", True),
+## "scatteredthunderstorms" : ( "weather-storm", "weather-storm", True),
+## }
+
+ # Available conditions by yahoo condition code
+ # Format: condition code: (day icon, night icon, is a severe weather condition, localized condition name)
_YahooConditions = {
'0' : ("weather-storm", "weather-storm", True, _("Tornado")),
'1' : ("weather-storm", "weather-storm", True, _("Tropical storm")),
@@ -628,55 +663,66 @@
'3200': (False, False, False, _("Unknown condition"))
}
- # Initialize and get fresh data
- def __init__(self, location_id, weather_datasource, metric_system, wind_unit, lat, lon):
+ # Available conditions by Weather.com condition code; same as Yahoo
+ _WeathercomConditions = _YahooConditions
+
+ def __init__(self, location_id, weather_datasource, metric_system,
+ wind_unit, heat_index, chill_index, lat, lon):
+ """ Initialize and get fresh weather data """
self.__weather_datasource = weather_datasource
self.__metric_system = metric_system
self._wind_unit = wind_unit
self.__current_condition = None
+ self.__heat_index = heat_index
+ self.__chill_index = chill_index
self.__lat = lat
self.__lon = lon
- # Get data from Google
- if self.__weather_datasource == WeatherDataSource.GOOGLE:
- # Get data in english locale, then - switch back
- self.__report = pywapi.get_weather_from_google (location_id, hl = 'en')
- # Get data in original locale for condition name
- self.__localized_report = pywapi.get_weather_from_google (location_id, hl = locale_name)
-
+ # TODO: modify pywapi to use UnitSystem class? (and rename __metric_system !)
+ if self.__metric_system == UnitSystem.SI:
+ unit_system = 'metric'
+ elif self.__metric_system == UnitSystem.IMPERIAL:
+ unit_system = 'imperial'
+ else:
+ unit_system = 'imperial'
+
+ # Get data from Weather.com
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ log.debug(("Weather: __init__: calling " +
+ "pywapi.get_weather_from_weather_com(location_id=%s, " +
+ "units=%s)") % (location_id, metric_system)) #DEBUG
+
+ self.__report = pywapi.get_weather_from_weather_com(location_id, unit_system)
+ ##self.__localized_report = self.__report
+ log.debug("Weather: __init__: checking Weather.com report for " +
+ "weather condition and icon name") #DEBUG
if 'current_conditions' not in self.__report.keys():
- log.error("Weather: could not get Google weather condition from report")
+ icon_name = ""
+ log.error("Weather: could not get Weather.com weather condition from report")
log.error("Weather: got data '%s'" % str(self.__report))
self.__current_condition = (False, False, False, _("Unknown condition"))
- if 'current_conditions' not in self.__localized_report.keys():
- log.error("Weather: could not get Google weather condition from localized report")
- log.error("Weather: got data '%s'" % str(self.__localized_report))
- self.__current_condition = (False, False, False, _("Unknown condition"))
+ elif 'icon' in self.__report['current_conditions'].keys():
+ icon_name = self.__report['current_conditions']['icon']
+ self.__current_condition = self._WeathercomConditions.get(icon_name)
- if 'icon' in self.__report['current_conditions'].keys():
- icon_path = self.__report['current_conditions']['icon']
- if '/ig/images/weather/' in icon_path:
- icon_name = icon_path.replace('/ig/images/weather/', '').replace('.gif', '')
- elif 'http://g0.gstatic.com/images/icons/onebox' in icon_path:
- icon_name = icon_path.replace('http://g0.gstatic.com/images/icons/onebox/weather_', '').replace('-40.gif', '')
- else:
- icon_name = icon_path
else:
- log.error("Weather: could not get weather icon from report")
+ icon_name = ""
+ log.error("Weather: could not get icon name from Weather.com report")
log.error("Weather: got data '%s'" % str(self.__report['current_conditions']))
- icon_name = ""
-
- self.__current_condition = self._GoogleConditions.get(icon_name)
- if self.__current_condition == None:
- log.error("ExtendedForecast: unknown Google weather condition '%s'" % icon_name)
self.__current_condition = (False, False, False, _("Unknown condition"))
-
+
# Get data from Yahoo
if self.__weather_datasource == WeatherDataSource.YAHOO:
- self.__report = pywapi.get_weather_from_yahoo (location_id, 'imperial')
- self.__localized_report = self.__report
+ log.debug(("Weather: __init__: calling " +
+ "pywapi.get_weather_from_yahoo(location_id=%s, " +
+ "units=%s)") % (location_id, metric_system)) #DEBUG
+ self.__report = pywapi.get_weather_from_yahoo(location_id, unit_system)
+ ##self.__localized_report = self.__report
+ log.debug("Weather: __init__: checking Yahoo report for " +
+ "weather condition and icon name") #DEBUG
if 'condition' not in self.__report.keys():
+ icon_name = ""
log.error("Weather: could not get Yahoo weather condition from report")
log.error("Weather: got data '%s'" % str(self.__report))
self.__current_condition = (False, False, False, _("Unknown condition"))
@@ -693,10 +739,11 @@
log.debug("Weather: current condition: '%s', '%s'" % (icon_name, str(self.__current_condition)))
#Prepare sunrise/sunset data
+ log.debug("Weather: __init__: preparing sunrise/sunset data") #DEBUG
self.get_sun_data()
- #Get sunrise/sunset times, calculate whether it is night already
def get_sun_data(self):
+ """ Get sunrise/sunset times and calculate whether it is night already """
self.__night = False
self.__sunrise_t = None
self.__sunset_t = None
@@ -705,6 +752,8 @@
url = 'http://www.earthtools.org/timezone-1.1/%s/%s' % \
(self.__lat, self.__lon)
try:
+ log.debug(("Weather: get_sun_data: getting local datetime and " +
+ "dst status from %s") % url) #DEBUG
f = urllib2.urlopen(url)
s = f.read()
parsed = parseString(s)
@@ -714,7 +763,7 @@
"dst")[0].firstChild.nodeValue
# strip timezone info
localtime = datetime.datetime.strptime(localtime.rsplit(' ',1)[0],
- '%Y-%m-%d %H:%M:%S')
+ '%Y-%m-%d %H:%M:%S')
dst = 1 if dst == "True" else 0
except urllib2.URLError:
@@ -725,6 +774,7 @@
url = 'http://www.earthtools.org/sun/%s/%s/%s/%s/99/%s' % \
(self.__lat, self.__lon, localtime.day, localtime.month, dst)
try:
+ log.debug("Weather: get_sun_data: getting sunrise/sunset from %s" % url) #DEBUG
f = urllib2.urlopen(url)
s=f.read()
parsed = parseString(s)
@@ -742,20 +792,20 @@
else:
self.__night = False
log.debug("Weather: got localtime " +
- "%s, dst %s, sunrise '%s', sunset '%s', night = %s" % (
- localtime, dst, self.__sunrise_t, self.__sunset_t, self.__night))
+ "%s, dst %s, sunrise '%s', sunset '%s', night = %s" % (
+ localtime, dst, self.__sunrise_t, self.__sunset_t, self.__night))
- # Return True, if weather condition is severe
def condition_is_severe(self):
+ """ Return True if weather condition is severe """
if self.__current_condition != None:
log.debug("Weather: got severe condition '%s'" % self.__current_condition[2])
return self.__current_condition[2]
else:
log.error("Weather: condition is not set while condition severity check")
- return False;
+ return False
- # Get associated icon name
def get_icon_name(self):
+ """ Get icon name associated with current condition """
if self.__current_condition != None:
if self.__night:
log.debug("Weather: night, show '%s' icon" % self.__current_condition[1])
@@ -767,217 +817,441 @@
log.error("Weather: return 'offline' icon due to empty condition")
return False
- # Get condition text
def get_condition_label(self):
- if self.__weather_datasource == WeatherDataSource.GOOGLE:
- if 'condition' in self.__localized_report['current_conditions'].keys():
- condition = self.__localized_report['current_conditions']['condition']
- else:
- condition = _("Unknown condition")
+ """ Get text of current condition """
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ condition = self.__report['current_conditions']['text']
if self.__weather_datasource == WeatherDataSource.YAHOO:
condition = self.__current_condition[3]
return condition
- # Get humidity label
def get_humidity_label(self):
+ """ Get text string for current humidity """
humidity = "%s: ---%%" % (_("Humidity"))
- if self.__weather_datasource == WeatherDataSource.GOOGLE \
- and 'humidity' in self.__localized_report['current_conditions']:
- humidity = self.__localized_report['current_conditions']['humidity']
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM \
+ and 'humidity' in self.__report['current_conditions']:
+ humidity = "%s: %s%%" % (_("Humidity"), self.__report['current_conditions']['humidity'])
if self.__weather_datasource == WeatherDataSource.YAHOO \
- and 'humidity' in self.__localized_report['atmosphere']:
- humidity = "%s: %s%%" % (_("Humidity"), self.__localized_report['atmosphere']['humidity'])
+ and 'humidity' in self.__report['atmosphere']:
+ humidity = "%s: %s%%" % (_("Humidity"), self.__report['atmosphere']['humidity'])
return humidity
- # Get dew point - using in humidex calculation
- #TODO: Update with NOAA
def get_dew_point_label(self):
- if self.__weather_datasource == WeatherDataSource.GOOGLE or self.__weather_datasource == WeatherDataSource.YAHOO:
- # Not returned by Google and Yahoo
+ """ Get dew point, which is used in humidex calculation """
+ #TODO: Update with NOAA
+ _value = "---"
+ _unit = ""
+ if self.__weather_datasource == WeatherDataSource.YAHOO:
+ # Not returned by Yahoo
return None
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ _value = self.__report['current_conditions']['dewpoint']
+ _unit = self.__report['units']['temperature']
+ return u"%s: %s °%s" % (_("Dewpoint"), _value, _unit)
- # Get pressure label
def get_pressure_label(self):
- if self.__weather_datasource == WeatherDataSource.GOOGLE:
- # TODO: Empty for Google, use NOAA data?
- value = "---"
- unit = ""
+ """ Get text string for current air pressure """
+ _value = "---"
+ _unit = ""
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM \
+ and 'barometer' in self.__report['current_conditions'].keys() \
+ and 'pressure' in self.__report['units'].keys():
+ _value = self.__report['current_conditions']['barometer']['reading']
+ _unit = self.__report['units']['pressure']
if self.__weather_datasource == WeatherDataSource.YAHOO \
- and 'pressure' in self.__localized_report['atmosphere'].keys() \
- and 'pressure' in self.__localized_report['units'].keys():
- value = self.__localized_report['atmosphere']['pressure']
- unit = self.__localized_report['units']['pressure']
- return "%s: %s %s" % (_("Pressure"), value, units)
+ and 'pressure' in self.__report['atmosphere'].keys() \
+ and 'pressure' in self.__report['units'].keys():
+ _value = self.__report['atmosphere']['pressure']
+ _unit = self.__report['units']['pressure']
+ return "%s: %s %s" % (_("Pressure"), _value, _unit)
- # Get temperature with units value - doesn't include 'Temperature' label
- def get_temperature(self, needs_rounding = False):
- _value = "---"
+## def get_temperature(self, needs_rounding = False):
+ def get_temperature(self):
+ """ Get temperature value and units string """
+ _value = None
_unit = ""
- if self.__weather_datasource == WeatherDataSource.GOOGLE:
- if (self.__metric_system == MetricSystem.SI) \
- and 'temp_c' in self.__report['current_conditions'].keys():
- _value = self.__report['current_conditions']['temp_c']
- _unit = "˚C"
- elif 'temp_f' in self.__report['current_conditions'].keys():
- _value = self.__report['current_conditions']['temp_f']
- _unit = "˚F"
- if self.__weather_datasource == WeatherDataSource.YAHOO:
- if (self.__metric_system == MetricSystem.SI) \
- and 'temp' in self.__report['condition'].keys():
- _value = NumberFormatter.format_float(
- ((float(self.__report['condition']['temp']) - 32) * 5/9), 1)
- _unit = "˚C"
- else:
+ if (self.__weather_datasource == WeatherDataSource.WEATHER_COM and
+ 'temperature' in self.__report['current_conditions'].keys() and
+ 'temperature' in self.__report['units'].keys()):
+ if ((self.__metric_system == UnitSystem.SI and
+ self.__report['units']['temperature'] == u"C") or
+ (self.__metric_system == UnitSystem.IMPERIAL and
+ self.__report['units']['temperature' ] == u"F")):
+ _value = self.__report['current_conditions']['temperature']
+ _unit = u"°%s" % self.__report['units']['temperature']
+ if (self.__weather_datasource == WeatherDataSource.YAHOO and
+ 'temp' in self.__report['condition'].keys() and
+ 'temperature' in self.__report['units'].keys()):
+ if ((self.__metric_system == UnitSystem.SI and
+ self.__report['units']['temperature'] == u"C") or
+ (self.__metric_system == UnitSystem.IMPERIAL and
+ self.__report['units']['temperature'] == u"F")):
_value = self.__report['condition']['temp']
- _unit = "˚F"
- # round the value if required
- if needs_rounding and _value != "---":
- _value = NumberFormatter.format_float(locale.atof(_value), 0)
- return ("%s %s" % (_value, _unit))
-
- # Get temperature label
+ _unit = u"°%s" % self.__report['units']['temperature']
+## # round the value if required
+## if needs_rounding and _value != "---":
+## _value = NumberFormatter.format_float(locale.atof(_value), 0)
+ return (_value, _unit)
+
+ def get_temperature_string(self):
+ """ Get temperature with units value - doesn't include 'Temperature' string """
+ (_value, _unit) = self.get_temperature()
+ if _value is None:
+ _value = "---"
+ _unit = ""
+ return (u"%s %s" % (_value, _unit))
+
def get_temperature_label(self):
- return "%s: %s" % (_("Temperature"), self.get_temperature())
-
- # Get humidex parameter
- def get_humidex_label(self):
- if self.__weather_datasource == WeatherDataSource.GOOGLE or self.__weather_datasource == WeatherDataSource.YAHOO:
- #Empty for Yahoo and Google
- return None
- #TODO: Update with NOAA data
- #dewPoint=2
- #temp_c = 1
- #self.vapour_pressure = 6.11 * math.exp(5417.7530 * ( (1/273.16) - (1/(dewPoint+273.16))))
- #self.humidex = temp_c + (0.5555)*(self.vapour_pressure - 10.0);
- #return ("%s: %.1f" % (_("Humidex"), self.humidex)).replace(".0", "")
-
- # Get wind label
+ """ Get text string for current temperature label """
+ return "%s: %s" % (_("Temperature"), self.get_temperature_string())
+
+ def get_relative_string(self):
+ """ Get relative temperature with units value - doesn't include 'Feels Like' string """
+ # try relative heat
+ if self.__heat_index == RelativeFormula.HUMIDEX:
+ (_value, _unit) = self.get_humidex()
+ if self.__heat_index == RelativeFormula.HEATINDEX:
+ (_value, _unit) = self.get_heat_index()
+ if _value is not None:
+ return (u"%s %s" % (_value, _unit))
+ # try relative chill
+ if self.__chill_index == RelativeFormula.WINDCHILL:
+ (_value, _unit) = self.get_wind_chill()
+ if self.__chill_index == RelativeFormula.APPARENT:
+ (_value, _unit) = self.get_apparent_temp()
+ if _value is not None:
+ return (u"%s %s" % (_value, _unit))
+ # use current temperature
+ return self.get_temperature_string()
+
+ def get_relative_label(self):
+ """ Get text string for relative temperature ("feels like") label """
+ return "%s: %s" % (_("Feels Like"), self.get_relative_string())
+
+ def get_humidex(self):
+ """ Calculate humidex and get value and units
+
+ The standard Humidex formula used by Environment Canada is:
+
+ humidex = (air temperature) + h
+
+ h = (0.5555)*(e - 10.0);
+ e = vapour pressure in hPa (mbar), given by:
+ e = 6.11 * exp [5417.7530 * ( (1/273.16) - (1/dewpoint) ) ]
+ where dewpoint is expressed in Kelvins
+ (temperature in K = temperature in °C + 273.1)
+ and 5417.7530 is a rounded constant based on the molecular weight
+ of water, latent heat of evaporation, and the universal gas constant.
+
+ """
+ #TODO: Update with NOAA data
+ log.debug("Weather: get_humidex_label: checking weather_datasource") # DEBUG
+
+ if self.__weather_datasource == WeatherDataSource.YAHOO:
+ log.debug("Weather: get_humidex_label: weather_datasource is Yahoo, returning None") # DEBUG
+ # Empty for Yahoo
+ return (None, "")
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ log.debug("Weather: get_humidex_label: weather_datasource is Weather.com, calculating humidex") # DEBUG
+ if self.__report['units']['temperature'] == "F":
+ # Humidex is calculated in C
+ dew_point_f = float(self.__report['current_conditions']['dewpoint'])
+ temp_f = float(self.__report['current_conditions']['temperature'])
+ dew_point_c = ((dew_point_f - 32.0) * 5.0/9.0)
+ temp_c = ((temp_f - 32.0) * 5.0/9.0)
+ else:
+ dew_point_c = float(self.__report['current_conditions']['dewpoint'])
+ temp_c = float(self.__report['current_conditions']['temperature'])
+ vapour_pressure = 6.11 * exp(5417.7530 * ( (1/273.16) - (1/(dew_point_c+273.16))))
+ humidex = temp_c + (0.5555)*(vapour_pressure - 10.0)
+ log.debug("humidex = temp + 0.555 * (6.11 * exp(5417.7530 * (1/273.16 - 1/dewpoint in kelvins)) - 10)") # DEBUG
+ log.debug("temp = %s, dewpoint in kelvins = %s" % (temp_c, dew_point_c+273.16)) #DEBUG
+ log.debug("Weather: get_humidex_label: humidex is %s (C)" % humidex) # DEBUG
+ # Humidex is meaningless if it is lower than temperature
+ if humidex < temp_c:
+ #return (u"%s: N/A" % _("Humidex"))
+ return (None, "")
+ if self.__report['units']['temperature'] == "F":
+ humidex_f = (humidex*9.0/5.0) + 32.0
+ # Humidex is unitless (represents Celsius) so in F show units
+ #return (u"%s: %s°F" % (_("Humidex"), NumberFormatter.format_float(humidex_f, 1))).replace(".0", "")
+ #return (NumberFormatter.format_float(humidex_f, 1).replace(".0", ""), u"°F")
+ return (int(round(humidex_f)), u"°F")
+ else:
+ #return ("%s: %.1f" % (_("Humidex"), humidex)).replace(".0", "")
+ #return (u"%s: %s" % (_("Humidex"), NumberFormatter.format_float(humidex, 1))).replace(".0", "")
+ #return (NumberFormatter.format_float(humidex, 1).replace(".0", ""), u"°C")
+ return (int(round(humidex)), u"°C")
+
+ def get_heat_index(self):
+ """ Calculate heat index and get value and units
+
+ The formula below approximates the heat index in degrees
+ Fahrenheit, to within ±1.3 °F. It is the result of a
+ multivariate fit (temperature equal to or greater than
+ 80°F and relative humidity equal to or greater than 40%)
+ to a model of the human body.
+
+ Heat Index = c_1 + (c_2 * T) + (c_3 * R) + (c_4 * T * R) +
+ (c_5 * T^2) + (c_6 * R^2) + (c_7 * T^2 * R) +
+ (c_8 * T * R^2) + (c_9 * T^2 * R^2)
+ where:
+ T = ambient dry-bulb temperature (in degrees Fahrenheit)
+ R = relative humidity (percentage value between 0 and 100)
+
+ """
+ #TODO: Update with NOAA data
+ _value = None
+
+ if self.__weather_datasource == WeatherDataSource.YAHOO:
+ log.debug("Weather: get_heat_index: weather_datasource is Yahoo, returning, checking temp and humidity") # DEBUG
+ if self.__report['units']['temperature'] == "C":
+ units = 'metric'
+ elif self.__report['units']['temperature'] == "F": # else here?
+ units = 'imperial'
+ T = float(self.__report['condition']['temp'])
+ R = float(self.__report['atmosphere']['humidity'])
+ _value = pywapi.heat_index(T, R, units)
+
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ log.debug("Weather: get_heat_index: weather_datasource is Weather.com, checking temp and humidity") # DEBUG
+ if self.__report['units']['temperature'] == "C":
+ units = 'metric'
+ elif self.__report['units']['temperature'] == "F": #else here?
+ units = 'imperial'
+ T = float(self.__report['current_conditions']['temperature'])
+ R = float(self.__report['current_conditions']['humidity'])
+ _value = pywapi.heat_index(T, R, units)
+
+ # Heat Index is only valid for temp >= 80°F and humidity >= 40%)
+ if _value is None:
+ return (_value, "")
+ if units == 'metric':
+ #return (u"%s: %s°C" % (_("Heat Index"), NumberFormatter.format_float(heat_index, 1))).replace(".0", "")
+ #return (NumberFormatter.format_float(_value, 1).replace(".0", ""), u"°C")
+ return (int(round(_value)), u"°C")
+
+ elif units == 'imperial': # else here?
+ #return (u"%s: %s°F" % (_("Heat Index"), NumberFormatter.format_float(heat_index, 1))).replace(".0", "")
+ #return (NumberFormatter.format_float(_value, 1).replace(".0", ""), u"°F")
+ return (int(round(_value)), u"°F")
+
+ def get_wind_chill(self):
+ """ Calculate wind chill index and get text string for label
+
+ The standard Wind Chill formula used by Environment Canada,
+ the 2001 JAG/TI Wind Chill Equivalent Temperature Index, is:
+
+ T_wc = 13.12 + 0.6215 * T_a -
+ 11.37 * V^0.16 +
+ 0.3965 * T_a * V^0.16
+ where:
+ T_wc is the wind chill index based on Celsius
+ T_a is the air temperature in °C
+ V is the wind speed in km/h, at 10 m (standard anemometer height)
+
+ The equivalent formula in US customary units is:
+
+ T_wc = 35.74 + 0.6215 * T_a -
+ 35.75 * V^0.16 +
+ 0.4275 * T_a * V^0.16
+
+ where:
+ T_wc is the wind chill index based on Fahrenheit
+ T_a is the air temperature °F
+ V is the wind speed in mph
+
+ Windchill temperature is defined only for temperatures at or
+ below 10 °C (50 °F) and wind speeds above 4.8 kilometres per
+ hour (3.0 mph).
+
+ """
+ #TODO: Update with NOAA data
+ _value = None
+
+ if self.__report['units']['temperature'] == "C":
+ units = 'metric'
+ elif self.__report['units']['temperature'] == "F": # else here?
+ units = 'imperial'
+
+ if self.__weather_datasource == WeatherDataSource.YAHOO:
+ log.debug("Weather: get_wind_chill: weather_datasource is Yahoo, returning, checking temp and humidity") # DEBUG
+ T_a = float(self.__report['condition']['temp'])
+ V = float(self.__report['wind']['speed'])
+
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ log.debug("Weather: get_wind_chill: weather_datasource is Weather.com, checking temp and humidity") # DEBUG
+ T_a = float(self.__report['current_conditions']['temperature'])
+ wind_speed = self.__report['current_conditions']['wind']['speed']
+ V = (0.0 if wind_speed == 'calm' else float(wind_speed))
+
+ # move below to pywapi
+ if units == 'metric':
+ _value = 13.12 + 0.6215 * T_a - 11.37 * pow(V, 0.16) + 0.3965 * T_a * pow(V, 0.16)
+ return (int(round(_value)), u"°C")
+ elif units == 'imperial':
+ _value = 35.74 + 0.6215 * T_a - 35.75 * pow(V, 0.16) + 0.4275 * T_a * pow(V, 0.16)
+ return (int(round(_value)), u"°F")
+
+ if _value is None:
+ return (_value, "")
+
+ def get_apparent_temp(self):
+ """ Calculate Australian apparent temperature and get text string for label
+
+ The standard formula for cooler temperatures used by the Australian
+ Bureau of Meteorology, the Australian Apparent Temperature, is:
+
+ AT = T_a + 0.33e - 0.70ws - 4.00
+
+ Where:
+ T_a = Dry bulb temperature (°C)
+ e = Water vapour pressure (hPa)
+ ws = Wind speed (m/s) at an elevation of 10 meters
+
+ The vapour pressure can be calculated from the temperature and
+ relative humidity using the equation:
+
+ e = (rh / 100) * 6.105 * exp^[(17.27 * T_a) / (237.7 + T_a)]
+
+ Where:
+ T_a = Dry bulb temperature (°C)
+ rh = Relative humidity [%]
+ exp^ represents the exponential function
+
+ The Australian chill formula is only defined for temperatures
+ at or below 20°C (68°F) and wind speeds above 4.8 km/h (3.0 mph).
+
+ """
+ #TODO: Update with NOAA data
+ _value = None
+
+ if self.__report['units']['temperature'] == "C":
+ units = 'metric'
+ elif self.__report['units']['temperature'] == "F": # else here?
+ units = 'imperial'
+
+ if self.__weather_datasource == WeatherDataSource.YAHOO:
+ log.debug("Weather: get_wind_chill: weather_datasource is Yahoo, returning, checking temp and humidity") # DEBUG
+ T_a = float(self.__report['condition']['temp'])
+ rh = float(self.__report['atmosphere']['humidity'])
+ ws = float(self.__report['wind']['speed'])
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ log.debug("Weather: get_wind_chill: weather_datasource is Weather.com, checking temp and humidity") # DEBUG
+ T_a = float(self.__report['current_conditions']['temperature'])
+ rh = float(self.__report['current_conditions']['humidity'])
+ ws = float(self.__report['current_conditions']['wind']['speed'])
+
+ # calculated in °C, so need to convert from °F
+ if units == 'imperial':
+ T_a = ((T_a - 32.0) * 5.0/9.0)
+
+ e = (rh / 100) * 6.105 * exp((17.27 * T_a) / (237.7 + T_a))
+ _value = T_a + 0.33 * e - 0.70 * ws - 4.00
+
+ # Now convert back to °F
+ if units == 'imperial':
+ _value = (_value*9.0/5.0) + 32.0
+ return (int(round(_value)), u"°F")
+ if units == 'metric':
+ return (int(round(_value)), u"°C")
+
+ if _value is None:
+ return (_value, "")
+
def get_wind_label(self):
- if self.__weather_datasource == WeatherDataSource.GOOGLE:
- # Convert units picked up from Google and replace units with currently configured
- if 'wind_condition' in self.__localized_report['current_conditions'].keys():
- localized_wind_info = self.__localized_report['current_conditions']['wind_condition'].split(' ')
- wind_direction = localized_wind_info[1]
- wind_info = self.__report['current_conditions']['wind_condition'].split(' ')
- wind_speed = wind_info[3]
- else:
- return _("Unknown")
-
+ """ Get text string for current wind speed and direction """
+ if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+ # Create a wind_info structure from Weather.com data
+ wind_direction = u"%s (%s°)" % (self.__report['current_conditions']['wind']['text'],
+ self.__report['current_conditions']['wind']['direction'])
+ wind_speed = self.__report['current_conditions']['wind']['speed']
+ wind_units = self.__report['units']['speed']
+ if wind_speed == "calm":
+ wind_speed = 0
+ ##wind_direction = wind_direction.replace("CALM","Calm")
+ wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
if self.__weather_datasource == WeatherDataSource.YAHOO:
- # Create a similar to Google wind_info structure from Yahoo data
- wind_direction = "%s (%s˚)" % (self.get_wind_direction(self.__localized_report['wind']['direction']), self.__localized_report['wind']['direction'])
- wind_speed = self.__localized_report['wind']['speed']
- wind_units = self.__localized_report['units']['speed']
- localized_wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
-
+ # Create a wind_info structure from Yahoo data
+ wind_direction = u"%s (%s°)" % (_(pywapi.get_wind_direction(self.__report['wind']['direction'])), self.__report['wind']['direction'])
+ wind_speed = self.__report['wind']['speed']
+ wind_units = self.__report['units']['speed']
+ wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
try:
_value = float(wind_speed)
except ValueError as e:
log.error("Could not parse '%s' as wind speed." % str(wind_speed))
_value = -1.0
-
+
# Parse Wind_direction - convert to selected scale
- if (self._wind_unit == WindUnits.MPH):
- _unit = __("mph", "mph", _value)
- if (self._wind_unit == WindUnits.MPS):
- _value *= 0.44704
- _unit = __("m/s", "m/s", _value)
- if (self._wind_unit == WindUnits.BEAUFORT):
- if _value >= 0.0:
- _value = self.get_beaufort_from_mph(_value)
- _unit = ""
- if (self._wind_unit == WindUnits.KPH):
- _value *= 1.609344
- _unit = __("km/h", "km/h", _value)
- if (self._wind_unit == WindUnits.KNOTS):
- _value *= 0.868976241900648
- _unit = __("knot", "knots", _value)
-
+ if wind_units == "mph":
+ if (self._wind_unit == WindUnits.MPH):
+ _unit = __("mph", "mph", _value)
+ if (self._wind_unit == WindUnits.MPS):
+ _value *= 0.44704
+ _unit = __("m/s", "m/s", _value)
+ if (self._wind_unit == WindUnits.BEAUFORT):
+ if _value >= 0.0:
+ _value = pywapi.wind_beaufort_scale(_value, WindUnits.MPH)
+ _unit = ""
+ if (self._wind_unit == WindUnits.KPH):
+ _value *= 1.609344
+ _unit = __("km/h", "km/h", _value)
+ if (self._wind_unit == WindUnits.KNOTS):
+ _value *= 0.868976241900648
+ _unit = __("knot", "knots", _value)
+ elif wind_units == "km/h":
+ if (self._wind_unit == WindUnits.MPH):
+ _value *= 0.621371
+ _unit = __("mph", "mph", _value)
+ if (self._wind_unit == WindUnits.MPS):
+ _value *= 0.277778
+ _unit = __("m/s", "m/s", _value)
+ if (self._wind_unit == WindUnits.BEAUFORT):
+ if _value >= 0.0:
+ _value = pywapi.wind_beaufort_scale(_value, WindUnits.KPH)
+ _unit = ""
+ if (self._wind_unit == WindUnits.KPH):
+ _unit = __("km/h", "km/h", _value)
+ if (self._wind_unit == WindUnits.KNOTS):
+ _value *= 0.539957
+ _unit = __("knot", "knots", _value)
+ else:
+ log.error("Could not parse '%s' as wind units." % wind_units)
+ _value = -1.0
+
# Join wind_info data in a label
- localized_wind_info[len(localized_wind_info)-1] = _unit
- localized_wind_info[len(localized_wind_info)-2] = \
+ wind_info[len(wind_info)-1] = _unit
+ wind_info[len(wind_info)-2] = \
NumberFormatter.format_float(_value, 1)
if _value < 0.0:
- localized_wind_info[1:] = ["", "N\A", ""]
- return "%s %s %s %s" % (localized_wind_info[0], localized_wind_info[1], \
- localized_wind_info[2], localized_wind_info[3])
+ wind_info[1:] = ["", "N\A", ""]
+ if _value == 0.0:
+ wind_info[1:] = [_("Calm"), "", ""]
+ return "%s %s %s %s" % (wind_info[0], wind_info[1], \
+ wind_info[2], wind_info[3])
- # Get sunrise label
def get_sunrise_label(self):
+ """ Get text string for sunrise time """
return "%s: %s" % (_("Sunrise"), TimeFormatter.format_time(self.__sunrise_t))
- # Get sunset label
def get_sunset_label(self):
+ """ Get text string for sunset time """
return "%s: %s" % (_("Sunset"), TimeFormatter.format_time(self.__sunset_t))
- # Additional functions
- # Convert wind direction from degrees to localized direction
- def get_wind_direction(self, degrees):
- try:
- degrees = int(degrees)
- except ValueError:
- return ''
-
- if degrees < 23 or degrees >= 338:
- #Short wind direction - north
- return _('N')
- elif degrees < 68:
- return _('NE')
- elif degrees < 113:
- return _('E')
- elif degrees < 158:
- return _('SE')
- elif degrees < 203:
- return _('S')
- elif degrees < 248:
- return _('SW')
- elif degrees < 293:
- return _('W')
- elif degrees < 338:
- return _('NW')
-
- # Convert mph to Beufort scale
- def get_beaufort_from_mph(self, value):
- if value < 1:
- return 0
- elif value < 4:
- return 1
- elif value < 8:
- return 2
- elif value < 13:
- return 3
- elif value < 18:
- return 4
- elif value < 25:
- return 5
- elif value < 27:
- return 6
- elif value < 39:
- return 7
- elif value < 47:
- return 8
- elif value < 89:
- return 9
- elif value < 64:
- return 10
- elif value < 73:
- return 11
- elif value >= 73:
- return 12
-
class indicator_weather(threading.Thread):
""" Indicator class """
last_update_time = None
# Settings values
# Formats: setting value, object name (for preferences dialog), value assigned (optional)
- metric_systems = { 'S': ('si', MetricSystem.SI),
- 'I': ('imperial', MetricSystem.IMPERIAL)}
+ metric_systems = { 'S': ('si', UnitSystem.SI),
+ 'I': ('imperial', UnitSystem.IMPERIAL)}
- weather_sources = { 'G': ('google', WeatherDataSource.GOOGLE),
- 'Y': ('yahoo', WeatherDataSource.YAHOO)}
+ weather_sources = { 'Y': ('yahoo', WeatherDataSource.YAHOO),
+ 'W': ('weather-com', WeatherDataSource.WEATHER_COM)}
notifications = {'N': 'nonotif',
'O': 'notifsevere',
@@ -989,16 +1263,27 @@
'beaufort': ("beaufort", WindUnits.BEAUFORT),
'knots': ("knots", WindUnits.KNOTS)}
- # Initializing and reading settings
+ heat_estimates = {'heatindex': ("heatindex", RelativeFormula.HEATINDEX),
+ 'humidex': ("humidex", RelativeFormula.HUMIDEX)}
+
+ chill_estimates = {'windchill': ("wctindex", RelativeFormula.WINDCHILL),
+ 'apparent': ("aatindex", RelativeFormula.APPARENT)}
+
def __init__(self):
+ """ Initializing and reading previously-saved settings """
log.debug("Indicator: creating")
threading.Thread.__init__(self)
self.main_icon = os.path.join
- self.winder = appindicator.Indicator ("indicator-weather", "weather-indicator", appindicator.CATEGORY_OTHER)
- self.winder.set_status (appindicator.STATUS_ACTIVE)
- self.winder.set_attention_icon ("weather-indicator-error")
-
+ self.winder = AppIndicator.Indicator.new("indicator-weather", "weather-indicator", AppIndicator.IndicatorCategory.OTHER)
+
self.menu_update_lock = threading.Lock()
+ self.status_update_lock = threading.Lock()
+
+ self.status_update_lock.acquire(True)
+ self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+ self.winder.set_attention_icon("weather-indicator-error")
+ self.status_update_lock.release()
+
self.refreshed_minutes_ago = -1
monitor_upower(self.on_system_sleep, self.on_system_resume, log)
@@ -1010,27 +1295,37 @@
self.unit = self.settings.get_value("unit")
self.notif = self.settings.get_value("notif")
self.wind = self.settings.get_value("wind")
+ self.heat = self.settings.get_value("heat")
+ self.chill = self.settings.get_value("chill")
self.source = self.settings.get_value("data_source")
self.placechosen = self.settings.get_value("placechosen")
self.places = str(self.settings.get_value("places"))
self.show_label = self.settings.get_value("show_label")
-
- log.debug("Preferences: got settings: rate=%s, unit=%s, notif=%s, wind=%s, placechosen=%s, places=%s" %
- (self.rate, self.unit, self.notif, self.wind, self.placechosen, self.places))
+ self.show_relative = self.settings.get_value("show_relative")
+ self.show_wind = self.settings.get_value("show_wind")
+ self.show_suntimes = self.settings.get_value("show_suntimes")
+
+ log.debug("Preferences: got settings: rate=%s, unit=%s, notif=%s, "
+ "wind=%s, placechosen=%s, places=%s, heat=%s, chill=%s" %
+ (self.rate, self.unit, self.notif, self.wind,
+ self.placechosen, self.places, self.heat, self.chill))
#Setting default values
- self.metric_system = MetricSystem.SI
+ self.metric_system = UnitSystem.SI
self.wind_unit = WindUnits.MPH
self.place = None
self.menu = None
self.condition = None
self.icon = None
-
+ self.heat_index = RelativeFormula.HUMIDEX
+ self.chill_index = RelativeFormula.WINDCHILL
+
#Parsing settings
# Metric system
if self.unit in (False, None):
default_value = 'S'
- log.debug("Indicator: could not parse unit, setting to %s" % default_value)
+ log.debug("Indicator: could not parse unit, "
+ "setting to %s" % default_value)
self.settings.set_value("unit", default_value)
self.unit = default_value
self.metric_system = self.metric_systems[self.unit][1]
@@ -1038,25 +1333,70 @@
# Notification
if self.notif in (False, None):
default_value = 'N'
- log.debug("Indicator: could not parse notif, setting to %s" % default_value)
+ log.debug("Indicator: could not parse notif, "
+ "setting to %s" % default_value)
self.settings.set_value("notif", default_value)
self.notif = default_value
+ Notify.init("weather-indicator")
# Wind units
if self.wind in (False, None):
default_value = 'mph'
- log.debug("Indicator: could not parse wind, setting to %s" % default_value)
+ log.debug("Indicator: could not parse wind, "
+ "setting to %s" % default_value)
self.settings.set_value("wind", default_value)
self.wind = default_value
self.wind_unit = self.wind_systems[self.wind][1]
+ # Heat estimate formula
+ if self.heat in (False, None):
+ default_value = 'humidex'
+ log.debug("Indicator: could not parse heat, "
+ "setting to %s" % default_value)
+ self.settings.set_value("heat", default_value)
+ self.heat = default_value
+ self.heat_index = self.heat_estimates[self.heat][1]
+
+ # Chill estimate formula
+ if self.chill in (False, None):
+ default_value = 'windchill'
+ log.debug("Indicator: could not parse chill, "
+ "setting to %s" % default_value)
+ self.settings.set_value("chill", default_value)
+ self.chill = default_value
+ self.chill_index = self.chill_estimates[self.chill][1]
+
# Show label in indicator?
- self.show_label = True if self.show_label == 1 else False
+ if self.show_label == 1:
+ self.show_label = True
+ self.label_guide = "100 ˚C" # Guide for width of label
+ else:
+ self.show_label = False
+ self.label_guide = " "
+ # Show relative temperature in dropdown?
+ if self.show_relative == 1:
+ self.show_relative = True
+ else:
+ self.show_relative = False
+
+ # Show windspeed & direction in dropdown?
+ if self.show_wind == 1:
+ self.show_wind = True
+ else:
+ self.show_wind = False
+
+ # Show sunrise & sunset times in dropdown?
+ if self.show_suntimes == 1:
+ self.show_suntimes = True
+ else:
+ self.show_suntimes = False
+
# Weather source
- if self.source in (False, None):
+ if self.source in (False, None, 'G'): # If set to Google, reset it
default_value = 'Y'
- log.debug("Indicator: could not parse data source, setting to %s" % default_value)
+ log.debug("Indicator: could not parse data source, "
+ "setting to %s" % default_value)
self.settings.set_value("data_source", default_value)
self.source = default_value
self.weather_source = self.weather_sources[self.source][1]
@@ -1064,7 +1404,8 @@
# Rate
if self.rate in (False, None):
default_value = 15
- log.debug("Indicator: could not parse rate, setting to %s" % str(default_value))
+ log.debug("Indicator: could not parse rate, "
+ "setting to %s" % str(default_value))
self.settings.set_value("refresh_rate", default_value)
self.rate = default_value
@@ -1077,9 +1418,11 @@
self.placechosen = int(self.placechosen)
# Places list
+ self.menu_update_lock.acquire(True)
if self.places in (False, None, '', '[]', "['']"):
log.debug("Indicator: could not parse places")
self.menu_noplace()
+ self.menu_update_lock.release()
else:
self.places = eval(self.places)
if self.placechosen >= len(self.places):
@@ -1089,89 +1432,107 @@
if self.location_details in (False, None, '', '[]', "['']"):
log.debug("Indicator: could not parse current location details")
self.menu_noplace()
+ self.menu_update_lock.release()
else:
+ log.debug("Indicator: __init__: location_details = %s" % self.location_details) #DEBUG
self.location_details = eval(self.location_details)
- self.menu_normal()
+ log.debug(" eval(location_details) = %s" % self.location_details) #DEBUG
+## log.debug("Indicator: __init__: calling menu_normal()") #DEBUG
+## self.menu_normal()
+ log.debug("Indicator: __init__: calling update_weather()") #DEBUG
+ self.menu_update_lock.release()
self.update_weather()
- # Set a label of indicator
def update_label(self, label):
+ """ Set the label of the indicator """
if (hasattr(self.winder, 'set_label')):
log.debug("Indicator: update_label: setting label to '%s'" % label)
self.previous_label_value = label
- self.winder.set_label(label) if self.show_label else self.winder.set_label(" ")
- self.winder.set_status(appindicator.STATUS_ATTENTION)
- self.winder.set_status(appindicator.STATUS_ACTIVE)
+ log.debug("Indicator: saved label ('%s') to previous_label_value" % label) #DEBUG
+ log.debug("Indicator: checking value of show_label") #DEBUG
+ self.status_update_lock.acquire(True)
+ self.winder.set_label(label, self.label_guide) if self.show_label else self.winder.set_label(" ", " ")
+ log.debug("Indicator: show_label is %s" % self.show_label) #DEBUG
+ log.debug("Indicator: calling set_status(AppIndicator.IndicatorStatus.ATTENTION)") #DEBUG
+ self.winder.set_status(AppIndicator.IndicatorStatus.ATTENTION)
+ log.debug("Indicator: calling set_status(AppIndicator.IndicatorStatus.ACTIVE)") #DEBUG
+ self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+ log.debug("Indicator: returned from set_status") # DEBUG
+ self.status_update_lock.release()
- # Show a menu if no places specified
def menu_noplace(self):
+ """ Show a menu if no places specified """
log.debug("Indicator: making a menu for no places")
- menu_noplace = gtk.Menu()
+ menu_noplace = Gtk.Menu()
- setup = gtk.MenuItem(_("Set Up Weather..."))
+ setup = Gtk.MenuItem(_("Set Up Weather..."))
setup.connect("activate", self.prefs)
setup.show()
menu_noplace.append(setup)
- quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+ quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
quit.connect("activate", self.quit)
quit.show()
menu_noplace.append(quit)
+ self.status_update_lock.acquire(True)
self.winder.set_menu(menu_noplace)
self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon.png"))
- self.winder.set_status(appindicator.STATUS_ATTENTION)
- self.winder.set_status(appindicator.STATUS_ACTIVE)
-
- # Show menu with data
+ self.winder.set_status(AppIndicator.IndicatorStatus.ATTENTION)
+ self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+ self.status_update_lock.release()
+
def menu_normal(self):
+ """ Show a menu with weather and location data """
+ # TODO: rewrite this ??!??
log.debug("Indicator: menu_normal: filling in a menu for found places")
- self.menu = gtk.Menu()
+
+ self.menu = Gtk.Menu()
##City
- self.city_show = gtk.MenuItem()
+ self.city_show = Gtk.MenuItem()
self.city_show.set_sensitive(True)
self.menu.append(self.city_show)
self.city_show.show()
##Condition
- self.cond_show = gtk.MenuItem()
+ self.cond_show = Gtk.MenuItem()
self.cond_show.set_sensitive(True)
self.cond_show.show()
self.menu.append(self.cond_show)
##Temperature
- self.temp_show = gtk.MenuItem()
+ self.temp_show = Gtk.MenuItem()
self.temp_show.set_sensitive(True)
self.temp_show.show()
self.menu.append(self.temp_show)
- ##Humidex
- self.humidex_show = gtk.MenuItem()
- self.humidex_show.set_sensitive(True)
- self.humidex_show.show()
- self.menu.append(self.humidex_show)
+ ##Relative Temperature
+ self.relative_show = Gtk.MenuItem()
+ self.relative_show.set_sensitive(True)
+ self.relative_show.show()
+ self.menu.append(self.relative_show)
##Humidity
- self.humid_show = gtk.MenuItem()
+ self.humid_show = Gtk.MenuItem()
self.humid_show.set_sensitive(True)
self.humid_show.show()
self.menu.append(self.humid_show)
##Wind
- self.wind_show = gtk.MenuItem()
+ self.wind_show = Gtk.MenuItem()
self.wind_show.set_sensitive(True)
self.wind_show.show()
self.menu.append(self.wind_show)
##Sunrise
- self.sunrise_show = gtk.MenuItem()
+ self.sunrise_show = Gtk.MenuItem()
self.sunrise_show.set_sensitive(True)
self.sunrise_show.show()
self.menu.append(self.sunrise_show)
##Sunset
- self.sunset_show = gtk.MenuItem()
+ self.sunset_show = Gtk.MenuItem()
self.sunset_show.set_sensitive(True)
self.sunset_show.show()
self.menu.append(self.sunset_show)
@@ -1179,65 +1540,68 @@
##Cities
if len(self.places) != 1:
##Breaker
- breaker = gtk.SeparatorMenuItem()
+ breaker = Gtk.SeparatorMenuItem()
breaker.show()
self.menu.append(breaker)
log.debug("Indicator: menu_normal: adding first location menu item '%s'" % self.places[0][1])
- loco1 = gtk.RadioMenuItem(None, self.places[0][1])
+ loco1 = Gtk.RadioMenuItem.new_with_label([], self.places[0][1])
if self.placechosen == 0:
loco1.set_active(True)
loco1.connect("toggled", self.on_city_changed)
loco1.show()
self.menu.append(loco1)
+ group = loco1.get_group()
for place in self.places[1:]:
log.debug("Indicator: menu_normal: adding location menu item '%s'" % place[1])
- loco = gtk.RadioMenuItem(loco1, place[1])
+ loco = Gtk.RadioMenuItem.new_with_label(group, place[1])
if self.places.index(place) == self.placechosen:
loco.set_active(True)
loco.connect("toggled", self.on_city_changed)
loco.show()
self.menu.append(loco)
+ group = loco.get_group()
##Breaker
- breaker = gtk.SeparatorMenuItem()
+ breaker = Gtk.SeparatorMenuItem()
breaker.show()
self.menu.append(breaker)
- self.refresh_show = gtk.MenuItem()
+ self.refresh_show = Gtk.MenuItem()
#label will be set later
self.refresh_show.connect("activate", self.update_weather)
self.refresh_show.show()
self.menu.append(self.refresh_show)
- ext_show = gtk.MenuItem(_("Forecast"))
+ ext_show = Gtk.MenuItem(_("Forecast"))
ext_show.connect("activate", self.extforecast)
ext_show.show()
self.menu.append(ext_show)
##Preferences
- prefs_show = gtk.MenuItem(_("Preferences..."))
+ prefs_show = Gtk.MenuItem(_("Preferences..."))
prefs_show.connect("activate", self.prefs)
prefs_show.show()
self.menu.append(prefs_show)
##About
- about_show = gtk.MenuItem(_("About..."))
+ about_show = Gtk.MenuItem(_("About..."))
about_show.connect("activate", self.about)
about_show.show()
self.menu.append(about_show)
##Quit
- quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+ quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
quit.connect("activate", self.quit)
quit.show()
self.menu.append(quit)
self.winder.set_menu(self.menu)
self.update_label(" ")
+
- # Another city has been selected from radiobutton
def on_city_changed(self,widget):
+ """ Another city has been selected from radiobutton """
if widget.get_active():
for place in self.places:
if (place[1] == widget.get_label()):
@@ -1251,28 +1615,30 @@
self.location_details = self.settings.get_location_details(self.place[0])
if self.location_details in (False, None, '', '[]', "['']"):
log.debug("Indicator: could not parse location details for placechosen='%s'" % self.placechosen)
+ self.menu_update_lock.acquire(True)
self.menu_noplace()
+ self.menu_update_lock.release()
else:
self.location_details = eval(self.location_details)
self.settings.set_value("placechosen", self.placechosen)
self.update_weather(False)
def on_system_sleep(self):
- """
- Callback from UPower that system suspends/hibernates
+ """Callback from UPower that system suspends/hibernates
+
"""
# store time
self.sleep_time = datetime.datetime.now()
log.debug("Indicator: system goes to sleep at %s" % self.sleep_time)
# remove gobject timeouts
if hasattr(self, "refresh_id"):
- gobject.source_remove(self.refresh_id)
+ GObject.source_remove(self.refresh_id)
if hasattr(self, "rate_id"):
- gobject.source_remove(self.rate_id)
+ GObject.source_remove(self.rate_id)
def on_system_resume(self):
- """
- Callback from UPower that system resumes
+ """Callback from UPower that system resumes
+
"""
now = datetime.datetime.now()
log.debug("Indicator: system resumes at %s" % now)
@@ -1291,25 +1657,25 @@
else:
self.update_weather()
- # Schedule weather update
def schedule_weather_update(self, rate_override = None):
+ """ Schedule the next weather update """
if hasattr(self, "rate_id"):
- gobject.source_remove(self.rate_id)
+ GObject.source_remove(self.rate_id)
if rate_override:
- self.rate_id = gobject.timeout_add(
+ self.rate_id = GObject.timeout_add(
int(rate_override) * 60000, self.update_weather)
else:
- self.rate_id = gobject.timeout_add(
+ self.rate_id = GObject.timeout_add(
int(self.rate) * 60000, self.update_weather)
- # Schedule weather update
def schedule_refresh_label_update(self):
+ """ Schedule the next 'Refresh' label update """
if hasattr(self, "refresh_id"):
- gobject.source_remove(self.refresh_id)
- self.refresh_id = gobject.timeout_add(60000, self.update_refresh_label)
+ GObject.source_remove(self.refresh_id)
+ self.refresh_id = GObject.timeout_add(60000, self.update_refresh_label)
- # Update 'Refresh' label with time since last successful data refresh
def update_refresh_label(self, reset_minutes = None):
+ """ Update 'Refresh' label with time since last successful data refresh """
if reset_minutes is not None:
self.refreshed_minutes_ago = reset_minutes
else:
@@ -1319,6 +1685,7 @@
return False
def set_refresh_label(self, refreshing=False):
+ """ Update the 'Refresh' label text """
if refreshing:
refresh_label=_("Refreshing, please wait")
elif self.refreshed_minutes_ago < 0:
@@ -1329,68 +1696,97 @@
refresh_label = "%s (%s)" % (_("Refresh"), _("%d min. ago") % self.refreshed_minutes_ago)
self.refresh_show.set_label(refresh_label)
- # Load weather data from cache and display its values
- def show_cached_weather(self):
+ def get_cached_weather(self, queue):
+ """ Load weather data from cache and put it onto the queue """
try:
- self.menu_update_lock.acquire(True)
+ log.debug("Indicator: show_cached_weather: setting previous_condition to None") #DEBUG
self.previous_condition = None
+ log.debug("Indicator: show_cached_weather: calling settings.get_weather('%s')" % self.places[self.placechosen][0]) #DEBUG
cached_weather = self.settings.get_weather(self.places[self.placechosen][0])
if cached_weather is not None:
+ log.debug("Indicator: show_cached_weather: got cached_weather: '%s', len=%i)" % (cached_weather, len(cached_weather))) #DEBUG
cached_weather = eval(cached_weather)
+ log.debug("Indicator: show_cached_weather: after eval(), cached_weather is: '%s', len=%i" % (cached_weather, len(cached_weather))) #DEBUG
log.debug("Indicator: loading weather from cache for %s" % self.places[self.placechosen])
- self.menu_normal()
- self.set_refresh_label(True)
- self.icon = cached_weather['icon']
- if (self.icon == False):
- self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
- else:
- self.winder.set_icon(self.icon)
+ # Put the cached weather onto to the Queue
+ queue.put(cached_weather)
+ except Exception, e:
+ log.error(e)
+ log.debug(traceback.format_exc(e))
- self.city_show.set_label(self.places[self.placechosen][1])
- self.previous_condition = cached_weather['condition']
- self.cond_show.set_label(cached_weather['condition'])
- self.temp_show.set_label(cached_weather['temper'])
- if cached_weather['humidex'] != None:
- self.humidex_show.set_label(cached_weather['humidex'])
- else:
- self.humidex_show.destroy()
- self.humid_show.set_label(cached_weather['humidity'])
+ def show_cached_weather(self, cached_weather):
+ """ Update the indicator icon, label and menu with cached weather data """
+ try:
+ self.menu_normal()
+ log.debug("Indicator: show_cached_weather: calling set_refresh_label") #DEBUG
+ self.set_refresh_label(True)
+ log.debug("Indicator: show_cached_weather: setting icon") #DEBUG
+ self.icon = cached_weather['icon']
+ if (self.icon == False):
+ self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
+ else:
+ self.winder.set_icon(self.icon)
+
+ log.debug("Indicator: show_cached_weather: set_label for city_show") #DEBUG
+ self.city_show.set_label(self.places[self.placechosen][1])
+ log.debug("Indicator: show_cached_weather: setting previous_condition from cache") #DEBUG
+ self.previous_condition = cached_weather['condition']
+ log.debug("Indicator: show_cached_weather: set_label for cond_show") #DEBUG
+ self.cond_show.set_label(cached_weather['condition'])
+ log.debug("Indicator: show_cached_weather: set_label for temp_show") #DEBUG
+ self.temp_show.set_label(cached_weather['temper'])
+ log.debug("Indicator: show_cached_weather: checking feelslike value") #DEBUG
+ if (self.show_relative and cached_weather['feelslike'] != None):
+ self.relative_show.set_visible(True)
+ self.relative_show.set_label(cached_weather['feelslike'])
+ else:
+ self.relative_show.set_visible(False)
+ log.debug("Indicator: show_cached_weather: set_label for humid_show") #DEBUG
+ self.humid_show.set_label(cached_weather['humidity'])
+ if self.show_wind:
+ log.debug("Indicator: show_cached_weather: set_label for wind_show") #DEBUG
+ self.wind_show.set_visible(True)
self.wind_show.set_label(cached_weather['wind'])
+ else:
+ self.wind_show.set_visible(False)
+ if self.show_suntimes:
+ log.debug("Indicator: show_cached_weather: set_label for sunrise_show") #DEBUG
+ self.sunrise_show.set_visible(True)
self.sunrise_show.set_label(cached_weather['sunrise'])
+ log.debug("Indicator: show_cached_weather: set_label for sunset_show") #DEBUG
+ self.sunset_show.set_visible(True)
self.sunset_show.set_label(cached_weather['sunset'])
- self.update_label(cached_weather['label'])
- self.winder.set_status(appindicator.STATUS_ATTENTION)
- self.winder.set_status(appindicator.STATUS_ACTIVE)
+ else:
+ self.sunrise_show.set_visible(False)
+ self.sunset_show.set_visible(False)
+ log.debug("Indicator: show_cached_weather: calling update_label") #DEBUG
+ self.update_label(cached_weather['label'])
+
except Exception, e:
log.error(e)
log.debug(traceback.format_exc(e))
- self.menu_update_lock.release()
-
- # Get fresh weather data
- def get_new_weather_data(self, notif = True):
-
+ def get_new_weather_data(self, notif, queue):
+ """ Get fresh weather data from source and put it onto the queue """
+ log.debug("Indicator: entered get_new_weather_data") #DEBUG
# get weather and catch any exception
weather = None
try:
weather = self.get_weather()
-
except urllib2.URLError, e:
weather = None
log.error("Indicator: networking error: %s" % e)
-
except Exception, e:
weather = None
log.error(e)
log.debug(traceback.format_exc(e))
+ # Put the new weather data onto the Queue
+ queue.put(weather)
+ def show_new_weather_data(self, weather):
+ """ Update the indicator icon, label and menu with new weather data """
try:
- # wait until cacher finishes
- log.debug("Indicator: updateWeather: waiting for 'Cacher' thread to terminate")
- self.menu_update_lock.acquire(True)
- self.menu_update_lock.release()
-
if weather is None:
# remove the "Refreshing" status
self.set_refresh_label()
@@ -1399,35 +1795,58 @@
# Repeat an attempt in one minute
self.schedule_weather_update(1)
return
-
+
# Fill in menu with data
log.debug("Indicator: updateWeather: got condition '%s', icon '%s'" % (self.condition, self.icon))
self.condition = weather.get_condition_label()
self.icon = weather.get_icon_name()
- log.debug("Indicator: fill in menu with params: city='%s', temp='%s', humid='%s', wind='%s', sunrise='%s', sunset='%s', puretemp=%s" % (self.places[self.placechosen][1], weather.get_temperature_label(), weather.get_humidity_label(), weather.get_wind_label(), weather.get_sunrise_label(), weather.get_sunset_label(), weather.get_temperature()))
-
+ log.debug("Indicator: fill in menu with params: " \
+ "city='%s', temp='%s', humid='%s', " \
+ "wind='%s', sunrise='%s', sunset='%s', " \
+ "puretemp=%s" % (self.places[self.placechosen][1],
+ weather.get_temperature_label(),
+ weather.get_humidity_label(),
+ weather.get_wind_label(),
+ weather.get_sunrise_label(),
+ weather.get_sunset_label(),
+ weather.get_temperature_string()))
self.menu_normal()
self.update_refresh_label(0)
self.city_show.set_label(self.places[self.placechosen][1])
self.cond_show.set_label(self.condition)
self.temp_show.set_label(weather.get_temperature_label())
- if (weather.get_humidex_label() != None):
- self.humidex_show.set_label(weather.get_humidex_label())
+ _relative_label = weather.get_relative_label()
+ if (self.show_relative and "---" not in _relative_label):
+ log.debug("Indicator: updateWeather: _relative_label is not None") # DEBUG
+ self.relative_show.set_visible(True)
+ self.relative_show.set_label(_relative_label)
else:
- self.humidex_show.destroy()
+ log.debug("Indicator: updateWeather: label = None") # DEBUG
+ self.relative_show.set_visible(False)
self.humid_show.set_label(weather.get_humidity_label())
- self.wind_show.set_label(weather.get_wind_label())
- self.sunrise_show.set_label(weather.get_sunrise_label())
- self.sunset_show.set_label(weather.get_sunset_label())
-
- # Saving cached data, unless correct icon is supplied
+ if self.show_wind:
+ self.wind_show.set_visible(True)
+ self.wind_show.set_label(weather.get_wind_label())
+ else:
+ self.wind_show.set_visible(False)
+ if self.show_suntimes:
+ self.sunrise_show.set_visible(True)
+ self.sunrise_show.set_label(weather.get_sunrise_label())
+ self.sunset_show.set_visible(True)
+ self.sunset_show.set_label(weather.get_sunset_label())
+ else:
+ self.sunrise_show.set_visible(False)
+ self.sunset_show.set_visible(False)
+
+ # Save cached data if correct icon is supplied
if (self.icon == False):
self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
else:
self.winder.set_icon(self.icon)
self.settings.save_weather(weather, self.places[self.placechosen][0])
- self.update_label(weather.get_temperature(needs_rounding=True))
-
+ # Update the indicator label
+ self.update_label(weather.get_temperature_string())
+
# Notify user, if notifications are enabled
if self.condition != self.previous_condition and self.notif == 'U':
# Weather condition has changed
@@ -1437,53 +1856,83 @@
# Severe weather condition notification
log.debug("Indicator: updateWeather: severe condition notification")
self.notify(self.condition, self.icon, severe=True)
-
+ # Save the current condition to track changes for notifications
self.previous_condition = self.condition
-
except Exception, e:
log.error(e)
log.debug(traceback.format_exc(e))
+ # Schedule the next weather fetch
self.schedule_weather_update()
-
- # Update weather
+
def update_weather(self, notif=True, widget=None):
- log.debug("Indicator: updateWeather: updating weather for %s" % self.places[self.placechosen])
+ """ Update the displayed weather data from cache and fetch new data """
+ #TODO: rewrite this to use a single queue? (have threads .put() dicts into queue?)
+
+ log.debug("Indicator: updateWeather: updating weather for %s" %
+ self.places[self.placechosen])
# First, display cached data
- threading.Thread(target=self.show_cached_weather, name='Cache').start()
+ cache_queue = Queue.Queue()
+ log.debug("Indicator: updateWeather: spawning Cache thread -> show_cached_weather()") #DEBUG
+ cache_thread = threading.Thread(target=self.get_cached_weather,
+ name='Cache', args=(cache_queue,))
+ cache_thread.start()
+
# Then, start a new thread with real data pickup
- threading.Thread(target=self.get_new_weather_data, name='Fetcher').start()
-
- # Get current weather for selected location
+ fetcher_queue = Queue.Queue()
+ log.debug("Indicator: updateWeather: spawning Fetcher thread -> get_new_weather_data()") #DEBUG
+ fetcher_thread = threading.Thread(target=self.get_new_weather_data,
+ name='Fetcher',
+ args=(self.notif, fetcher_queue))
+ fetcher_thread.start()
+
+ # Update the menu with the cached weather
+ cache_thread.join()
+ cached_weather = cache_queue.get()
+ if cached_weather is not None:
+ self.show_cached_weather(cached_weather)
+
+ # Update the menu with the new weather
+ fetcher_thread.join()
+ weather = fetcher_queue.get()
+ #TODO: is this conditional necessary?
+ if weather is not None:
+ self.show_new_weather_data(weather)
+
def get_weather(self):
- log.debug("Indicator: getWeather for location '%s'" % self.location_details['full name'])
- self.current_location = Location(self.metric_system, self.wind_unit, self.location_details)
+ """ Get current weather for selected location """
+ log.debug("Indicator: getWeather for location '%s'" %
+ self.location_details['full name'])
+ log.debug("Indicator: getWeather: location_details=%s" % self.location_details) #DEBUG
+ self.current_location = Location(self.metric_system, self.wind_unit,
+ self.heat_index, self.chill_index,
+ self.location_details)
log.debug("Indicator: getWeather: updating weather report")
self.current_location.update_weather_data(self.weather_source)
return self.current_location.weather
- # Show notification to user
- def notify(self,conditon,icon,severe=False):
- log.debug("Indicator: Notify on weather condition, severe=%s, condition=%s, icon=%s" % (severe, self.condition, icon))
+ def notify(self,condition,icon,severe=False):
+ """ Show notification to user according to preferences """
+ log.debug("Indicator: Notify on weather condition, severe=%s, condition=%s, icon=%s" % (severe, condition, icon))
if severe:
- n = pynotify.Notification (_("Severe weather alert"),
- self.condition,
- icon)
+ n = Notify.Notification (_("Severe weather alert"),
+ condition,
+ icon)
else:
- n = pynotify.Notification (self.condition, "", icon)
+ n = Notify.Notification (condition, "", icon)
n.show ()
- # Menu callbacks
- # Open Preferences dialog
def prefs(self, widget):
+ """ Menu callback to open Preferences dialog """
log.debug("Indicator: open Preferences")
if ((not hasattr(self, 'prefswindow')) or (not self.prefswindow.get_visible())):
self.prefswindow = PreferencesDialog()
self.prefswindow.show()
def about(self, widget):
+ """ Menu callback to open About dialog """
log.debug("Indicator: open About dialog")
- self.aboutdialog = gtk.AboutDialog()
+ self.aboutdialog = Gtk.AboutDialog()
self.aboutdialog.set_name(_("Weather Indicator"))
self.aboutdialog.set_version(VERSION)
@@ -1498,45 +1947,47 @@
self.aboutdialog.set_website("https://launchpad.net/weather-indicator")
self.aboutdialog.set_translator_credits(_("translator-credits"))
logo_path = os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon.png")
- self.aboutdialog.set_logo(gtk.gdk.pixbuf_new_from_file(logo_path))
-
+ self.aboutdialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(logo_path))
self.aboutdialog.connect("response", self.about_close)
self.aboutdialog.show()
def about_close(self, widget, event=None):
+ """ Menu callback to close About dialog """
log.debug("Indicator: closing About dialog")
self.aboutdialog.destroy()
- # Open Extended forecast window
def extforecast(self, widget):
+ """ Menu callback to open Extended forecast window """
log.debug("Indicator: open Forecast")
if ((not hasattr(self, 'forecastwd')) or (not self.forecastwd.get_visible())):
self.forecastwd = ExtendedForecast()
self.forecastwd.show()
- # Quit the applet
def quit(self, widget, data=None):
+ """ Menu callback to quit the indicator applet """
log.debug("Indicator: Quitting")
- gtk.main_quit()
+ Gtk.main_quit()
-class PreferencesDialog(gtk.Dialog):
+class PreferencesDialog(Gtk.Dialog):
""" Class for preferences dialog """
__gtype_name__ = "PreferencesDialog"
- # Creating a new preferences dialog
def __new__(cls):
+ """ Creating a new preferences dialog """
log.debug("Preferences: creating")
builder = get_builder('PreferencesDialog')
new_object = builder.get_object("preferences_dialog")
new_object.finish_initializing(builder)
return new_object
- # Fill in preferences dialog with currect data
def finish_initializing(self, builder):
+ """ Fill in preferences dialog with correct data """
log.debug("Preferences: finishing initialization")
- log.debug("Preferences: got settings: unit=%s, notif=%s, wind=%s, rate=%s, source=%s" %
- (wi.unit, wi.notif, wi.wind, wi.rate, wi.source))
+ log.debug("Preferences: got settings: unit=%s, notif=%s, wind=%s, "
+ "rate=%s, source=%s, heat=%s, chill=%s" %
+ (wi.unit, wi.notif, wi.wind, wi.rate, wi.source,
+ wi.heat, wi.chill))
self.builder = builder
# Set correct wind_unit using dictionary of wind value and object name
@@ -1547,11 +1998,16 @@
self.builder.get_object('show_label').set_active(wi.show_label)
self.builder.get_object('show_label').set_visible(hasattr(wi.winder, 'set_label'))
self.builder.get_object('rate').set_value(float(wi.rate))
+ self.builder.get_object(wi.heat_estimates[wi.heat][0]).set_active(True)
+ self.builder.get_object(wi.chill_estimates[wi.chill][0]).set_active(True)
+ self.builder.get_object('show_relative').set_active(wi.show_relative)
+ self.builder.get_object('show_wind').set_active(wi.show_wind)
+ self.builder.get_object('show_suntimes').set_active(wi.show_suntimes)
log.debug("Preferences: Loading places")
if wi.places != None:
for place in wi.places:
- if len(place)>1:
+ if len(place)>1 and place[0] is not None:
log.debug("Preferences: Places: got (%s, %s)" % (place[1], place[0]))
newplace = list()
newplace.append(place[1])
@@ -1563,32 +2019,65 @@
self.builder.connect_signals(self)
- # 'Remove' clicked - remove location from list
- #TODO: Update settings object
def on_remove_location(self, widget):
+ """ 'Remove' clicked - remove location from list """
+ # TODO: Update settings object
selection = self.builder.get_object('location_list').get_selection()
model, iter = selection.get_selected()
if iter != None:
log.debug("Preferences: Removing location %s (code %s)" % (model[iter][0], model[iter][1]))
+## placename = model[iter][0]
+ log.debug("Preferences: Need to update settings object here") # DEBUG
+ log.debug("wi.settings.places = %s" % wi.settings.get_value("places")) # DEBUG
+ log.debug("wi.places = %s" % wi.places) # DEBUG
+ log.debug("Should to remove above location from wi.places and wi.settings") # DEBUG
model.remove(iter)
-
+# TODO: Fix code to update Settings object here
+# need to update both of these:
+# wi.places
+# wi.settings.set_value("places").set_places
+##"""
+## # Get places from location list
+## newplaces = list()
+## item = self.builder.get_object('citieslist').get_iter_first()
+## while (item != None):
+## newplace = list()
+## newplace.append(self.builder.get_object('citieslist').get_value (item, 1))
+## newplace.append(self.builder.get_object('citieslist').get_value (item, 0))
+## newplaces.append(newplace)
+## item = self.builder.get_object('citieslist').iter_next(item)
+##
+## # If places have changed - update weather data
+## if newplaces != wi.places:
+## wi.places = newplaces
+## log.debug("Preferences: Places changed to '%s'" % str(wi.places))
+## wi.settings.set_value("places", str(wi.places))
+## if (type(wi.place) != None) and (wi.place in wi.places):
+## wi.placechosen = wi.places.index(wi.place)
+## else:
+## wi.placechosen = 0
+## wi.place = wi.places[0]
+##"""
+## places = eval(wi.places)
+
if (self.builder.get_object('citieslist').get_iter_first() == None):
self.builder.get_object('ok_button').set_sensitive(False)
-
- # 'Add' clicked - create a new Assistant
+
def on_add_location(self, widget):
+ """ 'Add' clicked - create a new Assistant """
log.debug("Preferences: Add location clicked")
if ((not hasattr(self, 'assistant')) or (not self.assistant.get_visible())):
self.assistant = Assistant()
self.assistant.show()
- # 'OK' clicked - save settings
def ok(self, widget, data=None):
+ """ 'OK' clicked - save settings """
+ #TODO: rewrite this to copy all pertinent values to a queue, then destroy the window
log.debug("Preferences: Saving settings")
need_to_update_weather = False
need_to_update_indicator = False
- #Show label near icon
+ # Show label near icon
new_show_label = self.builder.get_object('show_label').get_active()
if (wi.show_label != new_show_label):
wi.show_label = new_show_label
@@ -1597,6 +2086,30 @@
need_to_update_indicator = True
log.debug("Preferences: Show Label changed to '%s'" % wi.show_label)
+ # Show relative temperature
+ new_show_relative = self.builder.get_object('show_relative').get_active()
+ if (wi.show_relative != new_show_relative):
+ wi.show_relative = new_show_relative
+ wi.settings.set_value("show_relative", new_show_relative)
+ need_to_update_weather = True
+ log.debug("PreferencesDialog: Show Relative Temp changed to %s" % wi.show_relative)
+
+ # Show wind speed & direction
+ new_show_wind = self.builder.get_object('show_wind').get_active()
+ if (wi.show_wind != new_show_wind):
+ wi.show_wind = new_show_wind
+ wi.settings.set_value("show_relative", new_show_wind)
+ need_to_update_weather = True
+ log.debug("PreferencesDialog: Show Wind Data changed to %s" % wi.show_wind)
+
+ # Show sunrise & sunset times
+ new_show_suntimes = self.builder.get_object('show_suntimes').get_active()
+ if (wi.show_suntimes != new_show_suntimes):
+ wi.show_suntimes = new_show_suntimes
+ wi.settings.set_value("show_suntimes", new_show_suntimes)
+ need_to_update_weather = True
+ log.debug("PreferencesDialog: Show Sunrise/Sunset Times changed to %s" % wi.show_suntimes)
+
# Metric systems
for k in wi.metric_systems.keys():
if self.builder.get_object(wi.metric_systems[k][0]).get_active():
@@ -1634,6 +2147,32 @@
need_to_update_weather = True
log.debug("Preferences: Wind Unit changed to '%s'" % wi.wind)
+ # Heat estimate formula
+ for k in wi.heat_estimates.keys():
+ if self.builder.get_object(wi.heat_estimates[k][0]).get_active():
+ new_heat_index = k
+ new_heat_estimate = wi.heat_estimates[k][1]
+
+ if (wi.heat != new_heat_index):
+ wi.heat = new_heat_index
+ wi.heat_index = new_heat_estimate
+ wi.settings.set_value("heat", wi.heat)
+ need_to_update_weather = True
+ log.debug("Preferences: Heat Estimate changed to '%s'" % wi.heat)
+
+ # Chill estimate formula
+ for k in wi.chill_estimates.keys():
+ if self.builder.get_object(wi.chill_estimates[k][0]).get_active():
+ new_chill_index = k
+ new_chill_estimate = wi.chill_estimates[k][1]
+
+ if (wi.chill != new_chill_index):
+ wi.chill = new_chill_index
+ wi.chill_index = new_chill_estimate
+ wi.settings.set_value("chill", wi.chill)
+ need_to_update_weather = True
+ log.debug("Preferences: Chill Estimate changed to '%s'" % wi.chill)
+
# Weather source
for k in wi.weather_sources.keys():
if self.builder.get_object(wi.weather_sources[k][0]).get_active():
@@ -1677,8 +2216,8 @@
log.debug("Preferences: Place Chosen changed to '%s'" % wi.placechosen)
wi.settings.set_value("placechosen", wi.placechosen)
wi.location_details = eval(wi.settings.get_location_details(wi.place[0]))
- wi.menu_normal()
- wi.set_refresh_label()
+## wi.menu_normal()
+## wi.set_refresh_label()
need_to_update_weather = True
if need_to_update_weather:
@@ -1689,34 +2228,34 @@
self.destroy()
- # 'Cancel' click - forget all changes
def cancel(self, widget, data=None):
+ """ 'Cancel' clicked - forget all changes """
log.debug("Preferences: Cancelling")
self.destroy()
-class ExtendedForecast(gtk.Window):
+class ExtendedForecast(Gtk.Window):
""" Class for forecast window """
__gtype_name__ = "ExtendedForecast"
- # Create forecast
def __new__(cls):
+ """ Create forecast """
log.debug("ExtendedForecast: creating")
builder = get_builder('ExtendedForecast')
new_object = builder.get_object("extended_forecast")
new_object.finish_initializing(builder)
return new_object
- # Fill in forecast parameters
def finish_initializing(self, builder):
+ """ Fill in forecast parameters """
log.debug("ExtendedForecast: finishing initialization")
self.builder = builder
self.builder.connect_signals(self)
# Get forecast data using Forecast object
log.debug("ExtendedForecast: chosen place: %s (code %s)" % (wi.places[wi.placechosen][1], wi.places[wi.placechosen][0]))
- self.builder.get_object('extended_forecast').set_title("%s %s" % (_('Weather Forecast for '), wi.places[wi.placechosen][1]))
+ self.builder.get_object('extended_forecast').set_title("%s %s" % (_('Weather Forecast for'), wi.places[wi.placechosen][1]))
log.debug("ExtendedForecast: getting forecast data")
- forecast = Forecast(wi.metric_system, wi.current_location.location_details['latitude'], wi.current_location.location_details['longitude'], locale_name)
+ forecast = Forecast(wi.metric_system, wi.current_location.location_details['yahoo id'], locale_name)
forecast.prepare_forecast_data()
if forecast.error_message != None:
#Error occurred while getting forecast data
@@ -1728,9 +2267,9 @@
forecast_data = forecast.get_forecast_data()
if forecast_data == None:
# Forecast data unavailable - hide elements and show 'connection_error' label
- self.builder.get_object('connection_error').set_visible(True);
- self.builder.get_object('hbox1').set_visible(False);
- self.builder.get_object('hseparator1').set_visible(False);
+ self.builder.get_object('connection_error').set_visible(True)
+ self.builder.get_object('hbox1').set_visible(False)
+ self.builder.get_object('hseparator1').set_visible(False)
return
(highdata, lowdata) = forecast_data
icons = forecast.get_forecast_icons()
@@ -1745,19 +2284,19 @@
# Fill in icons
for i in xrange(1,5):
- # Get icon name from dictionary in Weather object for Google icons
+ # Get icon name from dictionary in Weather object for Yahoo condition codes
try:
- conds = Weather._GoogleConditions.get(icons[i-1])
+ conds = Weather._YahooConditions.get(icons[i-1])
if conds != None:
- google_icon = conds[0]
+ yahoo_icon = conds[0]
else:
- log.error("ExtendedForecast: unknown Google weather condition '%s'" % icons[i-1])
+ log.error("ExtendedForecast: unknown Yahoo weather condition code '%s'" % icons[i-1])
log.error(forecast.forecast)
- google_icon = 'weather-indicator-unknown'
- self.builder.get_object('day%simage' % str(i)).set_from_icon_name(google_icon,gtk.ICON_SIZE_BUTTON)
+ yahoo_icon = 'weather-indicator-unknown'
+ self.builder.get_object('day%simage' % str(i)).set_from_icon_name(yahoo_icon,Gtk.IconSize.BUTTON)
except IndexError:
- log.error("ExtendedForecast: Google didn't return condition for %s days" % i-1)
- log.error(forecast.forecast)
+ log.error("ExtendedForecast: Yahoo didn't return condition for %s days" % i-1)
+ log.error(forecast.forecast)
# Fill in condition labels
for i in xrange(1,5):
@@ -1768,38 +2307,38 @@
self.builder.get_object('day%scond' % str(i)).set_label(condition)
# Fill in High and Low temperatures
- if wi.metric_system == MetricSystem.SI:
- tempunit = '°C'
+ if wi.metric_system == UnitSystem.SI:
+ tempunit = u"°C"
else:
- tempunit = '°F'
+ tempunit = u"°F"
for i in xrange(1,5):
label = "%s: %s%s" % (_('High'), highdata[i-1],tempunit)
self.builder.get_object('day%stemphigh' % str(i)).set_label(label)
label = "%s: %s%s" % (_('Low'), lowdata[i-1],tempunit)
self.builder.get_object('day%stemplow' % str(i)).set_label(label)
- # Closing forecast window
def close(self, widget, data=None):
+ """ 'Close' clicked - close forecast window """
log.debug("ExtendedForecast: closing window")
self.destroy()
def on_destroy(self, widget):
pass
-class Assistant(gtk.Assistant):
+class Assistant(Gtk.Assistant):
""" Class for a wizard, which helps to add a new location in location list """
__gtype_name__ = "Assistant"
- # Create new object
def __new__(cls):
+ """ Create new object """
log.debug("Assistant: creating new Assistance instance")
builder = get_builder('Assistant')
new_object = builder.get_object("assistant")
new_object.finish_initializing(builder)
return new_object
- # Finish UI initialization - prepare combobox
def finish_initializing(self, builder):
+ """ Finish UI initialization - prepare combobox """
log.debug("Assistant: finishing initialization")
self.builder = builder
self.builder.connect_signals(self)
@@ -1809,18 +2348,18 @@
# Set up combobox
log.debug("Assistant: setting up location combobox")
- self.store = gtk.ListStore(str, str, str, str, str)
+ self.store = Gtk.ListStore(str, str, str, str, str)
self.location_input_combo = self.builder.get_object("combolocations")
self.location_input_combo.set_model(self.store)
- self.location_input_combo.set_text_column(0)
+ self.location_input_combo.set_entry_text_column(0)
self.location_entry = self.builder.get_object("entrylocation")
self.place_selected = None
self.location = None
- self.assistant.set_forward_page_func(self.next_page)
+ self.assistant.set_forward_page_func(self.next_page, None)
- # 'Get cities' button clicked - get suggested cities list
def on_get_city_names(self, widget):
+ """ 'Get cities' button clicked - get suggested cities list """
new_text = self.location_entry.get_text()
log.debug("Assistant: looking for location '%s'" % new_text)
try:
@@ -1843,8 +2382,8 @@
except urllib2.URLError:
log.error("Assistant: error reaching url '%s'" % url)
- # A city is selected from suggested list
def on_select_city(self, entry):
+ """ A city is selected from suggested list """
if self.location_input_combo.get_active() != -1:
self.place_selected = self.store[self.location_input_combo.get_active()]
self.assistant.set_page_complete(self.builder.get_object("placeinput"),True)
@@ -1853,13 +2392,13 @@
self.location = None
self.assistant.set_page_complete(self.builder.get_object("placeinput"), False)
- # Create a location object out of a selected location
- def next_page(self, current_page):
+ def next_page(self, current_page, data):
+ """ Create a location object out of a selected location """
log.debug("Assistant: moved to page %s" % current_page)
if (self.assistant.get_current_page() == 0) and not self.location and self.place_selected:
# Label input page
log.debug("Assistant: Page %s: got location with code %s" % (current_page, self.place_selected[1]))
- self.location = Location(wi.metric_system, wi.wind_unit)
+ self.location = Location(wi.metric_system, wi.wind_unit, wi.heat_index, wi.chill_index)
if self.location.prepare_location(self.place_selected):
log.debug("Assistant: Page %s: City %s found" % (current_page, self.place_selected[0]))
# Set a short city name as default label
@@ -1882,13 +2421,13 @@
return self.assistant.get_current_page() + 1
- # 'Cancel' clicked
def on_cancel(self,widget):
+ """ 'Cancel' clicked """
log.debug("Assistant: Cancelled")
self.destroy()
- # 'Apply' clicked - save location details, add an entry in a location list
def on_apply(self,widget):
+ """ 'Apply' clicked - save location details, add an entry in a location list """
(location_code, location_details) = self.location.export_location_details()
log.debug("Assistant: Apply: adding location ('%s', '%s')" % (self.location.location_details['label'], location_code))
newplace = list()
@@ -1904,8 +2443,8 @@
class SingleInstance(object):
""" Class to ensure, that single instance of the applet is run for each user """
- # Initialize, specifying a path to store pids
def __init__(self, pidPath):
+ """ Initialize, specifying a path to store pids """
self.pidPath=pidPath
# See if pidFile exists
if os.path.exists(pidPath):
@@ -1939,7 +2478,8 @@
os.unlink(self.pidPath)
def main():
- gtk.main()
+ Gtk.main()
+
return 0
if __name__ == "__main__":
@@ -1974,8 +2514,7 @@
TimeFormatter.monitor_indicator_datetime(log)
# not running, safe to continue...
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
+
# Remember locale name
global locale_name
locale_name = locale.getlocale()[0]
@@ -1984,6 +2523,20 @@
else:
locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
locale_name = "en"
+
+ # init GLib/GObject
+ GObject.threads_init()
+
+ # init Gdk threads and get Gdk lock
+ Gdk.threads_init()
+ Gdk.threads_enter()
+
+ # init Gtk
+ Gtk.init(None)
+
+ # create main thread and enter main loop
wi = indicator_weather()
main()
- gtk.gdk.threads_leave()
+
+ # release Gdk lock
+ Gdk.threads_leave()
\ No newline at end of file
=== modified file 'data/indicator-weather.gschema.xml'
--- data/indicator-weather.gschema.xml 2011-05-31 09:49:23 +0000
+++ data/indicator-weather.gschema.xml 2013-05-18 18:24:25 +0000
@@ -6,6 +6,21 @@
<summary>Display icon/label in the indicator</summary>
<description>0 - display icon only, 1 - display label only, 2 - display both icon and text</description>
</key>
+ <key type="b" name="relative-display">
+ <default>false</default>
+ <summary>Display relative temperature</summary>
+ <description>Display relative temperature</description>
+ </key>
+ <key type="b" name="wind-display">
+ <default>true</default>
+ <summary>Display wind speed and direction</summary>
+ <description>Display wind speed and direction</description>
+ </key>
+ <key type="b" name="suntimes-display">
+ <default>true</default>
+ <summary>Display sunrise and sunset times</summary>
+ <description>Display sunrise and sunset times</description>
+ </key>
<key type="s" name="notifications">
<default>'N'</default>
<summary>Notifications</summary>
@@ -36,6 +51,16 @@
<summary>wind unit</summary>
<description>wind unit</description>
</key>
+ <key type="s" name="heat-estimate">
+ <default>'humidex'</default>
+ <summary>heat estimate formula</summary>
+ <description>heat estimate formula</description>
+ </key>
+ <key type="s" name="chill-estimate">
+ <default>'windchill'</default>
+ <summary>chill estimate formula</summary>
+ <description>chill estimate formula</description>
+ </key>
<key type="b" name="show-forecast">
<default>true</default>
<summary>show forecast</summary>
=== modified file 'data/ui/Assistant.ui'
--- data/ui/Assistant.ui 2011-04-03 05:00:19 +0000
+++ data/ui/Assistant.ui 2013-05-18 18:24:25 +0000
@@ -1,29 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.16"/>
+ <!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires assistant 1.0 -->
- <!-- interface-naming-policy project-wide -->
<!-- interface-local-resource-path ../media -->
<object class="Assistant" id="assistant">
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Add a location</property>
+ <property name="resizable">False</property>
<property name="window_position">mouse</property>
<property name="default_width">400</property>
<property name="default_height">200</property>
- <property name="resizable">False</property>
- <signal name="apply" handler="on_apply"/>
- <signal name="cancel" handler="on_cancel"/>
- <!--<child>
- <placeholder/>
- </child> -->
+ <signal name="apply" handler="on_apply" swapped="no"/>
+ <signal name="cancel" handler="on_cancel" swapped="no"/>
<child>
<object class="GtkVBox" id="placeinput">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="lblplaceinput">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="ypad">6</property>
@@ -32,43 +31,56 @@
<property name="wrap_mode">word-char</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="city_input_vbox">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkComboBoxEntry" id="combolocations">
- <property name="visible">True</property>
- <signal name="changed" handler="on_select_city"/>
- <child internal-child="entry">
- <object class="GtkEntry" id="entrylocation">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="getcities">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Search</property>
- <signal name="clicked" handler="on_get_city_names"/>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
+ <object class="GtkHBox" id="city_input_vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBox" id="combolocations">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="has_entry">True</property>
+ <signal name="changed" handler="on_select_city" swapped="no"/>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="entrylocation">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="getcities">
+ <property name="label" translatable="yes">Search</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="receives_default">False</property>
+ <signal name="clicked" handler="on_get_city_names" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
- </packing>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
<packing>
@@ -78,16 +90,19 @@
<child>
<object class="GtkVBox" id="label">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="lblwould">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Please enter a name for this location:</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -99,6 +114,7 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -110,10 +126,12 @@
<child>
<object class="GtkVBox" id="review">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<child>
<object class="GtkLabel" id="lblreview">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="ypad">6</property>
<property name="label" translatable="yes">Please review the choices below. If anything is not correct, please go back and select the correct options.</property>
@@ -122,99 +140,120 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkHBox" id="revlabel">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkArrow" id="arrow3">
<property name="visible">True</property>
<property name="sensitive">False</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbl3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Label:</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="labellbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes"><b>Home</b></property>
<property name="use_markup">True</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="revplace">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">5</property>
<child>
<object class="GtkArrow" id="arrow2">
<property name="visible">True</property>
<property name="sensitive">False</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lbl2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Location:</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="placelbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes"><b>Orange, Texas</b></property>
<property name="use_markup">True</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -223,6 +262,7 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -235,5 +275,10 @@
<property name="title" translatable="yes">Review choices</property>
</packing>
</child>
+ <child internal-child="action_area">
+ <object class="GtkBox" id="Assistant-action_area1">
+ <property name="can_focus">False</property>
+ </object>
+ </child>
</object>
</interface>
=== modified file 'data/ui/ExtendedForecast.ui'
--- data/ui/ExtendedForecast.ui 2011-11-27 07:38:08 +0000
+++ data/ui/ExtendedForecast.ui 2013-05-18 18:24:25 +0000
@@ -1,64 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.16"/>
+ <!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires extended_forecast 1.0 -->
- <!-- interface-naming-policy project-wide -->
<!-- interface-local-resource-path ../media -->
<object class="ExtendedForecast" id="extended_forecast">
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Extended Forecast</property>
<property name="resizable">False</property>
<property name="window_position">mouse</property>
<property name="icon">../media/icon.png</property>
- <signal name="destroy" handler="on_destroy"/>
+ <signal name="destroy" handler="on_destroy" swapped="no"/>
<child>
<object class="GtkVBox" id="mainvbox">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
- <object class="GtkLabel" id="connection_error">
- <property name="visible">False</property>
- <property name="ypad">10</property>
- <property name="label"><big>Forecast information cannot be fetched. Connection cannot be established.</big></property>
- <property name="use_markup">True</property>
- <property name="wrap">False</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
+ <object class="GtkLabel" id="connection_error">
+ <property name="can_focus">False</property>
+ <property name="ypad">10</property>
+ <property name="label"><big>Forecast information cannot be fetched. Connection cannot be established.</big></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="right_padding">6</property>
<child>
<object class="GtkVBox" id="day1vbox">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day1lbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="ypad">10</property>
<property name="label"><big>Today (fri.)</big></property>
<property name="use_markup">True</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="day1image">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="pixel_size">50</property>
<property name="icon_name">weather-showers</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -66,6 +78,7 @@
<object class="GtkLabel" id="day1cond">
<property name="height_request">80</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Partially cloudy</property>
<property name="justify">center</property>
<property name="wrap">True</property>
@@ -73,33 +86,44 @@
<property name="width_chars">15</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="day1temphigh">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">High : 23°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="day1templow">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Low : 19°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
@@ -107,6 +131,8 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -114,45 +140,58 @@
<object class="GtkVSeparator" id="vseparator1">
<property name="width_request">2</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="right_padding">6</property>
<child>
<object class="GtkVBox" id="day2vbox">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day2lbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="ypad">10</property>
<property name="label"><big>Tomorrow (sat.)</big></property>
<property name="use_markup">True</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="day2image">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="pixel_size">50</property>
<property name="icon_name">weather-storm</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -160,6 +199,7 @@
<object class="GtkLabel" id="day2cond">
<property name="height_request">80</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Couverture nuageuse partielle</property>
<property name="justify">center</property>
<property name="wrap">True</property>
@@ -167,33 +207,44 @@
<property name="width_chars">15</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="day2temphigh">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">High : 26°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="day2templow">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Low : 16°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
@@ -201,6 +252,8 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -208,47 +261,58 @@
<object class="GtkVSeparator" id="vseparator2">
<property name="width_request">2</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="right_padding">6</property>
<child>
<object class="GtkVBox" id="day3vbox">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day3lbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="ypad">10</property>
<property name="label"><big>Sunday</big></property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="day3image">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="pixel_size">50</property>
<property name="icon_name">weather-fog</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -256,6 +320,7 @@
<object class="GtkLabel" id="day3cond">
<property name="height_request">80</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Fogs</property>
<property name="justify">center</property>
<property name="wrap">True</property>
@@ -263,32 +328,43 @@
<property name="width_chars">15</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day3temphigh">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">High : 28°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="day3templow">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Low : 16°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
@@ -296,50 +372,65 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVSeparator" id="vseparator3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox5">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkAlignment" id="alignment5">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="day4vbox">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day4lbl">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="ypad">10</property>
<property name="label"><big>Monday</big></property>
<property name="use_markup">True</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="day4image">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="pixel_size">50</property>
<property name="icon_name">weather-clear</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -347,6 +438,7 @@
<object class="GtkLabel" id="day4cond">
<property name="height_request">80</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Clear</property>
<property name="justify">center</property>
<property name="wrap">True</property>
@@ -354,32 +446,43 @@
<property name="width_chars">15</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="day4temphigh">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">High : 26°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="day4templow">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label">Low : 14°C</property>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
@@ -387,16 +490,21 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
@@ -404,26 +512,31 @@
<child>
<object class="GtkHSeparator" id="hseparator1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">1</property>
<child>
<object class="GtkVButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkButton" id="closebtn">
<property name="label">gtk-close</property>
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
- <signal name="clicked" handler="close"/>
+ <signal name="clicked" handler="close" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -435,6 +548,8 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
=== modified file 'data/ui/PreferencesDialog.ui'
--- data/ui/PreferencesDialog.ui 2012-03-12 04:53:24 +0000
+++ data/ui/PreferencesDialog.ui 2013-05-18 18:24:25 +0000
@@ -1,19 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.16"/>
+ <!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires preferences_dialog 1.0 -->
- <!-- interface-naming-policy project-wide -->
<object class="GtkListStore" id="citieslist">
<columns>
<!-- column-name Label -->
<column type="gchararray"/>
<!-- column-name City -->
<column type="gchararray"/>
- <!-- column-name Location Details -->
+ <!-- column-name Location -->
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkAdjustment" id="rate">
+ <property name="lower">1</property>
+ <property name="upper">30</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
<object class="PreferencesDialog" id="preferences_dialog">
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Weather Indicator Preferences</property>
<property name="window_position">mouse</property>
@@ -22,62 +28,118 @@
<property name="icon">../media/icon.png</property>
<property name="type_hint">normal</property>
<child internal-child="vbox">
- <object class="GtkVBox" id="dialog-vbox1">
+ <object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="cancel" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok_button">
+ <property name="label">gtk-ok</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">False</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="ok" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
<child>
<object class="GtkNotebook" id="notebook1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
- <object class="GtkVBox" id="vboxpreferences">
+ <object class="GtkBox" id="vboxpreferences">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
+ <property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
- <object class="GtkVBox" id="vbox10">
+ <object class="GtkBox" id="vbox10">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkCheckButton" id="enableindicator">
<property name="label" translatable="yes">Enable the Weather Indicator Applet</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="xalign">0.02</property>
+ <property name="xalign">0.019999999552965164</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_label">
- <property name="visible">True</property>
<property name="label" translatable="yes">Show temperature near indicator</property>
+ <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox_updateevery">
+ <object class="GtkBox" id="hbox_updateevery">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="updateevery">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Update every</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
@@ -86,6 +148,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
+ <property name="invisible_char_set">True</property>
<property name="adjustment">rate</property>
</object>
<packing>
@@ -97,31 +160,39 @@
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">minutes</property>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox1">
+ <object class="GtkBox" id="vbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="notificationslabel">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="ypad">3</property>
<property name="label" translatable="yes"><b>Notifications</b></property>
@@ -129,16 +200,20 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox4">
+ <object class="GtkBox" id="vbox4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkRadioButton" id="nonotif">
@@ -146,6 +221,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
@@ -161,6 +237,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">nonotif</property>
</object>
@@ -176,6 +253,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">nonotif</property>
</object>
@@ -189,12 +267,15 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="weathersourcelabel">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="ypad">3</property>
<property name="label" translatable="yes"><b>Weather Data Source</b></property>
@@ -202,40 +283,46 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox5">
+ <object class="GtkBox" id="vbox5">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
- <object class="GtkRadioButton" id="google">
- <property name="label" translatable="yes">Google</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
<object class="GtkRadioButton" id="yahoo">
<property name="label" translatable="yes">Yahoo!</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">google</property>
+ <property name="xalign">0.5</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="weather-com">
+ <property name="label" translatable="yes">Weather.com</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">yahoo</property>
</object>
<packing>
<property name="expand">False</property>
@@ -247,12 +334,15 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
@@ -261,6 +351,7 @@
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
</object>
<packing>
@@ -268,16 +359,296 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox9">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
+ <object class="GtkBox" id="boxdisplay">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="conditionslabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="ypad">3</property>
+ <property name="label" translatable="yes"><b>Weather Conditions</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkCheckButton" id="show_relative">
+ <property name="label" translatable="yes">Relative temperature ("Feels like")</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="show_wind">
+ <property name="label" translatable="yes">Wind speed and direction</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="show_suntimes">
+ <property name="label" translatable="yes">Sunrise and sunset times</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="heatlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="ypad">3</property>
+ <property name="label" translatable="yes"><b>Relative Heat Formula</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="heatindex">
+ <property name="label" translatable="yes">Heat Index (US)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="humidex">
+ <property name="label" translatable="yes">Humidex (Canada)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">heatindex</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="chilllabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="ypad">3</property>
+ <property name="label" translatable="yes"><b>Wind Chill Formula</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="wctindex">
+ <property name="label" translatable="yes">JAG/TI Wind Chill Index (US/UK/Canada)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="aatindex">
+ <property name="label" translatable="yes">Apparent Temperature (Australia)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">wctindex</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Conditions</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="vbox9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="Metric System Unit">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="ypad">3</property>
<property name="label" translatable="yes"><b>Temperature Scale</b></property>
@@ -285,16 +656,20 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox6">
+ <object class="GtkBox" id="box5">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkRadioButton" id="imperial">
@@ -302,6 +677,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
@@ -317,6 +693,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0</property>
<property name="draw_indicator">True</property>
<property name="group">imperial</property>
</object>
@@ -331,21 +708,26 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox3">
+ <object class="GtkBox" id="vbox3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="Wind Speed Unit">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="ypad">3</property>
<property name="label" translatable="yes"><b>Wind Speed Unit</b></property>
@@ -353,23 +735,28 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
- <object class="GtkVBox" id="vbox7">
+ <object class="GtkBox" id="vbox7">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkRadioButton" id="mps">
- <property name="label" translatable="yes">Meter per second (m/s)</property>
+ <property name="label" translatable="yes">Meters per second (m/s)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
@@ -385,6 +772,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">mps</property>
</object>
@@ -400,6 +788,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">mps</property>
</object>
@@ -411,10 +800,11 @@
</child>
<child>
<object class="GtkRadioButton" id="beaufort">
- <property name="label" translatable="yes">Beaufort</property>
+ <property name="label" translatable="yes">Beaufort number</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">mps</property>
</object>
@@ -430,6 +820,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">mps</property>
</object>
@@ -444,41 +835,44 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label" translatable="yes">Units</property>
</object>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox8">
+ <object class="GtkBox" id="vbox8">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
+ <property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
<property name="window_placement_set">True</property>
<property name="shadow_type">in</property>
<child>
@@ -490,6 +884,9 @@
<property name="headers_clickable">False</property>
<property name="reorderable">True</property>
<property name="search_column">0</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
<child>
<object class="GtkTreeViewColumn" id="City">
<property name="title">City</property>
@@ -506,12 +903,15 @@
</child>
</object>
<packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="layout_style">start</property>
<child>
@@ -521,7 +921,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
- <signal name="clicked" handler="on_add_location"/>
+ <signal name="clicked" handler="on_add_location" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -536,7 +936,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
- <signal name="clicked" handler="on_remove_location"/>
+ <signal name="clicked" handler="on_remove_location" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@@ -547,70 +947,33 @@
</object>
<packing>
<property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label" translatable="yes">Locations</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
- <child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="cancel_button">
- <property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="cancel"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="ok_button">
- <property name="label">gtk-ok</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="ok"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
</object>
</child>
<action-widgets>
@@ -618,10 +981,4 @@
<action-widget response="-5">ok_button</action-widget>
</action-widgets>
</object>
- <object class="GtkAdjustment" id="rate">
- <property name="lower">1</property>
- <property name="upper">30</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
</interface>
=== modified file 'debian/changelog'
--- debian/changelog 2012-07-30 04:02:24 +0000
+++ debian/changelog 2013-05-18 18:24:25 +0000
@@ -1,408 +1,247 @@
-indicator-weather (12.07.30~precise1) precise; urgency=low
- * Skip sunset and sunrise check as Earthtools.org is down (LP: #964365)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Mon, 30 Jul 2012 07:01:51 +0300
-
-indicator-weather (11.11.28~precise2) precise; urgency=low
- * Don't write too much debug info in the log (LP: #917253)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Wed, 18 Jan 2012 10:03:20 +0300
-
-indicator-weather (11.11.27~precise1) precise; urgency=low
-
- * Bugfix version for Cloudy 9
- * Preferences buttons OK and Cancel and Forecast's Close are not focusable (LP: #853774)
- * Fixed installation error due to incorrect icon copying (LP: #808538)
- * Don't crash if Google doesn't return icons (LP: #809187)
- * Display degrees in wind info item if Yahoo is selected (LP: #838369)
- * Fixed Assistant behavior for Forward/Back movements (LP: #804659)
- * Fixed a crash when Unknown wind condition was returned, thanks Tomasz Maciejewski! (LP: #886028)
- * Removed autostart feature - should be implemented in UI (LP: #873386)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 27 Nov 2011 10:47:41 +0300
-
-indicator-weather (11.05.31~precise7) precise; urgency=low
-
- * Ported from python-support to dh_python2
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Wed, 22 Jun 2011 02:27:38 -0700
-
-indicator-weather (11.05.31~precise6) precise; urgency=low
-
- * Bugfix version for Cloudy 8
- * Proper fix of self.db.list_keys() for precise users (LP: #791615)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Tue, 14 Jun 2011 05:12:19 -0700
-
-indicator-weather (11.05.31~precise5) precise; urgency=low
-
- * Bugfix version for Cloudy 8
- * Show default labels if some data from providers is missing (LP: #794473)
- * Using try-catch instead self.db.list_keys() for precise users (LP: #791615)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Tue, 14 Jun 2011 04:12:33 -0700
-
-indicator-weather (11.05.31~precise4) precise; urgency=low
-
- * Bugfix version for Cloudy 8
- * Another update for Google icon path changes
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Mon, 06 Jun 2011 02:57:42 -0700
-
-indicator-weather (11.05.31~precise3) precise; urgency=low
-
- * Bugfix version for Cloudy 8
- * Display correct icon and description for empty condition in forecast (LP: #791733)
- * Updated google icon paths for Google icons (LP: #791724)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 02 Jun 2011 02:15:24 -0700
-
-indicator-weather (11.05.31~precise2) precise; urgency=low
-
- * Bugfix version for Cloudy 8
- * Attach dconf settings to apport results (LP: #731911)
- * Store show_label in dconf correctly (LP: #791398)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 02 Jun 2011 00:53:06 -0700
-
-indicator-weather (11.05.31~precise1) precise; urgency=low
-
- * New release in Cloudy series
- * Ported settings to dconf, which will solve a number of desktopcouch-related bugs
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Tue, 31 May 2011 02:43:24 -0700
-
-indicator-weather (11.05.30~precise1) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #776586 "I get "Unknown error occurred while picking up weather data" when trying to open forecast."
- * Fix for LP: #784935 "indicator-weather crash - KeyError: 'wind_condition'"
- * Fix for LP: #788780 "indicator disappears with no reason"
- * Fix for LP: #774406 "Insufficient http-proxy detection", thanks Panagiotis
- * Fix for LP: #782572 "The log should contain Weather Indicator version"
- * Fix for LP: #780585 "Celsius is not an SI unit"
- * Fix for LP: #780817 "units mislabeled as kph"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Mon, 30 May 2011 03:20:58 -0700
-
-indicator-weather (11.05.01~precise2) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #765464 "sunrise and sunset info incorrect", thanks Panagiotis!
- * Fix for LP: #775630 "package indicator-weather 11.05.01~precise1 failed to install/upgrade"
- * Fix for LP: #772552 "weather applet doesn't start"
- * Fix for LP: #769842 "Weather Indicator should clear up corrupted DB"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Mon, 02 May 2011 19:59:36 +0300
-
-indicator-weather (11.04.24~precise4) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #747733 "indicator-weather crashed with TypeError in next_page(): unknown type (null)"
- * Fix for LP: #757195 "Again: Version 11.04.10~precise4 doesn't start"
- * Fix for LP: #758309 "dpkg error when installing latest build on Ubuntu 11.04 Beta", using patch from Andrew Starr-Bochicchio
- * Fix for LP: #766049 "Traceback on startup: No module named desktopcouch.records.server"
- * Fix for LP: #753309 "weather applet displays wrong sunset/sunrise times", using earthtools for both Google and Yahoo
- * Fix for LP: #765464 "do not see indicator-weather on the panel"
- * python-apport is now recommended only, thanks Andrew
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 24 Apr 2011 10:57:00 +0300
-
-indicator-weather (11.04.10~precise4) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #743375 "indicator-weather crashed with error in _try_request_with_retries(): [Errno 111] Connection refused"
- * Fix for LP: #747562 "indicator-weather crashed with AttributeError in get_value(): Settings instance has no attribute 'settings_design_doc'"
- * Fix for LP: #743840 "Crashes on forecast view"
- * Fix for LP: #750809 "No "Thunderstorm" icon shown in Forecast only empty place holder.", thanks Felix!
- * Fix for LP: #743375 "indicator-weather should re-use the time-format of other indicators", thanks Panagiotis!
- * debian/postinst: copy few-clouds to clouds to show all icons (LP: #710295)
- * Updated dependencies - added python-gconf
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 10 Apr 2011 10:05:12 +0300
-
-indicator-weather (11.04.02~precise) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #739420 "indicator-weather crashed with KeyError in prepare_forecast_data(): 'unit_system'", thanks Felix!
- * Fix for LP: #732569 "weather applet freezes on clicking refresh", thanks Panagiotis!
- * Fix for LP: #745504 "no degree marker ℃ ℉ displayed", thanks Lucian!
- * Fix for LP: #739029 "Indicator takes up too much space"
- * Fix for LP: #739029 "Quit button doesn't work", thanks Panagiotis!
- * Fix for LP: #745634 "http proxy not supported", thanks Panagiotis!
- * Fix for LP: #742397 "weather applet doesn't refresh information after resume", thanks Panagiotis!
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sat, 02 Apr 2011 12:08:56 +0300
-
-indicator-weather (11.03.27~precise) precise; urgency=low
-
- * New release in Cloudy series
- * Fix for LP: #739907 "indicator-weather failed to start falsely reporting duplicate instance", thanks Felix!
- * Fix for LP: #720030 "indicator invisible on first run", thanks Felix!
- * Fix for LP: #743347 "what's the meaning of Mixed rain and snow/Sleet/Mixed rain and sleet/Mixed snow and sleet"
- * Fix for LP: #738671 "Allow only one instance of any dialog"
- * Fix for LP: #735667 "indicator-weather crashed with NetworkException in FetchReport(): HTTP Error 408: Request Time-out"
- * Fix for LP: #739209 "indicator-weather crashed with AttributeError in get_value(): 'NoneType' object has no attribute 'execute_view'"
- * Fix for LP: #738845 "indicator-weather crashed with IOError in about(): [Errno 2] No such file or directory: '/usr/share/doc/indicator-weather/COPYING'"
- * Fix for LP: #743366 "Location selected but no weather"
- * Updated Refresh label for plural forms
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 27 Mar 2011 13:27:42 +0300
-
-indicator-weather (11.03.20~precise2) precise; urgency=low
-
- * Quick fix release for Cloudy
- * Fix for LP: #738804 "indicator-weather crashed with KeyError in on_get_city_names(): 'geonames'"
- * Fix for LP: #738762 "indicator-weather crashed with ImportError in /usr/lib/pymodules/python2.7/desktopcouch/records/server.py: No module named application.server"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 20 Mar 2011 20:05:29 +0200
-
-indicator-weather (11.03.20~precise) precise; urgency=low
-
- * Releasing 11.03.20 "Cloudy" version
- * Fix for LP: #738503 "indicator-weather crashed with IOError in about(): [Errno 2] No such file or directory: '../AUTHORS' after clicking About..."
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 20 Mar 2011 07:54:50 +0200
-
-indicator-weather (11.02.13+unstable+bzr217+rc3~precise) precise; urgency=low
-
- * Release Candidate 3
- * Fix for LP: #713846 "Weather Indicator should have About page"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sat, 19 Mar 2011 11:26:54 +0200
-
-indicator-weather (11.02.13+unstable+bzr214+rc1~precise) precise; urgency=low
-
- * Release Candidate 2
- * Fix for LP: #735928 "indicator-weather crashed with NameError in prepare_settings_store(): global name 'DBusException' is not defined"
- * Fix for LP: #734362 "Use plural forms in translations for units"
- * Fix for LP: #721714 "Refresh label should contain info about time from last refresh"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sat, 19 Mar 2011 01:33:31 +0200
-
-indicator-weather (11.02.13+unstable+bzr210+rc1~precise) precise; urgency=low
-
- * Release Candidate 1
- * Fix for LP: #733760 "indicator-weather crashed with KeyError in save_location_details(): 'yahoo id'"
- * Fix for LP: #730193 "indicator-weather crashed with AttributeError in get_forecast_daysofweek(): Location instance has no attribute '_Location__parsedforecast'"
- * Fix for LP: #728473 "Sunrise/sunset time being shown in DST"
- * Fix for LP: #731236 "Sunset/sunrise time should not include seconds"
- * Fix for LP: #719886 "An option to display temperature near the icon"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 10 Mar 2011 09:21:57 +0200
-
-indicator-weather (11.02.13+unstable+bzr204~precise) precise; urgency=low
-
- * Fix for LP: #732434 "indicator-weather crashed with DBusException in call_blocking(): org.freedesktop.DBus.Error.NoReply"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 10 Mar 2011 09:21:57 +0200
-
-indicator-weather (11.02.13+unstable+bzr203~precise) precise; urgency=low
-
- * Fixes for incorrect and missing icons
- * Fix for LP: #732275 "CouchDB exception on db.compact()"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 10 Mar 2011 00:23:14 +0200
-
-indicator-weather (11.02.13~unstable+bzr200~precise) precise; urgency=low
-
- * Implemented Desktopcouch support
- * Using PyWAPI to get data
- * Two data sources are available - Yahoo and Google
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Wed, 09 Mar 2011 22:55:00 +0200
-
-indicator-weather (11.02.13+bzr180~precise) precise; urgency=low
-
- * Implemented UI improvements. Thanks, Andrew
- * Fix for LP: #719693 "[regression] Menu item will not show up in GNOME-Menu", thanks Andrew Starr-Bochicchio
- * Fix for LP: #720112 "unsafe tempfile handling"
- * Fix for LP: #719884 "Metric scales labels should include temperature units"
- * Immideate update of icons
- * Fix for missing kph setting on UI
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Thu, 17 Feb 2011 00:13:01 +0200
-
-indicator-weather (11.02.13~precise) precise; urgency=low
-
- * Migrate to gweather + pymetar data sources
- * Added an option to choose wind units
- * Fix for labels crash in precise
- * Removed countries without cities from the tree
- * Updated connection handling
- * Minor fixes for UI in Preferences dialog
- * Updated settings store logic
- * Removed knots - caused exceptions, see Bug #712434 in pymetar
- * Updated icons
- * Fixed error with incorrect permissions for pid file - now using /tmp
- * Fix for LP: #712359 "'OK' button in Preferences dialog should be disabled, if location list is empty"
- * Fix for LP: #712347 "Synapse launcher shows Preferences window instead of Weather Indicator"
- * Fix for LP: #711891 "cannot go back from "Confirm the place" dialog"
- * Fix for LP: #711889 "Translation issues"
- * Fix for LP: #670796 "weather indicator does not wake up after suspend"
- * Fix for LP: #617801 "Weather Indicator should show humidex value"
- * Fix for LP: #703561 "Show temperature in icon"
- * Fix for LP: #705673 "Add city dialogs should have city tree"
- * Fix for LP: #710870 "Indicator-weather crashed with AttributeError in get_city(): indicator_weather instance has no attribute '_wind_unit'"
- * Fix for LP: #707681 "Allow only one instance of WI"
- * Fix for LP: #712680 "Full city name from 'Australasia & Oceania' is not displayed on Assistant page 2"
- * Fix for LP: #706805 "indicator-weather crashed with AttributeError in get_city(): 'Assistant' object has no attribute 'metric_system'"
- * Fix for LP: #706796 "indicator-weather crashed with ImportError in __main__: No module named gtkcrashhandler"
- * Fix for LP: #703681 "Indicator-Weather doesn't recheck for Internet connectivity"
- * Fix for LP: #703842 "Menus look pale in Ambiance theme"
- * Fix for LP: #703617 "Use icons of ubuntus date indicator"
- * Fix for LP: #703693 "Weather applet does not start (icon missing)"
- * Fix for LP: #706148 "indicator doesn't respect temperature scale preferences (Fahrenheit, Celsius)"
- * Fix for LP: #703819 "Weather indicator confuses time"
- * Fix for LP: #703838 "Weather Indicator should have a Quit menu entry"
- * Fix for LP: #606481 "indicator-weather crashes on startup"
- * Fix for LP: #703730 "indicator-weather doesn't display an icon for some cities"
- * Fix for LP: #703838 "Weather Indicator should have a Quit menu entry"
- * Fix for LP: #618108 "Label is not shown in the dialogs when specified"
- * Fix for LP: #604265 "First configuration weather unit setting not saved"
- * Fix for LP: #717907 "Not having a condition name should not be a big deal" - updated error text and icon
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 13 Feb 2011 09:28:08 +0200
-
-indicator-weather (11.01.16~precise) precise; urgency=low
-
- * Fix for Bug #618108 "Label is not shown in the dialogs when specified"
- * Fix for Bug #604265 "First configuration weather unit setting not saved"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx> Sun, 16 Jan 2011 14:17:27 +0200
-
-indicator-weather (10.07.16~precise) precise; urgency=low
-
- * Bugfix : list index out of range fixed
-
- -- ridem <mehd36@xxxxxxxxx> Sun, 11 Jul 2010 01:11:10 +0200
-
-indicator-weather (10.07.15~precise) precise; urgency=low
-
- * Sunlight-sunset added/night-day icons/ assistant made thanks to
- cullen, but no label support for now
-
- -- ridem <mehd36@xxxxxxxxx> Sat, 10 Jul 2010 21:32:53 +0200
-
-indicator-weather (10.07.14~precise) precise; urgency=low
-
- * Autostart hidden and works, Assistant works, but needs polish now
-
- -- ridem <mehd36@xxxxxxxxx> Sat, 10 Jul 2010 04:06:24 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 02:48:49 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 02:44:18 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 02:36:52 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 02:31:03 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
- * Autostart, right category, find location in assistant, assistant not
- finished yet
-
- -- ridem <mehd36@xxxxxxxxx> Sat, 10 Jul 2010 02:01:21 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 02:00:37 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 01:01:59 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:54:23 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:53:35 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:49:41 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:45:09 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:44:28 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:42:08 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:38:48 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:36:36 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi> Sat, 10 Jul 2010 00:27:40 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
- * Work on assistant
-
- -- ridem <mehd36@xxxxxxxxx> Fri, 09 Jul 2010 01:26:35 +0200
-
-indicator-weather (10.07.11~precise) precise; urgency=low
-
- * No intrusion for the first run
-
- -- ridem <mehd36@xxxxxxxxx> Fri, 09 Jul 2010 01:23:33 +0200
-
-indicator-weather (10.07.10~precise) precise; urgency=low
-
- * Now etended forecast uses chosen unit
- * places addded/edited/removed only after Ok. Nice editing and
- reordering
-
- -- ridem <mehd36@xxxxxxxxx> Tue, 06 Jul 2010 20:45:27 +0200
+indicator-weather (13.05.17-0ubuntu0-ppa1) quantal; urgency=low
+
+ * Ported to GTK3 and GObject from PyGTK
+ * Rewrite threading code to avoid dbus-related crashes (LP: #743541)
+ * Added "feels like" temperature (humidex/heat index/wind chill)
+ * New "Conditions" tab in Preferences dialog to choose temperature
+ formulas and toggle display of some condition information
+ * Bumped version number to reflect massive changes
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Sat, 18 May 2013 12:59:03 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.4) quantal; urgency=low
+
+ * Don't crash if Yahoo doesn't return conditions
+ * Fixed a crash when reading saved Places with no location IDs
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Sat, 04 May 2013 01:20:38 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.3) quantal; urgency=low
+
+ * Fix units in Forecast when metric is selected
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Sat, 27 Apr 2013 18:33:26 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.2) quantal; urgency=low
+
+ * One-line fix for outdated data sources
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Wed, 24 Apr 2013 20:39:42 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.1) quantal; urgency=low
+
+ * Updated package dependency on pywapi (>= 0.3)
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Wed, 17 Apr 2013 16:22:46 -0400
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2) quantal; urgency=low
+
+ * Fix adding location, now uses Yahoo's YQL service
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Wed, 10 Apr 2013 14:16:18 -0400
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa1) quantal; urgency=low
+
+ * Fix for "Forecast", now uses Yahoo instead of Google
+ * Bump dependency for python-pywapi to 0.3
+ * Hide Google radio button on Preferences UI
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx> Tue, 09 Apr 2013 02:27:04 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1) quantal-proposed; urgency=low
+
+ * fix crash when adding new location (LP: #821233)
+ Thanks to Mantas Kriaučiūnas (mantas)
+
+ -- Michael Vogt <michael.vogt@xxxxxxxxxx> Tue, 18 Dec 2012 09:59:40 +0100
+
+indicator-weather (12.07.30-0ubuntu1) quantal; urgency=low
+
+ * New upstream release.
+ - If Earthtools.org is down, report 'Unknown' rather than
+ blocking on sunset and sunrise times (LP: #964365).
+ - Correctly preform .pid file matching so we can restart after
+ a crash (LP: #926433).
+ - Fixed flurries condition being marked as 'Unknown' (LP: #928596).
+ - Km in the units tab now written in full as kilometres (LP: #952661).
+ * debian/control: Bump standards version to 3.9.3, no changes needed.
+ * debian/postinst: Don't manually install or compile gschema. Distutils.Extras
+ now installs it correctly and an apt trigger compiles it.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Mon, 30 Jul 2012 16:32:33 -0400
+
+indicator-weather (11.11.28-0ubuntu1) precise; urgency=low
+
+ * New upstream release.
+ - Preferences buttons OK and Cancel and Forecast's Close
+ are not focusable (LP: #853774)
+ - Don't crash if Google doesn't return icons (LP: #809187)
+ - Display degrees in wind info item if Yahoo is selected (LP: #838369)
+ - Fixed Assistant behavior for Forward/Back movements (LP: #804659)
+ - Fixed a crash when Unknown wind condition was returned, thanks
+ Tomasz Maciejewski! (LP: #886028)
+ - Don't write too much debug info in the log (LP: #917253)
+ * Drop debian/patches/autostart.patch, applied upstream.
+ * Drop debian/README.source, no longer needed.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Fri, 20 Jan 2012 15:25:46 -0500
+
+indicator-weather (11.05.31-0ubuntu3) precise; urgency=low
+
+ * Forward port fix for LP: #873386 from oneiric-proposed.
+ * debian/copyright: Bring up-to-date with latest Dep-5 spec.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Fri, 04 Nov 2011 17:13:10 -0400
+
+indicator-weather (11.05.31-0ubuntu2.1) oneiric-proposed; urgency=low
+
+ * debian/postinst: Do not attempt to install autostart
+ file in user's home directory (LP: #873386).
+ * debian/patches/autostart.patch: Instead, check for file's
+ existance at runtime. If it is not there, properly create it.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Wed, 02 Nov 2011 11:51:55 -0400
+
+indicator-weather (11.05.31-0ubuntu2) oneiric; urgency=low
+
+ * debian/postinst: Make sure script only opperates on
+ directories and not files (LP: #819292).
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Wed, 03 Aug 2011 14:12:39 -0400
+
+indicator-weather (11.05.31-0ubuntu1) oneiric; urgency=low
+
+ * New upstream release.
+ - Ported settings to dconf, which will solve a number of
+ desktopcouch-related bugs
+ - Fix for LP: #747733 "indicator-weather crashed with
+ TypeError in next_page(): unknown type (null)"
+ - Fix for LP: #756704 "Numbers (temperature etc.) do
+ not use local number format"
+ - Fix for LP: #770652 "sunrise and sunset info incorrect"
+ - Fix for LP: #765464 "do not see indicator-weather on the panel"
+ - Fix for LP: #769842 "Weather Indicator should clear up corrupted DB"
+ - Fix for LP: #778941 "Weather Indicator can't be disabled"
+ - Fix for LP: #796314 "ROUND_CEiLiNG error in Turkish locale"
+ - Fix for LP: #780973 "indicator-weather crashed with Unauthorized in
+ request(): ('unauthorized', 'Authentication required.')"
+ * debian/control:
+ - Adjust dependencies for desktop-couch to dconf transition.
+ - Bump Standards-Version to 3.9.2.
+ - Explictily depend on libgtk2.0-bin to ensure we have
+ /usr/bin/gtk-update-icon-cache (LP: #808387).
+ * Convert from python-support to dh_python2.
+ * debian/rules:
+ - Drop get-orig-source target, not needed.
+ - Fix debian/postinst to check for symbolic links as well.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Tue, 12 Jul 2011 01:44:53 -0400
+
+indicator-weather (11.04.10+repack-0ubuntu2) natty; urgency=low
+
+ * debian/postinst: Test to make sure file doesn't already
+ exist before creating link. (LP: #758323)
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Mon, 11 Apr 2011 23:11:03 -0400
+
+indicator-weather (11.04.10+repack-0ubuntu1) natty; urgency=low
+
+ * New upstream bug fix release.
+ - Fix for LP: #720066 "indicator-weather should re-use the
+ time-format of other indicators"
+ - Fix for LP: #750809 "No "Thunderstorm" icon shown in Forecast
+ only empty place holder."
+ - Fix for LP: #747562 "indicator-weather crashed with AttributeError
+ in get_value(): Settings instance has no attribute 'settings_design_doc'"
+ - Fix for LP: #743375 "indicator-weather crashed with error
+ in _try_request_with_retries(): [Errno 111] Connection refused"
+ * Drop python-apport from Depends to Recommends. (LP: #757568)
+ * Drop patches. Included upstream.
+ * debian/postinst: Link weather-few-clouds{-night}.png with
+ weather-clouds{-night}.png, work-a-round for incomplete icon
+ themes. Add Depends on gnome-icon-theme and xdg-utils.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Mon, 11 Apr 2011 15:08:07 -0400
+
+indicator-weather (11.03.27+repack-0ubuntu1) natty; urgency=low
+
+ * New upstream release.
+ - Fix for LP: #720030 "indicator invisible on first run",
+ thanks Felix!
+ - Fix for LP: #739209 "indicator-weather crashed with
+ AttributeError in get_value(): 'NoneType' object has no
+ attribute 'execute_view'"
+ - Fix for LP: #739907 "indicator-weather failed to start
+ falsely reporting duplicate instance", thanks Felix!
+ - Fix for LP: #735667 "indicator-weather crashed with NetworkException
+ in FetchReport(): HTTP Error 408: Request Time-out"
+ - And even more bug fixes.
+ * debian/indicator-weather.install: COPYING file no longer
+ needed. Now uses common-license version.
+ * Drop lintian over-ride for extra-license-file.
+ * Drop debian/patches/01_lp_738804.patch, applied upstream.
+ * debian/rules: No need to delete empty dir anymore.
+ * fix-google-coordinates-lp739420.patch: Fix formatting
+ of coordinates Google. Patch by Felix Lawrence!
+ Fixes LP: #739420 and LP: #744702.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Mon, 28 Mar 2011 18:39:38 -0400
+
+indicator-weather (11.03.20+repack-0ubuntu2) natty; urgency=low
+
+ * Directly depend on desktopcouch to work-around LP: #738762.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Wed, 23 Mar 2011 22:31:37 -0400
+
+indicator-weather (11.03.20+repack-0ubuntu1) natty; urgency=low
+
+ * New upstream release.
+ - Fix unsafe tempfile handling (LP: #720112).
+ - Fix gconf related crashers (LP: #723557).
+ - Fix TypeError in getHumidex() (LP: #730287).
+ - Allow two userid's to run indicator-weather
+ simultaneously (LP: #730378).
+ - Fix night icon showing during daytime (LP: #715657).
+ - Fix indicator invisible on first run (LP: #720030).
+ - Fix AttributeError in __find_city_by_code() (LP: #733681).
+ - Fix AttributeError when clicking "Forecast" if there is
+ no network connection (LP: # 730193).
+ * debian/control:
+ - Drop depends on python-simplejson, python-gconf,
+ python-pymetar, and python-gweather.
+ - Add depends on python-desktopcouch-records and
+ python-pywapi.
+ * Drop all old patches, applied upstream.
+ * 01_lp_738804.patch: Fix crash on city names with spaces.
+ * debian/rules:
+ - Tweak get-orig-source target for new upstream
+ directory naming.
+ - Don't compress AUTHORS and COPYING. Needed for
+ about dialog.
+ * debian/indicator-weather.install: Install AUTHORS
+ and COPYING files to /usr/share/doc/indicator-weather
+ to fix crash in about dialog.
+ * debian/indicator-weather.lintian-overrides: Overide
+ lintian warning about extra copyright file.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Sun, 20 Mar 2011 22:16:35 -0400
+
+indicator-weather (11.02.13+repack-0ubuntu1) natty; urgency=low
+
+ * New upstream release.
+ - Fixes crash due to icon missing (LP: #703693).
+ * debian/control: Depend on python-pymetar, python-gweather,
+ and python-apport.
+ * debian/patches/01_US_units.patch: Cherry pick upstream
+ revision 174 containing fix for forecast with US units.
+ * Install apport hook.
+ * debian/patches/02_menu_entry.patch: Allow indicator-weather
+ to show in GNOME menu and validate with desktop-file-validate.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Mon, 14 Feb 2011 22:43:07 -0500
+
+indicator-weather (11.01.16+repack-0ubuntu1) natty; urgency=low
+
+ * Initial Ubuntu release. (LP: #711518)
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx> Tue, 01 Feb 2011 16:45:54 -0500
=== modified file 'debian/control'
--- debian/control 2011-06-22 09:52:46 +0000
+++ debian/control 2013-05-18 18:24:25 +0000
@@ -1,26 +1,33 @@
Source: indicator-weather
Section: python
Priority: extra
-Build-Depends: cdbs (>= 0.4.90-1~),
- debhelper (>= 6),
- python (>= 2.6.6-3~),
- gobject-introspection,
- python-distutils-extra (>= 2.10)
-Maintainer: Vadim Rutkovsky <roignac@xxxxxxxxx>
-Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7.0.50~),
+ gobject-introspection,
+ python (>= 2.6.6-3~),
+ python-distutils-extra (>= 2.10)
+X-Python-Version: >= 2.6
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@xxxxxxxxxxxxxxxx>
+Standards-Version: 3.9.3
+Homepage: https://launchpad.net/weather-indicator
Package: indicator-weather
Architecture: all
-Depends: ${misc:Depends},
- ${python:Depends},
- libglib2.0-bin,
- python-appindicator,
- python-notify,
- python-gobject,
- python-gtk2,
- python-gconf,
- python-pywapi
+Depends: gir1.2-glib-2.0,
+ gir1.2-gtk-3.0,
+ gir1.2-appindicator3-0.1
+ gnome-icon-theme,
+ libglib2.0-bin,
+ libgtk-3-bin,
+ python-gconf,
+ python-gi,
+ python-pywapi (>= 0.3.1),
+ xdg-utils,
+ ${misc:Depends},
+ ${python:Depends}
Recommends: python-apport
-Description: A weather indicator for Ubuntu's Indicator Applet
- A weather indicator that displays information for one or multiple places
- in the world
+Description: indicator that displays weather information
+ Indicator-Weather displays information for one or multiple places
+ in the world. Current weather status is displayed directly on your
+ panel and detailed forecasts are no more than a click away.
+ .
+ It is implemented using the Indicator Applet API.
=== modified file 'debian/copyright'
--- debian/copyright 2011-06-22 09:52:46 +0000
+++ debian/copyright 2013-05-18 18:24:25 +0000
@@ -1,12 +1,31 @@
-Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat
-Upstream-Name: indicator-weather
-Upstream-Maintainer: Vadim Rutkovsky <roignac@xxxxxxxxx>
-Upstream-Source: https://launchpad.net/weather-indicator
+Format: http://dep.debian.net/deps/dep5
+Upstream-Name: Indicator-Weather
+Upstream-Contact: Vadim Rutkovsky <roignac@xxxxxxxxx>
+Source: https://launchpad.net/weather-indicator/+download
Files: *
-Copyright: (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
-Copyright: (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
-Copyright: (C) 2011 Vadim Rutkovsky <roignac@xxxxxxxxx>
-License: GPL-3
- The full text of the GPL is distributed in
- /usr/share/common-licenses/GPL-3 on Debian systems.
+Copyright: 2010, Mehdi Rejraji <mehd36@xxxxxxxxx>
+ 2010, Sebastian MacDonald <Sebas310@xxxxxxxxx>
+ 2011, Vadim Rutkovsky <roignac@xxxxxxxxx>
+ 2013, Joshua Tasker <jtasker@xxxxxxxxx>
+License: GPL-3
+
+Files: debian/*
+Copyright: 2011, Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>
+License: GPL-3
+
+License: GPL-3
+ This package 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; version 3 of the License.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ .
+ On Debian systems, see `/usr/share/common-licenses/GPL-3'
=== modified file 'debian/indicator-weather.install'
--- debian/indicator-weather.install 2011-01-23 14:08:21 +0000
+++ debian/indicator-weather.install 2013-05-18 18:24:25 +0000
@@ -1,1 +1,2 @@
+AUTHORS /usr/share/doc/indicator-weather
debian/source_indicator-weather.py usr/share/apport/package-hooks
=== modified file 'debian/postinst'
--- debian/postinst 2011-11-02 15:34:54 +0000
+++ debian/postinst 2013-05-18 18:24:25 +0000
@@ -1,19 +1,18 @@
#!/bin/sh
-
+
+set -e
+
#DEBHELPER#
+
echo "Installing indicator-specific icons..."
xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon.png weather-indicator
xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon_unknown_condition.png weather-indicator-unknown
xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon_connection_error.png weather-indicator-error
-#installing dconf schema
-echo "Installing indicator dconf schema..."
-cp /usr/share/indicator-weather/indicator-weather.gschema.xml /usr/share/glib-2.0/schemas
-glib-compile-schemas /usr/share/glib-2.0/schemas
-
#quick fix for incomplete icon themes
echo "Fixing incomplete weather icons..."
-if [ ! -e "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ]; then
+if [ ! -e "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ] && \
+ [ ! -L "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ]; then
ln -s /usr/share/icons/gnome/22x22/status/weather-few-clouds.png /usr/share/icons/gnome/22x22/status/weather-clouds.png
ln -s /usr/share/icons/gnome/22x22/status/weather-clouds-night.png /usr/share/icons/gnome/22x22/status/weather-clouds-night.png
=== modified file 'debian/rules'
--- debian/rules 2011-06-22 09:52:46 +0000
+++ debian/rules 2013-05-18 18:24:25 +0000
@@ -1,5 +1,11 @@
#!/usr/bin/make -f
-DEB_PYTHON2_MODULE_PACKAGES:=indicator-weather
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/python-distutils.mk
+
+%:
+ dh $@ --with python2
+
+override_dh_auto_install:
+ dh_auto_install
+ find -iname "*.desktop" -exec chmod a-x {} \;
+
+override_dh_compress:
+ dh_compress -XAUTHORS
=== modified file 'indicator_weather/helpers.py'
--- indicator_weather/helpers.py 2012-07-30 03:58:13 +0000
+++ indicator_weather/helpers.py 2013-05-18 18:24:25 +0000
@@ -31,10 +31,10 @@
except ImportError:
DCONF_SCHEMAS = []
-import gconf
+from gi.repository import GConf
import traceback
import os
-import gtk
+from gi.repository import Gtk
import urllib2
import locale
import re
@@ -47,7 +47,7 @@
gettext.textdomain('indicator-weather')
def get_builder(builder_file_name):
- """Return a fully-instantiated gtk.Builder instance from specified ui
+ """Return a fully-instantiated Gtk.Builder instance from specified ui
file
:param builder_file_name: The name of the builder file, without extension.
@@ -58,7 +58,7 @@
if not os.path.exists(ui_filename):
ui_filename = None
- builder = gtk.Builder()
+ builder = Gtk.Builder()
builder.set_translation_domain('indicator-weather')
builder.add_from_file(ui_filename)
return builder
@@ -101,10 +101,10 @@
proxy_settings.connect("changed", ProxyMonitor.dconf_proxy_changed)
else:
# load gconf settings
- client = gconf.client_get_default()
- client.add_dir("/system/http_proxy", gconf.CLIENT_PRELOAD_ONELEVEL)
+ client = GConf.Client.get_default()
+ client.add_dir("/system/http_proxy", GConf.ClientPreloadType.PRELOAD_ONELEVEL)
ProxyMonitor.gconf_proxy_changed(client)
- client.notify_add("/system/http_proxy", ProxyMonitor.gconf_proxy_changed)
+ client.notify_add("/system/http_proxy", ProxyMonitor.gconf_proxy_changed, None)
except Exception, e:
log.error("ProxyMonitor: %s" % e)
@@ -113,7 +113,7 @@
@staticmethod
def dconf_proxy_changed(settings, changed_key=None):
"""
- Loads dconf hhtp proxy settings
+ Loads dconf http proxy settings
"""
try:
ProxyMonitor.log.debug("ProxyMonitor: loading dconf settings")
@@ -135,7 +135,7 @@
@staticmethod
def gconf_proxy_changed(client, cnxn_id=None, entry=None, data=None):
"""
- Loads gconf hhtp proxy settings
+ Loads gconf http proxy settings
"""
try:
ProxyMonitor.log.debug("ProxyMonitor: loading gconf settings")
=== modified file 'indicator_weather/indicator_weatherconfig.py'
--- indicator_weather/indicator_weatherconfig.py 2010-07-06 12:10:37 +0000
+++ indicator_weather/indicator_weatherconfig.py 2013-05-18 18:24:25 +0000
@@ -28,7 +28,7 @@
# Where your project will look for your data (for instance, images and ui
# files). By default, this is ../data, relative your trunk layout
-__indicator_weather_data_directory__ = '../data'
+__indicator_weather_data_directory__ = '/usr/share/indicator-weather'
__license__ = 'GPL-3'
import os
@@ -62,7 +62,7 @@
# Get pathname absolute or relative.
path = os.path.join(
os.path.dirname(__file__), __indicator_weather_data_directory__)
-
+
abs_data_path = os.path.abspath(path)
if not os.path.exists(abs_data_path):
raise project_path_not_found
=== modified file 'po/indicator-weather.pot'
--- po/indicator-weather.pot 2011-06-22 09:52:46 +0000
+++ po/indicator-weather.pot 2013-05-18 18:24:25 +0000
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-06-22 02:48-0700\n"
+"POT-Creation-Date: 2012-07-30 07:11+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -18,422 +18,425 @@
"Content-Transfer-Encoding: 8bit\n"
#: ../data/ui/PreferencesDialog.ui.h:1
-msgid "<b>Notifications</b>"
+msgid "Weather Indicator Preferences"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:2
-msgid "<b>Temperature Scale</b>"
+msgid "Enable the Weather Indicator Applet"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:3
-msgid "<b>Weather Data Source</b>"
+msgid "Show temperature near indicator"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:4
-msgid "<b>Wind Speed Unit</b>"
+msgid "Update every"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:5
-msgid "Beaufort"
+msgid "minutes"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:6
-msgid "Enable the Weather Indicator Applet"
+msgid "<b>Notifications</b>"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:7
-msgid "General"
+msgid "No notifications"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:8
-msgid "Google"
+msgid "Only use notifications to give severe weather alerts"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:9
-msgid "Imperial (°F)"
+msgid "Use notifications to give every weather condition change"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:10
-msgid "Km per hour (km/h)"
+msgid "<b>Weather Data Source</b>"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:11
-msgid "Knots"
+msgid "Google"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:12
-msgid "Locations"
+msgid "Yahoo!"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:13
-msgid "Meter per second (m/s)"
+msgid "General"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:14
-msgid "Miles per hour (mph)"
+msgid "<b>Temperature Scale</b>"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:15
-msgid "No notifications"
+msgid "Imperial (°F)"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:16
-msgid "Only use notifications to give severe weather alerts"
+msgid "SI (metric, °C)"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:17
-msgid "SI (metric, °C)"
+msgid "<b>Wind Speed Unit</b>"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:18
-msgid "Show temperature near indicator"
+msgid "Meter per second (m/s)"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:19
-msgid "Units"
+msgid "Miles per hour (mph)"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:20
-msgid "Update every"
+msgid "Kilometers per hour (km/h)"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:21
-msgid "Use notifications to give every weather condition change"
+msgid "Beaufort"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:22
-msgid "Weather Indicator Preferences"
+msgid "Knots"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:23
-msgid "Yahoo!"
+msgid "Units"
msgstr ""
#: ../data/ui/PreferencesDialog.ui.h:24
-msgid "minutes"
+msgid "Locations"
msgstr ""
-#: ../bin/indicator-weather.py:463
+#: ../bin/indicator-weather.py:489
msgid "Unknown error occurred while picking up weather data"
msgstr ""
-#: ../bin/indicator-weather.py:551
+#: ../bin/indicator-weather.py:579
msgid "Tornado"
msgstr ""
-#: ../bin/indicator-weather.py:552
+#: ../bin/indicator-weather.py:580
msgid "Tropical storm"
msgstr ""
-#: ../bin/indicator-weather.py:553
+#: ../bin/indicator-weather.py:581
msgid "Hurricane"
msgstr ""
-#: ../bin/indicator-weather.py:554
+#: ../bin/indicator-weather.py:582
msgid "Severe thunderstorms"
msgstr ""
-#: ../bin/indicator-weather.py:555
+#: ../bin/indicator-weather.py:583
msgid "Thunderstorms"
msgstr ""
-#: ../bin/indicator-weather.py:556
+#: ../bin/indicator-weather.py:584
msgid "Mixed rain and snow"
msgstr ""
#. Use American meaning of sleet - see http://en.wikipedia.org/wiki/Sleet
-#: ../bin/indicator-weather.py:558
+#: ../bin/indicator-weather.py:586
msgid "Mixed rain and sleet"
msgstr ""
-#: ../bin/indicator-weather.py:559
+#: ../bin/indicator-weather.py:587
msgid "Mixed snow and sleet"
msgstr ""
-#: ../bin/indicator-weather.py:560
+#: ../bin/indicator-weather.py:588
msgid "Freezing drizzle"
msgstr ""
-#: ../bin/indicator-weather.py:561
+#: ../bin/indicator-weather.py:589
msgid "Drizzle"
msgstr ""
-#: ../bin/indicator-weather.py:562
+#: ../bin/indicator-weather.py:590
msgid "Freezing rain"
msgstr ""
-#: ../bin/indicator-weather.py:563 ../bin/indicator-weather.py:564
+#: ../bin/indicator-weather.py:591 ../bin/indicator-weather.py:592
msgid "Showers"
msgstr ""
-#: ../bin/indicator-weather.py:565
+#: ../bin/indicator-weather.py:593
msgid "Snow flurries"
msgstr ""
-#: ../bin/indicator-weather.py:566
+#: ../bin/indicator-weather.py:594
msgid "Light snow showers"
msgstr ""
-#: ../bin/indicator-weather.py:567
+#: ../bin/indicator-weather.py:595
msgid "Blowing snow"
msgstr ""
-#: ../bin/indicator-weather.py:568
+#: ../bin/indicator-weather.py:596
msgid "Snow"
msgstr ""
-#: ../bin/indicator-weather.py:569
+#: ../bin/indicator-weather.py:597
msgid "Hail"
msgstr ""
-#: ../bin/indicator-weather.py:570
+#: ../bin/indicator-weather.py:598
msgid "Sleet"
msgstr ""
-#: ../bin/indicator-weather.py:571
+#: ../bin/indicator-weather.py:599
msgid "Dust"
msgstr ""
-#: ../bin/indicator-weather.py:572
+#: ../bin/indicator-weather.py:600
msgid "Foggy"
msgstr ""
-#: ../bin/indicator-weather.py:573
+#: ../bin/indicator-weather.py:601
msgid "Haze"
msgstr ""
-#: ../bin/indicator-weather.py:574
+#: ../bin/indicator-weather.py:602
msgid "Smoky"
msgstr ""
-#: ../bin/indicator-weather.py:575
+#: ../bin/indicator-weather.py:603
msgid "Blustery"
msgstr ""
-#: ../bin/indicator-weather.py:576
+#: ../bin/indicator-weather.py:604
msgid "Windy"
msgstr ""
-#: ../bin/indicator-weather.py:577
+#: ../bin/indicator-weather.py:605
msgid "Cold"
msgstr ""
-#: ../bin/indicator-weather.py:578
+#: ../bin/indicator-weather.py:606
msgid "Cloudy"
msgstr ""
-#: ../bin/indicator-weather.py:579 ../bin/indicator-weather.py:580
+#: ../bin/indicator-weather.py:607 ../bin/indicator-weather.py:608
msgid "Mostly cloudy"
msgstr ""
-#: ../bin/indicator-weather.py:581 ../bin/indicator-weather.py:582
-#: ../bin/indicator-weather.py:596
+#: ../bin/indicator-weather.py:609 ../bin/indicator-weather.py:610
+#: ../bin/indicator-weather.py:624
msgid "Partly cloudy"
msgstr ""
-#: ../bin/indicator-weather.py:583
+#: ../bin/indicator-weather.py:611
msgid "Clear"
msgstr ""
-#: ../bin/indicator-weather.py:584
+#: ../bin/indicator-weather.py:612
msgid "Sunny"
msgstr ""
-#: ../bin/indicator-weather.py:585 ../bin/indicator-weather.py:586
+#: ../bin/indicator-weather.py:613 ../bin/indicator-weather.py:614
msgid "Fair"
msgstr ""
-#: ../bin/indicator-weather.py:587
+#: ../bin/indicator-weather.py:615
msgid "Mixed rain and hail"
msgstr ""
-#: ../bin/indicator-weather.py:588
+#: ../bin/indicator-weather.py:616
msgid "Hot"
msgstr ""
-#: ../bin/indicator-weather.py:589
+#: ../bin/indicator-weather.py:617
msgid "Isolated thunderstorms"
msgstr ""
-#: ../bin/indicator-weather.py:590 ../bin/indicator-weather.py:591
+#: ../bin/indicator-weather.py:618 ../bin/indicator-weather.py:619
msgid "Scattered thunderstorms"
msgstr ""
-#: ../bin/indicator-weather.py:592
+#: ../bin/indicator-weather.py:620
msgid "Scattered showers"
msgstr ""
-#: ../bin/indicator-weather.py:593 ../bin/indicator-weather.py:595
+#: ../bin/indicator-weather.py:621 ../bin/indicator-weather.py:623
msgid "Heavy snow"
msgstr ""
-#: ../bin/indicator-weather.py:594
+#: ../bin/indicator-weather.py:622
msgid "Scattered snow showers"
msgstr ""
-#: ../bin/indicator-weather.py:597
+#: ../bin/indicator-weather.py:625
msgid "Thundershowers"
msgstr ""
-#: ../bin/indicator-weather.py:598
+#: ../bin/indicator-weather.py:626
msgid "Snow showers"
msgstr ""
-#: ../bin/indicator-weather.py:599
+#: ../bin/indicator-weather.py:627
msgid "Isolated thundershowers"
msgstr ""
-#: ../bin/indicator-weather.py:600 ../bin/indicator-weather.py:622
-#: ../bin/indicator-weather.py:627 ../bin/indicator-weather.py:645
-#: ../bin/indicator-weather.py:654 ../bin/indicator-weather.py:664
-#: ../bin/indicator-weather.py:748 ../bin/indicator-weather.py:1730
+#: ../bin/indicator-weather.py:628 ../bin/indicator-weather.py:650
+#: ../bin/indicator-weather.py:655 ../bin/indicator-weather.py:673
+#: ../bin/indicator-weather.py:682 ../bin/indicator-weather.py:692
+#: ../bin/indicator-weather.py:776 ../bin/indicator-weather.py:1767
msgid "Unknown condition"
msgstr ""
-#: ../bin/indicator-weather.py:755 ../bin/indicator-weather.py:761
+#: ../bin/indicator-weather.py:783 ../bin/indicator-weather.py:789
msgid "Humidity"
msgstr ""
-#: ../bin/indicator-weather.py:782
+#: ../bin/indicator-weather.py:810
msgid "Pressure"
msgstr ""
-#: ../bin/indicator-weather.py:812
+#: ../bin/indicator-weather.py:840
msgid "Temperature"
msgstr ""
-#: ../bin/indicator-weather.py:836 ../bin/indicator-weather.py:837
-#: ../bin/indicator-weather.py:838
+#: ../bin/indicator-weather.py:864
msgid "Unknown"
msgstr ""
-#: ../bin/indicator-weather.py:845
+#: ../bin/indicator-weather.py:871
msgid "Wind"
msgstr ""
-#: ../bin/indicator-weather.py:872
+#: ../bin/indicator-weather.py:908
msgid "Sunrise"
msgstr ""
-#: ../bin/indicator-weather.py:876
+#: ../bin/indicator-weather.py:912
msgid "Sunset"
msgstr ""
#. Short wind direction - north
-#: ../bin/indicator-weather.py:889
+#: ../bin/indicator-weather.py:925
msgid "N"
msgstr ""
-#: ../bin/indicator-weather.py:891
+#: ../bin/indicator-weather.py:927
msgid "NE"
msgstr ""
-#: ../bin/indicator-weather.py:893
+#: ../bin/indicator-weather.py:929
msgid "E"
msgstr ""
-#: ../bin/indicator-weather.py:895
+#: ../bin/indicator-weather.py:931
msgid "SE"
msgstr ""
-#: ../bin/indicator-weather.py:897
+#: ../bin/indicator-weather.py:933
msgid "S"
msgstr ""
-#: ../bin/indicator-weather.py:899
+#: ../bin/indicator-weather.py:935
msgid "SW"
msgstr ""
-#: ../bin/indicator-weather.py:901
+#: ../bin/indicator-weather.py:937
msgid "W"
msgstr ""
-#: ../bin/indicator-weather.py:903
+#: ../bin/indicator-weather.py:939
msgid "NW"
msgstr ""
-#: ../bin/indicator-weather.py:1074
+#: ../bin/indicator-weather.py:1111
msgid "Set Up Weather..."
msgstr ""
-#: ../bin/indicator-weather.py:1176
+#: ../bin/indicator-weather.py:1213
msgid "Forecast"
msgstr ""
#. #Preferences
-#: ../bin/indicator-weather.py:1182
+#: ../bin/indicator-weather.py:1219
msgid "Preferences..."
msgstr ""
#. #About
-#: ../bin/indicator-weather.py:1188
+#: ../bin/indicator-weather.py:1225
msgid "About..."
msgstr ""
-#: ../bin/indicator-weather.py:1289
+#: ../bin/indicator-weather.py:1323
msgid "Refreshing, please wait"
msgstr ""
-#: ../bin/indicator-weather.py:1291 ../bin/indicator-weather.py:1293
-#: ../bin/indicator-weather.py:1295
+#: ../bin/indicator-weather.py:1325 ../bin/indicator-weather.py:1327
+#: ../bin/indicator-weather.py:1329
msgid "Refresh"
msgstr ""
-#: ../bin/indicator-weather.py:1293
+#: ../bin/indicator-weather.py:1327
msgid "just now"
msgstr ""
-#: ../bin/indicator-weather.py:1295
+#: ../bin/indicator-weather.py:1329
#, python-format
msgid "%d min. ago"
msgstr ""
-#: ../bin/indicator-weather.py:1436
+#: ../bin/indicator-weather.py:1469
msgid "Severe weather alert"
msgstr ""
-#: ../bin/indicator-weather.py:1454 ../indicator-weather.desktop.in.h:2
+#: ../bin/indicator-weather.py:1487 ../indicator-weather.desktop.in.h:1
msgid "Weather Indicator"
msgstr ""
-#: ../bin/indicator-weather.py:1466
+#: ../bin/indicator-weather.py:1499
msgid "translator-credits"
msgstr ""
-#: ../bin/indicator-weather.py:1684
+#: ../bin/indicator-weather.py:1717
msgid "Weather Forecast for "
msgstr ""
-#: ../bin/indicator-weather.py:1739
+#: ../bin/indicator-weather.py:1776
msgid "High"
msgstr ""
-#: ../bin/indicator-weather.py:1741
+#: ../bin/indicator-weather.py:1778
msgid "Low"
msgstr ""
-#: ../bin/indicator-weather.py:1842 ../data/ui/Assistant.ui.h:4
+#: ../bin/indicator-weather.py:1879 ../data/ui/Assistant.ui.h:8
msgid "Label:"
msgstr ""
-#: ../bin/indicator-weather.py:1932
+#: ../bin/indicator-weather.py:1969
msgid "Another instance of this program is already running"
msgstr ""
#: ../data/ui/Assistant.ui.h:1
-msgid "<b>Home</b>"
+msgid "Add a location"
msgstr ""
#: ../data/ui/Assistant.ui.h:2
-msgid "<b>Orange, Texas</b>"
+msgid "Please search our database for your location:"
msgstr ""
#: ../data/ui/Assistant.ui.h:3
-msgid "Add a location"
+msgid "Search"
+msgstr ""
+
+#: ../data/ui/Assistant.ui.h:4
+msgid "Select a location"
msgstr ""
#: ../data/ui/Assistant.ui.h:5
-msgid "Location:"
+msgid "Please enter a name for this location:"
msgstr ""
#: ../data/ui/Assistant.ui.h:6
@@ -441,36 +444,32 @@
msgstr ""
#: ../data/ui/Assistant.ui.h:7
-msgid "Please enter a name for this location:"
-msgstr ""
-
-#: ../data/ui/Assistant.ui.h:8
msgid ""
"Please review the choices below. If anything is not correct, please go back "
"and select the correct options."
msgstr ""
#: ../data/ui/Assistant.ui.h:9
-msgid "Please search our database for your location:"
+msgid "<b>Home</b>"
msgstr ""
#: ../data/ui/Assistant.ui.h:10
-msgid "Review choices"
+msgid "Location:"
msgstr ""
#: ../data/ui/Assistant.ui.h:11
-msgid "Search"
+msgid "<b>Orange, Texas</b>"
msgstr ""
#: ../data/ui/Assistant.ui.h:12
-msgid "Select a location"
+msgid "Review choices"
msgstr ""
#: ../data/ui/ExtendedForecast.ui.h:1
msgid "Extended Forecast"
msgstr ""
-#: ../indicator-weather.desktop.in.h:1
+#: ../indicator-weather.desktop.in.h:2
msgid ""
"A weather indicator that displays information for one or multiple places in "
"the world"
=== modified file 'setup.py'
--- setup.py 2011-12-10 10:11:20 +0000
+++ setup.py 2013-05-18 18:24:25 +0000
@@ -4,6 +4,7 @@
# Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
# Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
# Copyright (C) 2011 Vadim Rutkovsky roignac@xxxxxxxxx
+# Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
@@ -85,10 +86,10 @@
DistUtilsExtra.auto.setup(
name='indicator-weather',
- version='11.05.31',
+ version='13.05.17',
license='GPL-3',
- author='Vadim Rutkovsky | Sebastian MacDonald | Mehdi Rejraji',
- author_email='roignac@xxxxxxxxx',
+ author='Joshua Tasker | Vadim Rutkovsky | Sebastian MacDonald | Mehdi Rejraji',
+ author_email='jtasker@xxxxxxxxx, roignac@xxxxxxxxx',
description="A weather indicator for Ubuntu's Indicator Applet",
long_description='A weather indicator that displays information for one or multiple places in the world',
url='https://launchpad.net/weather-indicator',
Follow ups