From 4a4876e7e3f56c1b5d0777444439e8967c9b34b4 Mon Sep 17 00:00:00 2001
From: Aleksey Lim <alsroot@member.fsf.org>
Date: Thu, 17 Sep 2009 08:34:02 +0000
Subject: Cancel updating process in Update control panel component #1361
---
extensions/cpsection/updater/model.py | 40 +++++++++++++++++-
extensions/cpsection/updater/view.py | 75 ++++++++++++++++++++++++--------
2 files changed, 94 insertions(+), 21 deletions(-)
diff --git a/extensions/cpsection/updater/model.py b/extensions/cpsection/updater/model.py
index 102edea..b518808 100755
a
|
b
|
class UpdateModel(gobject.GObject): |
59 | 59 | self._bundles_to_check = None |
60 | 60 | self._bundles_to_update = None |
61 | 61 | self._total_bundles_to_update = 0 |
| 62 | self._bundles_updated = 0 |
62 | 63 | self._downloader = None |
| 64 | self._is_canceled = False |
| 65 | |
| 66 | def cancel(self): |
| 67 | logging.debug('Cancel updating') |
| 68 | |
| 69 | self._is_canceled = True |
| 70 | if self._downloader is not None: |
| 71 | self._downloader.cancel() |
63 | 72 | |
64 | 73 | def check_updates(self): |
| 74 | self._is_canceled = False |
65 | 75 | self.updates = [] |
66 | 76 | self._bundles_to_check = \ |
67 | 77 | [bundle for bundle in bundleregistry.get_registry()] |
… |
… |
class UpdateModel(gobject.GObject): |
85 | 95 | if version is not None and version > bundle.get_activity_version(): |
86 | 96 | self.updates.append(BundleUpdate(bundle, version, link, size)) |
87 | 97 | |
| 98 | if self._is_canceled: |
| 99 | self.emit('progress', UpdateModel.ACTION_CHECKING, None, 0, 0) |
| 100 | return |
| 101 | |
88 | 102 | if self._bundles_to_check: |
89 | 103 | gobject.idle_add(self._check_next_update) |
90 | 104 | else: |
… |
… |
class UpdateModel(gobject.GObject): |
97 | 111 | total) |
98 | 112 | |
99 | 113 | def update(self, bundle_ids): |
| 114 | self._is_canceled = False |
100 | 115 | self._bundles_to_update = [] |
101 | 116 | for bundle_update in self.updates: |
102 | 117 | if bundle_update.bundle.get_bundle_id() in bundle_ids: |
103 | 118 | self._bundles_to_update.append(bundle_update) |
104 | 119 | |
105 | 120 | self._total_bundles_to_update = len(self._bundles_to_update) |
| 121 | self._bundles_updated = 0 |
| 122 | |
106 | 123 | self._download_next_update() |
107 | 124 | |
108 | 125 | def _download_next_update(self): |
| 126 | if self._is_canceled: |
| 127 | self.emit('progress', UpdateModel.ACTION_DOWNLOADING, None, 0, 0) |
| 128 | return |
| 129 | |
109 | 130 | bundle_update = self._bundles_to_update.pop() |
110 | 131 | |
111 | 132 | total = self._total_bundles_to_update * 2 |
… |
… |
class UpdateModel(gobject.GObject): |
145 | 166 | |
146 | 167 | def _install_update(self, bundle_update, local_file_path): |
147 | 168 | |
| 169 | self._bundles_updated += 1 |
148 | 170 | total = self._total_bundles_to_update * 2 |
149 | 171 | current = total - len(self._bundles_to_update) * 2 - 1 |
150 | 172 | |
… |
… |
class UpdateModel(gobject.GObject): |
175 | 197 | gobject.idle_add(self._download_next_update) |
176 | 198 | |
177 | 199 | def get_total_bundles_to_update(self): |
178 | | return self._total_bundles_to_update |
| 200 | return self._bundles_updated |
179 | 201 | |
180 | 202 | |
181 | 203 | class BundleUpdate(object): |
… |
… |
class _Downloader(gobject.GObject): |
208 | 230 | self._input_file = gio.File(bundle_update.link) |
209 | 231 | self._output_file = None |
210 | 232 | self._downloaded_size = 0 |
| 233 | self._is_canceled = False |
211 | 234 | |
212 | 235 | self._input_file.read_async(self.__file_read_async_cb) |
213 | 236 | |
… |
… |
class _Downloader(gobject.GObject): |
217 | 240 | except: |
218 | 241 | self.emit('error', traceback.format_exc()) |
219 | 242 | return |
220 | | |
| 243 | |
221 | 244 | temp_file_path = self._get_temp_file_path(self.bundle_update.link) |
222 | 245 | self._output_file = gio.File(temp_file_path) |
223 | 246 | self._output_stream = self._output_file.create() |
… |
… |
class _Downloader(gobject.GObject): |
225 | 248 | self._input_stream.read_async(self._CHUNK_SIZE, self.__read_async_cb, |
226 | 249 | gobject.PRIORITY_LOW) |
227 | 250 | |
| 251 | def cancel(self): |
| 252 | logging.debug('Cancel downloading') |
| 253 | self._is_canceled = True |
| 254 | |
228 | 255 | def __read_async_cb(self, input_stream, result): |
| 256 | if self._is_canceled: |
| 257 | self._input_stream.close() |
| 258 | self._output_stream.close() |
| 259 | self.emit('error', 'downloading canceled') |
| 260 | return |
| 261 | |
229 | 262 | data = input_stream.read_finish(result) |
230 | 263 | |
231 | 264 | if data is None: |
… |
… |
class _Downloader(gobject.GObject): |
270 | 303 | urlparse(uri) |
271 | 304 | path = os.path.basename(path) |
272 | 305 | |
| 306 | if not os.path.exists(env.get_user_activities_path()): |
| 307 | os.makedirs(env.get_user_activities_path()) |
| 308 | |
273 | 309 | base_name, extension_ = os.path.splitext(path) |
274 | 310 | fd, file_path = tempfile.mkstemp(dir=env.get_user_activities_path(), |
275 | 311 | prefix=base_name, suffix='.xo') |
diff --git a/extensions/cpsection/updater/view.py b/extensions/cpsection/updater/view.py
index 9a77743..b39e555 100644
a
|
b
|
class ActivityUpdater(SectionView): |
66 | 66 | |
67 | 67 | self._update_box = None |
68 | 68 | self._progress_pane = None |
| 69 | self._finish_box = None |
69 | 70 | |
70 | 71 | self._refresh() |
71 | 72 | |
| 73 | def _clear_center(self): |
| 74 | if self._progress_pane in self.get_children(): |
| 75 | self.remove(self._progress_pane) |
| 76 | self._progress_pane = None |
| 77 | |
| 78 | if self._update_box in self.get_children(): |
| 79 | self.remove(self._update_box) |
| 80 | self._update_box = None |
| 81 | |
| 82 | if self._finish_box in self.get_children(): |
| 83 | self.remove(self._finish_box) |
| 84 | self._finish_box = None |
| 85 | |
72 | 86 | def _switch_to_update_box(self): |
73 | 87 | if self._update_box in self.get_children(): |
74 | 88 | return |
75 | 89 | |
76 | | if self._progress_pane in self.get_children(): |
77 | | self.remove(self._progress_pane) |
78 | | self._progress_pane = None |
| 90 | self._clear_center() |
79 | 91 | |
80 | 92 | if self._update_box is None: |
81 | 93 | self._update_box = UpdateBox(self._model) |
… |
… |
class ActivityUpdater(SectionView): |
91 | 103 | if self._progress_pane in self.get_children(): |
92 | 104 | return |
93 | 105 | |
94 | | if self._update_box in self.get_children(): |
95 | | self.remove(self._update_box) |
96 | | self._update_box = None |
| 106 | self._clear_center() |
97 | 107 | |
98 | 108 | if self._progress_pane is None: |
99 | 109 | self._progress_pane = ProgressPane() |
| 110 | self._progress_pane.cancel_button.connect('clicked', |
| 111 | self.__cancel_button_clicked_cb) |
100 | 112 | |
101 | 113 | self.pack_start(self._progress_pane, expand=True, fill=False) |
102 | 114 | self._progress_pane.show() |
103 | 115 | |
104 | | def _clear_center(self): |
105 | | if self._progress_pane in self.get_children(): |
106 | | self.remove(self._progress_pane) |
107 | | self._progress_pane = None |
| 116 | def __cancel_button_clicked_cb(self, button): |
| 117 | self._model.cancel() |
108 | 118 | |
109 | | if self._update_box in self.get_children(): |
110 | | self.remove(self._update_box) |
111 | | self._update_box = None |
| 119 | def _switch_to_finish_box(self): |
| 120 | if self._finish_box in self.get_children(): |
| 121 | return |
| 122 | |
| 123 | self._clear_center() |
| 124 | |
| 125 | if self._finish_box is None: |
| 126 | self._finish_box = FinishBox() |
| 127 | self._finish_box.refresh_button.connect('clicked', |
| 128 | self.__refresh_button_clicked_cb) |
| 129 | |
| 130 | self.pack_start(self._finish_box, expand=True, fill=True) |
| 131 | self._finish_box.show() |
112 | 132 | |
113 | 133 | def __progress_cb(self, model, action, bundle_name, current, total): |
114 | 134 | if current == total and action == UpdateModel.ACTION_CHECKING: |
… |
… |
class ActivityUpdater(SectionView): |
141 | 161 | top_message = gobject.markup_escape_text(top_message) |
142 | 162 | |
143 | 163 | self._top_label.set_markup('<big>%s</big>' % top_message) |
144 | | |
| 164 | |
145 | 165 | if not available_updates: |
146 | | self._clear_center() |
| 166 | self._switch_to_finish_box() |
147 | 167 | else: |
148 | 168 | self._switch_to_update_box() |
149 | 169 | self._update_box.refresh() |
… |
… |
class ActivityUpdater(SectionView): |
167 | 187 | top_message = top_message % installed_updates |
168 | 188 | top_message = gobject.markup_escape_text(top_message) |
169 | 189 | self._top_label.set_markup('<big>%s</big>' % top_message) |
170 | | self._clear_center() |
| 190 | self._switch_to_finish_box() |
171 | 191 | |
172 | 192 | |
173 | 193 | class ProgressPane(gtk.VBox): |
… |
… |
class ProgressPane(gtk.VBox): |
195 | 215 | self.pack_start(alignment_box) |
196 | 216 | alignment_box.show() |
197 | 217 | |
198 | | cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) |
199 | | alignment_box.add(cancel_button) |
200 | | cancel_button.show() |
| 218 | self.cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) |
| 219 | alignment_box.add(self.cancel_button) |
| 220 | self.cancel_button.show() |
201 | 221 | |
202 | 222 | def set_message(self, message): |
203 | 223 | self._label.set_text(message) |
… |
… |
class UpdateBox(gtk.VBox): |
280 | 300 | return bundles_to_update |
281 | 301 | |
282 | 302 | |
| 303 | class FinishBox(gtk.VBox): |
| 304 | |
| 305 | def __init__(self): |
| 306 | gtk.VBox.__init__(self) |
| 307 | |
| 308 | self.set_spacing(style.DEFAULT_PADDING) |
| 309 | |
| 310 | bottom_box = gtk.HBox() |
| 311 | bottom_box.set_spacing(style.DEFAULT_SPACING) |
| 312 | self.pack_end(bottom_box, expand=False) |
| 313 | bottom_box.show() |
| 314 | |
| 315 | self.refresh_button = gtk.Button(stock=gtk.STOCK_REFRESH) |
| 316 | bottom_box.pack_end(self.refresh_button, expand=False) |
| 317 | self.refresh_button.show() |
| 318 | |
| 319 | |
283 | 320 | class UpdateList(gtk.TreeView): |
284 | 321 | |
285 | 322 | def __init__(self, model): |