conduit r1769 - in trunk: . conduit/dataproviders conduit/modules/FileModule conduit/platform
- From: jstowers svn gnome org
- To: svn-commits-list gnome org
- Subject: conduit r1769 - in trunk: . conduit/dataproviders conduit/modules/FileModule conduit/platform
- Date: Mon, 20 Oct 2008 19:57:46 +0000 (UTC)
Author: jstowers
Date: Mon Oct 20 19:57:45 2008
New Revision: 1769
URL: http://svn.gnome.org/viewvc/conduit?rev=1769&view=rev
Log:
2008-10-20 John Stowers <john stowers gmail com>
* conduit/platform/FileGio.py:
* conduit/platform/FileGnomeVfs.py:
* conduit/platform/__init__.py: Change the base class interface as necessary
to add a GIO VolumeMonitor implementation
* conduit/dataproviders/VolumeFactory.py: Derive directly from HalFactory
and no longer use the Vfs.VolumeMonitor implementations to monitor volumes,
it was not in the spirit of what other derived classes were using VF for
* conduit/dataproviders/HalFactory.py: Doc updates.
* conduit/modules/FileModule/FileModule.py: Use the VolumeMonitor class
directly, and no longer through VolumeFactory.
Fixes #557105
Modified:
trunk/ChangeLog
trunk/conduit/dataproviders/HalFactory.py
trunk/conduit/dataproviders/VolumeFactory.py
trunk/conduit/modules/FileModule/FileModule.py
trunk/conduit/platform/FileGio.py
trunk/conduit/platform/FileGnomeVfs.py
trunk/conduit/platform/__init__.py
Modified: trunk/conduit/dataproviders/HalFactory.py
==============================================================================
--- trunk/conduit/dataproviders/HalFactory.py (original)
+++ trunk/conduit/dataproviders/HalFactory.py Mon Oct 20 19:57:45 2008
@@ -34,14 +34,16 @@
self.item_removed(device_udi)
def _get_properties(self, device):
+ buf = {}
try:
device_dbus_obj = self.bus.get_object("org.freedesktop.Hal" ,device)
- buffer = {}
for x, y in device_dbus_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device").items():
- buffer[str(x)] = str(y)
- return buffer
+ #DBus *still* does not marshal dbus.String to str correctly,
+ #so we force it to
+ buf[str(x)] = str(y)
except:
- return {}
+ log.warn("Could not get HAL properties for %s" % device_udi)
+ return buf
def probe(self):
""" Enumerate HAL for any entries of interest """
Modified: trunk/conduit/dataproviders/VolumeFactory.py
==============================================================================
--- trunk/conduit/dataproviders/VolumeFactory.py (original)
+++ trunk/conduit/dataproviders/VolumeFactory.py Mon Oct 20 19:57:45 2008
@@ -1,81 +1,31 @@
import logging
-log = logging.getLogger("dataproviders.SimpleFactory")
+log = logging.getLogger("dataproviders.VolumeFactory")
import conduit
-import conduit.dataproviders.SimpleFactory as SimpleFactory
-import conduit.utils as Utils
-import conduit.Vfs as Vfs
+import conduit.dataproviders.HalFactory as HalFactory
-import dbus
-
-class VolumeFactory(SimpleFactory.SimpleFactory):
+class VolumeFactory(HalFactory.HalFactory):
"""
- Generic factory for dataproviders that are removable file system based
+ Generic factory for dataproviders that are removable file system based, or
+ more technically, that have the volume capability defined in HAL. This
+ usually results in them being mounted as removable volumes.
"""
- def __init__(self, **kwargs):
- SimpleFactory.SimpleFactory.__init__(self, **kwargs)
-
- self.vol_monitor = Vfs.VolumeMonitor()
- self.bus = dbus.SystemBus()
-
- if Utils.dbus_service_available('org.freedesktop.Hal', self.bus):
- log.info("HAL Initialized")
- self.vol_monitor.connect("volume-mounted",self._volume_mounted_cb)
- self.vol_monitor.connect("volume-unmounted",self._volume_unmounted_cb)
- else:
- log.warn("HAL Could not be Initialized")
-
- def _volume_mounted_cb(self, monitor, device_udi):
- log.info("Volume mounted, udi: %s" % device_udi)
- if device_udi :
- props = self._get_properties(device_udi)
- if self.is_interesting(device_udi, props):
- mount, label = self._get_device_info(props)
- kwargs = { "mount": mount, "label": label }
- self.item_added(device_udi, **kwargs)
- return True
-
- def _volume_unmounted_cb(self, monitor, device_udi):
- log.info("Volume unmounted, udi: %s" % device_udi)
- if device_udi :
- if self.is_interesting(device_udi, self._get_properties(device_udi)):
- self.item_removed(device_udi)
- return False
-
- def _get_properties(self, device_udi):
- try:
- device_dbus_obj = self.bus.get_object("org.freedesktop.Hal" ,device_udi)
- return device_dbus_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
- except:
- return {}
-
- def _get_device_info(self, properties):
- """
- Returns the mount point and label in a 2-tuple
- """
- if properties.has_key("volume.mount_point"):
- mount = str(properties["volume.mount_point"])
- else:
- mount = ""
- if properties.has_key("volume.label"):
- label = str(properties["volume.label"])
- else:
- label = ""
-
- return (mount, label)
-
def probe(self):
"""
Called after VolumeFactory is initialised to detect already connected volumes
"""
- for device_udi in self.vol_monitor.get_mounted_volumes():
- if device_udi != None:
- props = self._get_properties(device_udi)
- if self.is_interesting(device_udi, props):
- mount, label = self._get_device_info(props)
- kwargs = { "mount": mount, "label": label }
- self.item_added(device_udi, **kwargs)
+ for device_udi in self.hal.FindDeviceByCapability("volume"):
+ props = self._get_properties(device_udi)
+
+ #convert the mountpoint to a string uri because that is what
+ #all the folder dataproviders work on
+ if props.get("volume.mount_point"):
+ props["mount"] = "file://" + str(props["volume.mount_point"])
+ log.debug("Adjusted mount: %s", props["mount"])
+
+ if self.is_interesting(device_udi, props):
+ self.item_added(device_udi, **kwargs)
def get_args(self, udi, **kwargs):
""" VolumeFactory passes mount point and udi to dataproviders """
Modified: trunk/conduit/modules/FileModule/FileModule.py
==============================================================================
--- trunk/conduit/modules/FileModule/FileModule.py (original)
+++ trunk/conduit/modules/FileModule/FileModule.py Mon Oct 20 19:57:45 2008
@@ -7,7 +7,7 @@
import conduit.dataproviders.DataProvider as DataProvider
import conduit.dataproviders.DataProviderCategory as DataProviderCategory
import conduit.dataproviders.File as FileDataProvider
-import conduit.dataproviders.VolumeFactory as VolumeFactory
+import conduit.dataproviders.SimpleFactory as SimpleFactory
import conduit.dataproviders.AutoSync as AutoSync
import conduit.utils as Utils
import conduit.Vfs as Vfs
@@ -133,12 +133,26 @@
elif event == self._monitor.MONITOR_EVENT_DELETED:
self.handle_deleted(event_uri)
-class RemovableDeviceFactory(VolumeFactory.VolumeFactory):
+class RemovableDeviceFactory(SimpleFactory.SimpleFactory):
def __init__(self, **kwargs):
- VolumeFactory.VolumeFactory.__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)
@@ -152,67 +166,61 @@
klass = type(
"FolderTwoWay",
(FolderTwoWay,),
- info
- )
+ 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 VolumeFactory.VolumeFactory.emit_added(self,
+ return SimpleFactory.SimpleFactory.emit_added(self,
klass,
initargs,
category,
customKey="%s-%s" % (klass.DEFAULT_FOLDER, klass._udi_)
)
- def is_interesting(self, udi, props):
- if props.has_key("info.parent") and props.has_key("info.parent") != "":
- prop2 = self._get_properties(props["info.parent"])
- if prop2.has_key("storage.removable") and prop2["storage.removable"] == True:
- mount,label = self._get_device_info(props)
- log.info("Detected removable volume %s %s" % (label,mount))
-
- #short circuit the logic here to test if this is a volume being
- #unmounted. Its still interesting, we just dont make a
- #klass for it
- if udi in self._volumes and not mount:
- log.debug("This is a FileModule being removed")
- del(self._volumes[udi])
- return True
-
- #check for the presence of a mount/.conduit group file
- #which describe the folder sync groups, and their names,
- mountUri = "file://%s" % mount
- 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:
- if Vfs.uri_is_on_removable_volume(mountUri):
- klass = self._make_class(
- udi=udi,
- folder=mountUri,
- name=None)
- self._volumes[udi] = [klass]
-
- return True
- return False
-
def get_category(self, udi, **kwargs):
if not self._categories.has_key(udi):
self._categories[udi] = DataProviderCategory.DataProviderCategory(
Modified: trunk/conduit/platform/FileGio.py
==============================================================================
--- trunk/conduit/platform/FileGio.py (original)
+++ trunk/conduit/platform/FileGio.py Mon Oct 20 19:57:45 2008
@@ -276,7 +276,27 @@
return False, None
class VolumeMonitor(conduit.platform.VolumeMonitor):
- pass
+
+ def __init__(self):
+ conduit.platform.VolumeMonitor.__init__(self)
+ self._vm = gio.volume_monitor_get()
+ self._vm.connect("mount-added", self._mounted_cb)
+ self._vm.connect("mount-removed", self._unmounted_cb)
+
+ def _mounted_cb(self, sender, mount):
+ self.emit("volume-mounted",
+ mount.get_uuid(),
+ mount.get_root().get_uri(),
+ mount.get_name())
+
+ def _unmounted_cb(self, sender, mount):
+ self.emit("volume-unmounted", mount.get_uuid())
+
+ def get_mounted_volumes(self):
+ vols = {}
+ for m in self._vm.get_mounts():
+ vols[m.get_uuid()] = (m.get_root().get_uri(), m.get_name())
+ return vols
class FileMonitor(conduit.platform.FileMonitor):
pass
Modified: trunk/conduit/platform/FileGnomeVfs.py
==============================================================================
--- trunk/conduit/platform/FileGnomeVfs.py (original)
+++ trunk/conduit/platform/FileGnomeVfs.py Mon Oct 20 19:57:45 2008
@@ -182,19 +182,19 @@
def is_on_removale_volume(self):
path = self.get_local_path()
if path:
- return VolumeMonitor().volume_is_removable(path)
+ return gnomevfs.VolumeMonitor().get_volume_for_path(path).is_user_visible()
return False
def get_removable_volume_root_uri(self):
path = self.get_local_path()
if path:
- return VolumeMonitor().volume_get_root_uri(path)
+ return gnomevfs.VolumeMonitor().get_volume_for_path(path).get_activation_uri()
return False
def get_filesystem_type(self):
path = self.get_local_path()
if path:
- return VolumeMonitor().volume_get_fstype(path)
+ return gnomevfs.VolumeMonitor().get_volume_for_path(path).get_filesystem_type()
return None
@staticmethod
@@ -287,23 +287,23 @@
def __init__(self):
conduit.platform.VolumeMonitor.__init__(self)
self._vm = gnomevfs.VolumeMonitor()
- self._vm.connect("volume-mounted", self._mounted_unmounted_cb, "volume-mounted")
- self._vm.connect("volume-unmounted", self._mounted_unmounted_cb, "volume-unmounted")
+ self._vm.connect("volume-mounted", self._mounted_cb)
+ self._vm.connect("volume-unmounted", self._unmounted_cb)
- def _mounted_unmounted_cb(self, sender, volume, signalname):
- self.emit(signalname, volume.get_hal_udi())
+ def _mounted_cb(self, sender, volume):
+ self.emit("volume-mounted",
+ volume.get_hal_udi(),
+ volume.get_activation_uri(),
+ volume.get_display_name())
- def get_mounted_volumes(self):
- return [volume.get_hal_udi() for volume in self._vm.get_mounted_volumes()]
-
- def volume_is_removable(self, path):
- return self._vm.get_volume_for_path(path).is_user_visible()
+ def _unmounted_cb(self, sender, volume):
+ self.emit("volume-unmounted", volume.get_hal_udi())
- def volume_get_fstype(self, path):
- return self._vm.get_volume_for_path(path).get_filesystem_type()
-
- def volume_get_root_uri(self, path):
- return self._vm.get_volume_for_path(path).get_activation_uri()
+ def get_mounted_volumes(self):
+ vols = {}
+ for v in self._vm.get_mounted_volumes():
+ vols[v.get_hal_udi()] = (v.get_activation_uri(), v.get_display_name())
+ return vols
class FileMonitor(conduit.platform.FileMonitor):
Modified: trunk/conduit/platform/__init__.py
==============================================================================
--- trunk/conduit/platform/__init__.py (original)
+++ trunk/conduit/platform/__init__.py Mon Oct 20 19:57:45 2008
@@ -97,25 +97,21 @@
class VolumeMonitor(gobject.GObject):
__gsignals__ = {
"volume-mounted" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
- gobject.TYPE_STRING]), #udi
+ gobject.TYPE_STRING, #udi/uuid
+ gobject.TYPE_STRING, #mount point
+ gobject.TYPE_STRING]), #label
"volume-unmounted" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
- gobject.TYPE_STRING]) #udi
+ gobject.TYPE_STRING]) #udi/uuid
}
def __init__(self):
gobject.GObject.__init__(self)
def get_mounted_volumes(self):
- return []
-
- def volume_is_removable(self, path):
- return False
-
- def volume_get_fstype(self, path):
- return None
-
- def volume_get_root_uri(self, path):
- return None
+ """
+ @returs: Dict of mounted volumes, uuid : (mount, name)
+ """
+ return {}
class FileMonitor(gobject.GObject):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]