2 # -*- coding: utf-8 -*-
5 # gPodder - A media aggregator and podcast client
6 # Copyright (c) 2005-2009 Thomas Perl and the gPodder Team
8 # gPodder is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # gPodder is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 # gpo - A better command-line interface to gPodder using the gPodder API
24 # by Thomas Perl <thp@gpodder.org>; 2009-05-07
28 Usage: gpo [COMMAND] [params...]
30 Subscription management
31 -----------------------
33 subscribe URL [TITLE] Subscribe to a new feed at URL (as TITLE)
34 rename URL TITLE Rename feed at URL to TITLE
35 unsubscribe URL Unsubscribe from feed at URL
37 info URL Show information about feed at URL
38 list List all subscribed podcasts
39 update Refresh all feeds (check for new episodes)
44 download [URL] Download all new (=pending) episodes; if
45 URL is an episode URL, download only one
46 episode; if it's a channel URL, download
47 all pending episodes from that channel
48 pending [URL] Show episodes that are marked as new; if
49 URL is given, show only pending downloads
50 from the channel at this URL
51 queue URL Add episode at URL to pending episodes
52 skip URL Remove episode at URL from pending episodes
54 details URL Show information about episode at URL
55 episodes [URL] Show a list of all episodes; if URL is given
56 it should be a channel URL and only episodes
57 from that channel will be displayed
59 delete URL Delete the downloaded episode at URL
61 Portable device synchronization
62 -------------------------------
64 device Show information about your device
65 sync Synchronize downloaded episodes to device
70 youtube resolve [URL] Resolve the YouTube URL to a download URL
71 youtube download [URL] Download a video from YouTube via its URL
79 gpodder_script
= sys
.argv
[0]
80 if os
.path
.islink(gpodder_script
):
81 gpodder_script
= os
.readlink(gpodder_script
)
82 gpodder_dir
= os
.path
.join(os
.path
.dirname(gpodder_script
), '..')
83 prefix
= os
.path
.abspath(os
.path
.normpath(gpodder_dir
))
85 src_dir
= os
.path
.join(prefix
, 'src')
86 data_dir
= os
.path
.join(prefix
, 'data')
88 if os
.path
.exists(src_dir
) and os
.path
.exists(data_dir
) and \
89 not prefix
.startswith('/usr'):
90 # Run gPodder from local source folder (not installed)
91 sys
.path
.insert(0, src_dir
)
97 # This is the command-line interface to gPodder
98 gpodder
.interface
= gpodder
.CLI
100 # Use only the gPodder API here, so this serves both as an example
101 # and as a motivation to provide all functionality in the API :)
102 from gpodder
import api
106 class gPodderCli(object):
108 self
.client
= api
.PodcastClient()
110 # -------------------------------------------------------------------
112 def subscribe(self
, url
, title
=None):
113 if self
.client
.get_podcast(url
) is not None:
114 self
._info
(_('You are already subscribed to %s.' % url
))
117 if self
.client
.create_podcast(url
, title
) is None:
118 self
._error
(_('Cannot download feed for %s.') % url
)
123 self
._info
(_('Successfully added %s.' % url
))
126 def rename(self
, url
, title
):
127 podcast
= self
.client
.get_podcast(url
)
130 self
._error
(_('You are not subscribed to %s.') % url
)
132 old_title
= podcast
.title
133 podcast
.rename(title
)
135 self
._info
(_('Renamed %s to %s.') % (old_title
, title
))
139 def unsubscribe(self
, url
):
140 podcast
= self
.client
.get_podcast(url
)
143 self
._error
(_('You are not subscribed to %s.') % url
)
147 self
._error
(_('Unsubscribed from %s.') % url
)
152 podcast
= self
.client
.get_podcast(url
)
155 self
._error
(_('You are not subscribed to %s.') % url
)
157 title
, url
= podcast
.title
, podcast
.url
158 def status_str(episode
):
161 if episode
.is_downloaded
:
163 if episode
.is_deleted
:
168 episodes
= ('%3d. %s %s' % (i
+1, status_str(e
), e
.title
) for i
, e
in enumerate(podcast
.get_episodes()))
169 episodes
= '\n '.join(episodes
)
170 print >>sys
.stdout
, """
181 for podcast
in self
.client
.get_podcasts():
187 for podcast
in self
.client
.get_podcasts():
188 print 'Updating', podcast
.title
196 for podcast
in self
.client
.get_podcasts():
197 podcast_printed
= False
198 for episode
in podcast
.get_episodes():
200 if not podcast_printed
:
202 podcast_printed
= True
203 print ' ', episode
.title
206 print count
, 'episodes pending.'
211 for podcast
in self
.client
.get_podcasts():
212 podcast_printed
= False
213 for episode
in podcast
.get_episodes():
215 if not podcast_printed
:
217 podcast_printed
= True
218 print ' ', episode
.title
222 print count
, 'episodes downloaded.'
226 self
.client
.synchronize_device()
229 # -------------------------------------------------------------------
231 def _error(self
, *args
):
232 print >>sys
.stderr
, ' '.join(args
)
234 def _info(self
, *args
):
235 print >>sys
.stdout
, ' '.join(args
)
237 def _checkargs(self
, func
, command_line
):
238 args
, varargs
, keywords
, defaults
= inspect
.getargspec(func
)
239 args
.pop(0) # Remove "self" from args
240 defaults
= defaults
or ()
241 minarg
, maxarg
= len(args
)-len(defaults
), len(args
)
243 if len(command_line
) < minarg
or len(command_line
) > maxarg
:
244 self
._error
('Wrong argument count for %s.' % func
.__name
__)
247 return func(*command_line
)
250 def _parse(self
, command_line
):
254 command
= command_line
.pop(0)
255 if command
.startswith('_'):
256 self
._error
(_('This command is not available.'))
259 for name
, func
in inspect
.getmembers(self
):
260 if inspect
.ismethod(func
) and name
== command
:
261 return self
._checkargs
(func
, command_line
)
266 if __name__
== '__main__':
268 cli
._parse
(sys
.argv
[1:]) or sys
.stderr
.write(__doc__
)