60
62
# Open the DB and prepare views
61
63
#TODO: Create view when package is installed?
62
64
def prepare_settings_store(self):
64
log.debug("Settings: preparing settings store")
65
self.db = CouchDatabase("weatherindicator", create = True)
68
self.settings_design_doc = "settings"
69
self.settings_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.name, doc);}}" % self.settings_design_doc
70
self.db.add_view("get_setting", self.settings_view, None, self.settings_design_doc)
73
self.weather_design_doc = "weather"
74
self.weather_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.location, doc)} ;}" % self.weather_design_doc
75
self.db.add_view("get_weather", self.weather_view, None, self.weather_design_doc)
78
self.location_design_doc = "location"
79
self.location_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.location, doc)} ;}" % self.location_design_doc
80
self.db.add_view("get_location", self.location_view, None, self.location_design_doc)
82
except dbus.exceptions.DBusException as e:
83
log.debug("Settings: DBus exception occurred, retrying")
84
self.db = CouchDatabase("weatherindicator", create = True)
65
log.debug("Settings: preparing settings store")
68
self.db = CouchDatabase("weatherindicator", create = True)
70
except dbus.exceptions.DBusException as e:
71
log.debug("Settings: DBus exception occurred, retrying")
75
self.settings_design_doc = "settings"
76
self.settings_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.name, doc);}}" % self.settings_design_doc
77
self.db.add_view("get_setting", self.settings_view, None, self.settings_design_doc)
80
self.weather_design_doc = "weather"
81
self.weather_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.location, doc)} ;}" % self.weather_design_doc
82
self.db.add_view("get_weather", self.weather_view, None, self.weather_design_doc)
85
self.location_design_doc = "location"
86
self.location_view = "function(doc) {if (doc.record_type == '%s') {emit(doc.location, doc)} ;}" % self.location_design_doc
87
self.db.add_view("get_location", self.location_view, None, self.location_design_doc)
86
89
# Get a value of the setting
87
90
def get_value(self, setting, return_id = False):
406
431
"haze" : ( "weather-fog", "weather-fog", False),
407
432
"chance_of_storm" : ( "weather-storm", "weather-storm", True),
408
433
"storm" : ( "weather-storm", "weather-storm", True),
409
"thunderstorm" : ( "weather-stoom", "weather-storm", True),
434
"thunderstorm" : ( "weather-storm", "weather-storm", True),
410
435
"chance_of_tstorm" : ( "weather-storm", "weather-storm", True),
419
444
'3' : ("weather-storm", "weather-storm", True, _("Severe thunderstorms")),
420
445
'4' : ("weather-storm", "weather-storm", True, _("Thunderstorms")),
421
446
'5' : ("weather-snow", "weather-snow", False, _("Mixed rain and snow")),
422
# Use Americal meaning of sleet - see http://en.wikipedia.org/wiki/Sleet
447
# Use American meaning of sleet - see http://en.wikipedia.org/wiki/Sleet
423
448
'6' : ("weather-showers", "weather-showers", False, _("Mixed rain and sleet")),
424
449
'7' : ("weather-snow", "weather-snow", False, _("Mixed snow and sleet")),
425
450
'8' : ("weather-showers", "weather-showers", False, _("Freezing drizzle")),
593
622
return "%s: %s %s" % (_("Pressure"), value, units)
595
624
# Get temperature with units value - doesn't include 'Temperature' label
596
def get_temperature(self):
625
def get_temperature(self, needs_rounding = False):
597
626
if self.__weather_datasource == WeatherDataSource.GOOGLE:
598
627
if (self.__metric_system == MetricSystem.SI):
599
628
_value = self.__report['current_conditions']['temp_c']
602
631
_value = self.__report['current_conditions']['temp_f']
604
633
if self.__weather_datasource == WeatherDataSource.YAHOO:
605
634
if (self.__metric_system == MetricSystem.SI):
606
635
_value = "%.1f" % ((float(self.__report['condition']['temp']) - 32) * 5/9)
609
638
_value = self.__report['condition']['temp']
640
# round the value if required
642
_value = round(float(_value))
611
643
# Removing unnecessary '.0' in the end, if exists
612
644
return ("%s %s" % (_value, _unit)).replace(".0", "")
1008
1045
self.settings.set_value("placechosen", self.placechosen)
1009
1046
self.update_weather(False)
1048
def on_system_sleep(self):
1050
Callback from UPower that system suspends/hibernates
1053
self.sleep_time = datetime.datetime.now()
1054
log.debug("Indicator: system goes to sleep at %s" % self.sleep_time)
1055
# remove gobject timeouts
1056
if hasattr(self, "refresh_id"):
1057
gobject.source_remove(self.refresh_id)
1058
if hasattr(self, "rate_id"):
1059
gobject.source_remove(self.rate_id)
1061
def on_system_resume(self):
1063
Callback from UPower that system resumes
1065
now = datetime.datetime.now()
1066
log.debug("Indicator: system resumes at %s" % now)
1067
# update refresh label
1068
td = now - self.sleep_time
1069
mins_elapsed = td.days/24*60 + td.seconds/60 + self.refreshed_minutes_ago
1070
self.update_refresh_label(mins_elapsed)
1071
# check if we need to update the weather now or to reschedule the update
1072
if mins_elapsed > int(self.rate):
1073
self.update_weather()
1075
self.schedule_weather_update(int(self.rate) - mins_elapsed)
1077
# Schedule weather update
1078
def schedule_weather_update(self, rate_override = None):
1079
if hasattr(self, "rate_id"):
1080
gobject.source_remove(self.rate_id)
1082
log.debug("Indicator: scheduling update in %s mins" % rate_override)
1083
self.rate_id = gobject.timeout_add(
1084
int(rate_override) * 60000, self.update_weather)
1086
log.debug("Indicator: scheduling update in %s mins" % self.rate)
1087
self.rate_id = gobject.timeout_add(
1088
int(self.rate) * 60000, self.update_weather)
1090
# Schedule weather update
1091
def schedule_refresh_label_update(self):
1092
if hasattr(self, "refresh_id"):
1093
gobject.source_remove(self.refresh_id)
1094
log.debug("Indicator: scheduling refresh label update in 1 min")
1095
self.refresh_id = gobject.timeout_add(60000, self.update_refresh_label)
1011
1097
# Update 'Refresh' label with time since last successful data refresh
1012
def update_refresh_label(self):
1013
self.refreshed_minutes_ago += 1
1014
log.debug("Indicator: updating refresh label, %s min. ago" % self.refreshed_minutes_ago)
1015
refresh_label = "%s (%s)" % (_("Refresh"), _("%d min. ago") % self.refreshed_minutes_ago)
1098
def update_refresh_label(self, reset_minutes = None):
1099
if reset_minutes is not None:
1100
self.refreshed_minutes_ago = reset_minutes
1102
self.refreshed_minutes_ago += 1
1103
self.set_refresh_label()
1104
self.schedule_refresh_label_update()
1107
def set_refresh_label(self, refreshing=False):
1109
refresh_label=_("Refreshing, please wait")
1110
elif self.refreshed_minutes_ago == 0:
1111
refresh_label="%s (%s)" % (_("Refresh"), _("just now"))
1113
log.debug("Indicator: updating refresh label, %d min. ago" % self.refreshed_minutes_ago)
1114
refresh_label = "%s (%s)" % (_("Refresh"), _("%d min. ago") % self.refreshed_minutes_ago)
1016
1115
self.refresh_show.set_label(refresh_label)
1017
self.refresh_id = gobject.timeout_add(60000, self.update_refresh_label)
1019
1117
# Load weather data from cache and display its values
1020
1118
def show_cached_weather(self):
1052
1150
# No data returned - leave cached data to be displayed
1053
1151
log.error("Indicator: updateWeather: could not get weather, leaving cached data")
1054
1152
# Repeat an attempt in one minute
1055
log.debug("Indicator: updateWeather: setting rate to one minute")
1056
self.rateid = gobject.timeout_add(60000, self.update_weather)
1153
self.schedule_weather_update(1)
1059
# Set a 'Refresh' label update interval to 1 min
1060
if hasattr(self, 'refresh_id'):
1061
gobject.source_remove(self.refresh_id)
1062
self.refreshed_minutes_ago = 0
1063
self.refresh_id = gobject.timeout_add(60000, self.update_refresh_label)
1065
1156
# Fill in menu with data
1066
1157
log.debug("Indicator: updateWeather: got condition '%s', icon '%s'" % (self.condition, self.icon))
1067
1158
self.condition = weather.get_condition_label()
1176
1266
# Quit the applet
1177
1267
def quit(self, widget, data=None):
1178
# Compact the settings DB
1179
self.settings.db.db.compact()
1180
log.debug("Indicator: Quitting")
1268
log.debug("Indicator: Quitting")
1270
# Compact the settings DB
1271
#self.settings.db.db.compact()
1273
# There is a bug in python client v0.6, db.compact raises error
1274
# http://code.google.com/p/couchdb-python/issues/detail?id=141
1276
# It seems that the client should always set the
1277
# 'Content-Type': 'application/json' header
1278
# So we bypass that compact command and execute a post directly
1279
# until the python client gets fixed
1281
'Content-Type': 'application/json'
1283
self.settings.db.db.resource.post('_compact', headers=headers)
1284
except Exception, e:
1181
1286
gtk.main_quit()
1183
1288
class PreferencesDialog(gtk.Dialog):
1378
1481
log.debug("ExtendedForecast: getting forecast data")
1379
1482
forecast = Forecast(wi.metric_system, wi.current_location.location_details['latitude'], wi.current_location.location_details['longitude'], locale_name)
1380
1483
forecast.prepare_forecast_data()
1381
daysofweek = forecast.get_forecast_daysofweek()
1382
forecast_data = forecast.get_forecast_data()
1383
if forecast_data == None:
1384
# Forecast data unavailable - hide elements and show 'connection_error' label
1385
self.builder.get_object('connection_error').set_visible(True);
1386
self.builder.get_object('hbox1').set_visible(False);
1387
self.builder.get_object('hseparator1').set_visible(False);
1389
(highdata, lowdata) = forecast_data
1390
icons = forecast.get_forecast_icons()
1391
conditions = forecast.get_forecast_conditions()
1393
log.debug("ExtendedForecast: parsing forecast data")
1394
# Create labels for each weekday
1395
self.builder.get_object('day1lbl').set_label('<big>%s</big>' % daysofweek[0].capitalize())
1396
self.builder.get_object('day2lbl').set_label('<big>%s</big>' % daysofweek[1].capitalize())
1397
self.builder.get_object('day3lbl').set_label('<big>%s</big>' % daysofweek[2].capitalize())
1398
self.builder.get_object('day4lbl').set_label('<big>%s</big>' % daysofweek[3].capitalize())
1401
for i in xrange(1,5):
1402
# Get icon name from dictionary in Weather object for Google icons
1403
google_icon = Weather._GoogleConditions[icons[i-1]][0]
1404
self.builder.get_object('day%simage' % str(i)).set_from_icon_name(google_icon,gtk.ICON_SIZE_BUTTON)
1406
# Fill in condition labels
1407
for i in xrange(1,5):
1408
self.builder.get_object('day%scond' % str(i)).set_label(conditions[i-1])
1410
# Fill in High and Low temperatures
1411
if wi.metric_system == MetricSystem.SI:
1484
if forecast.error_message != None:
1485
#Error occurred while getting forecast data
1486
self.builder.get_object('connection_error').set_text("%s" % forecast.error_message)
1487
self.builder.get_object('connection_error').set_visible(True)
1488
self.builder.get_object('hbox1').set_visible(False)
1415
for i in xrange(1,5):
1416
label = "%s: %s%s" % (_('High'), highdata[i-1],tempunit)
1417
self.builder.get_object('day%stemphigh' % str(i)).set_label(label)
1418
label = "%s: %s%s" % (_('Low'), lowdata[i-1],tempunit)
1419
self.builder.get_object('day%stemplow' % str(i)).set_label(label)
1490
daysofweek = forecast.get_forecast_daysofweek()
1491
forecast_data = forecast.get_forecast_data()
1492
if forecast_data == None:
1493
# Forecast data unavailable - hide elements and show 'connection_error' label
1494
self.builder.get_object('connection_error').set_visible(True);
1495
self.builder.get_object('hbox1').set_visible(False);
1496
self.builder.get_object('hseparator1').set_visible(False);
1498
(highdata, lowdata) = forecast_data
1499
icons = forecast.get_forecast_icons()
1500
conditions = forecast.get_forecast_conditions()
1502
log.debug("ExtendedForecast: parsing forecast data")
1503
# Create labels for each weekday
1504
self.builder.get_object('day1lbl').set_label('<big>%s</big>' % daysofweek[0].capitalize())
1505
self.builder.get_object('day2lbl').set_label('<big>%s</big>' % daysofweek[1].capitalize())
1506
self.builder.get_object('day3lbl').set_label('<big>%s</big>' % daysofweek[2].capitalize())
1507
self.builder.get_object('day4lbl').set_label('<big>%s</big>' % daysofweek[3].capitalize())
1510
for i in xrange(1,5):
1511
# Get icon name from dictionary in Weather object for Google icons
1512
conds = Weather._GoogleConditions.get(icons[i-1])
1514
google_icon = conds[0]
1516
log.error("ExtendedForecast: unknown Google weather condition '%s'" % icons[i-1])
1517
log.error(forecast.forecast)
1518
google_icon = 'weather-unknown-condition'
1519
self.builder.get_object('day%simage' % str(i)).set_from_icon_name(google_icon,gtk.ICON_SIZE_BUTTON)
1521
# Fill in condition labels
1522
for i in xrange(1,5):
1523
self.builder.get_object('day%scond' % str(i)).set_label(conditions[i-1])
1525
# Fill in High and Low temperatures
1526
if wi.metric_system == MetricSystem.SI:
1530
for i in xrange(1,5):
1531
label = "%s: %s%s" % (_('High'), highdata[i-1],tempunit)
1532
self.builder.get_object('day%stemphigh' % str(i)).set_label(label)
1533
label = "%s: %s%s" % (_('Low'), lowdata[i-1],tempunit)
1534
self.builder.get_object('day%stemplow' % str(i)).set_label(label)
1421
1536
# Closing forecast window
1422
1537
def close(self, widget, data=None):