[conduit/gsoc09_alexandre: 5/6] Separated RemovableMedia and SynCE factory, fixed some cache issues, improved SynCE.



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]