def do_transfer_progress(self, stats): # Ignore callbacks after we finish progress if self.done: return # Start tracking after first call to transfer_progress if not self.started_at: self.started_at = time.time() fraction = stats.get_received_objects() / float(max(1, stats.get_total_objects())) duration = time.time() - self.started_at hours = duration / (60 * 60) minutes = (duration % (60 * 60)) / 60 seconds = duration % 60 prefix = "%02u:%02u:%02u" % (hours, minutes, seconds) rate = stats.get_received_bytes() / max(1, duration) ratestr = GLib.format_size(rate) if len(ratestr) < 8: ratestr = (' ' * (8 - len(ratestr))) + ratestr if fraction == 1.0: transfered = GLib.format_size(stats.get_received_bytes()) self.tool.clear_line() self.tool.write_progress(fraction, prefix, transfered) self.tool.write_line("") self.done = True else: self.tool.clear_line() self.tool.write_progress(fraction, prefix, ratestr)
def do_transfer_progress(self, stats): # Ignore callbacks after we finish progress if self.done: return # Start tracking after first call to transfer_progress if not self.started_at: self.started_at = time.time() fraction = stats.get_received_objects() / float( max(1, stats.get_total_objects())) duration = time.time() - self.started_at hours = duration / (60 * 60) minutes = (duration % (60 * 60)) / 60 seconds = duration % 60 prefix = "%02u:%02u:%02u" % (hours, minutes, seconds) rate = stats.get_received_bytes() / max(1, duration) ratestr = GLib.format_size(rate) if len(ratestr) < 8: ratestr = (' ' * (8 - len(ratestr))) + ratestr if fraction == 1.0: transfered = GLib.format_size(stats.get_received_bytes()) self.tool.clear_line() self.tool.write_progress(fraction, prefix, transfered) self.tool.write_line("") self.done = True else: self.tool.clear_line() self.tool.write_progress(fraction, prefix, ratestr)
def _on_speed_refresh(self, *args): subtitle = '' down = self.client.props.download_speed up = self.client.props.upload_speed if down: subtitle += '↓ {}/s'.format(GLib.format_size(down)) if down and up: subtitle += ' — ' if up: subtitle += '↑ {}/s'.format(GLib.format_size(up)) self.header_bar.props.subtitle = subtitle
def _log_installation_free_space(self): """Write a log entry with the available installation space Use os.statvfs to get the free and blocks at the installation's path and then print a log message with the information. """ stats = os.statvfs(self.installation_path) free = stats.f_bsize * stats.f_bfree total = stats.f_bsize * stats.f_blocks percent = (100.0 * stats.f_bfree) / stats.f_blocks logger.info('%s free space: %s / %s (%.1f%%)', self.installation_path, GLib.format_size(free), GLib.format_size(total), percent)
def _on_progress_details_changed(self, trans, current_items, total_items, current_bytes, total_bytes, current_cps, eta): #print "_on_progress_details_changed: ", trans, progress for row in self: if row[self.COL_TID] == trans.tid: if trans.is_downloading(): name = row[self.COL_NAME] current_bytes_str = GLib.format_size(current_bytes) total_bytes_str = GLib.format_size(total_bytes) status = _("Downloaded %s of %s") % \ (current_bytes_str, total_bytes_str) row[self.COL_STATUS] = self._render_status_text(name, status)
def _on_progress_details_changed(self, trans, current_items, total_items, current_bytes, total_bytes, current_cps, eta): #print "_on_progress_details_changed: ", trans, progress for row in self: if row[self.COL_TID] == trans.tid: if trans.is_downloading(): name = row[self.COL_NAME] current_bytes_str = GLib.format_size(current_bytes) total_bytes_str = GLib.format_size(total_bytes) status = _("Downloaded %s of %s") % \ (current_bytes_str, total_bytes_str) row[self.COL_STATUS] = self._render_status_text( name, status)
def update_progress(self, size_read): self.total_transferred += size_read now = GLib.get_monotonic_time() if ((now - self.last_update_time) > util.PROGRESS_UPDATE_FREQ): self.last_update_time = now progress = self.total_transferred / self.total_size elapsed = now - self.transfer_start_time bytes_per_micro = self.total_transferred / elapsed bytes_per_sec = int(bytes_per_micro * 1000 * 1000) if bytes_per_sec == 0: bytes_per_sec = 1 # no a/0 time_left_sec = (self.total_size - self.total_transferred) / bytes_per_sec print("%s time left, %s/s" % (util.format_time_span(time_left_sec), GLib.format_size(bytes_per_sec))) progress_report = Progress(progress, time_left_sec, bytes_per_sec) self.op.progress_report(progress_report)
def update_ui_info(self, error): if error == None: self.size_string = GLib.format_size(self.total_size) print("Calculated %d files, with a size of %s" % (self.total_count, self.size_string)) if self.total_count > 1: # Translators: Don't need to translate singular, we show the filename if there's only one self.description = gettext.ngettext( "%d file", "%d files", self.total_count) % (self.total_count, ) self.gicon = Gio.ThemedIcon.new("edit-copy-symbolic") else: self.description = self.resolved_files[0].basename self.gicon = Gio.content_type_get_symbolic_icon( self.mime_if_single) self.set_status(OpStatus.WAITING_PERMISSION) else: if isinstance( error, GLib.Error) and error.code == Gio.IOErrorEnum.NOT_FOUND: self.status = OpStatus.FILE_NOT_FOUND self.description = "" self.error_msg = "" self.first_missing_file = self.top_dir_basenames[-1] self.gicon = Gio.ThemedIcon.new("dialog-error-symbolic") else: self.status = OpStatus.FAILED_UNRECOVERABLE self.description = "" self.set_error(error) self.emit_initial_setup_complete() self.emit_status_changed()
def ask_my_permission(self, request): self.active_receive_request = request markup = gettext.ngettext("<b>%s</b> wants to send you %d file (%s)", "<b>%s</b> wants to send you %d files (%s)", request.count) \ % (self.proxy_nick, request.count, GLib.format_size(request.size)) self.widget.get_toplevel().present() dialog = Gtk.MessageDialog( title=_("Incoming file"), # parent=self.widget.get_toplevel(), destroy_with_parent=True, message_type=Gtk.MessageType.QUESTION, use_markup=True, modal=True, text=markup) dialog.add_buttons(_("Refuse"), Gtk.ResponseType.CANCEL, _("Accept"), Gtk.ResponseType.ACCEPT) self.active_receive_request.permission_dialog = dialog res = dialog.run() dialog.destroy() # request may have been cancelled. Destroying the dialog elsewhere will still return a code, # quit early if we're no longer tracking the request (see self.receive_request_withdrawn) if not self.active_receive_request: return if res == Gtk.ResponseType.ACCEPT: self.active_receive_request.permission = util.TRANSFER_REQUEST_GRANTED else: self.active_receive_request.permission = util.TRANSFER_REQUEST_REFUSED self.active_receive_request = None
def __init__(self, package): super().__init__() text_view = TextViewWithLinks() text_view.set_editable(False) text_view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self.add(text_view) # TODO: Handle multiple versions. version = package.candidate text_buffer = text_view.get_buffer() it = text_buffer.get_start_iter() text_buffer.insert_markup( it, # I18N This is the format of the first line of the package # view. _('<span size="x-large" weight="bold">{name}</span>' ' version <span size="large">{version}</span>\n' ).format(name=package.name, version=version.version), -1) summary = re.sub(r' --? ', ' — ', version.summary) text_buffer.insert_markup(it, f'<big>{summary}</big>\n', -1) description = get_description(version) description = format_package_description(description) text_buffer.insert_markup(it, description, -1) text_buffer.insert_markup(it, '\n<span size="xx-small">\n</span>', -1) text_buffer.insert(it, _("Homepage:")) text_buffer.insert(it, ' ') text_view.insert_link(it, version.homepage, version.homepage) text_buffer.insert(it, '\n') # FIXME: I don’t think this formats according to the current # locale. text_buffer.insert( it, _("Download size: {}").format(GLib.format_size(version.size))) text_buffer.insert(it, '\n') text_buffer.insert( it, _("Installed size: {}").format( GLib.format_size(version.installed_size))) text_buffer.insert(it, '\n') text_buffer.insert(it, _("Source package: {}").format(version.source_name)) text_buffer.insert(it, '\n') text_buffer.insert(it, _("Section: {}").format(version.section))
def prepare_receive_info(self): self.size_string = GLib.format_size(self.total_size) logging.debug("Op: details: %d files, with a size of %s" % (self.total_count, self.size_string)) self.have_space = util.have_free_space(self.total_size) self.existing = util.files_exist(self.top_dir_basenames) self.update_ui_info()
def have_free_space(size): save_file = Gio.File.new_for_path(prefs.get_save_path()) try: info = save_file.query_filesystem_info(Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE, None) except GLib.Error: print("Unable to check free space in save location (%s), but proceeding anyhow" % prefs.get_save_path()) return True free = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE) # I guess we could have exactly 0 bytes free, but I think you'd have larger problems. I want to make sure # here that we don't fail because we didn't get a valid number. if free == 0: return True print("Need: %s, have %s" % (GLib.format_size(size), GLib.format_size(free))) return size < free
def query_info_cb(gfile, result): try: file_info = gfile.query_info_finish(result) except GLib.Error as err: logging.error("Could not query file info: %s", err.message) else: size = file_info.get_size() # In bytes. self.size_row.props.subtitle = GLib.format_size(size)
def start_transfer_op(self, op): logging.debug("Remote RPC: calling StartTransfer on '%s'" % (self.display_hostname)) start_time = GLib.get_monotonic_time() op.progress_tracker = transfers.OpProgressTracker(op) op.current_progress_report = None receiver = transfers.FileReceiver(op) op.set_status(OpStatus.TRANSFERRING) op.file_iterator = self.stub.StartTransfer( warp_pb2.OpInfo(timestamp=op.start_time, ident=self.local_ident, readable_name=util.get_hostname(), use_compression=op.use_compression and prefs.use_compression())) def report_receive_error(error): op.set_error(error) try: # If we leave an io stream open, it locks the location. For instance, # if this was a mounted location, we wouldn't be able to terminate until # we closed warp. if receiver.current_stream != None: receiver.current_stream.close() except GLib.Error: pass logging.critical("An error occurred receiving data from %s: %s" % (op.sender, op.error_msg)) op.set_status(OpStatus.FAILED) op.stop_transfer() try: for data in op.file_iterator: receiver.receive_data(data) except grpc.RpcError: if op.file_iterator.code() == grpc.StatusCode.CANCELLED: op.file_iterator = None return else: report_receive_error(op.file_iterator) return except Exception as e: report_receive_error(e) return op.file_iterator = None receiver.receive_finished() logging.debug("Remote: receipt of %s files (%s) finished in %s" % \ (op.total_count, GLib.format_size(op.total_size),\ util.precise_format_time_span(GLib.get_monotonic_time() - start_time))) op.set_status(OpStatus.FINISHED)
def prepare_receive_info(self): self.size_string = GLib.format_size(self.total_size) print("Transfer request received for %d files, with a size of %s" % (self.total_count, self.size_string)) self.have_space = util.have_free_space(self.total_size) self.existing = util.files_exist( self.top_dir_basenames) and prefs.prevent_overwriting() self.update_ui_info()
def _write_table(self, stream, title, refs, display_branch=False): if not refs: return stream.write('== {} ==\n\n'.format(title)) stream.write(self.header) for ref in refs: row = [ ref.remote.name, self._describe_ref(ref), GLib.format_size(ref.installed_size), GLib.format_size(ref.download_size), ] if self.verdicts: row.append(self.verdicts.get(ref.name, '')) stream.write(self.format_string.format(*row)) stream.write('\n')
def transfer_done(): if sender.error != None: op.set_error(sender.error) op.stop_transfer() op.set_status(OpStatus.FAILED_UNRECOVERABLE) elif op.file_send_cancellable.is_set(): print("File send cancelled") else: print("Transfer of %s files (%s) finished in %s" % \ (op.total_count, GLib.format_size(op.total_size),\ util.precise_format_time_span(GLib.get_monotonic_time() - start_time)))
def set_free_space_label(self): self.details_label = None if self.current_uri.startswith("file://"): file = Gio.File.new_for_uri(self.current_uri) fileinfo = file.query_filesystem_info( Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE, None) if fileinfo != None: volume_free = fileinfo.get_attribute_uint64( Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE) if volume_free != 0: self.details_label = GLib.format_size(volume_free) self.space_bar.set_property("details_label", self.details_label)
def progress_report(self, report): self.current_progress_report = report report.progress_text = _("%(time_left)s (%(bytes_per_sec)s/s)") \ % ({ "time_left": util.format_time_span(report.time_left_sec), "bytes_per_sec": GLib.format_size(report.bytes_per_sec) }) if report.progress == 1.0: self.status = OpStatus.FINISHED self.emit_status_changed() return self.emit("progress-changed")
def get_ram_memory(self): self.__ram_memory = "" try: self.__memory = os.popen( "sed -n 's/^MemTotal[ \t]*: *//p' /proc/meminfo").readlines() self.__ram_memory = str(self.__memory[0].replace(" kB", "")) except Exception as err: print("ORG.GCLEANER.APP.SPECS: [ERROR::RAM Memory Not found [ " + str(err) + " ]]") self.__ram_memory = "0" self.__memory = GLib.format_size((int(self.__ram_memory) * 1024)) return self.__memory
def _update_progress(self, cb_info): if cb_info.finished: with self.proxy.lock: # Don't send NeverStartedSending errors to the other end. if cb_info.error and isinstance(cb_info.error, Aborted): e_str = str(cb_info.error) else: e_str = None self.proxy.update_progress(self.app_name, 0, "", "", cb_info.finished, e_str) GLib.idle_add(self.progress_callback, cb_info, priority=GLib.PRIORITY_DEFAULT) print("finished: %s" % util.precise_format_time_span(GLib.get_monotonic_time() - self.start_time)) return if cb_info.is_informational(): GLib.idle_add(self.progress_callback, cb_info, priority=GLib.PRIORITY_DEFAULT) return cb_info.progress = self.current_transfer_size / self.total_transfer_size cur_time = GLib.get_monotonic_time() total_elapsed = cur_time - self.start_time if (cur_time - self.interval_start_time) > self.PROGRESS_INTERVAL: self.interval_start_time = cur_time bytes_per_micro = self.current_transfer_size / total_elapsed bytes_per_sec = int(bytes_per_micro * 1000 * 1000) bytes_left = self.total_transfer_size - self.current_transfer_size time_left_sec = bytes_left / bytes_per_sec cb_info.speed = _("%s/s") % GLib.format_size(bytes_per_sec) cb_info.time_left = util.format_time_span(time_left_sec) with self.proxy.lock: self.proxy.update_progress(self.app_name, cb_info.progress, cb_info.speed, cb_info.time_left, cb_info.finished, None) GLib.idle_add(self.progress_callback, cb_info, priority=GLib.PRIORITY_DEFAULT)
def __init__(self, file: Gio.File, info: Gio.FileInfo): if info.get_file_type() == Gio.FileType.DIRECTORY: name_attrs = ('folder', 'folder focused') else: name_attrs = (None, None) columns = urwid.Columns([ urwid.AttrMap(urwid.Text(info.get_display_name()), *name_attrs), ('pack', urwid.Text(GLib.format_size(info.get_size()), 'right')), (8, urwid.Text(get_basic_content_type(info.get_content_type()))), (11, urwid.Text(format_time(info.get_modification_time()))) ], dividechars=3) super().__init__(columns, None, 'focused') self._file = file self._info = info self._name_key = GLib.utf8_collate_key_for_filename( info.get_display_name(), -1)
def show_diskfull_message(self, size): self.widget.get_toplevel().present() text = _("The target machine (<b>%s</b>) does not have enough disk space to complete the transfer (approximately %s required)" \ % (self.proxy_nick, GLib.format_size(size))) dialog = Gtk.MessageDialog( title=_("Insufficient Disk Space"), # parent=self.widget.get_toplevel(), destroy_with_parent=True, message_type=Gtk.MessageType.WARNING, use_markup=True, text=text) dialog.add_buttons(_("Dismiss"), Gtk.ResponseType.CLOSE) res = dialog.run() dialog.destroy()
def send_notification(self): if prefs.get_show_notifications(): notification = Gio.Notification.new(_("Transfer complete")) body =gettext.ngettext( _("%s (%s) received from %s."), _("%s files (%s) received from %s"), self.op.total_count) \ % (self.op.top_dir_basenames[0] if self.op.total_count == 1 else str(self.op.total_count), GLib.format_size(self.op.total_size), self.op.sender_name) notification.set_body(body) notification.set_icon(Gio.ThemedIcon(name="emblem-ok-symbolic")) notification.set_priority(Gio.NotificationPriority.NORMAL) Gio.Application.get_default().send_notification( self.op.sender, notification)
def _read_bytes_async_cb(self, inputstream: Gio.InputStream, result: Gio.AsyncResult, *user_data): with self._pause_lock: if self._should_pause: self._pause_main_loop = GLib.MainLoop.new(None, False) self._should_pause = False self._paused = True self.notify("paused") # this has to be done outside the mutex as it will start a blocking loop if self._pause_main_loop: self._pause_main_loop.run() try: gbytes: GLib.Bytes = inputstream.read_bytes_finish(result) except GLib.Error as e: self._error_message = e.message self._abort() return if gbytes.get_size() == 0: # EOF -> download complete logger.info(f"No bytes returned for {self._filename}") self._progress = 1.0 filesize_str = GLib.format_size(self._filesize) self._status_message = f"{filesize_str} of {filesize_str}" self.notify("progress") self._abort() return else: # write bytes to file self._outputstream.write_bytes_async( bytes=gbytes, io_priority=GLib.PRIORITY_DEFAULT, cancellable=self._cancellable, callback=self._write_bytes_async_cb, )
def _on_size_change(self, prop, param): self.set_property('text', GLib.format_size(self.size))
def sizeof_fmt(num): return GLib.format_size(num)
def _on_speed_change(self, prop, param): if self.speed: self.props.text = GLib.format_size(self.speed) + '/s' else: self.props.text = ''
def _show_changes(self): """Show a message and the dependencies in the dialog.""" self.treestore.clear() # Run parent method for apt if self.task.pkginfo.pkg_hash.startswith("a"): super(ChangesConfirmDialog, self)._show_changes() else: # flatpak self.set_title(_("Flatpaks")) if len(self.task.to_install) > 0: piter = self.treestore.append(None, ["<b>%s</b>" % _("Install")]) for ref in self.task.to_install: if self.task.pkginfo.refid == ref.format_ref(): continue self.treestore.append(piter, [ref.get_name()]) if len(self.task.to_remove) > 0: piter = self.treestore.append(None, ["<b>%s</b>" % _("Remove")]) for ref in self.task.to_remove: if self.task.pkginfo.refid == ref.format_ref(): continue self.treestore.append(piter, [ref.get_name()]) if len(self.task.to_update) > 0: piter = self.treestore.append(None, ["<b>%s</b>" % _("Upgrade")]) for ref in self.task.to_update: if self.task.pkginfo.refid == ref.format_ref(): continue self.treestore.append(piter, [ref.get_name()]) msg = _("Please take a look at the list of changes below.") if len(self.treestore) == 1: filtered_store = self.treestore.filter_new( Gtk.TreePath.new_first()) self.treeview.expand_all() self.treeview.set_model(filtered_store) self.treeview.set_show_expanders(False) if len(self.task.to_install) > 0: title = _("Additional software has to be installed") elif len(self.task.to_remove) > 0: title = _("Additional software has to be removed") elif len(self.task.to_update) > 0: title = _("Additional software has to be upgraded") if len(filtered_store) < 6: self.set_resizable(False) self.scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER) else: self.treeview.set_size_request(350, 200) else: title = _("Additional changes are required") self.treeview.set_size_request(350, 200) self.treeview.collapse_all() if self.task.download_size > 0: msg += "\n" msg += (_("%s will be downloaded in total.") % GLib.format_size(self.task.download_size)) if self.task.freed_size > 0: msg += "\n" msg += (_("%s of disk space will be freed.") % GLib.format_size(self.task.freed_size)) elif self.task.install_size > 0: msg += "\n" msg += (_("%s more disk space will be used.") % GLib.format_size(self.task.install_size)) self.label.set_markup("<b><big>%s</big></b>\n\n%s" % (title, msg))
def __init__(self, progress, time_left_sec, bytes_per_sec): self.progress = progress self.time_left_sec = time_left_sec self.bytes_per_sec = bytes_per_sec self.progress_text = _("%s (%s/s)") % (util.format_time_span( time_left_sec), GLib.format_size(bytes_per_sec))
def show_apps(config, split, excess, by, stream): '''Lists apps that will be installed for this image, with their installed (uncompressed) and download (compressed) sizes. If excess > 0, we also suggest which apps to remove to save that amount of space in the compressed image. We use the compressed download size according to Flatpak as an approximation for how the uncompressed app will affect the compressed size in the image. Args: config (ConfigParser): the image config split (bool): true to consider the split image configuration excess (int): bytes that need to be saved to fit within the size, or 0 if there's no size limit and you just want the list of apps by (str): 'nature' or 'runtime' stream (file): stream to which to write the lists ''' # Use a temporary repo in the image builder tmpdir where it will be # cleaned up later tmpdir = config['build']['tmpdir'] installation_path = os.path.join(tmpdir, 'applist') os.makedirs(installation_path, exist_ok=True) installation_file = Gio.File.new_for_path(installation_path) installation = Flatpak.Installation.new_for_path(installation_file, user=False) # Enumerate remotes and resolve all refs needed for installation manager = eibflatpak.FlatpakManager(installation, config) manager.add_remotes() manager.enumerate_remotes() manager.resolve_refs(split=split) # Make a simple list of FlatpakFullRefs sorted by descending # download size order, then by app name # TODO: .Locale extensions will appear to be enormous, but in fact their # size is normally much smaller due to being only partially installed. # TODO: sort later, after bundling extensions together with the app(s) that # use them. Without this com.endlessm.extra.pt_BR.Content (421 MB) sorts # below com.endlessm.math.pt (25.5 MB) because the app size (3.2 MB) is the # effective sort key ( refs = sorted([ install_ref.full_ref for install_ref in manager.install_refs.values() ], key=lambda ref: (-ref.download_size, ref.name)) total_installed = sum(ref.installed_size for ref in refs) total = sum(ref.download_size for ref in refs) excess_after_removals = excess verdicts = {} if excess > 0: for name in MUST_KEEP_APPS: verdicts[name] = 'No' # Remove any app which we're happy to sacrifice for ref in refs: if excess_after_removals <= 0: break if ref.name in verdicts: continue if (ref.name in PREFER_REMOVE_APPS or any( ref.name.startswith(prefix) for prefix in PREFER_REMOVE_NS)): verdicts[ref.name] = 'Yes' excess_after_removals -= ref.download_size # Propose removing the largest n apps until we're under budget. # TODO: prefer to remove generic apps? # TODO: some non-greedy algorithm that prefers to remove smaller apps # to minimize free excess_after_removals for ref in refs: if excess_after_removals <= 0: break if ref.name in verdicts: continue verdicts[ref.name] = 'Maybe' excess_after_removals -= ref.download_size stream.write('\n') stream.write('Estimated installed size of apps: {}\n'.format( GLib.format_size(total_installed))) stream.write('Estimated compressed size of apps: {}\n'.format( GLib.format_size(total))) if excess > 0: stream.write('Over budget: {}\n'.format(GLib.format_size(excess))) if excess_after_removals > 0: stream.write('Over budget after proposed removals: {}\n'.format( GLib.format_size(excess_after_removals))) else: stream.write('Free space after proposed removals: {}\n'.format( GLib.format_size(-excess_after_removals))) stream.write('\n') personality = config['build']['personality'] formatter = AppListFormatter(refs, personality, verdicts) formatter.write_by(by)(stream)
def _process_files(self, uri_list): self.current_send_request = request = TransferRequest() # These are the first-level base names (no path, just the filename) that we'll send to the server # to check for pre-existence. We know that if these files/folders don't exist, none of their children # will. This is a bit simple, but until we need more, it's fine. top_dir_basenames = [] # Recursive function for processing folders and their contents. def process_folder(folder_uri, top_dir): folder_file = Gio.File.new_for_uri(folder_uri) try: enumerator = folder_file.enumerate_children( FILE_INFOS, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, None) info = enumerator.next_file(None) except GLib.Error as e: raise NeverStartedSending(e.message) while info: child = enumerator.get_child(info) child_uri = child.get_uri() child_basename = child.get_basename() file_type = info.get_file_type() if file_type == Gio.FileType.DIRECTORY: if uri not in self.file_to_size_map.keys(): request.add_file(child_basename, child_uri, top_dir, info) process_folder(child_uri, top_dir) else: if child_uri not in self.file_to_size_map.keys(): size = info.get_size() request.add_file(child_basename, child_uri, top_dir, info) try: info = enumerator.next_file(None) except GLib.Error as e: raise NeverStartedSending(e.message) try: # Process the initial list. for uri in uri_list: file = Gio.File.new_for_uri(uri) top_dir_basenames.append(file.get_basename()) try: info = file.query_info(FILE_INFOS, Gio.FileQueryInfoFlags.NONE, None) except GLib.Error as e: raise NeverStartedSending(e.message) basename = file.get_basename() if info and info.get_file_type() == Gio.FileType.DIRECTORY: top_dir = file.get_parent().get_uri() if uri not in self.file_to_size_map.keys(): request.add_file(basename, uri, None, info) process_folder(uri, top_dir) continue else: size = info.get_size() if uri not in self.file_to_size_map.keys(): request.add_file(basename, uri, None, info) if request.transfer_count == 0: #what? exit() except NeverStartedSending as e: self._update_progress( util.ProgressCallbackInfo(transfer_cancelled=True, error=e)) exit() with self.proxy.lock: if self.proxy.prevent_overwriting() and self.proxy.files_exist( top_dir_basenames): self._update_progress( util.ProgressCallbackInfo(transfer_exists=True, count=request.transfer_count)) exit() permission = False with self.proxy.lock: need = self.proxy.permission_needed() if need: self._update_progress( util.ProgressCallbackInfo(sender_awaiting_approval=True, count=request.transfer_count)) request.stamp = GLib.get_monotonic_time() while True: with self.proxy.lock: response = self.proxy.get_permission( self.app_name, self.proxy_nick, str(request.transfer_size ), # XML RPC can't handle longs str(request.transfer_count), str(request.stamp)) if response == util.TRANSFER_REQUEST_PENDING: time.sleep(1) continue elif response == util.TRANSFER_REQUEST_CANCELLED: break elif response == util.TRANSFER_REQUEST_REFUSED: self._update_progress( util.ProgressCallbackInfo(transfer_refused=True)) break elif response == util.TRANSFER_REQUEST_DISKFULL: self._update_progress( util.ProgressCallbackInfo(transfer_diskfull=True, size=request.transfer_size)) break else: permission = response == util.TRANSFER_REQUEST_GRANTED break else: permission = True if permission: new_total = 0 self.file_to_size_map.update(request.transfer_file_to_size_map) for size in self.file_to_size_map.values(): new_total += size self.total_transfer_size = new_total self._update_progress( util.ProgressCallbackInfo(transfer_starting=True)) print("Starting send: %d files (%s)" % (request.transfer_count, GLib.format_size(request.transfer_size))) GLib.idle_add(self._queue_files, request, priority=GLib.PRIORITY_DEFAULT) else: self._update_progress( util.ProgressCallbackInfo(transfer_cancelled=True)) exit()