first cut of opml input support ("subscribe to channels from web")
git-svn-id: svn://svn.berlios.de/gpodder/trunk@120 b0d088ad-0a06-0410-aad2-9ed5178a7e87
This commit is contained in:
parent
37119822d7
commit
4bea57b125
|
@ -1,3 +1,10 @@
|
|||
Tue, 13 Jun 2006 22:38:17 +0200 <thp@perli.net>
|
||||
* Added libopmlreader, first cut of OPML input support -- you
|
||||
can now select from a list of channels and add them to your
|
||||
local channel list
|
||||
* Added config option "opml_url" to specify URL which will
|
||||
be used as source for the OPML input support feature
|
||||
|
||||
Tue, 13 Jun 2006 20:20:07 +0200 <thp@perli.net>
|
||||
* Removed ipod-dbus support (has now its extra branch in svn)
|
||||
* Bumped version date + release date
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<property name="use_underline">True</property>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image336">
|
||||
<widget class="GtkImage" id="image383">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-cdrom</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -63,7 +63,7 @@
|
|||
<signal name="activate" handler="on_itemUpdate_activate" last_modification_time="Sat, 29 Oct 2005 11:28:10 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image337">
|
||||
<widget class="GtkImage" id="image384">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -90,7 +90,7 @@
|
|||
<signal name="activate" handler="on_sync_to_ipod_activate" last_modification_time="Wed, 05 Apr 2006 21:49:38 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image338">
|
||||
<widget class="GtkImage" id="image385">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-save</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -111,7 +111,7 @@
|
|||
<signal name="activate" handler="on_cleanup_ipod_activate" last_modification_time="Wed, 05 Apr 2006 22:14:51 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image339">
|
||||
<widget class="GtkImage" id="image386">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -138,7 +138,7 @@
|
|||
<signal name="activate" handler="on_itemPreferences_activate" last_modification_time="Sat, 29 Oct 2005 11:29:01 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image340">
|
||||
<widget class="GtkImage" id="image387">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-preferences</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -165,7 +165,7 @@
|
|||
<signal name="activate" handler="close_gpodder" last_modification_time="Sat, 29 Oct 2005 11:54:31 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image341">
|
||||
<widget class="GtkImage" id="image388">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-quit</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -189,7 +189,7 @@
|
|||
<property name="use_underline">True</property>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image342">
|
||||
<widget class="GtkImage" id="image389">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-justify-left</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -211,7 +211,7 @@
|
|||
<signal name="activate" handler="on_itemAddChannel_activate" last_modification_time="Sat, 29 Oct 2005 11:33:59 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image343">
|
||||
<widget class="GtkImage" id="image390">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-open</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -232,7 +232,7 @@
|
|||
<signal name="activate" handler="on_itemEditChannel_activate" last_modification_time="Sat, 29 Oct 2005 11:34:38 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image344">
|
||||
<widget class="GtkImage" id="image391">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -253,7 +253,7 @@
|
|||
<signal name="activate" handler="on_itemRemoveChannel_activate" last_modification_time="Sat, 29 Oct 2005 11:35:16 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image345">
|
||||
<widget class="GtkImage" id="image392">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -280,7 +280,7 @@
|
|||
<signal name="activate" handler="on_itemExportChannels_activate" last_modification_time="Sat, 29 Oct 2005 11:37:45 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image346">
|
||||
<widget class="GtkImage" id="image393">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -292,6 +292,27 @@
|
|||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="itemImportChannels">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Import from web</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_itemImportChannels_activate" last_modification_time="Tue, 13 Jun 2006 19:39:42 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image394">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-redo</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -304,7 +325,7 @@
|
|||
<property name="use_underline">True</property>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image347">
|
||||
<widget class="GtkImage" id="image395">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-help</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -326,7 +347,7 @@
|
|||
<signal name="activate" handler="on_itemAbout_activate" last_modification_time="Sat, 29 Oct 2005 11:40:19 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image348">
|
||||
<widget class="GtkImage" id="image396">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-about</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
@ -1725,7 +1746,7 @@
|
|||
<widget class="GtkTable" id="table2">
|
||||
<property name="border_width">10</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">5</property>
|
||||
|
@ -1893,6 +1914,83 @@
|
|||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label41">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Autostart:</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label42">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Podcast directory:</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="opmlURL">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="activates_default">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
|
@ -2876,4 +2974,116 @@ you can use the usual format of the environment variables:
|
|||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkWindow" id="gPodderOpmlLister">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Select channels to subscribe to</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">500</property>
|
||||
<property name="default_height">300</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<signal name="destroy" handler="on_gPodderOpmlLister_destroy" last_modification_time="Tue, 13 Jun 2006 19:28:07 GMT"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vboxOPML">
|
||||
<property name="border_width">10</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">5</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="treeviewChannelChooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hboxBottomButtons">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">5</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="btnOK">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_btnOK_clicked" last_modification_time="Tue, 13 Jun 2006 19:31:12 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="btnCancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_btnCancel_clicked" last_modification_time="Tue, 13 Jun 2006 19:31:15 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
|
|
|
@ -46,6 +46,7 @@ from libpodcasts import channelsToModel
|
|||
|
||||
from librssreader import rssReader
|
||||
from libopmlwriter import opmlWriter
|
||||
from libopmlreader import opmlReader
|
||||
from libwget import downloadThread
|
||||
from libwget import downloadStatusManager
|
||||
|
||||
|
@ -324,6 +325,11 @@ class Gpodder(SimpleGladeApp):
|
|||
|
||||
def add_new_channel( self, result = None):
|
||||
if result != None and result != "" and (result[:4] == "http" or result[:3] == "ftp"):
|
||||
for old_channel in self.channels:
|
||||
if old_channel.url == result:
|
||||
if libgpodder.isDebugging():
|
||||
print 'channel already exists in my list :)'
|
||||
return
|
||||
if libgpodder.isDebugging():
|
||||
print ("Will add channel :%s") % result
|
||||
self.statusLabel.set_text( _("Fetching channel index..."))
|
||||
|
@ -525,6 +531,18 @@ class Gpodder(SimpleGladeApp):
|
|||
# end dlg.run()
|
||||
#-- Gpodder.on_itemExportChannels_activate }
|
||||
|
||||
#-- Gpodder.on_itemImportChannels_activate {
|
||||
def on_itemImportChannels_activate(self, widget, *args):
|
||||
if libgpodder.isDebugging:
|
||||
print "on_itemImportChannels_activate called with self.%s" % widget.get_name()
|
||||
opml_lister = Gpodderopmllister()
|
||||
|
||||
gl = gPodderLib()
|
||||
url = gl.opml_url
|
||||
|
||||
opml_lister.get_channels_from_url( url, self.add_new_channel)
|
||||
#-- Gpodder.on_itemImportChannels_activate }
|
||||
|
||||
#-- Gpodder.on_itemAbout_activate {
|
||||
def on_itemAbout_activate(self, widget, *args):
|
||||
if libgpodder.isDebugging():
|
||||
|
@ -814,6 +832,7 @@ class Gpodderproperties(SimpleGladeApp):
|
|||
self.ftpProxy.set_text( gl.ftp_proxy)
|
||||
self.openApp.set_text( gl.open_app)
|
||||
self.iPodMountpoint.set_text( gl.ipod_mount)
|
||||
self.opmlURL.set_text( gl.opml_url)
|
||||
self.updateonstartup.set_active(gl.update_on_startup)
|
||||
# the use proxy env vars check box
|
||||
self.cbEnvironmentVariables.set_active( gl.proxy_use_environment)
|
||||
|
@ -906,6 +925,7 @@ class Gpodderproperties(SimpleGladeApp):
|
|||
gl.open_app = self.openApp.get_text()
|
||||
gl.proxy_use_environment = self.cbEnvironmentVariables.get_active()
|
||||
gl.ipod_mount = self.iPodMountpoint.get_text()
|
||||
gl.opml_url = self.opmlURL.get_text()
|
||||
gl.update_on_startup = self.updateonstartup.get_active()
|
||||
gl.propertiesChanged()
|
||||
# create or remove symlink to download dir on desktop
|
||||
|
@ -1004,6 +1024,84 @@ class Gpoddersync(SimpleGladeApp):
|
|||
#-- Gpoddersync.on_gPodderSync_destroy }
|
||||
|
||||
|
||||
class Gpodderopmllister(SimpleGladeApp):
|
||||
|
||||
def __init__(self, path="gpodder.glade",
|
||||
root="gPodderOpmlLister",
|
||||
domain=app_name, **kwargs):
|
||||
path = os.path.join(glade_dir, path)
|
||||
SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
|
||||
|
||||
#-- Gpodderopmllister.new {
|
||||
def new(self):
|
||||
if libgpodder.isDebugging():
|
||||
print "A new %s has been created" % self.__class__.__name__
|
||||
|
||||
# initiate channels list
|
||||
self.channels = []
|
||||
self.callback_for_channel = None
|
||||
|
||||
togglecell = gtk.CellRendererToggle()
|
||||
togglecell.set_property( 'activatable', True)
|
||||
togglecell.connect( 'toggled', self.callback_edited)
|
||||
togglecolumn = gtk.TreeViewColumn( _("Subscribe"), togglecell, active=0)
|
||||
|
||||
titlecell = gtk.CellRendererText()
|
||||
titlecolumn = gtk.TreeViewColumn( _("Channel name"), titlecell, text=1)
|
||||
|
||||
for itemcolumn in ( togglecolumn, titlecolumn ):
|
||||
self.treeviewChannelChooser.append_column( itemcolumn)
|
||||
#-- Gpodderopmllister.new }
|
||||
|
||||
#-- Gpodderopmllister custom methods {
|
||||
# Write your own methods here
|
||||
def callback_edited( self, cell, path):
|
||||
model = self.treeviewChannelChooser.get_model()
|
||||
activated = not model[path][0]
|
||||
url = model[path][2]
|
||||
|
||||
model[path][0] = activated
|
||||
|
||||
if activated:
|
||||
self.channels.append( url)
|
||||
else:
|
||||
self.channels.remove( url)
|
||||
|
||||
if libgpodder.isDebugging():
|
||||
print url
|
||||
|
||||
def get_channels_from_url( self, url, callback):
|
||||
reader = opmlReader()
|
||||
reader.parseXML( url)
|
||||
self.treeviewChannelChooser.set_model( reader.get_model())
|
||||
self.callback_for_channel = callback
|
||||
#-- Gpodderopmllister custom methods }
|
||||
|
||||
#-- Gpodderopmllister.on_gPodderOpmlLister_destroy {
|
||||
def on_gPodderOpmlLister_destroy(self, widget, *args):
|
||||
if libgpodder.isDebugging():
|
||||
print "on_gPodderOpmlLister_destroy called with self.%s" % widget.get_name()
|
||||
#-- Gpodderopmllister.on_gPodderOpmlLister_destroy }
|
||||
|
||||
#-- Gpodderopmllister.on_btnOK_clicked {
|
||||
def on_btnOK_clicked(self, widget, *args):
|
||||
if libgpodder.isDebugging():
|
||||
print "on_btnOK_clicked called with self.%s" % widget.get_name()
|
||||
self.gPodderOpmlLister.destroy()
|
||||
# add channels that have been selected
|
||||
for url in self.channels:
|
||||
if self.callback_for_channel != None:
|
||||
self.callback_for_channel (url)
|
||||
#-- Gpodderopmllister.on_btnOK_clicked }
|
||||
|
||||
#-- Gpodderopmllister.on_btnCancel_clicked {
|
||||
def on_btnCancel_clicked(self, widget, *args):
|
||||
if libgpodder.isDebugging():
|
||||
print "on_btnCancel_clicked called with self.%s" % widget.get_name()
|
||||
self.gPodderOpmlLister.destroy()
|
||||
#-- Gpodderopmllister.on_btnCancel_clicked }
|
||||
|
||||
|
||||
#-- main {
|
||||
|
||||
def main( __version__ = None):
|
||||
|
@ -1018,6 +1116,7 @@ def main( __version__ = None):
|
|||
#g_podder_properties = Gpodderproperties()
|
||||
#g_podder_episode = Gpodderepisode()
|
||||
#g_podder_sync = Gpoddersync()
|
||||
#g_podder_opml_lister = Gpodderopmllister()
|
||||
|
||||
g_podder.set_icon()
|
||||
g_podder.run()
|
||||
|
|
|
@ -85,6 +85,11 @@ class Gpodder(SimpleGladeApp):
|
|||
print "on_itemExportChannels_activate called with self.%s" % widget.get_name()
|
||||
#-- Gpodder.on_itemExportChannels_activate }
|
||||
|
||||
#-- Gpodder.on_itemImportChannels_activate {
|
||||
def on_itemImportChannels_activate(self, widget, *args):
|
||||
print "on_itemImportChannels_activate called with self.%s" % widget.get_name()
|
||||
#-- Gpodder.on_itemImportChannels_activate }
|
||||
|
||||
#-- Gpodder.on_itemAbout_activate {
|
||||
def on_itemAbout_activate(self, widget, *args):
|
||||
print "on_itemAbout_activate called with self.%s" % widget.get_name()
|
||||
|
@ -273,6 +278,39 @@ class Gpoddersync(SimpleGladeApp):
|
|||
#-- Gpoddersync.on_gPodderSync_destroy }
|
||||
|
||||
|
||||
class Gpodderopmllister(SimpleGladeApp):
|
||||
|
||||
def __init__(self, path="gpodder.glade",
|
||||
root="gPodderOpmlLister",
|
||||
domain=app_name, **kwargs):
|
||||
path = os.path.join(glade_dir, path)
|
||||
SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
|
||||
|
||||
#-- Gpodderopmllister.new {
|
||||
def new(self):
|
||||
print "A new %s has been created" % self.__class__.__name__
|
||||
#-- Gpodderopmllister.new }
|
||||
|
||||
#-- Gpodderopmllister custom methods {
|
||||
# Write your own methods here
|
||||
#-- Gpodderopmllister custom methods }
|
||||
|
||||
#-- Gpodderopmllister.on_gPodderOpmlLister_destroy {
|
||||
def on_gPodderOpmlLister_destroy(self, widget, *args):
|
||||
print "on_gPodderOpmlLister_destroy called with self.%s" % widget.get_name()
|
||||
#-- Gpodderopmllister.on_gPodderOpmlLister_destroy }
|
||||
|
||||
#-- Gpodderopmllister.on_btnOK_clicked {
|
||||
def on_btnOK_clicked(self, widget, *args):
|
||||
print "on_btnOK_clicked called with self.%s" % widget.get_name()
|
||||
#-- Gpodderopmllister.on_btnOK_clicked }
|
||||
|
||||
#-- Gpodderopmllister.on_btnCancel_clicked {
|
||||
def on_btnCancel_clicked(self, widget, *args):
|
||||
print "on_btnCancel_clicked called with self.%s" % widget.get_name()
|
||||
#-- Gpodderopmllister.on_btnCancel_clicked }
|
||||
|
||||
|
||||
#-- main {
|
||||
|
||||
def main():
|
||||
|
@ -281,6 +319,7 @@ def main():
|
|||
g_podder_properties = Gpodderproperties()
|
||||
g_podder_episode = Gpodderepisode()
|
||||
g_podder_sync = Gpoddersync()
|
||||
g_podder_opml_lister = Gpodderopmllister()
|
||||
|
||||
g_podder.run()
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ globalLock = threading.RLock()
|
|||
# my gpodderlib variable
|
||||
g_podder_lib = None
|
||||
|
||||
# default url to use for opml directory on the web
|
||||
default_opml_directory = 'http://share.opml.org/opml/topPodcasts.opml'
|
||||
|
||||
def isDebugging():
|
||||
return debugging
|
||||
|
||||
|
@ -94,6 +97,7 @@ class gPodderLibClass( object):
|
|||
proxy_use_environment = False
|
||||
open_app = ""
|
||||
ipod_mount = ""
|
||||
opml_url = ""
|
||||
desktop_link = _("gPodder downloads")
|
||||
gpodderconf_section = 'gpodder-conf-1'
|
||||
|
||||
|
@ -149,6 +153,7 @@ class gPodderLibClass( object):
|
|||
self.write_to_parser( parser, 'proxy_use_env', self.proxy_use_environment)
|
||||
self.write_to_parser( parser, 'ipod_mount', self.ipod_mount)
|
||||
self.write_to_parser( parser, 'update_on_startup', self.update_on_startup)
|
||||
self.write_to_parser( parser, 'opml_url', self.opml_url)
|
||||
fn = self.getConfigFilename()
|
||||
fp = open( fn, "w")
|
||||
parser.write( fp)
|
||||
|
@ -199,6 +204,7 @@ class gPodderLibClass( object):
|
|||
http = self.get_from_parser( parser, 'http_proxy')
|
||||
ftp = self.get_from_parser( parser, 'ftp_proxy')
|
||||
app = self.get_from_parser( parser, 'player', 'gnome-open')
|
||||
opml_url = self.get_from_parser( parser, 'opml_url', default_opml_directory)
|
||||
self.proxy_use_environment = self.get_boolean_from_parser( parser, 'proxy_use_env', True)
|
||||
self.ipod_mount = self.get_from_parser( parser, 'ipod_mount', '/media/ipod/')
|
||||
self.update_on_startup = self.get_boolean_from_parser(parser, 'update_on_startup', default=False)
|
||||
|
@ -212,10 +218,15 @@ class gPodderLibClass( object):
|
|||
self.open_app = strip( app)
|
||||
else:
|
||||
self.open_app = 'gnome-open'
|
||||
if strip( opml_url) != '':
|
||||
self.opml_url = strip( opml_url)
|
||||
else:
|
||||
self.opml_url = default_opml_directory
|
||||
except:
|
||||
# TODO: well, well.. (http + ftp?)
|
||||
self.open_app = 'gnome-open'
|
||||
self.ipod_mount = '/media/ipod/'
|
||||
self.opml_url = default_opml_directory
|
||||
if was_oldstyle:
|
||||
self.saveConfig()
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
#
|
||||
# gPodder (a media aggregator / podcast client)
|
||||
# Copyright (C) 2005-2006 Thomas Perl <thp at perli.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# libopmlreader.py -- opml ("podcast list") reader functionality
|
||||
# thomas perl <thp@perli.net> 20060613
|
||||
#
|
||||
#
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
|
||||
import libgpodder
|
||||
|
||||
from xml.sax.saxutils import DefaultHandler
|
||||
from xml.sax.handler import ErrorHandler
|
||||
from xml.sax import make_parser
|
||||
from string import strip
|
||||
|
||||
from libpodcasts import opmlChannel
|
||||
from libpodcasts import stripHtml
|
||||
|
||||
from librssreader import rssErrorHandler
|
||||
|
||||
|
||||
class opmlReader( DefaultHandler):
|
||||
channels = []
|
||||
title = 'Unknown OPML Channel'
|
||||
|
||||
current_item = None
|
||||
current_element_data = ""
|
||||
|
||||
def __init__( self):
|
||||
None
|
||||
|
||||
def get_model( self):
|
||||
new_model = gtk.ListStore( gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING)
|
||||
|
||||
for channel in self.channels:
|
||||
new_iter = new_model.append()
|
||||
new_model.set( new_iter, 0, False)
|
||||
new_model.set( new_iter, 1, channel.title)
|
||||
new_model.set( new_iter, 2, channel.xmlurl)
|
||||
|
||||
return new_model
|
||||
|
||||
def parseXML( self, filename):
|
||||
self.channels = []
|
||||
parser = make_parser()
|
||||
parser.returns_unicode = True
|
||||
parser.setContentHandler( self)
|
||||
parser.setErrorHandler( rssErrorHandler())
|
||||
# no multithreaded access to filename
|
||||
libgpodder.getLock()
|
||||
try:
|
||||
parser.parse( filename)
|
||||
finally:
|
||||
libgpodder.releaseLock()
|
||||
|
||||
def startElement( self, name, attrs):
|
||||
self.current_element_data = ""
|
||||
|
||||
if name == 'outline' and attrs.get( 'type', '???') == 'rss':
|
||||
self.channels.append( opmlChannel( attrs.get( 'xmlUrl', ''), attrs.get( 'title', '') ))
|
||||
|
||||
def endElement( self, name):
|
||||
if name == 'title':
|
||||
self.title = self.current_element_data
|
||||
|
||||
def characters( self, ch):
|
||||
self.current_element_data = self.current_element_data + ch
|
||||
|
||||
|
|
@ -391,6 +391,13 @@ class podcastItem(object):
|
|||
|
||||
return '%d Bytes' % size
|
||||
|
||||
|
||||
class opmlChannel(object):
|
||||
def __init__( self, xmlurl, title = 'Unknown OPML Channel'):
|
||||
self.title = title
|
||||
self.xmlurl = xmlurl
|
||||
|
||||
|
||||
def channelsToModel( channels):
|
||||
new_model = gtk.ListStore( gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_OBJECT)
|
||||
|
||||
|
|
Loading…
Reference in New Issue