Special-casing loading of all episodes from DB
[gpodder.git] / src / gpodder / dbusproxy.py
blobab3c8a22258d6421318da62e5f1516079fabcc6d
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
4 # gPodder - A media aggregator and podcast client
5 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
7 # gPodder is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # gPodder is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # gpodder.dbusproxy - Expose Podcasts over D-Bus
22 # Based on a patch by Iwan van der Kleijn <iwanvanderkleyn@gmail.com>
23 # See also: http://gpodder.org/bug/699
25 import gpodder
27 import os
29 from gpodder import model
30 from gpodder import util
32 try:
33 import dbus
34 import dbus.service
35 except ImportError:
36 # Import Mock D-Bus interfaces when D-Bus bindings are not installed
37 from gpodder.gui import dbus
39 def safe_str(txt):
40 if txt:
41 return txt.encode()
42 else:
43 return ''
45 def safe_first_line(txt):
46 txt = safe_str(txt)
47 lines = util.remove_html_tags(txt).strip().splitlines()
48 if not lines or lines[0] == '':
49 return ''
50 else:
51 return lines[0]
53 class DBusPodcastsProxy(dbus.service.Object):
54 """ Implements API accessible through D-Bus
56 Methods on DBusPodcastsProxy can be called by D-Bus clients. They implement
57 safe-guards to work safely over D-Bus while having type signatures applied
58 for parameter and return values.
59 """
61 #DBusPodcastsProxy(lambda: self.channels, self.on_itemUpdate_activate(), self.playback_episodes, self.download_episode_list, bus_name)
62 def __init__(self, get_podcast_list, \
63 check_for_updates, playback_episodes, \
64 download_episodes, bus_name):
65 self._get_podcasts = get_podcast_list
66 self._on_check_for_updates = check_for_updates
67 self._playback_episodes = playback_episodes
68 self._download_episodes = download_episodes
69 dbus.service.Object.__init__(self, \
70 object_path=gpodder.dbus_podcasts_object_path, \
71 bus_name=bus_name)
73 def _get_episode_refs(self, urls):
74 """Get Episode instances associated with URLs"""
75 episodes = []
76 for p in self._get_podcasts():
77 for e in p.get_all_episodes():
78 if e.url in urls:
79 episodes.append(e)
80 return episodes
82 @dbus.service.method(dbus_interface=gpodder.dbus_podcasts, in_signature='', out_signature='a(ssss)')
83 def get_podcasts(self):
84 """Get all podcasts in gPodder's subscription list"""
85 def podcast_to_tuple(podcast):
86 title = safe_str(podcast.title)
87 url = safe_str(podcast.url)
88 description = safe_first_line(podcast.description)
89 cover_file = safe_str(podcast.cover_file)
91 return (title, url, description, cover_file)
93 return [podcast_to_tuple(p) for p in self._get_podcasts()]
95 @dbus.service.method(dbus_interface=gpodder.dbus_podcasts, in_signature='s', out_signature='a(sssssbbb)')
96 def get_episodes(self, url):
97 """Return all episodes of the podcast with the given URL"""
98 podcast = None
99 for channel in self._get_podcasts():
100 if channel.url == url:
101 podcast = channel
102 break
104 if podcast is None:
105 return []
107 def episode_to_tuple(episode):
108 title = safe_str(episode.title)
109 url = safe_str(episode.url)
110 description = safe_first_line(episode.description)
111 filename = safe_str(episode.filename)
112 file_type = safe_str(episode.file_type())
113 is_new = (episode.state == gpodder.STATE_NORMAL and not episode.is_played)
114 is_downloaded = episode.was_downloaded(and_exists=True)
115 is_deleted = (episode.state == gpodder.STATE_DELETED)
117 return (title, url, description, filename, file_type, is_new, is_downloaded, is_deleted)
119 return [episode_to_tuple(e) for e in podcast.get_all_episodes()]
121 @dbus.service.method(dbus_interface=gpodder.dbus_podcasts, in_signature='as', out_signature='(bs)')
122 def play_or_download_episode(self, urls):
123 """Play (or download) a list of episodes given by URL"""
124 episodes = self._get_episode_refs(urls)
125 if not episodes:
126 return (0, 'No episodes found')
128 to_playback = [e for e in episodes if e.was_downloaded(and_exists=True)]
129 to_download = [e for e in episodes if e not in to_playback]
131 if to_playback:
132 self._playback_episodes(to_playback)
134 if to_download:
135 self._download_episodes(to_download)
137 return (1, 'Success')
139 @dbus.service.method(dbus_interface=gpodder.dbus_podcasts, in_signature='', out_signature='')
140 def check_for_updates(self):
141 """Check for new episodes or offer subscriptions"""
142 self._on_check_for_updates()