Ticket #394: 0001-Cancel-a-download-if-space-is-very-tight-SL-394.4.patch
File 0001-Cancel-a-download-if-space-is-very-tight-SL-394.4.patch, 6.3 KB (added by humitos, 11 years ago) |
---|
-
downloadmanager.py
From f075a18ce5d3a9ad30420c569b4eb5e84db442b5 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann <humitos@gmail.com> Date: Mon, 17 Sep 2012 11:19:02 -0300 Subject: [PATCH Browse] Cancel a download if space is very tight SL #394 It checks for enough space[1] before downloading the file. If there is no enough space, Browse will cancel the download process before starting it and an Alert will be shown to the user to inform this situation. [1] this check is: free_space - file_to_download > 50Mb Signed-off-by: Manuel Kaufmann <humitos@gmail.com> --- downloadmanager.py | 88 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/downloadmanager.py b/downloadmanager.py index 9950c16..155864a 100644
a b DS_DBUS_PATH = '/org/laptop/sugar/DataStore' 38 38 _active_downloads = [] 39 39 _dest_to_window = {} 40 40 41 SPACE_THRESHOLD = 52428800 42 41 43 42 44 def can_quit(): 43 45 return len(_active_downloads) == 0 … … class Download(object): 61 63 self._activity = browser.get_toplevel() 62 64 self._source = download.get_uri() 63 65 64 self._download.connect('notify::progress', self.__progress_change_cb)65 66 self._download.connect('notify::status', self.__state_change_cb) 66 67 self._download.connect('error', self.__error_cb) 67 68 … … class Download(object): 74 75 self._stop_alert = None 75 76 76 77 # figure out download URI 77 temp_path = os.path.join(activity.get_activity_root(), 'instance')78 if not os.path.exists( temp_path):79 os.makedirs( temp_path)78 self.temp_path = os.path.join(activity.get_activity_root(), 'instance') 79 if not os.path.exists(self.temp_path): 80 os.makedirs(self.temp_path) 80 81 81 fd, self._dest_path = tempfile.mkstemp(dir= temp_path,82 fd, self._dest_path = tempfile.mkstemp(dir=self.temp_path, 82 83 suffix=download.get_suggested_filename(), 83 84 prefix='tmp') 84 85 os.close(fd) 85 86 logging.debug('Download destination path: %s' % self._dest_path) 86 87 88 # We have to start the download to get 'total-size' 89 # property. It not, 0 is returned 87 90 self._download.set_destination_uri('file://' + self._dest_path) 88 91 self._download.start() 89 92 … … class Download(object): 95 98 def __state_change_cb(self, download, gparamspec): 96 99 state = self._download.get_status() 97 100 if state == WebKit.DownloadStatus.STARTED: 98 self._create_journal_object() 99 self._object_id = self.dl_jobject.object_id 100 101 alert = TimeoutAlert(9) 102 alert.props.title = _('Download started') 103 alert.props.msg = _('%s' % self._download.get_suggested_filename()) 104 self._activity.add_alert(alert) 105 alert.connect('response', self.__start_response_cb) 106 alert.show() 107 global _active_downloads 108 _active_downloads.append(self) 101 # Check free space and cancel the download if there is not enough. 102 total_size = self._download.get_total_size() 103 logging.debug('Total size of the file: %s', total_size) 104 enough_space = self.enough_space( 105 total_size, path=self.temp_path) 106 if not enough_space: 107 logging.debug('Download canceled because of Disk Space') 108 self.cancel() 109 110 self._canceled_alert = Alert() 111 self._canceled_alert.props.title = _('Not enough space ' 112 'to download') 113 114 total_size_mb = total_size / 1024.0 ** 2 115 free_space_mb = self._free_available_space( 116 path=self.temp_path) - SPACE_THRESHOLD \ 117 / 1024.0 ** 2 118 filename = self._download.get_suggested_filename() 119 self._canceled_alert.props.msg = \ 120 _('Download "%s" requires %.2f MB of free space, only ' 121 '%.2f MB is available' % (filename, total_size_mb, 122 free_space_mb)) 123 ok_icon = Icon(icon_name='dialog-ok') 124 self._canceled_alert.add_button(Gtk.ResponseType.OK, 125 _('Ok'), ok_icon) 126 ok_icon.show() 127 self._canceled_alert.connect('response', 128 self.__stop_response_cb) 129 self._activity.add_alert(self._canceled_alert) 130 else: 131 self._download.connect('notify::progress', 132 self.__progress_change_cb) 133 self._create_journal_object() 134 self._object_id = self.dl_jobject.object_id 135 136 alert = TimeoutAlert(9) 137 alert.props.title = _('Download started') 138 alert.props.msg = _('%s' % 139 self._download.get_suggested_filename()) 140 self._activity.add_alert(alert) 141 alert.connect('response', self.__start_response_cb) 142 alert.show() 143 global _active_downloads 144 _active_downloads.append(self) 109 145 110 146 elif state == WebKit.DownloadStatus.FINISHED: 111 147 self._stop_alert = Alert() … … class Download(object): 197 233 def cancel(self): 198 234 self._download.cancel() 199 235 236 def enough_space(self, size, path='/'): 237 """Check if there is enough (size) free space on path 238 239 size -- free space requested in Kb 240 241 path -- device where the check will be done. For example: '/tmp' 242 243 This method is useful to check the free space, for example, 244 before starting a download from internet, creating a big map 245 in some game or whatever action that needs some space in the 246 Hard Disk. 247 """ 248 249 free_space = self._free_available_space(path=path) 250 return free_space - size > SPACE_THRESHOLD 251 252 def _free_available_space(self, path='/'): 253 s = os.statvfs(path) 254 return s.f_bavail * s.f_frsize 255 200 256 def _create_journal_object(self): 201 257 self.dl_jobject = datastore.create() 202 258 self.dl_jobject.metadata['title'] = \