Daniel Brötzmann pushed to branch master at gajim / gajim
Commits: d065741d by wurstsalat at 2022-01-12T17:17:06+01:00 FileProps: Typing
- - - - - 1b52bb71 by wurstsalat at 2022-01-12T17:17:06+01:00 Tooltips: Typing
- - - - -
2 changed files:
- gajim/common/file_props.py - gajim/gtk/tooltips.py
Changes:
===================================== gajim/common/file_props.py ===================================== @@ -17,48 +17,54 @@ True """
-from typing import Any # pylint: disable=unused-import -from typing import ClassVar # pylint: disable=unused-import -from typing import Dict # pylint: disable=unused-import -from typing import Tuple # pylint: disable=unused-import +from __future__ import annotations + +from typing import Callable +from typing import Literal +from typing import Optional +from typing import ClassVar
class FilesProp: - _files_props = {} # type: ClassVar[Dict[Tuple[str, str], Any]] + _files_props: ClassVar[dict[tuple[str, str], FileProp]] = {}
def __init__(self): raise Exception('this class should not be instantiated')
@classmethod - def getNewFileProp(cls, account, sid): + def getNewFileProp(cls, account: str, sid: str) -> FileProp: fp = FileProp(account, sid) cls.setFileProp(fp, account, sid) return fp
@classmethod - def getFileProp(cls, account, sid): - return cls._files_props.get(account, sid) + def getFileProp(cls, account: str, sid: str) -> Optional[FileProp]: + return cls._files_props.get((account, sid))
@classmethod - def getFilePropByAccount(cls, account): + def getFilePropByAccount(cls, account: str) -> list[FileProp]: # Returns a list of file_props in one account - file_props = [] + file_props: list[FileProp] = [] for account_, sid in cls._files_props: if account_ == account: file_props.append(cls._files_props[account, sid]) return file_props
@classmethod - def getFilePropByType(cls, type_, sid): + def getFilePropByType(cls, + type_: Literal['r', 's'], + sid: str + ) -> Optional[FileProp]: # This method should be deleted. Getting fileprop by type and sid is not # unique enough. More than one fileprop might have the same type and sid files_prop = cls.getAllFileProp() for fp in files_prop: if fp.type_ == type_ and fp.sid == sid: return fp + return None
@classmethod - def getFilePropBySid(cls, sid): + def getFilePropBySid(cls, sid: str) -> Optional[FileProp]: # This method should be deleted. It is kept to make things compatible # This method should be replaced and instead get the file_props by # account and sid @@ -66,99 +72,98 @@ def getFilePropBySid(cls, sid): for fp in files_prop: if fp.sid == sid: return fp + return None
@classmethod - def getFilePropByTransportSid(cls, account, sid): + def getFilePropByTransportSid(cls, + account: str, + sid: str + ) -> Optional[FileProp]: files_prop = cls.getAllFileProp() for fp in files_prop: if fp.account == account and fp.transport_sid == sid: return fp + return None
@classmethod - def getAllFileProp(cls): + def getAllFileProp(cls) -> list[FileProp]: return list(cls._files_props.values())
@classmethod - def setFileProp(cls, fp, account, sid): + def setFileProp(cls, fp: FileProp, account: str, sid: str) -> None: cls._files_props[account, sid] = fp
@classmethod - def deleteFileProp(cls, file_prop): + def deleteFileProp(cls, file_prop: FileProp) -> None: files_props = cls._files_props - a = s = None + acc = sid_ = None for key in files_props: account, sid = key fp = files_props[account, sid] if fp is file_prop: - a = account - s = sid - if a is not None and s is not None: - del files_props[a, s] + acc = account + sid_ = sid + if acc is not None and sid_ is not None: + del files_props[acc, sid_]
class FileProp: - - def __init__(self, account, sid): - # Do not instantiate this class directly. Call FilesProp.getNeFileProp - # instead + def __init__(self, account: str, sid: str) -> None: + # Do not instantiate this class directly! + # Call FilesProp.getNeFileProp instead self.streamhosts = [] - self.transfered_size = [] - self.started = False - self.completed = False - self.paused = False - self.stalled = False - self.connected = False - self.stopped = False - self.is_a_proxy = False + self.transfered_size: list[int] = [] + self.started: bool = False + self.completed: bool = False + self.paused: bool = False + self.stalled: bool = False + self.connected: bool = False + self.stopped: bool = False + self.is_a_proxy: bool = False self.proxyhost = None self.proxy_sender = None self.proxy_receiver = None self.streamhost_used = None - # method callback called in case of transfer failure - self.failure_cb = None - # method callback called when disconnecting + self.failure_cb: Optional[Callable[[str], None]] = None self.disconnect_cb = None - self.continue_cb = None - self.sha_str = None + self.continue_cb: Optional[Callable[..., None]] = None + self.sha_str: Optional[str] = None # transfer type: 's' for sending and 'r' for receiving - self.type_ = None - self.error = None - # Elapsed time of the file transfer - self.elapsed_time = 0 - self.last_time = None - self.received_len = None - # full file path - self.file_name = None - self.name = None - self.date = None - self.desc = None - self.offset = None - self.sender = None - self.receiver = None - self.tt_account = None - self.size = None + self.type_: Optional[Literal['r', 's']] = None + self.error: Optional[int] = None + self.elapsed_time: float = 0 # Elapsed time of the file transfer + self.last_time: Optional[float] = None + self.received_len: Optional[int] = None + self.file_name: Optional[str] = None # full file path + self.name: Optional[str] = None + self.date: Optional[str] = None + self.desc: Optional[str] = None + self.offset: Optional[int] = None + self.sender: Optional[str] = None + self.receiver: Optional[str] = None + self.tt_account: Optional[str] = None + self.size: Optional[int] = None self._sid = sid - self.transport_sid = None + self.transport_sid: Optional[str] = None self.account = account - self.mime_type = None - self.algo = None - self.direction = None - self.syn_id = None - self.seq = None - self.hash_ = None - self.fd = None - self.startexmpp = None + self.mime_type: Optional[str] = None + self.algo: Optional[str] = None + self.direction: Optional[Literal['<', '>']] = None + self.syn_id: Optional[str] = None + self.seq: Optional[int] = None + self.hash_: Optional[str] = None + self.fd: Optional[int] = None # Type of the session, if it is 'jingle' or 'si' - self.session_type = None - self.request_id = None + self.session_type: Optional[str] = None + self.request_id: Optional[str] = None self.proxyhosts = None self.dstaddr = None
- def getsid(self): + def getsid(self) -> str: # Getter of the property sid return self._sid
- def setsid(self, value): + def setsid(self, value: str) -> None: # The sid value will change # we need to change the in _files_props key as well del FilesProp._files_props[self.account, self._sid]
===================================== gajim/gtk/tooltips.py ===================================== @@ -44,6 +44,7 @@ from gajim.common.const import PEPEventType from gajim.common.i18n import Q_ from gajim.common.i18n import _ +from gajim.common.file_props import FileProp
from .avatar import get_show_circle from .builder import get_builder @@ -120,7 +121,7 @@ def _populate_grid(self, contact: types.GroupchatParticipant) -> None: app.plugin_manager.gui_extension_point( 'gc_tooltip_populate', self, contact, self._ui.tooltip_grid)
- def destroy(self): + def destroy(self) -> None: self._ui.tooltip_grid.destroy()
@@ -262,7 +263,7 @@ def _append_pep_info(self, contact: types.BareContact) -> None: self._ui.location.show() self._ui.location_label.show()
- def destroy(self): + def destroy(self) -> None: self.clear_tooltip()
@@ -279,52 +280,54 @@ def clear_tooltip(self) -> None: self.sid = None self.widget = None
- def get_tooltip(self, file_props, sid) -> tuple[bool, Gtk.Widget]: + def get_tooltip(self, + file_prop: FileProp, + sid: str + ) -> tuple[bool, Gtk.Widget]: if self.sid == sid: + assert self.widget is not None return True, self.widget
- self.widget = self._create_tooltip(file_props, sid) + self.widget = self._create_tooltip(file_prop, sid) self.sid = sid return False, self.widget
- def _create_tooltip(self, file_props, _sid) -> None: - ft_grid = Gtk.Grid.new() + def _create_tooltip(self, file_prop: FileProp, _sid: str) -> Gtk.Grid: + ft_grid = Gtk.Grid(row_spacing=6, column_spacing=12) ft_grid.insert_column(0) - ft_grid.set_row_spacing(6) - ft_grid.set_column_spacing(12) current_row = 0 - properties = [] - name = file_props.name - if file_props.type_ == 'r': - file_name = os.path.split(file_props.file_name)[1] + properties: list[tuple[str, str]] = [] + name = file_prop.name + if file_prop.type_ == 'r': + file_name = os.path.split(file_prop.file_name)[1] else: - file_name = file_props.name + file_name = file_prop.name properties.append((_('File Name: '), GLib.markup_escape_text(file_name)))
- client = app.get_client(file_props.tt_account) - if file_props.type_ == 'r': + client = app.get_client(file_prop.tt_account) + if file_prop.type_ == 'r': type_ = Q_('?Noun:Download') actor = _('Sender: ') - sender = JID.from_string(file_props.sender) + sender = JID.from_string(file_prop.sender) name = client.get_module('Contacts').get_contact(sender.bare).name else: type_ = Q_('?Noun:Upload') actor = _('Recipient: ') - receiver = JID.from_string(file_props.receiver) + receiver = JID.from_string(file_prop.receiver) name = client.get_module('Contacts').get_contact( receiver.bare).name properties.append((Q_('?transfer type:Type: '), type_)) properties.append((actor, GLib.markup_escape_text(name)))
- transfered_len = file_props.received_len + transfered_len = file_prop.received_len if not transfered_len: transfered_len = 0 properties.append((Q_('?transfer status:Transferred: '), GLib.format_size_full(transfered_len, self.units))) - status = self._get_current_status(file_props) + status = self._get_current_status(file_prop) properties.append((Q_('?transfer status:Status: '), status)) - file_desc = file_props.desc or '' + file_desc = file_prop.desc or '' properties.append((_('Description: '), GLib.markup_escape_text(file_desc)))
@@ -347,19 +350,19 @@ def _create_tooltip(self, file_props, _sid) -> None: return ft_grid
@staticmethod - def _get_current_status(file_props) -> None: - if file_props.stopped: + def _get_current_status(file_prop: FileProp) -> str: + if file_prop.stopped: return Q_('?transfer status:Aborted') - if file_props.completed: + if file_prop.completed: return Q_('?transfer status:Completed') - if file_props.paused: + if file_prop.paused: return Q_('?transfer status:Paused') - if file_props.stalled: + if file_prop.stalled: # stalled is not paused. it is like 'frozen' it stopped alone return Q_('?transfer status:Stalled')
- if file_props.connected: - if file_props.started: + if file_prop.connected: + if file_prop.started: return Q_('?transfer status:Transferring') return Q_('?transfer status:Not started') return Q_('?transfer status:Not started')
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/ffa79c74a49b8d70fb71779849d63f6e...