Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Kaufmann <humitos@gmail.com>2012-09-17 14:19:02 (GMT)
committer Manuel QuiƱones <manuq@laptop.org>2012-11-16 18:15:15 (GMT)
commitf96848a9fb4537e01994c096659541a967dd749f (patch)
tree0ad7c24028d66a90823315ff29fa209b0177c842
parentdbb17470b79bb230b0019ac306811ef956cec71d (diff)
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> Acked-by: Manuel QuiƱones <manuq@laptop.org>
-rw-r--r--downloadmanager.py88
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'] = \