improved status list, removed status window, better url handling, cleaner shutdowns

git-svn-id: svn://svn.berlios.de/gpodder@15 b0d088ad-0a06-0410-aad2-9ed5178a7e87
This commit is contained in:
Thomas Perl 2005-11-23 19:53:18 +00:00
parent 75d8b17735
commit fd6668a94a
5 changed files with 147 additions and 40 deletions

View File

@ -553,24 +553,73 @@
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<widget class="GtkVBox" id="vboxDownloadStatusWidgets">
<property name="border_width">5</property>
<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>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<widget class="GtkTreeView" id="treeDownloads">
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<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="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="treeDownloads">
<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>
<signal name="row_activated" handler="on_treeDownloads_row_activated" last_modification_time="Wed, 23 Nov 2005 18:51:28 GMT"/>
</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="hboxDownloadStatusButtonBox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkButton" id="btnCancelDownloadStatus">
<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_btnCancelDownloadStatus_clicked" last_modification_time="Wed, 23 Nov 2005 19:02:29 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>
<packing>

View File

@ -3,7 +3,7 @@
# Python module src/gpodder/gpodder.py
# Autogenerated from gpodder.glade
# Generated on Tue Nov 22 23:01:23 2005
# Generated on Wed Nov 23 20:49:28 2005
# Warning: Do not modify any context comment such as #--
# They are required to keep user's code
@ -222,6 +222,10 @@ class Gpodder(SimpleGladeApp):
if self.channels_loaded:
gPodderChannelWriter().write( self.channels)
# cancel downloads by killing all threads in the list
if self.download_status_manager:
self.download_status_manager.cancelAll()
self.gtk_main_quit()
#-- Gpodder.close_gpodder }
@ -333,14 +337,15 @@ class Gpodder(SimpleGladeApp):
self.active_item = self.channels[self.active_channel].getActiveByUrl( url)
status = Gpodderstatus()
current_channel = self.channels[self.active_channel]
current_podcast = current_channel.items[self.active_item]
if status.setup( current_channel, current_podcast, self.download_status_manager):
status.download()
filename = gPodderLib().getPodcastFilename( current_channel, current_podcast.url)
if os.path.exists( filename) == False and self.download_status_manager.is_download_in_progress( current_podcast.url) == False:
downloadThread( current_podcast.url, filename, None, self.download_status_manager, current_podcast.title).download()
else:
message_dialog = gtk.MessageDialog( self.gPodder, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK)
message_dialog.set_markup( "<big><b>Already downloaded</b></big>\n\nYou have already downloaded this episode.")
message_dialog.set_markup( "<big><b>Already downloaded</b></big>\n\nYou have already downloaded this episode.\nOr you are currently downloading it.")
message_dialog.run()
message_dialog.destroy()
#-- Gpodder.on_treeAvailable_row_activated }
@ -352,6 +357,24 @@ class Gpodder(SimpleGladeApp):
self.on_treeAvailable_row_activated( widget, args)
#-- Gpodder.on_btnDownload_clicked }
#-- Gpodder.on_treeDownloads_row_activated {
def on_treeDownloads_row_activated(self, widget, *args):
if libgpodder.isDebugging():
print "on_treeDownloads_row_activated called with self.%s" % widget.get_name()
selection_tuple = self.treeDownloads.get_selection().get_selected()
selection_iter = selection_tuple[1]
if selection_iter != None:
url = self.download_status_manager.tree_model.get_value( selection_iter, 3)
self.download_status_manager.cancel_by_url( url)
#-- Gpodder.on_treeDownloads_row_activated }
#-- Gpodder.on_btnCancelDownloadStatus_clicked {
def on_btnCancelDownloadStatus_clicked(self, widget, *args):
if libgpodder.isDebugging():
print "on_btnCancelDownloadStatus_clicked called with self.%s" % widget.get_name()
self.on_treeDownloads_row_activated( widget, None)
#-- Gpodder.on_btnCancelDownloadStatus_clicked }
class Gpodderstatus(SimpleGladeApp):
event = None
@ -380,15 +403,6 @@ class Gpodderstatus(SimpleGladeApp):
self.labelFrom.set_markup( "<b>" + self.channel.title + "</b>")
self.labelFilename.set_markup( "<b>" + self.podcast.title + "</b>")
filename = gPodderLib().getPodcastFilename( self.channel, self.podcast.url)
if os.path.exists( filename) == False:
self.event = Event()
self.thread = downloadThread( self.podcast.url, filename, self.event, download_status_manager, self.podcast.title)
return True
else:
self.cancel()
return False
def download( self):
self.thread.download()

View File

@ -3,7 +3,7 @@
# Python module src/gpodder/gpodder.py
# Autogenerated from gpodder.glade
# Generated on Tue Nov 22 23:01:23 2005
# Generated on Wed Nov 23 20:49:28 2005
# Warning: Do not modify any context comment such as #--
# They are required to keep user's code
@ -96,6 +96,16 @@ class Gpodder(SimpleGladeApp):
print "on_btnDownload_clicked called with self.%s" % widget.get_name()
#-- Gpodder.on_btnDownload_clicked }
#-- Gpodder.on_treeDownloads_row_activated {
def on_treeDownloads_row_activated(self, widget, *args):
print "on_treeDownloads_row_activated called with self.%s" % widget.get_name()
#-- Gpodder.on_treeDownloads_row_activated }
#-- Gpodder.on_btnCancelDownloadStatus_clicked {
def on_btnCancelDownloadStatus_clicked(self, widget, *args):
print "on_btnCancelDownloadStatus_clicked called with self.%s" % widget.get_name()
#-- Gpodder.on_btnCancelDownloadStatus_clicked }
class Gpodderstatus(SimpleGladeApp):

View File

@ -74,7 +74,13 @@ class gPodderLib( object):
return self.cachedir + filename + ".xml"
def getPodcastFilename( self, channel, url):
return self.getChannelSaveDir( configChannel( channel.title).filename) + basename( url)
# strip question mark (and everything behind it), fix %20 errors
filename = basename( url).replace( "%20", " ")
indexOfQuestionMark = filename.rfind( "?")
if indexOfQuestionMark != -1:
filename = filename[:indexOfQuestionMark]
# end strip questionmark
return self.getChannelSaveDir( configChannel( channel.title).filename) + filename
def downloadRss( self, channel_url, channel_filename = "__unknown__", force_update = True):
if channel_filename == "":

View File

@ -64,7 +64,7 @@ class downloadThread( object):
if self.statusmgr != None:
# request new id from status manager
self.statusmgr_id = self.statusmgr.getNextId()
self.statusmgr.registerId( self.statusmgr_id)
self.statusmgr.registerId( self.statusmgr_id, self)
def thread_function( self):
command = "/usr/bin/wget \"" + self.url + "\" -O \"" + self.tempname + "\""
@ -88,7 +88,7 @@ class downloadThread( object):
self.speed = speed_string.group(0).strip()
if self.statusmgr != None:
self.statusmgr.updateInfo( self.statusmgr_id, { 'episode':self.cutename, 'speed':self.speed, 'progress':int(self.percentage*100)})
self.statusmgr.updateInfo( self.statusmgr_id, { 'episode':self.cutename, 'speed':self.speed, 'progress':int(self.percentage*100), 'url':self.url})
# self.statusmgr
if process.wait() == 0:
@ -120,26 +120,54 @@ class downloadStatusManager( object):
def __init__( self):
self.status_list = {}
self.next_status_id = 0
self.tree_model = gtk.ListStore( gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT)
self.next_status_id = 0 # Episode name Speed progress (100) url of download
self.tree_model = gtk.ListStore( gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
def getNextId( self):
res = self.next_status_id
self.next_status_id = res + 1
return res
def registerId( self, id):
self.status_list[id] = self.tree_model.append()
def registerId( self, id, thread):
self.status_list[id] = { 'iter':self.tree_model.append(), 'thread':thread }
def unregisterId( self, id):
self.tree_model.remove( self.status_list[id])
del self.status_list[id]
iter = self.status_list[id]['iter']
if iter != None:
self.tree_model.remove( iter)
self.status_list[id]['thread'].cancel()
del self.status_list[id]
def updateInfo( self, id, new_status = { 'episode':"unknown", 'speed':"0b/s", 'progress':0 }):
iter = self.status_list[id]
self.tree_model.set( iter, 0, new_status['episode'])
self.tree_model.set( iter, 1, new_status['speed'])
self.tree_model.set( iter, 2, new_status['progress'])
def updateInfo( self, id, new_status = { 'episode':"unknown", 'speed':"0b/s", 'progress':0, 'url':"unknown" }):
iter = self.status_list[id]['iter']
if iter != None:
self.tree_model.set( iter, 0, new_status['episode'])
self.tree_model.set( iter, 1, new_status['speed'])
self.tree_model.set( iter, 2, new_status['progress'])
self.tree_model.set( iter, 3, new_status['url'])
def is_download_in_progress( self, url):
for element in self.status_list:
thread = self.status_list[element]['thread']
if thread != None and thread.url == url:
return True
return False
def cancelAll( self):
self.tree_model.clear()
for element in self.status_list:
self.status_list[element]['iter'] = None
self.status_list[element]['thread'].cancel()
def cancel_by_url( self, url):
for element in self.status_list:
thread = self.status_list[element]['thread']
if thread != None and thread.url == url:
thread.cancel()
return True
return False
def getModel( self):
return self.tree_model