[gnome-clocks] Port to GSettings
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-clocks] Port to GSettings
- Date: Fri, 1 Feb 2013 21:16:53 +0000 (UTC)
commit 6dba72ecaac2254d7bc214825094bffc75a71ba4
Author: Paolo Borelli <pborelli gnome org>
Date: Fri Feb 1 22:14:44 2013 +0100
Port to GSettings
This removes the dependency on json parsing and uses a data store more
natural in the gnome world.
Besides, GWeatherLocations are serialized as GVariants, so it becomes
natural to store them in GSettings.
https://bugzilla.gnome.org/show_bug.cgi?id=689487
Makefile.am | 5 ++
configure.ac | 2 +
data/org.gnome.clocks.gschema.xml.in | 18 ++++++++
gnomeclocks/alarm.py | 78 +++++++++++---------------------
gnomeclocks/world.py | 80 ++++++++++++++--------------------
5 files changed, 85 insertions(+), 98 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 4b88c4d..40beb4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,6 +10,11 @@ applicationsdir = $(datadir)/applications
applications_DATA = data/gnome-clocks.desktop
dist_noinst_DATA = data/gnome-clocks.desktop.in
+# gsettings
+gsettings_SCHEMAS = data/org.gnome.clocks.gschema.xml
+ INTLTOOL_XML_NOMERGE_RULE@
+ GSETTINGS_RULES@
+
# icons
icon16dir = $(datadir)/icons/hicolor/16x16/apps
icon16_DATA = data/icons/hicolor/16x16/apps/gnome-clocks.png
diff --git a/configure.ac b/configure.ac
index 7f97ab4..4af5fa1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,8 @@ GETTEXT_PACKAGE=AC_PACKAGE_NAME
AC_SUBST([GETTEXT_PACKAGE])
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext domain])
+GLIB_GSETTINGS
+
PKG_PROG_PKG_CONFIG([0.22])
PKG_CHECK_MODULES(CLOCKS, [
diff --git a/data/org.gnome.clocks.gschema.xml.in b/data/org.gnome.clocks.gschema.xml.in
new file mode 100644
index 0000000..ec38d29
--- /dev/null
+++ b/data/org.gnome.clocks.gschema.xml.in
@@ -0,0 +1,18 @@
+<schemalist>
+ <schema id="org.gnome.clocks" path="/org/gnome/clocks/" gettext-domain="@GETTEXT_PACKAGE@">
+ <key name="world-clocks" type="aa{sv}">
+ <default>[]</default>
+ <_summary>Configured world clocks</_summary>
+ <_description>
+ List of world clocks to show.
+ </_description>
+ </key>
+ <key name="alarms" type="aa{sv}">
+ <default>[]</default>
+ <_summary>Configured alarms</_summary>
+ <_description>
+ List of alarms set.
+ </_description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/gnomeclocks/alarm.py b/gnomeclocks/alarm.py
index 6211929..27e292a 100644
--- a/gnomeclocks/alarm.py
+++ b/gnomeclocks/alarm.py
@@ -20,7 +20,7 @@ import os
import errno
import json
from datetime import timedelta
-from gi.repository import GLib, GObject, Gtk
+from gi.repository import GLib, Gio, GObject, Gtk
from .clocks import Clock
from .utils import Alert, Dirs, LocalizedWeekdays, SystemSettings, TimeString, WallClock
from .widgets import Toolbar, ToolButton, SymbolicToolButton, SelectableIconView, ContentView
@@ -29,46 +29,6 @@ from .widgets import Toolbar, ToolButton, SymbolicToolButton, SelectableIconView
wallclock = WallClock.get_default()
-class AlarmsStorage:
- def __init__(self):
- self.filename = os.path.join(Dirs.get_user_data_dir(), "alarms.json")
-
- def save(self, alarms):
- alarm_list = []
- for a in alarms:
- d = {
- "name": a.name,
- "hour": a.hour,
- "minute": a.minute,
- "days": a.days,
- "active": a.active
- }
- alarm_list.append(d)
- with open(self.filename, 'w', encoding='utf-8') as f:
- json.dump(alarm_list, f, ensure_ascii=False)
-
- def load(self):
- alarms = []
- try:
- with open(self.filename, encoding='utf-8') as f:
- alarm_list = json.load(f)
- for a in alarm_list:
- try:
- n, h, m, d = (a['name'], int(a['hour']), int(a['minute']), a['days'])
- # support the old format that didn't have the active key
- active = a['active'] if 'active' in a else True
- except:
- # skip alarms which do not have the required fields
- continue
- alarm = AlarmItem(n, h, m, d, active)
- alarms.append(alarm)
- except IOError as e:
- if e.errno == errno.ENOENT:
- # File does not exist yet, that's ok
- pass
- return alarms
-
-
class AlarmItem:
EVERY_DAY = [0, 1, 2, 3, 4, 5, 6]
# TODO: For now the alarm never rings that long
@@ -187,6 +147,15 @@ class AlarmItem:
self.stop()
return self.state != last_state
+ def serialize(self):
+ return {
+ "name": GLib.Variant('s', self.name),
+ "hour": GLib.Variant('i', self.hour),
+ "minute": GLib.Variant('i', self.minute),
+ "days": GLib.Variant('ai', self.days),
+ "active": GLib.Variant('b', self.active)
+ }
+
class AlarmDialog(Gtk.Dialog):
def __init__(self, parent, alarm=None):
@@ -454,6 +423,8 @@ class Alarm(Clock):
def __init__(self, toolbar, embed):
Clock.__init__(self, _("Alarm"), toolbar, embed)
+ self.settings = Gio.Settings(schema='org.gnome.clocks')
+
# Translators: "New" refers to an alarm
self.new_button = ToolButton(_("New"))
self.new_button.connect('clicked', self._on_new_clicked)
@@ -488,11 +459,22 @@ class Alarm(Clock):
self.insert_page(self.standalone, Alarm.Page.STANDALONE)
self.set_current_page(Alarm.Page.OVERVIEW)
- self.storage = AlarmsStorage()
- self.load_alarms()
+ self._load()
wallclock.connect("time-changed", self._tick_alarms)
+ def _save(self):
+ v = GLib.Variant('aa{sv}', [a.serialize() for a in self.alarms])
+ self.settings.set_value('alarms', v)
+
+ def _load(self):
+ self.alarms = []
+ for a in self.settings.get_value('alarms'):
+ self.alarms.append(AlarmItem(**a))
+ for a in self.alarms:
+ self._add_alarm_item(a)
+ self.select_button.set_sensitive(self.alarms)
+
def _on_new_clicked(self, button):
self.activate_new()
@@ -556,16 +538,10 @@ class Alarm(Clock):
else:
self._embed.hide_floatingbar()
- def load_alarms(self):
- self.alarms = self.storage.load()
- for alarm in self.alarms:
- self._add_alarm_item(alarm)
- self.select_button.set_sensitive(self.alarms)
-
def save_alarms(self):
- self.storage.save(self.alarms)
+ self._save()
self.liststore.clear()
- self.load_alarms()
+ self._load()
def add_alarm(self, alarm):
if alarm in self.alarms:
diff --git a/gnomeclocks/world.py b/gnomeclocks/world.py
index 6cb9fc4..9a2ac5c 100644
--- a/gnomeclocks/world.py
+++ b/gnomeclocks/world.py
@@ -33,42 +33,6 @@ gweather_world = GWeather.Location.new_world(True)
wallclock = WallClock.get_default()
-class WorldClockStorage:
- def __init__(self):
- self.filename = os.path.join(Dirs.get_user_data_dir(), "clocks.json")
-
- def save(self, clocks):
- locations = [str(c.location.serialize()) for c in clocks]
- with open(self.filename, 'w', encoding='utf-8') as f:
- json.dump(locations, f, ensure_ascii=False)
-
- def load(self):
- clocks = []
- try:
- with open(self.filename, encoding='utf-8') as f:
- locations = json.load(f)
- for l in locations:
- try:
- variant = GLib.Variant.parse(None, l, None, None)
- location = GWeather.Location.deserialize(gweather_world, variant)
- except:
- location = None
- if not location:
- # This is for backward compatibility importing the old clocks which
- # just saved the metar location code... for now we may end up here
- # both if deserialize fails of if variant parse throws an exception
- location = GWeather.Location.find_by_station_code(gweather_world, l)
- if location:
- clock = ClockItem(location)
- clocks.append(clock)
- except IOError as e:
- if e.errno == errno.ENOENT:
- # File does not exist yet, that's ok
- pass
-
- return clocks
-
-
class NewWorldClockDialog(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, _("Add a New World Clock"), parent)
@@ -211,6 +175,9 @@ class ClockItem:
self.day_string = self._get_day_string()
self._update_sunrise_sunset()
+ def serialize(self):
+ return {"location": self.location.serialize()}
+
class WorldStandalone(Gtk.EventBox):
def __init__(self):
@@ -297,6 +264,8 @@ class World(Clock):
def __init__(self, toolbar, embed):
Clock.__init__(self, _("World"), toolbar, embed)
+ self.settings = Gio.Settings(schema='org.gnome.clocks')
+
# Translators: "New" refers to a world clock
self.new_button = ToolButton(_("New"))
self.new_button.connect('clicked', self._on_new_clicked)
@@ -333,11 +302,34 @@ class World(Clock):
self.insert_page(self.standalone, World.Page.STANDALONE)
self.set_current_page(World.Page.OVERVIEW)
- self.storage = WorldClockStorage()
- self.load_clocks()
+ self._load()
wallclock.connect("time-changed", self._tick_clocks)
+ def _save(self):
+ v = GLib.Variant('aa{sv}', [c.serialize() for c in self.clocks])
+ self.settings.set_value('world-clocks', v)
+
+ def _load(self):
+ self.clocks = []
+ # NOTE: we have to manually parse the variant because pygobject
+ # automatically unpacks all the variant to native python objects
+ # while we need to extract the variant object to pass to gweather
+ locations = self.settings.get_value('world-clocks')
+ for i in range(locations.n_children()):
+ l = {}
+ location_variant = locations.get_child_value(i)
+ for j in range(location_variant.n_children()):
+ v = location_variant.get_child_value(j)
+ l[v.get_child_value(0).get_string()] = v.get_child_value(1).get_child_value(0)
+ location = GWeather.Location.deserialize(gweather_world, l["location"])
+ if location:
+ self.clocks.append(ClockItem(location))
+
+ for clock in self.clocks:
+ self._add_clock_item(clock)
+ self.select_button.set_sensitive(self.clocks)
+
def _on_new_clicked(self, button):
self.activate_new()
@@ -391,19 +383,13 @@ class World(Clock):
else:
self._embed.hide_floatingbar()
- def load_clocks(self):
- self.clocks = self.storage.load()
- for clock in self.clocks:
- self._add_clock_item(clock)
- self.select_button.set_sensitive(self.clocks)
-
def add_clock(self, location):
if any(c.location.equal(location) for c in self.clocks):
# duplicate
return
clock = ClockItem(location)
self.clocks.append(clock)
- self.storage.save(self.clocks)
+ self._save()
self._add_clock_item(clock)
self.select_button.set_sensitive(True)
self.show_all()
@@ -414,9 +400,9 @@ class World(Clock):
def delete_clocks(self, clocks):
self.clocks = [c for c in self.clocks if c not in clocks]
- self.storage.save(self.clocks)
+ self._save()
self.liststore.clear()
- self.load_clocks()
+ self._load()
def update_toolbar(self):
self._toolbar.clear()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]