gajim3/gajim/gtk/filetransfer_progress.py

134 lines
4.2 KiB
Python

# 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 <http://www.gnu.org/licenses/>.
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