diff options
Diffstat (limited to 'downloadmanager.py')
-rw-r--r-- | downloadmanager.py | 88 |
1 files changed, 72 insertions, 16 deletions
diff --git a/downloadmanager.py b/downloadmanager.py index 9950c16..155864a 100644 --- a/downloadmanager.py +++ b/downloadmanager.py @@ -38,6 +38,8 @@ DS_DBUS_PATH = '/org/laptop/sugar/DataStore' _active_downloads = [] _dest_to_window = {} +SPACE_THRESHOLD = 52428800 + def can_quit(): return len(_active_downloads) == 0 @@ -61,7 +63,6 @@ class Download(object): self._activity = browser.get_toplevel() self._source = download.get_uri() - self._download.connect('notify::progress', self.__progress_change_cb) self._download.connect('notify::status', self.__state_change_cb) self._download.connect('error', self.__error_cb) @@ -74,16 +75,18 @@ class Download(object): self._stop_alert = None # figure out download URI - temp_path = os.path.join(activity.get_activity_root(), 'instance') - if not os.path.exists(temp_path): - os.makedirs(temp_path) + self.temp_path = os.path.join(activity.get_activity_root(), 'instance') + if not os.path.exists(self.temp_path): + os.makedirs(self.temp_path) - fd, self._dest_path = tempfile.mkstemp(dir=temp_path, + fd, self._dest_path = tempfile.mkstemp(dir=self.temp_path, suffix=download.get_suggested_filename(), prefix='tmp') os.close(fd) logging.debug('Download destination path: %s' % self._dest_path) + # We have to start the download to get 'total-size' + # property. It not, 0 is returned self._download.set_destination_uri('file://' + self._dest_path) self._download.start() @@ -95,17 +98,50 @@ class Download(object): def __state_change_cb(self, download, gparamspec): state = self._download.get_status() if state == WebKit.DownloadStatus.STARTED: - self._create_journal_object() - self._object_id = self.dl_jobject.object_id - - alert = TimeoutAlert(9) - alert.props.title = _('Download started') - alert.props.msg = _('%s' % self._download.get_suggested_filename()) - self._activity.add_alert(alert) - alert.connect('response', self.__start_response_cb) - alert.show() - global _active_downloads - _active_downloads.append(self) + # Check free space and cancel the download if there is not enough. + total_size = self._download.get_total_size() + logging.debug('Total size of the file: %s', total_size) + enough_space = self.enough_space( + total_size, path=self.temp_path) + if not enough_space: + logging.debug('Download canceled because of Disk Space') + self.cancel() + + self._canceled_alert = Alert() + self._canceled_alert.props.title = _('Not enough space ' + 'to download') + + total_size_mb = total_size / 1024.0 ** 2 + free_space_mb = self._free_available_space( + path=self.temp_path) - SPACE_THRESHOLD \ + / 1024.0 ** 2 + filename = self._download.get_suggested_filename() + self._canceled_alert.props.msg = \ + _('Download "%s" requires %.2f MB of free space, only ' + '%.2f MB is available' % (filename, total_size_mb, + free_space_mb)) + ok_icon = Icon(icon_name='dialog-ok') + self._canceled_alert.add_button(Gtk.ResponseType.OK, + _('Ok'), ok_icon) + ok_icon.show() + self._canceled_alert.connect('response', + self.__stop_response_cb) + self._activity.add_alert(self._canceled_alert) + else: + self._download.connect('notify::progress', + self.__progress_change_cb) + self._create_journal_object() + self._object_id = self.dl_jobject.object_id + + alert = TimeoutAlert(9) + alert.props.title = _('Download started') + alert.props.msg = _('%s' % + self._download.get_suggested_filename()) + self._activity.add_alert(alert) + alert.connect('response', self.__start_response_cb) + alert.show() + global _active_downloads + _active_downloads.append(self) elif state == WebKit.DownloadStatus.FINISHED: self._stop_alert = Alert() @@ -197,6 +233,26 @@ class Download(object): def cancel(self): self._download.cancel() + def enough_space(self, size, path='/'): + """Check if there is enough (size) free space on path + + size -- free space requested in Kb + + path -- device where the check will be done. For example: '/tmp' + + This method is useful to check the free space, for example, + before starting a download from internet, creating a big map + in some game or whatever action that needs some space in the + Hard Disk. + """ + + free_space = self._free_available_space(path=path) + return free_space - size > SPACE_THRESHOLD + + def _free_available_space(self, path='/'): + s = os.statvfs(path) + return s.f_bavail * s.f_frsize + def _create_journal_object(self): self.dl_jobject = datastore.create() self.dl_jobject.metadata['title'] = \ |