Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/downloadmanager.py
diff options
context:
space:
mode:
Diffstat (limited to 'downloadmanager.py')
-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'] = \