# This file is part of Gajim. # # Gajim is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 3 only. # # Gajim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . import time from gi.repository import Gtk from gi.repository import GLib from gajim.common import app from gajim.common.i18n import _ from .util import get_builder from .util import EventHelper from .dialogs import ErrorDialog class FileTransferProgress(Gtk.ApplicationWindow, EventHelper): def __init__(self, transfer): Gtk.ApplicationWindow.__init__(self) EventHelper.__init__(self) self.set_name('FileTransferProgress') self.set_application(app.app) self.set_position(Gtk.WindowPosition.CENTER) self.set_show_menubar(False) self.set_title(_('File Transfer')) self._destroyed = False self._transfer = transfer self._transfer.connect('state-changed', self._on_transfer_state_change) self._transfer.connect('progress', self._on_transfer_progress) if app.settings.get('use_kib_mib'): self._units = GLib.FormatSizeFlags.IEC_UNITS else: self._units = GLib.FormatSizeFlags.DEFAULT self._start_time = time.time() self._ui = get_builder('filetransfer_progress.ui') self._ui.file_name_label.set_text(transfer.filename) self.add(self._ui.box) self._pulse = GLib.timeout_add(100, self._pulse_progressbar) self.show_all() self.connect('destroy', self._on_destroy) self._ui.connect_signals(self) def _on_transfer_state_change(self, transfer, _signal_name, state): if self._destroyed: return if state.is_error: ErrorDialog(_('Error'), transfer.error_text, transient_for=app.interface.roster.window) self.destroy() if state.is_finished or state.is_cancelled: self.destroy() return description = transfer.get_state_description() if description: self._ui.label.set_text(description) def _pulse_progressbar(self): self._ui.progressbar.pulse() return True def _on_cancel_button_clicked(self, _widget): self.destroy() def _on_destroy(self, *args): self._destroyed = True if self._transfer.state.is_active: self._transfer.cancel() self._transfer = None if self._pulse is not None: GLib.source_remove(self._pulse) def _on_transfer_progress(self, transfer, _signal_name): if self._destroyed: return if self._pulse is not None: GLib.source_remove(self._pulse) self._pulse = None time_now = time.time() bytes_sec = round(transfer.seen / (time_now - self._start_time), 1) size_progress = GLib.format_size_full(transfer.seen, self._units) size_total = GLib.format_size_full(transfer.size, self._units) speed = '%s/s' % GLib.format_size_full(bytes_sec, self._units) if bytes_sec == 0: eta = '∞' else: eta = self._format_eta( round((transfer.size - transfer.seen) / bytes_sec)) self._ui.progress_label.set_text( _('%(progress)s of %(total)s') % { 'progress': size_progress, 'total': size_total}) self._ui.speed_label.set_text(speed) self._ui.eta_label.set_text(eta) self._ui.progressbar.set_fraction(float(transfer.seen) / transfer.size) @staticmethod def _format_eta(time_): times = {'minutes': 0, 'seconds': 0} time_ = int(time_) times['seconds'] = time_ % 60 if time_ >= 60: time_ /= 60 times['minutes'] = round(time_ % 60) return _('%(minutes)s min %(seconds)s sec') % times