1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 # gpodder.gtkui.download -- Download management in GUIs (2009-08-24)
23 # Based on code from gpodder.services (thp, 2007-08-24)
27 from gpodder
.liblogger
import log
29 from gpodder
import util
30 from gpodder
import download
40 class DownloadStatusModel(gtk
.ListStore
):
41 # Symbolic names for our columns, so we know what we're up to
42 C_TASK
, C_NAME
, C_URL
, C_PROGRESS
, C_PROGRESS_TEXT
, C_ICON_NAME
= range(6)
44 SEARCH_COLUMNS
= (C_NAME
, C_URL
)
47 gtk
.ListStore
.__init
__(self
, object, str, str, int, str, str)
49 # Set up stock icon IDs for tasks
50 self
._status
_ids
= collections
.defaultdict(lambda: None)
51 self
._status
_ids
[download
.DownloadTask
.DOWNLOADING
] = gtk
.STOCK_GO_DOWN
52 self
._status
_ids
[download
.DownloadTask
.DONE
] = gtk
.STOCK_APPLY
53 self
._status
_ids
[download
.DownloadTask
.FAILED
] = gtk
.STOCK_STOP
54 self
._status
_ids
[download
.DownloadTask
.CANCELLED
] = gtk
.STOCK_CANCEL
55 self
._status
_ids
[download
.DownloadTask
.PAUSED
] = gtk
.STOCK_MEDIA_PAUSE
57 def _format_message(self
, episode
, message
, podcast
):
58 return '%s\n<small>%s - %s</small>' % (episode
, message
, podcast
)
60 def request_update(self
, iter, task
=None):
62 # Ongoing update request from UI - get task from model
63 task
= self
.get_value(iter, self
.C_TASK
)
65 # Initial update request - update non-changing fields
70 if task
.status
== task
.FAILED
:
71 status_message
= '%s: %s' % (\
72 task
.STATUS_MESSAGE
[task
.status
], \
74 elif task
.status
== task
.DOWNLOADING
:
75 status_message
= '%s (%s, %s/s)' % (\
76 task
.STATUS_MESSAGE
[task
.status
], \
77 util
.format_filesize(task
.total_size
), \
78 util
.format_filesize(task
.speed
))
80 status_message
= '%s (%s)' % (\
81 task
.STATUS_MESSAGE
[task
.status
], \
82 util
.format_filesize(task
.total_size
))
85 self
.C_NAME
, self
._format
_message
(task
.markup_name
, \
86 status_message
, task
.markup_podcast_name
),
87 self
.C_PROGRESS
, 100.*task
.progress
,
88 self
.C_PROGRESS_TEXT
, '%.0f%%' % (task
.progress
*100.,),
89 self
.C_ICON_NAME
, self
._status
_ids
[task
.status
])
91 def __add_new_task(self
, task
):
93 self
.request_update(iter, task
)
95 def register_task(self
, task
):
96 util
.idle_add(self
.__add
_new
_task
, task
)
98 def tell_all_tasks_to_quit(self
):
100 task
= row
[DownloadStatusModel
.C_TASK
]
102 # Pause currently-running (and queued) downloads
103 if task
.status
in (task
.QUEUED
, task
.DOWNLOADING
):
104 task
.status
= task
.PAUSED
106 # Delete cancelled and failed downloads
107 if task
.status
in (task
.CANCELLED
, task
.FAILED
):
108 task
.removed_from_list()
110 def are_downloads_in_progress(self
):
112 Returns True if there are any downloads in the
113 QUEUED or DOWNLOADING status, False otherwise.
116 task
= row
[DownloadStatusModel
.C_TASK
]
117 if task
is not None and \
118 task
.status
in (task
.DOWNLOADING
, \
124 def cancel_by_url(self
, url
):
126 task
= row
[DownloadStatusModel
.C_TASK
]
127 if task
is not None and task
.url
== url
and \
128 task
.status
in (task
.DOWNLOADING
, \
130 task
.status
= task
.CANCELLED
136 class DownloadTaskMonitor(object):
137 """A helper class that abstracts download events"""
138 def __init__(self
, episode
, on_can_resume
, on_can_pause
, on_finished
):
139 self
.episode
= episode
141 self
._on
_can
_resume
= on_can_resume
142 self
._on
_can
_pause
= on_can_pause
143 self
._on
_finished
= on_finished
145 def task_updated(self
, task
):
146 if self
.episode
.url
== task
.episode
.url
and self
._status
!= task
.status
:
147 if task
.status
in (task
.DONE
, task
.FAILED
, task
.CANCELLED
):
149 elif task
.status
== task
.PAUSED
:
150 self
._on
_can
_resume
()
151 elif task
.status
in (task
.QUEUED
, task
.DOWNLOADING
):
153 self
._status
= task
.status