Add status_changed to DownloadTask for monitoring

This allows our UI to directly monitor the status
of all running DownloadTask objects by checking the
truth value of the status_changed attribute and
updating the UI for all relevant episodes.
This commit is contained in:
Thomas Perl 2009-04-02 00:02:07 +02:00
parent 3f6b04ccca
commit ed7a71dd97
2 changed files with 48 additions and 8 deletions

View File

@ -249,6 +249,7 @@ class DownloadTask(object):
task.speed # in bytes per second
str(task) # name of the episode
task.status # current status
task.status_changed # True if the status has been changed
You can cancel a running download task by setting its status:
@ -258,6 +259,18 @@ class DownloadTask(object):
of downloading data, this can take a while when the Internet is
busy).
The "status_changed" attribute gets set to True everytime the
"status" attribute changes its value. After you get the value of
the "status_changed" attribute, it is always reset to False:
if task.status_changed:
new_status = task.status
# .. update the UI accordingly ..
Obviously, this also means that you must have at most *one*
place in your UI code where you check for status changes and
broadcast the status updates from there.
While the download is taking place and after the .run() method
has finished, you can get the final status to check if the download
was successful:
@ -294,10 +307,21 @@ class DownloadTask(object):
return self.__status
def __set_status(self, status):
self.__status = status
if status != self.__status:
self.__status_changed = True
self.__status = status
status = property(fget=__get_status, fset=__set_status)
def __get_status_changed(self):
if self.__status_changed:
self.__status_changed = False
return True
else:
return False
status_changed = property(fget=__get_status_changed)
def __get_url(self):
return self.__episode.url
@ -309,6 +333,7 @@ class DownloadTask(object):
def __init__(self, episode):
self.__status = DownloadTask.INIT
self.__status_changed = True
self.__episode = episode
# Create the target filename and save it in the database

View File

@ -790,8 +790,9 @@ class gPodder(GladeWidget, dbus.service.Object):
total_speed, total_size, done_size = 0, 0, 0
# Keep a list of all download tasks that we've seen
old_download_tasks_seen = self.download_tasks_seen
self.download_tasks_seen = set()
last_download_count = sum(1 for task in self.download_tasks_seen \
if task.status in (task.DOWNLOADING, task.QUEUED))
download_tasks_seen = set()
# Remember the progress and speed for the episode that
# has been opened in the episode shownotes dialog (if any)
@ -816,7 +817,7 @@ class gPodder(GladeWidget, dbus.service.Object):
episode_window_progress = progress
episode_window_speed = speed
self.download_tasks_seen.add(task)
download_tasks_seen.add(task)
if status == download.DownloadTask.DOWNLOADING:
downloading += 1
@ -828,6 +829,9 @@ class gPodder(GladeWidget, dbus.service.Object):
elif status == download.DownloadTask.QUEUED:
queued += 1
# Remember which tasks we have seen after this run
self.download_tasks_seen = download_tasks_seen
text = [_('Downloads')]
if downloading + failed + finished + queued > 0:
s = []
@ -844,9 +848,8 @@ class gPodder(GladeWidget, dbus.service.Object):
title = [self.default_title]
# Calculate the difference based on what we've seen now and before
episode_urls = [task.url for task in self.download_tasks_seen.symmetric_difference(old_download_tasks_seen)]
last_download_count = sum(1 for task in old_download_tasks_seen if task.status in (task.DOWNLOADING, task.QUEUED))
# We have to update all episode icons for which the status has changed
episode_urls = [task.url for task in self.download_tasks_seen if task.status_changed]
count = downloading + queued
if count > 0:
@ -1066,6 +1069,7 @@ class gPodder(GladeWidget, dbus.service.Object):
def make_menu_item(label, stock_id, tasks, status):
# This creates a menu item for selection-wide actions
def for_each_task_set_status(tasks, status):
changed_episode_urls = []
for row_reference, task in tasks:
if status is not None:
if status == download.DownloadTask.QUEUED:
@ -1088,8 +1092,19 @@ class gPodder(GladeWidget, dbus.service.Object):
if task.status in (task.QUEUED, task.DOWNLOADING):
task.status = task.CANCELLED
model.remove(model.get_iter(row_reference.get_path()))
# Remember the URL, so we can tell the UI to update
try:
# We don't "see" this task anymore - remove it;
# this is needed, so update_episode_list_icons()
# below gets the correct list of "seen" tasks
self.download_tasks_seen.remove(task)
except KeyError, key_error:
log('Cannot remove task from "seen" list: %s', task, sender=self)
changed_episode_urls.append(task.url)
# Tell the task that it has been removed (so it can clean up)
task.removed_from_list()
# Tell the podcasts tab to update icons for our removed podcasts
self.update_episode_list_icons(changed_episode_urls)
return True
item = gtk.ImageMenuItem(label)
item.set_image(gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_MENU))
@ -1531,7 +1546,7 @@ class gPodder(GladeWidget, dbus.service.Object):
Only update the episodes that have an URL in
the "urls" iterable object (e.g. a list of URLs)
"""
if self.active_channel is None:
if self.active_channel is None or not urls:
return
model = self.treeAvailable.get_model()