Hello.  I've recently switched from an iPod to a Sony Ericsson mobile
phone, which is accessible as an MTP device.  It has support for
podcasts, but it only recognizes tracks as podcasts if they're in
certain folders, namely:

    Music/podcast
    Video/podcast
    Picture/podcast

Tracks from these folders show up in the "Podcasts" menu, are
highlighted until played and per-file playback positions are
remembered.

gPodder currently sends all episodes to the root folder, which makes
them regular MP3 files, without podcast-specific properties.  I'm
attaching a patch which adds configurable folders for audio, video and
image podcasts.  There is also a new option to create folders per
podcast (e.g., Music/podcast/No Agenda).  The complete list of added
config options is:

    mtp_audio_folder (str)
    mtp_video_folder (str)
    mtp_image_folder (str)
    mtp_podcast_folders (bool)

These options are only editable using the extended config editor, no
UI.

A patched version of pymtp is required for this to work on modern
systems, see <https://bugs.gpodder.org/show_bug.cgi?id=307>.

The patch applies to revision 85ba576213 from git.  I would like to
read improvement suggestions and bug reports.

PS: image podcasts only work in theory, I was unable to make gPodder
synchronize a Flickr RSS feed.  Pictures just aren't seen as episodes,
although the files are downloaded.  This is a separate issue.

-- 
Justin Forest    PGP Key-ID: 0x6B442D10
umonkey.net | deadchannel.ru | cms.molinos.ru
From 56c6555d3aa05ef6bb1550c31f8f90e5373c188c Mon Sep 17 00:00:00 2001
From: Justin Forest <[email protected]>
Date: Thu, 29 Jul 2010 01:27:08 +0400
Subject: [PATCH] Configurable podcast folders for MTP.

---
 src/gpodder/config.py |    9 ++++++
 src/gpodder/sync.py   |   66 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/src/gpodder/config.py b/src/gpodder/config.py
index 558d2a1..438c1cf 100644
--- a/src/gpodder/config.py
+++ b/src/gpodder/config.py
@@ -203,6 +203,15 @@ gPodderSettings = {
     'open_torrent_after_download': (bool, False,
       ("Automatically open torrents after they have finished downloading")),
 
+    'mtp_audio_folder': (str, '',
+      ("The relative path to where audio podcasts are stored on an MTP device.")),
+    'mtp_video_folder': (str, '',
+      ("The relative path to where video podcasts are stored on an MTP device.")),
+    'mtp_image_folder': (str, '',
+      ("The relative path to where image podcasts are stored on an MTP device.")),
+    'mtp_podcast_folders': (bool, False,
+      ("Whether to create a folder per podcast on MTP devices.")),
+
     'allow_empty_feeds': (bool, True,
       ('Allow subscribing to feeds without episodes')),
 
diff --git a/src/gpodder/sync.py b/src/gpodder/sync.py
index 00f967a..bacb7ac 100644
--- a/src/gpodder/sync.py
+++ b/src/gpodder/sync.py
@@ -77,6 +77,50 @@ import os.path
 import glob
 import time
 
+if pymtp_available:
+    class MTP(pymtp.MTP):
+        sep = os.path.sep
+
+        def __init__(self):
+            pymtp.MTP.__init__(self)
+            self.folders = {}
+
+        def connect(self):
+            pymtp.MTP.connect(self)
+            self.folders = self.unfold(self.mtp.LIBMTP_Get_Folder_List(self.device))
+
+        def get_folder_list(self):
+            return self.folders
+
+        def unfold(self, folder, path=''):
+            result = {}
+            while folder:
+                folder = folder.contents
+                name = self.sep.join([path, folder.name]).lstrip(self.sep)
+                result[name] = folder.folder_id
+                if folder.child:
+                    result.update(self.unfold(folder.child, name))
+                folder = folder.sibling
+            return result
+
+        def mkdir(self, path):
+            folder_id = 0
+            prefix = []
+            parts = path.split(self.sep)
+            while parts:
+                prefix.append(parts[0])
+                tmpath = self.sep.join(prefix)
+                if self.folders.has_key(tmpath):
+                    folder_id = self.folders[tmpath]
+                else:
+                    folder_id = self.create_folder(parts[0], parent=folder_id)
+                    # log('Creating subfolder %s in %s (id=%u)' % (parts[0], self.sep.join(prefix), folder_id))
+                    tmpath = self.sep.join(prefix + [parts[0]])
+                    self.folders[tmpath] = folder_id
+                # log(">>> %s = %s" % (tmpath, folder_id))
+                del parts[0]
+            # log('MTP.mkdir: %s = %u' % (path, folder_id))
+            return folder_id
 
 def open_device(config):
     device_type = config.device_type
@@ -775,7 +819,7 @@ class MTPDevice(Device):
         Device.__init__(self, config)
         self.__model_name = None
         try:
-            self.__MTPDevice = pymtp.MTP()
+            self.__MTPDevice = MTP()
         except NameError, e:
             # pymtp not available / not installed (see bug 924)
             log('pymtp not found: %s', str(e), sender=self)
@@ -920,10 +964,28 @@ class MTPDevice(Device):
             metadata.date = self.__date_to_mtp(episode.pubDate)
             metadata.duration = get_track_length(str(filename))
 
+            folder_name = ''
+            if episode.mimetype.startswith('audio/') and self._config.mtp_audio_folder:
+                folder_name = self._config.mtp_audio_folder
+            if episode.mimetype.startswith('video/') and self._config.mtp_video_folder:
+                folder_name = self._config.mtp_video_folder
+            if episode.mimetype.startswith('image/') and self._config.mtp_image_folder:
+                folder_name = self._config.mtp_image_folder
+
+            if folder_name != '' and self._config.mtp_podcast_folders:
+                folder_name += os.path.sep + str(episode.channel.title)
+
+            # log('Target MTP folder: %s' % folder_name)
+
+            if folder_name == '':
+                folder_id = 0
+            else:
+                folder_id = self.__MTPDevice.mkdir(folder_name)
+
             # send the file
             self.__MTPDevice.send_track_from_file(filename,
                     util.sanitize_filename(metadata.title)+episode.extension(),
-                    metadata, 0, callback=self.__callback)
+                    metadata, folder_id, callback=self.__callback)
         except:
             log('unable to add episode %s', episode.title, sender=self, traceback=True)
             return False
-- 
1.7.0.4

Attachment: signature.asc
Description: Digital signature

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

Reply via email to