Byron Clark avatar Byron Clark committed e182381

Move to the device interface.

Comments (0)

Files changed (3)

udiskie/device.py

+import logging
+
+DBUS_PROPS_INTERFACE = 'org.freedesktop.DBus.Properties'
+UDISKS_INTERFACE = 'org.freedesktop.UDisks'
+UDISKS_DEVICE_INTERFACE = 'org.freedesktop.UDisks.Device'
+
+UDISKS_OBJECT = 'org.freedesktop.UDisks'
+UDISKS_OBJECT_PATH = '/org/freedesktop/UDisks'
+
+class Device:
+    def __init__(self, bus, device_path):
+        self.log = logging.getLogger('udiskie.device.Device')
+        self.bus = bus
+        self.device = self.bus.get_object(UDISKS_OBJECT, device_path)
+
+    def _get_property(self, property):
+        return self.device.Get(UDISKS_DEVICE_INTERFACE, property,
+                               dbus_interface=DBUS_PROPS_INTERFACE)
+
+    def partition_slave(self):
+        return self._get_property('PartitionSlave')
+
+    def is_removable(self):
+        return self._get_property('DeviceIsRemovable')
+
+    def is_partition(self):
+        return self._get_property('DeviceIsPartition')
+
+    def is_handleable(self):
+        """Should this device be handled by udiskie.
+
+        Currently this just means that the device is removable or that the
+        device it is part of is removable."""
+
+        if self.is_removable():
+            return True
+        else:
+            if self.is_partition():
+                parent = Device(self.bus, self.partition_slave())
+                return parent.is_handleable()
+            else:
+                return False
+
+    def is_mounted(self):
+        return self._get_property('DeviceIsMounted')
+
+    def mount_paths(self):
+        return self._get_property('DeviceMountPaths')
+
+    def device_file(self):
+        return self._get_property('DeviceFile')
+
+    def unmount(self):
+        self.device.FilesystemUnmount([], dbus_interface=UDISKS_DEVICE_INTERFACE)
+
+
+def get_all(bus):
+    udisks = bus.get_object(UDISKS_OBJECT, UDISKS_OBJECT_PATH)
+    for path in udisks.EnumerateDevices(dbus_interface=UDISKS_INTERFACE):
+        yield Device(bus, path)

udiskie/umount.py

 import logging
 
+import dbus
+
 from udiskie import system_bus
 from udiskie.names import UDISKS_OBJECT, UDISKS_DEVICE_INTERFACE
+import udiskie.device
 import udiskie.util
 
 def unmount(path):
     The filesystem must match the criteria for a filesystem mountable by
     udiskie.  path is either the physical device node (e.g. /dev/sdb1) or the
     mount point (e.g. /media/Foo)."""
-    
+
+    bus = dbus.SystemBus()
     logger = logging.getLogger('udiskie.umount.unmount')
-    device_path = udiskie.util.find_device(path)
-    if udiskie.util.handleable(device_path) \
-       and udiskie.util.mounted(device_path):
-        logger.info('Unmounting %s (udisks path: %s)' % (path, device_path))
-        device_object = system_bus.get_object(UDISKS_OBJECT, device_path)
-        device_object.FilesystemUnmount([],
-                                        dbus_interface=UDISKS_DEVICE_INTERFACE)
-        logger.info('Finished unmounting %s' % (path,))
+    for device in udiskie.device.get_all(bus):
+        if path in device.mount_paths() or path == device.device_file():
+            logger.debug('Found device owning "%s": "%s"' % (path, device))
+            if device.is_handleable() and device.is_mounted():
+                logger.info('Unmounting %s (device: %s)' % (path, device))
+                device.unmount()
+                logger.info('Finished unmounting %s' % (path,))
+            else:
+                logger.info('Skipping unhandled device %s' % (device_path,))
 
 def cli(args):
+    logging.basicConfig(level=logging.DEBUG)
     for path in args[1:]:
         unmount(path)
 def find_device(path):
     logger = logging.getLogger('udiskie.util.find_device')
 
+    found = []
+
     for device in _get_all_devices():
         logger.debug('examining %s' % (device,))
 
         mounted_paths = _get_property(device, 'DeviceMountPaths')
         if path in mounted_paths:
-            return device
+            found.append(device)
 
         # device path
         device_file = _get_property(device, 'DeviceFile')
         if path == device_file:
-            return device
+            found.append(device)
+
+    return found
 
 def handleable(device_path):
     """Check if the device should be handled by udiskie.
     
     Right now this just means that the device is removable."""
 
-    return _get_property(device_path, 'DeviceIsRemovable')
+    removable = _get_property(device_path, 'DeviceIsRemovable')
+    logger = logging.getLogger('udiskie.util.handleable')
+    logger.debug('device_path: %s, removable: %s' % (device_path, removable))
+    return removable
 
 def mounted(device_path):
     """Check if the device is currently mounted."""
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.