new updating feed cache dialog following gnome hig guidelines
git-svn-id: svn://svn.berlios.de/gpodder/trunk@265 b0d088ad-0a06-0410-aad2-9ed5178a7e87
This commit is contained in:
parent
d56aad02bf
commit
f180ab24bb
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Sat, 10 Mar 2007 16:52:22 +0100 <thp@perli.net>
|
||||
* src/gpodder/libpodcasts.py: Support cancelling downloading an RSS
|
||||
file by supplying a callback_is_cancelled variable that should
|
||||
return True when the download should be cancelled (and the old,
|
||||
backed up cache file [if any] be used instead); additionally, get
|
||||
rid of gtk events_pending code, as we call downloadRss only in
|
||||
threads as of now
|
||||
* src/gpodder/libgpodder.py: Support for cancelling the read()
|
||||
operation of a gPodderChannelReader (uses old cache files instead)
|
||||
* src/gpodder/gpodder.py: Re-design of the update feed cache dialog
|
||||
following Gnome HIG guidelines for progress windows and making
|
||||
use of the update_feed_cache() function (which now is threaded) in
|
||||
every part of the gpodder window code; also provide the option of
|
||||
cancelling a running update of the feed cache :)
|
||||
|
||||
Fri, 9 Mar 2007 20:05:20 +0100 <thp@perli.net>
|
||||
* src/gpodder/libgpodder.py: Fix sanitize_feed_url() function
|
||||
* src/gpodder/gpodder.py: Add support for dialogs to be centered on
|
||||
|
|
|
@ -153,15 +153,6 @@ class Gpodder(SimpleGladeApp):
|
|||
self.download_status_manager = downloadStatusManager( main_window = self.gPodder, change_notification = self.updateTreeView)
|
||||
self.treeDownloads.set_model( self.download_status_manager.getModel())
|
||||
|
||||
# read and display subscribed channels
|
||||
self.active_channel = None
|
||||
self.channels = []
|
||||
reader = gPodderChannelReader()
|
||||
self.channels = reader.read( False)
|
||||
|
||||
# update view
|
||||
self.updateComboBox()
|
||||
|
||||
# tooltips :)
|
||||
self.tooltips = gtk.Tooltips()
|
||||
self.tooltips.set_tip( self.btnEditChannel, _("Channel Info"))
|
||||
|
@ -176,9 +167,10 @@ class Gpodder(SimpleGladeApp):
|
|||
|
||||
gl = gPodderLib()
|
||||
|
||||
# Update the feed list if the user has set it up
|
||||
if gl.update_on_startup:
|
||||
self.update_feed_cache()
|
||||
# Subscribed channels
|
||||
self.active_channel = None
|
||||
self.channels = gPodderChannelReader().read( force_update = False)
|
||||
self.update_feed_cache( force_update = gl.update_on_startup)
|
||||
|
||||
# create a localDB object
|
||||
self.ldb = localDB()
|
||||
|
@ -293,16 +285,13 @@ class Gpodder(SimpleGladeApp):
|
|||
channels_should_be = len( self.channels)
|
||||
|
||||
gPodderChannelWriter().write( self.channels)
|
||||
self.channels = gPodderChannelReader().read( False)
|
||||
self.update_feed_cache( force_update = False)
|
||||
|
||||
# check if gPodderChannelReader has successfully added the channel
|
||||
if channels_should_be > len( self.channels):
|
||||
self.showMessage( _("There has been an error adding the channel.\nMaybe the URL is wrong?"))
|
||||
|
||||
def add_new_channel( self, result = None):
|
||||
# Treat "feed://" URLs like "http://" ones
|
||||
gl = gPodderLib()
|
||||
|
||||
result = gl.sanitize_feed_url( result)
|
||||
if result:
|
||||
for old_channel in self.channels:
|
||||
|
@ -314,7 +303,6 @@ class Gpodder(SimpleGladeApp):
|
|||
self.comboAvailable.set_active( i)
|
||||
return
|
||||
log( 'Adding new channel: %s', result)
|
||||
self.statusLabel.set_text( _("Fetching channel index..."))
|
||||
channel = podcastChannel( url = result)
|
||||
channel.remove_cache_file()
|
||||
num_channels_before = len(self.channels)
|
||||
|
@ -323,10 +311,6 @@ class Gpodder(SimpleGladeApp):
|
|||
# download changed channels
|
||||
self.refetch_channel_list()
|
||||
|
||||
# try to update combo box
|
||||
self.updateComboBox()
|
||||
self.statusLabel.set_text( "")
|
||||
|
||||
if num_channels_before < len(self.channels):
|
||||
# ask user to download some new episodes
|
||||
self.comboAvailable.set_active( len( self.channels)-1)
|
||||
|
@ -395,39 +379,79 @@ class Gpodder(SimpleGladeApp):
|
|||
sync.clean_playlist()
|
||||
sync.close()
|
||||
|
||||
def update_feed_cache_callback( self, progressbar, position, count):
|
||||
try:
|
||||
progressbar.set_text( _("Updating: %s") % ( self.channels[position].title, ))
|
||||
except:
|
||||
progressbar.set_text( _("%d of %d") % ( position, count ))
|
||||
def update_feed_cache_callback( self, label, progressbar, position, count):
|
||||
title = _('Please wait...')
|
||||
|
||||
if len(self.channels) > position:
|
||||
title = _('Updating %s') % self.channels[position].title
|
||||
|
||||
label.set_markup( '<i>%s</i>' % title)
|
||||
progressbar.set_text( _('%d of %d channels updated') % ( position, count ))
|
||||
progressbar.set_fraction( ((1.00*position) / (1.00*count)))
|
||||
|
||||
def update_feed_cache(self):
|
||||
reader = gPodderChannelReader()
|
||||
please_wait = gtk.Dialog( _("Updating feed cache"), self.gPodder)
|
||||
please_wait.vbox.set_spacing( 5)
|
||||
please_wait.set_border_width( 5)
|
||||
def update_feed_cache_proc( self, reader, force_update, callback_proc, callback_error, finish_proc):
|
||||
self.channels = reader.read( force_update, callback_proc = callback_proc, callback_error = callback_error)
|
||||
finish_proc()
|
||||
|
||||
def update_feed_cache(self, force_update = True):
|
||||
title = _('Downloading podcast feeds')
|
||||
heading = _('Downloading feeds')
|
||||
body = _('Podcast feeds contain channel metadata and information about current episodes.')
|
||||
|
||||
if not force_update:
|
||||
title = _('Reading podcast feeds')
|
||||
heading = _('Reading feeds')
|
||||
|
||||
please_wait = gtk.Dialog( title, self.gPodder, gtk.DIALOG_MODAL, ( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, ))
|
||||
please_wait.set_transient_for( self.gPodder)
|
||||
please_wait.set_position( gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
please_wait.vbox.set_spacing( 5)
|
||||
please_wait.set_border_width( 10)
|
||||
please_wait.set_resizable( False)
|
||||
|
||||
label_heading = gtk.Label()
|
||||
label_heading.set_alignment( 0.0, 0.5)
|
||||
label_heading.set_markup( '<span weight="bold" size="larger">%s</span>' % heading)
|
||||
|
||||
label_body = gtk.Label()
|
||||
label_body.set_text( body)
|
||||
label_body.set_alignment( 0.0, 0.5)
|
||||
label_body.set_line_wrap( True)
|
||||
|
||||
label = gtk.Label( _("Please wait - gPodder is updating its feed cache..."))
|
||||
myprogressbar = gtk.ProgressBar()
|
||||
|
||||
mylabel = gtk.Label()
|
||||
mylabel.set_alignment( 0.0, 0.5)
|
||||
mylabel.set_ellipsize( pango.ELLIPSIZE_END)
|
||||
|
||||
# put it all together
|
||||
please_wait.vbox.pack_start( label)
|
||||
please_wait.vbox.pack_end( myprogressbar)
|
||||
please_wait.vbox.pack_start( label_heading)
|
||||
please_wait.vbox.pack_start( label_body)
|
||||
please_wait.vbox.pack_start( myprogressbar)
|
||||
please_wait.vbox.pack_end( mylabel)
|
||||
please_wait.show_all()
|
||||
|
||||
# hide action anre and separator line
|
||||
please_wait.action_area.hide()
|
||||
# hide separator line
|
||||
please_wait.set_has_separator( False)
|
||||
|
||||
# let's get down to business..
|
||||
self.channels = reader.read( True, callback_proc = lambda pos, count: self.update_feed_cache_callback( myprogressbar, pos, count), callback_error = lambda x: self.showMessage( x, _('Channel update status')))
|
||||
please_wait.destroy()
|
||||
callback_proc = lambda pos, count: gobject.idle_add( self.update_feed_cache_callback, mylabel, myprogressbar, pos, count)
|
||||
callback_error = lambda x: gobject.idle_add( self.showMessage( x))
|
||||
finish_proc = lambda: gobject.idle_add( please_wait.destroy)
|
||||
reader = gPodderChannelReader()
|
||||
|
||||
args = ( reader, force_update, callback_proc, callback_error, finish_proc, )
|
||||
|
||||
thread = Thread( target = self.update_feed_cache_proc, args = args)
|
||||
thread.start()
|
||||
if please_wait.run() == gtk.RESPONSE_CANCEL:
|
||||
reader.cancel()
|
||||
please_wait.destroy()
|
||||
thread.join( 0.5)
|
||||
self.updateComboBox()
|
||||
|
||||
# download all new?
|
||||
if gPodderLib().download_after_update:
|
||||
if force_update and gPodderLib().download_after_update:
|
||||
self.on_itemDownloadAllNew_activate( self.gPodder)
|
||||
|
||||
def download_podcast_by_url( self, url, want_message_dialog = True, widget = None):
|
||||
|
@ -594,15 +618,8 @@ class Gpodder(SimpleGladeApp):
|
|||
active = self.comboAvailable.get_active()
|
||||
if result != self.active_channel.url and result != None and result != "" and (result[:4] == "http" or result[:3] == "ftp"):
|
||||
log( 'Changing channel #%d from "%s" to "%s"', active, self.active_channel.url, result)
|
||||
self.statusLabel.set_text( _("Fetching channel index..."))
|
||||
|
||||
self.channels = self.channels[0:active] + [ podcastChannel( url = result) ] + self.channels[active+1:]
|
||||
|
||||
# fetch new channels
|
||||
self.refetch_channel_list()
|
||||
|
||||
self.updateComboBox()
|
||||
self.statusLabel.set_text( "")
|
||||
#-- Gpodder.on_itemEditChannel_activate }
|
||||
|
||||
#-- Gpodder.on_itemRemoveChannel_activate {
|
||||
|
@ -616,8 +633,7 @@ class Gpodder(SimpleGladeApp):
|
|||
gPodderLib().clean_up_downloads( delete_partial)
|
||||
self.channels.remove( self.active_channel)
|
||||
gPodderChannelWriter().write( self.channels)
|
||||
self.channels = gPodderChannelReader().read( False)
|
||||
self.updateComboBox()
|
||||
self.update_feed_cache( force_update = False)
|
||||
except:
|
||||
pass
|
||||
#-- Gpodder.on_itemRemoveChannel_activate }
|
||||
|
|
|
@ -473,6 +473,13 @@ class gPodderChannelReader( DefaultHandler):
|
|||
self.channels = []
|
||||
self.current_item = None
|
||||
self.current_element_data = ''
|
||||
self.is_cancelled = False
|
||||
|
||||
def cancel( self):
|
||||
self.is_cancelled = True
|
||||
|
||||
def callback_is_cancelled( self):
|
||||
return self.is_cancelled
|
||||
|
||||
def read( self, force_update = False, callback_proc = None, callback_url = None, callback_error = None):
|
||||
"""Read channels from a file into gPodder's cache
|
||||
|
@ -516,7 +523,7 @@ class gPodderChannelReader( DefaultHandler):
|
|||
if callback_url:
|
||||
callback_url( channel.url)
|
||||
|
||||
cachefile = channel.downloadRss( force_update, callback_error = callback_error)
|
||||
cachefile = channel.downloadRss( force_update, callback_error = callback_error, callback_is_cancelled = self.callback_is_cancelled)
|
||||
# check if download was a success
|
||||
if cachefile != None:
|
||||
reader.parseXML( channel.url, cachefile)
|
||||
|
|
|
@ -249,18 +249,24 @@ class podcastChannel(ListType):
|
|||
|
||||
return None
|
||||
|
||||
def downloadRss( self, force_update = True, callback_error = None):
|
||||
def downloadRss( self, force_update = True, callback_error = None, callback_is_cancelled = None):
|
||||
if callback_is_cancelled:
|
||||
if callback_is_cancelled() == True:
|
||||
return self.cache_file
|
||||
|
||||
if not exists( self.cache_file) or force_update:
|
||||
# remove old cache file
|
||||
self.remove_cache_file()
|
||||
event = Event()
|
||||
downloadThread( self.url, self.cache_file, event).download()
|
||||
download_thread = downloadThread( self.url, self.cache_file, event)
|
||||
download_thread.download()
|
||||
|
||||
while event.isSet() == False:
|
||||
while not event.isSet():
|
||||
if callback_is_cancelled:
|
||||
if callback_is_cancelled() == True:
|
||||
download_thread.cancel()
|
||||
self.restore_cache_file()
|
||||
event.wait( 0.2)
|
||||
#FIXME: we do not want gtk code when not needed
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration( False)
|
||||
|
||||
# check if download was a success
|
||||
if not exists( self.cache_file):
|
||||
|
|
Loading…
Reference in New Issue