Hi.

I have a patch that adds support for the GVFS volume monitor.  When a new vfat
volume is mounted, gPodder asks if you want to synchronize your podcasts.

It detects iPods, everything else is treated like a fs based device. I'm not
sure how MTP devices work, so they're not covered by this patch.

In the root of the volume there can be a gpodder.conf file, which is applied to
the current configuration before syncing.  The file should look like this:

[default]
on_sync_delete = False
bluetooth_use_converter = False

And so on.  Later this could be used to tell which types of files the device
supports, if we add some GUI.

Please test and report any issues here:

http://bugs.gpodder.org/show_bug.cgi?id=332#c0
From 26bc6965cc732eabde3ceea541ae77ce7e2c8816 Mon Sep 17 00:00:00 2001
From: Justin Forest <[email protected]>
Date: Tue, 27 Jan 2009 00:59:01 +0300
Subject: [PATCH] Use GVFS to detect mounted volumes.

When a new volume is mounted, gPodder asks whether you want
to synchronize podcasts with it.  Only vfat volumes are supported.
iPods are recognized automatically.

If there is a gpodder.conf file in the root of the volume,
it is read and applied to the current configuration.  Could
be something like:

[default]
on_sync_delete = False
---
 src/gpodder/gui.py |   25 ++++++++++++++++
 src/gpodder/hal.py |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 0 deletions(-)
 create mode 100644 src/gpodder/hal.py

diff --git a/src/gpodder/gui.py b/src/gpodder/gui.py
index adf2149..4a431b8 100644
--- a/src/gpodder/gui.py
+++ b/src/gpodder/gui.py
@@ -50,6 +50,7 @@ from gpodder import my
 from gpodder.liblogger import log
 from gpodder.dbsqlite import db
 from gpodder import resolver
+from gpodder import hal
 
 try:
     from gpodder import trayicon
@@ -705,6 +706,30 @@ class gPodder(GladeWidget):
         if len(self.channels) == 0:
             util.idle_add(self.on_itemUpdate_activate, None)
 
+        # Start monitoring for mounted devices.
+        hal.DeviceMonitor(self.onDeviceMounted)
+
+    def onDeviceMounted(self, info):
+        result = self.show_confirmation(_("Do you want to synchronize your podcasts with %s?") % info["name"], _("New device connected"))
+        if result:
+            # set new config options, remember the old ones
+            old = { }
+            for k in info["config"]:
+                if hasattr(gl.config, k):
+                    old[k] = getattr(gl.config, k)
+                    setattr(gl.config, k, info["config"][k])
+
+            try:
+                self.on_sync_to_ipod_activate(None, None)
+            except:
+                pass
+
+            # this currently doesn't work, because syncing is threaded.
+            """
+            for k in old:
+                setattr(gl.config, k, old[k])
+            """
+
     def on_tree_channels_resize(self, widget, allocation):
         if not gl.config.podcast_sidebar_save_space:
             return
diff --git a/src/gpodder/hal.py b/src/gpodder/hal.py
new file mode 100644
index 0000000..926f552
--- /dev/null
+++ b/src/gpodder/hal.py
@@ -0,0 +1,82 @@
+import os
+import gobject
+import gnomevfs
+import dbus
+import ConfigParser
+
+class DeviceMonitor(object):
+    def __init__(self, callback):
+        self.callback = callback
+        self.dbus = dbus.SystemBus()
+
+        # set up signals
+        self.vol_monitor = gnomevfs.VolumeMonitor()
+        self.vol_monitor.connect("volume_mounted", self.device_added)
+        self.vol_monitor.connect("volume_unmounted", self.device_removed)
+
+        # found already mounted volumes
+        """
+        for volume in self.vol_monitor.get_mounted_volumes():
+            self.device_added(self.vol_monitor, volume)
+        """
+
+    def device_added(self, monitor, volume):
+        self.log("added", volume)
+
+    def device_removed(self, monitor, volume):
+        self.log("removed", volume)
+
+    def log(self, status, volume):
+        if volume.is_mounted() and self.is_mm_device(volume):
+            self.callback(self.get_volume_info(volume))
+
+    def is_mm_device(self, volume):
+        if volume.get_filesystem_type() == "vfat":
+            return True
+        return False
+
+    def get_volume_info(self, volume):
+        path = volume.get_activation_uri()[7:]
+        info = {
+            "name": volume.get_display_name(),
+            "icon": volume.get_icon(),
+            "config": { }
+        }
+
+        try:
+            parser = ConfigParser.RawConfigParser()
+            parser.read(os.path.join(path, "gpodder.conf"))
+            for k in parser.options("default"):
+                value = None
+                try:
+                    value = int(parser.get("default", k))
+                except ValueError:
+                    value = parser.get("default", k)
+                    if value == "False":
+                        value = False
+                    elif value == "True":
+                        value = True
+                info["config"][k] = value
+        except:
+            pass
+
+        if self.is_ipod(volume):
+            info["config"]["device_type"] = "ipod"
+            info["config"]["ipod_mount"] = path
+        else:
+            info["config"]["device_type"] = "filesystem"
+            info["config"]["mp3_player_folder"] = path
+
+        return info
+
+    def is_ipod(self, volume):
+        udi = volume.get_hal_udi()
+        if udi is not None:
+            obj = self.dbus.get_object("org.freedesktop.Hal", udi)
+            dev = obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
+            if dev.has_key("info.parent"):
+                obj2 = self.dbus.get_object("org.freedesktop.Hal", dev["info.parent"])
+                dev2 = obj2.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
+                if dev2.has_key("storage.model") and dev2["storage.model"] == "iPod":
+                    return True
+        return False
-- 
1.5.6.3

_______________________________________________
gpodder-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/gpodder-devel

Reply via email to