From b0f24a0bcbd9b1f31394783f2041c0b1cb5e64a4 Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Wed, 8 Jun 2011 11:01:36 +0200 Subject: [PATCH] Add episode context menu hook, refactor playback code --- examples/hooks.py | 6 +++++- src/gpodder/gui.py | 18 ++++++++++-------- src/gpodder/hooks.py | 21 ++++++++++++++++++++- src/gpodder/model.py | 14 ++++++++++++++ src/gpodder/youtube.py | 10 +++++++++- 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/examples/hooks.py b/examples/hooks.py index 8d28a85f..4baa7ac9 100644 --- a/examples/hooks.py +++ b/examples/hooks.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Example hooks script for gPodder. -# To use, copy it as a Python script into ~/.config/gpodder/hooks/mySetOfHooks.py +# To use, copy it as a Python script into $GPODDER_HOME/Hooks/mySetOfHooks.py +# (The default value of $GPODDER_HOME is ~/gPodder/ on Desktop installations) # See the module "gpodder.hooks" for a description of when each hook # gets called and what the parameters of each hook are. @@ -24,3 +25,6 @@ class gPodderHooks(object): def on_episode_save(self, episode): log(u'on_episode_save(%s)' % episode.title) + def on_episodes_context_menu(self, episodes): + log(u'on_episodes_context_menu(%d episodes)', % len(episodes)) + diff --git a/src/gpodder/gui.py b/src/gpodder/gui.py index 05e7fe73..eb743a03 100644 --- a/src/gpodder/gui.py +++ b/src/gpodder/gui.py @@ -1954,6 +1954,14 @@ class gPodder(BuilderWidget, dbus.service.Object): item.connect('activate', self.on_btnDownloadedDelete_clicked) menu.append(item) + result = gpodder.user_hooks.on_episodes_context_menu(episodes) + if result: + menu.append(gtk.SeparatorMenuItem()) + for label, callback in result: + item = gtk.MenuItem(label) + item.connect('activate', lambda item: callback(episodes)) + menu.append(item) + ICON = lambda x: x # Ok, this probably makes sense to only display for downloaded files @@ -2104,14 +2112,8 @@ class gPodder(BuilderWidget, dbus.service.Object): episode.playback_mark() self.mygpo_client.on_playback([episode]) - filename = episode.local_filename(create=False) - if filename is None or not os.path.exists(filename): - filename = episode.url - if youtube.is_video_link(filename): - fmt_id = self.config.youtube_preferred_fmt_id - if gpodder.ui.fremantle: - fmt_id = 5 - filename = youtube.get_real_download_url(filename, fmt_id) + fmt_id = self.config.youtube_preferred_fmt_id + filename = episode.get_playback_url(fmt_id) # Determine the playback resume position - if the file # was played 100%, we simply start from the beginning diff --git a/src/gpodder/hooks.py b/src/gpodder/hooks.py index df72a3be..cfd5310f 100644 --- a/src/gpodder/hooks.py +++ b/src/gpodder/hooks.py @@ -48,15 +48,17 @@ def call_hooks(func): @functools.wraps(func) def handler(self, *args, **kwargs): + result = None for filename, module in self.modules: try: callback = getattr(module, method_name, None) if callback is not None: - callback(*args, **kwargs) + result = callback(*args, **kwargs) except Exception, e: log('Error in %s, function %s: %s', filename, method_name, \ e, traceback=True, sender=self) func(self, *args, **kwargs) + return result return handler @@ -150,3 +152,20 @@ class HookManager(object): """ pass + # FIXME: When multiple hooks are used, concatenate the resulting lists + @call_hooks + def on_episodes_context_menu(self, episodes): + """Called when the episode list context menu is opened + + You can add additional context menu entries here. You have to + return a list of tuples, where the first item is a label and + the second item is a callable that will get the episode as its + first and only parameter. + + Example return value: + + [('Mark as new', lambda episodes: ...)] + + @param episode: A list of gpodder.model.PodcastEpisode instances + """ + diff --git a/src/gpodder/model.py b/src/gpodder/model.py index 3cbf631e..7c8077fa 100644 --- a/src/gpodder/model.py +++ b/src/gpodder/model.py @@ -361,6 +361,20 @@ class PodcastEpisode(PodcastModelObject): self.set_state(gpodder.STATE_DELETED) + def get_playback_url(self, fmt_id=None): + """Local (or remote) playback/streaming filename/URL + + Returns either the local filename or a streaming URL that + can be used to playback this episode. + """ + url = self.local_filename(create=False) + if url is None or not os.path.exists(url): + url = self.url + if youtube.is_video_link(url): + url = youtube.get_real_download_url(url, fmt_id) + + return url + def find_unique_file_name(self, filename, extension): current_try = util.sanitize_filename(filename, self.MAX_FILENAME_LENGTH)+extension next_try_id = 2 diff --git a/src/gpodder/youtube.py b/src/gpodder/youtube.py index 26c6e9df..5dbebbdc 100644 --- a/src/gpodder/youtube.py +++ b/src/gpodder/youtube.py @@ -48,7 +48,15 @@ supported_formats = [ class YouTubeError(Exception): pass -def get_real_download_url(url, preferred_fmt_id=18): +def get_real_download_url(url, preferred_fmt_id=None): + # Default fmt_id when none preferred + if preferred_fmt_id is None: + preferred_fmt_id = 18 + + # For Maemo 5, we force fmt_id 5 for performance reasons + if gpodder.ui.fremantle: + preferred_fmt_id = 5 + vid = get_youtube_id(url) if vid is not None: page = None -- 2.11.4.GIT