[conduit/gsoc09_alexandre: 5/6] Separated RemovableMedia and SynCE factory, fixed some cache issues, improved SynCE.
- From: Alexandre Rosenfeld <arosenfeld src gnome org>
- To: svn-commits-list gnome org
- Subject: [conduit/gsoc09_alexandre: 5/6] Separated RemovableMedia and SynCE factory, fixed some cache issues, improved SynCE.
- Date: Sun, 7 Jun 2009 23:41:53 -0400 (EDT)
commit 1f59cf6c011dd68b603515662fdbff6b6cab1088
Author: Alexandre Rosenfeld <airmind gmail com>
Date: Sun May 31 21:03:19 2009 -0300
Separated RemovableMedia and SynCE factory, fixed some cache issues, improved SynCE.
---
conduit/Module.py | 20 ++--
conduit/ModuleWrapper.py | 4 +-
conduit/modules/FileModule/FileModule.py | 103 --------------
.../modules/FileModule/RemovableDeviceFactory.py | 122 ++++++++++++++++
conduit/modules/SynceFactory.py | 149 ++++++++++++++++++++
conduit/modules/SynceModule.py | 118 +---------------
conduit/modules/iPodModule/iPodFactory.py | 1 +
7 files changed, 286 insertions(+), 231 deletions(-)
diff --git a/conduit/Module.py b/conduit/Module.py
index 075e22b..50b1b7e 100644
--- a/conduit/Module.py
+++ b/conduit/Module.py
@@ -74,7 +74,7 @@ class ModuleManager(gobject.GObject):
for key, value in self.modules_cache.iteritems():
if not isinstance(key, basestring) and not isinstance(value, float):
raise Exception()
- log.critical("Modules cache loaded %s" % self.modules_cache)
+ #log.critical("Modules cache loaded %s" % self.modules_cache)
except:
log.warn("Modules cache invalid")
self.modules_cache = {}
@@ -210,7 +210,7 @@ class ModuleManager(gobject.GObject):
"""
try:
if self._is_factory(filename) or not (filename in self.modules_cache and self.modules_cache[filename]['mtime'] == os.stat(filename).st_mtime):
- log.critical("Importing file %s" % filename)
+ #log.critical("Importing file %s" % filename)
mod = self._import_file(filename)
modules_cache = []
for modules, infos in mod.MODULES.items():
@@ -245,7 +245,7 @@ class ModuleManager(gobject.GObject):
self.filelist[filename]['modules'] = modules_cache
self.filelist[filename]['mtime'] = os.stat(filename).st_mtime
else:
- log.critical("File %s in cache" % filename)
+ #log.critical("File %s in cache" % filename)
self.filelist[filename] = self.modules_cache[filename]
for module in self.modules_cache[filename]['modules']:
module['filename'] = filename
@@ -284,12 +284,14 @@ class ModuleManager(gobject.GObject):
else:
self._load_modules_in_file(f, f_data)
- self.modules_cache = self.filelist
- cache_file = open(self.cache_path, "wb")
- try:
- pickle.dump(self.filelist, cache_file)
- finally:
- cache_file.close()
+ if self.modules_cache != self.filelist:
+ log.critical("Saving cache")
+ self.modules_cache = self.filelist
+ cache_file = open(self.cache_path, "wb")
+ try:
+ pickle.dump(self.filelist, cache_file)
+ finally:
+ cache_file.close()
for i in self.dataproviderFactories:
log.critical("Probing %s" % i)
diff --git a/conduit/ModuleWrapper.py b/conduit/ModuleWrapper.py
index 296f6f1..e3f49a8 100644
--- a/conduit/ModuleWrapper.py
+++ b/conduit/ModuleWrapper.py
@@ -44,7 +44,7 @@ class ModuleWrapper:
#extract class parameters
if cached_info:
- log.critical("Creating module wrapper cached info %s" % cached_info)
+ #log.critical("Creating module wrapper cached info %s" % cached_info)
self.name = cached_info.get("name", "")
self.description = cached_info.get("description", "")
self.icon_name = cached_info.get("icon_name", "")
@@ -54,7 +54,7 @@ class ModuleWrapper:
self.configurable = cached_info.get("configurable", False)
self.classname = cached_info.get("classname", "")
elif klass:
- log.critical("Creating module wrapper for %s" % klass)
+ #log.critical("Creating module wrapper for %s" % klass)
self.name = getattr(klass, "_name_", "")
self.description = getattr(klass, "_description_", "")
self.icon_name = getattr(klass, "_icon_", "")
diff --git a/conduit/modules/FileModule/FileModule.py b/conduit/modules/FileModule/FileModule.py
index d98beae..3b03999 100644
--- a/conduit/modules/FileModule/FileModule.py
+++ b/conduit/modules/FileModule/FileModule.py
@@ -15,7 +15,6 @@ import conduit.Vfs as Vfs
MODULES = {
"FileSource" : { "type": "dataprovider" },
"FolderTwoWay" : { "type": "dataprovider" },
- "RemovableDeviceFactory" : { "type": "dataprovider-factory" }
}
class FileSource(FileDataProvider.FileSource):
@@ -165,105 +164,3 @@ class FolderTwoWay(FileDataProvider.FolderTwoWay, AutoSync.AutoSync):
elif event == self._monitor.MONITOR_EVENT_DELETED:
self.handle_deleted(event_uri)
-class RemovableDeviceFactory(SimpleFactory.SimpleFactory):
-
- def __init__(self, **kwargs):
- SimpleFactory.SimpleFactory.__init__(self, **kwargs)
- self._volumes = {}
- self._categories = {}
- self._vm = Vfs.VolumeMonitor()
- self._vm.connect("volume-mounted",self._volume_mounted_cb)
- self._vm.connect("volume-unmounted",self._volume_unmounted_cb)
-
- def _volume_mounted_cb(self, monitor, device_udi, mount, label):
- log.info("Volume mounted, %s : (%s : %s)" % (device_udi,mount,label))
- if device_udi:
- self._check_preconfigured(device_udi, mount, label)
- self.item_added(device_udi, mount=mount, label=label)
-
- def _volume_unmounted_cb(self, monitor, device_udi):
- log.info("Volume unmounted, %s" % device_udi)
- if device_udi and device_udi in self._volumes:
- self.item_removed(device_udi)
-
- def _make_class(self, udi, folder, name):
- log.info("Creating preconfigured folder dataprovider: %s" % folder)
- info = {
- "DEFAULT_FOLDER": folder,
- "_udi_" : udi
- }
- if name:
- info["_name_"] = name
-
- klass = type(
- "FolderTwoWay",
- (FolderTwoWay,),
- info)
- return klass
-
- def _check_preconfigured(self, udi, mountUri, label):
- #check for the presence of a mount/.conduit group file
- #which describe the folder sync groups, and their names,
- try:
- groups = FileDataProvider.read_removable_volume_group_file(mountUri)
- except Exception, e:
- log.warn("Error reading volume group file: %s" % e)
- groups = ()
-
- if len(groups) > 0:
- self._volumes[udi] = []
- for relativeUri,name in groups:
- klass = self._make_class(
- udi=udi,
- #uri is relative, make it absolute
- folder="%s%s" % (mountUri,relativeUri),
- name=name)
- self._volumes[udi].append(klass)
- else:
- klass = self._make_class(
- udi=udi,
- folder=mountUri,
- name=None)
- self._volumes[udi] = [klass]
-
- def probe(self):
- """
- Called after initialised to detect already connected volumes
- """
- volumes = self._vm.get_mounted_volumes()
- for device_udi in volumes:
- if device_udi:
- mount,label = volumes[device_udi]
- self._check_preconfigured(device_udi, mount, label)
- self.item_added(device_udi, mount=mount, label=label)
- if device_udi:
- mount,label = volumes[device_udi]
- self.item_added(device_udi, mount=mount, label=label)
-
- def emit_added(self, klass, initargs, category):
- """
- Override emit_added to allow duplictes. The custom key is based on
- the folder and the udi to allow multiple preconfigured groups per
- usb key
- """
- return SimpleFactory.SimpleFactory.emit_added(self,
- klass,
- initargs,
- category,
- customKey="%s-%s" % (klass.DEFAULT_FOLDER, klass._udi_)
- )
-
- def get_category(self, udi, **kwargs):
- if not self._categories.has_key(udi):
- self._categories[udi] = DataProviderCategory.DataProviderCategory(
- kwargs['label'],
- "drive-removable-media",
- udi)
- return self._categories[udi]
-
- def get_dataproviders(self, udi, **kwargs):
- return self._volumes.get(udi,())
-
- def get_args(self, udi, **kwargs):
- return ()
-
diff --git a/conduit/modules/FileModule/RemovableDeviceFactory.py b/conduit/modules/FileModule/RemovableDeviceFactory.py
new file mode 100644
index 0000000..c93e05d
--- /dev/null
+++ b/conduit/modules/FileModule/RemovableDeviceFactory.py
@@ -0,0 +1,122 @@
+import os.path
+from gettext import gettext as _
+import logging
+log = logging.getLogger("modules.RemovableDeviceFactory")
+
+import conduit
+import conduit.dataproviders.DataProvider as DataProvider
+import conduit.dataproviders.DataProviderCategory as DataProviderCategory
+import conduit.dataproviders.File as FileDataProvider
+import conduit.dataproviders.SimpleFactory as SimpleFactory
+import conduit.dataproviders.AutoSync as AutoSync
+import conduit.utils as Utils
+import conduit.Vfs as Vfs
+
+MODULES = {
+ "RemovableDeviceFactory" : { "type": "dataprovider-factory" }
+ }
+
+class RemovableDeviceFactory(SimpleFactory.SimpleFactory):
+
+ def __init__(self, **kwargs):
+ SimpleFactory.SimpleFactory.__init__(self, **kwargs)
+ self._volumes = {}
+ self._categories = {}
+ self._vm = Vfs.VolumeMonitor()
+ self._vm.connect("volume-mounted",self._volume_mounted_cb)
+ self._vm.connect("volume-unmounted",self._volume_unmounted_cb)
+
+ def _volume_mounted_cb(self, monitor, device_udi, mount, label):
+ log.info("Volume mounted, %s : (%s : %s)" % (device_udi,mount,label))
+ if device_udi:
+ self._check_preconfigured(device_udi, mount, label)
+ self.item_added(device_udi, mount=mount, label=label)
+
+ def _volume_unmounted_cb(self, monitor, device_udi):
+ log.info("Volume unmounted, %s" % device_udi)
+ if device_udi and device_udi in self._volumes:
+ self.item_removed(device_udi)
+
+ def _make_class(self, udi, folder, name):
+ import conduit.modules.FileModule.FileModule as FileModule
+
+ log.info("Creating preconfigured folder dataprovider: %s" % folder)
+ info = {
+ "DEFAULT_FOLDER": folder,
+ "_udi_" : udi
+ }
+ if name:
+ info["_name_"] = name
+
+ klass = type(
+ "FolderTwoWay",
+ (FileModule.FolderTwoWay,),
+ info)
+ return klass
+
+ def _check_preconfigured(self, udi, mountUri, label):
+ #check for the presence of a mount/.conduit group file
+ #which describe the folder sync groups, and their names,
+ try:
+ groups = FileDataProvider.read_removable_volume_group_file(mountUri)
+ except Exception, e:
+ log.warn("Error reading volume group file: %s" % e)
+ groups = ()
+
+ if len(groups) > 0:
+ self._volumes[udi] = []
+ for relativeUri,name in groups:
+ klass = self._make_class(
+ udi=udi,
+ #uri is relative, make it absolute
+ folder="%s%s" % (mountUri,relativeUri),
+ name=name)
+ self._volumes[udi].append(klass)
+ else:
+ klass = self._make_class(
+ udi=udi,
+ folder=mountUri,
+ name=None)
+ self._volumes[udi] = [klass]
+
+ def probe(self):
+ """
+ Called after initialised to detect already connected volumes
+ """
+ volumes = self._vm.get_mounted_volumes()
+ for device_udi in volumes:
+ if device_udi:
+ mount,label = volumes[device_udi]
+ self._check_preconfigured(device_udi, mount, label)
+ self.item_added(device_udi, mount=mount, label=label)
+ if device_udi:
+ mount,label = volumes[device_udi]
+ self.item_added(device_udi, mount=mount, label=label)
+
+ def emit_added(self, klass, initargs, category):
+ """
+ Override emit_added to allow duplictes. The custom key is based on
+ the folder and the udi to allow multiple preconfigured groups per
+ usb key
+ """
+ return SimpleFactory.SimpleFactory.emit_added(self,
+ klass,
+ initargs,
+ category,
+ customKey="%s-%s" % (klass.DEFAULT_FOLDER, klass._udi_)
+ )
+
+ def get_category(self, udi, **kwargs):
+ if not self._categories.has_key(udi):
+ self._categories[udi] = DataProviderCategory.DataProviderCategory(
+ kwargs['label'],
+ "drive-removable-media",
+ udi)
+ return self._categories[udi]
+
+ def get_dataproviders(self, udi, **kwargs):
+ return self._volumes.get(udi,())
+
+ def get_args(self, udi, **kwargs):
+ return ()
+
diff --git a/conduit/modules/SynceFactory.py b/conduit/modules/SynceFactory.py
new file mode 100644
index 0000000..e5ab3e9
--- /dev/null
+++ b/conduit/modules/SynceFactory.py
@@ -0,0 +1,149 @@
+import conduit
+import conduit.utils as Utils
+import conduit.dataproviders.DataProvider as DataProvider
+import conduit.dataproviders.DataProviderCategory as DataProviderCategory
+import conduit.dataproviders.HalFactory as HalFactory
+import conduit.datatypes.Note as Note
+import conduit.datatypes.Contact as Contact
+import conduit.Exceptions as Exceptions
+
+import xml.dom.minidom
+import vobject
+
+import logging
+log = logging.getLogger("modules.SynCEFactory")
+
+import os.path
+import traceback
+import dbus
+import threading
+import gobject
+import array
+
+from gettext import gettext as _
+
+MODULES = {
+ "SynceFactory" : { "type": "dataprovider-factory" },
+}
+
+class SynceFactory(HalFactory.HalFactory):
+
+ SUPPORTED_PARTNERSHIPS = ("Calendar", "Contacts", "Tasks")
+
+ def __init__(self, **kwargs):
+ HalFactory.HalFactory.__init__(self, **kwargs)
+ self._found = False
+ self._item_types = {}
+ self._partnerships = []
+
+ def _get_item_types_rx(self, item_types):
+ self._item_types = item_types
+
+ def _get_partnerships_rx(self, partnerships):
+ self._partnerships = partnerships
+
+ def _create_partnership_rx(self, guid):
+ print args
+
+ def _create_partnership_error(self, e):
+ log.warn("Failed to create partnership: %s" % e._dbus_error_name)
+
+ def _on_create_partnership_clicked(self, sender, mod):
+ #create partnerships for Contact, Calendar, Tasks
+ ids = [id for id, name in self._item_types.items() if str(name) in self.SUPPORTED_PARTNERSHIPS]
+ self.engine.CreatePartnership(
+ "Conduit", #partnership name
+ ids, #ids of those items to sync
+ reply_handler=self._create_partnership_rx,
+ error_handler=self._create_partnership_error
+ )
+
+ def _found_device(self):
+ self._found = True
+
+ #call async so we dont block at startup
+ #reply_handler will be called with the method's return values as arguments; or
+ #the error_handler
+ self.engine = dbus.Interface(
+ dbus.SessionBus().get_object('org.synce.SyncEngine', '/org/synce/SyncEngine'),
+ 'org.synce.SyncEngine'
+ )
+ self.engine.GetItemTypes(
+ reply_handler=self._get_item_types_rx,
+ error_handler=lambda *args: None
+ )
+ self.engine.GetPartnerships(
+ reply_handler=self._get_partnerships_rx,
+ error_handler=lambda *args: None
+ )
+
+ def probe(self):
+ """
+ Enumerate HAL for any entries of interest
+ """
+ for device in self.hal.FindDeviceStringMatch("sync.plugin", "synce"):
+ self._maybe_new(str(device))
+
+ def is_interesting(self, device, props):
+ if props.has_key("sync.plugin") and props["sync.plugin"]=="synce":
+ self._found_device()
+ return True
+ return False
+
+ def get_category(self, udi, **kwargs):
+ return DataProviderCategory.DataProviderCategory(
+ "Windows Mobile",
+ "windows",
+ udi)
+
+ def get_dataproviders(self, udi, **kwargs):
+ from SynceModule import SynceContactsTwoWay, SynceCalendarTwoWay, SynceTasksTwoWay
+ return [SynceContactsTwoWay, SynceCalendarTwoWay, SynceTasksTwoWay]
+
+ def setup_configuration_widget(self):
+
+ if self._found:
+ import gtk
+ import socket
+
+ vbox = gtk.VBox(False,5)
+ mod = gtk.ListStore(
+ gobject.TYPE_PYOBJECT, #parnership id
+ gobject.TYPE_PYOBJECT, #parnership guid
+ str,str,str) #device name, pc name, items
+ treeview = gtk.TreeView(mod)
+
+ #Three colums: device name, pc name, items
+ index = 2
+ for name in ("Device", "Computer", "Items to Synchronize"):
+ col = gtk.TreeViewColumn(
+ name,
+ gtk.CellRendererText(),
+ text=index)
+ treeview.append_column(col)
+ index = index + 1
+ vbox.pack_start(treeview,True,True)
+
+ btn = gtk.Button(None,gtk.STOCK_ADD)
+ btn.set_label("Create Partnership")
+ btn.connect("clicked", self._on_create_partnership_clicked, mod)
+ vbox.pack_start(btn, False, False)
+
+ #add the existing partnerships
+ for id,guid,name,hostname,devicename,storetype,items in self._partnerships:
+ mod.append((
+ id,
+ guid,
+ str(devicename),
+ str(hostname),
+ ", ".join([str(self._item_types[item]) for item in items]))
+ )
+ #disable partnership if one exists
+ if str(hostname) == socket.gethostname():
+ btn.set_sensitive(False)
+
+ return vbox
+ return None
+
+ def save_configuration(self, ok):
+ pass
diff --git a/conduit/modules/SynceModule.py b/conduit/modules/SynceModule.py
index 3b0e749..873bb10 100644
--- a/conduit/modules/SynceModule.py
+++ b/conduit/modules/SynceModule.py
@@ -41,123 +41,7 @@ CHANGE_ADDED = 1
CHANGE_MODIFIED = 4
CHANGE_DELETED = 3
-MODULES = {
- "SynceFactory" : { "type": "dataprovider-factory" },
-}
-
-class SynceFactory(HalFactory.HalFactory):
-
- SUPPORTED_PARTNERSHIPS = ("Calendar", "Contacts", "Tasks")
-
- def __init__(self, **kwargs):
- HalFactory.HalFactory.__init__(self, **kwargs)
- self._found = False
- self._item_types = {}
- self._partnerships = []
-
- def _get_item_types_rx(self, item_types):
- self._item_types = item_types
-
- def _get_partnerships_rx(self, partnerships):
- self._partnerships = partnerships
-
- def _create_partnership_rx(self, guid):
- print args
-
- def _create_partnership_error(self, e):
- log.warn("Failed to create partnership: %s" % e._dbus_error_name)
-
- def _on_create_partnership_clicked(self, sender, mod):
- #create partnerships for Contact, Calendar, Tasks
- ids = [id for id, name in self._item_types.items() if str(name) in self.SUPPORTED_PARTNERSHIPS]
- self.engine.CreatePartnership(
- "Conduit", #partnership name
- ids, #ids of those items to sync
- reply_handler=self._create_partnership_rx,
- error_handler=self._create_partnership_error
- )
-
- def _found_device(self):
- self._found = True
-
- #call async so we dont block at startup
- #reply_handler will be called with the method's return values as arguments; or
- #the error_handler
- self.engine = dbus.Interface(
- dbus.SessionBus().get_object('org.synce.SyncEngine', '/org/synce/SyncEngine'),
- 'org.synce.SyncEngine'
- )
- self.engine.GetItemTypes(
- reply_handler=self._get_item_types_rx,
- error_handler=lambda *args: None
- )
- self.engine.GetPartnerships(
- reply_handler=self._get_partnerships_rx,
- error_handler=lambda *args: None
- )
-
- def is_interesting(self, device, props):
- if props.has_key("sync.plugin") and props["sync.plugin"]=="synce":
- self._found_device()
- return True
- return False
-
- def get_category(self, udi, **kwargs):
- return DataProviderCategory.DataProviderCategory(
- "Windows Mobile",
- "windows",
- udi)
-
- def get_dataproviders(self, udi, **kwargs):
- return [SynceContactsTwoWay, SynceCalendarTwoWay, SynceTasksTwoWay]
-
- def setup_configuration_widget(self):
-
- if self._found:
- import gtk
- import socket
-
- vbox = gtk.VBox(False,5)
- mod = gtk.ListStore(
- gobject.TYPE_PYOBJECT, #parnership id
- gobject.TYPE_PYOBJECT, #parnership guid
- str,str,str) #device name, pc name, items
- treeview = gtk.TreeView(mod)
-
- #Three colums: device name, pc name, items
- index = 2
- for name in ("Device", "Computer", "Items to Synchronize"):
- col = gtk.TreeViewColumn(
- name,
- gtk.CellRendererText(),
- text=index)
- treeview.append_column(col)
- index = index + 1
- vbox.pack_start(treeview,True,True)
-
- btn = gtk.Button(None,gtk.STOCK_ADD)
- btn.set_label("Create Partnership")
- btn.connect("clicked", self._on_create_partnership_clicked, mod)
- vbox.pack_start(btn, False, False)
-
- #add the existing partnerships
- for id,guid,name,hostname,devicename,storetype,items in self._partnerships:
- mod.append((
- id,
- guid,
- str(devicename),
- str(hostname),
- ", ".join([str(self._item_types[item]) for item in items]))
- )
- #disable partnership if one exists
- if str(hostname) == socket.gethostname():
- btn.set_sensitive(False)
-
- return vbox
- return None
-
- def save_configuration(self, ok):
- pass
+MODULES = {}
class SyncEngineWrapper(object):
"""
diff --git a/conduit/modules/iPodModule/iPodFactory.py b/conduit/modules/iPodModule/iPodFactory.py
index cf71ff0..abf58ee 100644
--- a/conduit/modules/iPodModule/iPodFactory.py
+++ b/conduit/modules/iPodModule/iPodFactory.py
@@ -58,6 +58,7 @@ class iPodFactory(VolumeFactory.VolumeFactory):
def get_dataproviders(self, udi, **kwargs):
import iPodModule
+ from iPodModule import IPodMusicTwoWay, IPodVideoTwoWay, IPodNoteTwoWay, IPodContactsTwoWay, IPodCalendarTwoWay, IPodPhotoSink
if not iPodModule.availiable:
return None
#Read information about the ipod, like if it supports
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]