diff --git a/gajim/application.py b/gajim/application.py
index c46a39c05..7ab32c38b 100644
--- a/gajim/application.py
+++ b/gajim/application.py
@@ -273,7 +273,8 @@ class GajimApplication(Gtk.Application):
self.activate()
return 0
- def _handle_local_options(self, application,
+ def _handle_local_options(self,
+ application: Gtk.Application,
options: GLib.VariantDict) -> int:
# Parse all options that have to be executed before ::startup
if options.contains('profile'):
diff --git a/gajim/chat_control.py b/gajim/chat_control.py
index cd2b0419f..0687c6527 100644
--- a/gajim/chat_control.py
+++ b/gajim/chat_control.py
@@ -413,7 +413,7 @@ class ChatControl(ChatControlBase):
img = self._pep_images[pep_type]
if pep_type in pep:
img.set_from_pixbuf(gtkgui_helpers.get_pep_as_pixbuf(pep[pep_type]))
- img.set_tooltip_markup(pep[pep_type].asMarkupText())
+ img.set_tooltip_markup(pep[pep_type].as_markup_text())
img.show()
else:
img.hide()
diff --git a/gajim/command_system/dispatcher.py b/gajim/command_system/dispatcher.py
index ccdce57b5..11de2ea70 100644
--- a/gajim/command_system/dispatcher.py
+++ b/gajim/command_system/dispatcher.py
@@ -31,62 +31,77 @@ to automatic discovery and dispatching, also features manual control
over the process.
"""
+from typing import Any # pylint: disable=unused-import
+from typing import Dict # pylint: disable=unused-import
+
from gajim.command_system.tools import remove
-COMMANDS = {}
-CONTAINERS = {}
+COMMANDS = {} # type: Dict[Any, Any]
+CONTAINERS = {} # type: Dict[Any, Any]
+
def add_host(host):
CONTAINERS[host] = []
+
def remove_host(host):
remove(CONTAINERS, host)
+
def add_container(container):
for host in container.HOSTS:
CONTAINERS[host].append(container)
+
def remove_container(container):
for host in container.HOSTS:
remove(CONTAINERS[host], container)
+
def add_commands(container):
commands = COMMANDS.setdefault(container, {})
for command in traverse_commands(container):
for name in command.names:
commands[name] = command
+
def remove_commands(container):
remove(COMMANDS, container)
+
def traverse_commands(container):
for name in dir(container):
attribute = getattr(container, name)
if is_command(attribute):
yield attribute
+
def is_command(attribute):
from gajim.command_system.framework import Command
return isinstance(attribute, Command)
+
def is_root(namespace):
metaclass = namespace.get("__metaclass__", None)
if not metaclass:
return False
return issubclass(metaclass, Dispatchable)
+
def get_command(host, name):
for container in CONTAINERS[host]:
command = COMMANDS[container].get(name)
if command:
return command
+
def list_commands(host):
for container in CONTAINERS[host]:
commands = COMMANDS[container]
for name, command in commands.items():
yield name, command
+
class Dispatchable(type):
# pylint: disable=no-value-for-parameter
def __init__(self, name, bases, namespace):
@@ -99,6 +114,7 @@ class Dispatchable(type):
if self.AUTOMATIC:
self.enable()
+
class Host(Dispatchable):
def enable(self):
@@ -107,6 +123,7 @@ class Host(Dispatchable):
def disable(self):
remove_host(self)
+
class Container(Dispatchable):
def enable(self):
diff --git a/gajim/command_system/implementation/custom.py b/gajim/command_system/implementation/custom.py
index 5380c2699..6aace07dc 100644
--- a/gajim/command_system/implementation/custom.py
+++ b/gajim/command_system/implementation/custom.py
@@ -34,6 +34,7 @@ code in here will not be executed and commands defined here will not be
detected.
"""
+from gajim.common.i18n import _
from gajim.command_system.framework import CommandContainer, command, doc
from gajim.command_system.implementation.hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
diff --git a/gajim/command_system/implementation/execute.py b/gajim/command_system/implementation/execute.py
index 2766cbdbe..4e6eb9530 100644
--- a/gajim/command_system/implementation/execute.py
+++ b/gajim/command_system/implementation/execute.py
@@ -37,6 +37,7 @@ from os.path import expanduser
from gi.repository import GLib
+from gajim.common.i18n import _
from gajim.command_system.framework import CommandContainer, command, doc
from gajim.command_system.implementation.hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
diff --git a/gajim/command_system/implementation/standard.py b/gajim/command_system/implementation/standard.py
index 58f2fc997..89b3cf9e8 100644
--- a/gajim/command_system/implementation/standard.py
+++ b/gajim/command_system/implementation/standard.py
@@ -23,6 +23,7 @@ from datetime import date
from gajim import dialogs
from gajim.common import app
from gajim.common import helpers
+from gajim.common.i18n import _
from gajim.common.exceptions import GajimGeneralException
from gajim.common.const import KindConstant
diff --git a/gajim/common/app.py b/gajim/common/app.py
index 3541964e4..61562830d 100644
--- a/gajim/common/app.py
+++ b/gajim/common/app.py
@@ -42,7 +42,7 @@ from gajim.common.contacts import LegacyContactsAPI
from gajim.common.events import Events
from gajim.common.css_config import CSSConfig
-interface = None # The actual interface (the gtk one for the moment)
+interface = None # type: gajim.interface.Interface
thread_interface = lambda *args: None # Interface to run a thread and then a callback
config = c_config.Config()
version = gajim.__version__
@@ -52,10 +52,10 @@ ipython_window = None
app = None # Gtk.Application
ged = ged_module.GlobalEventsDispatcher() # Global Events Dispatcher
-nec = None # Network Events Controller
+nec = None # type: gajim.common.nec.NetworkEventsController
plugin_manager = None # Plugins Manager
-logger = None
+logger = None # type: gajim.common.logger.Logger
# For backwards compatibility needed
# some plugins use that
@@ -122,7 +122,7 @@ SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
ZEROCONF_ACC_NAME = 'Local'
# These will be set in app.gui_interface.
-idlequeue = None
+idlequeue = None # type: nbxmpp.idlequeue.IdleQueue
socks5queue = None
gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'}
diff --git a/gajim/common/config.py b/gajim/common/config.py
index 0d9138268..a9741a41c 100644
--- a/gajim/common/config.py
+++ b/gajim/common/config.py
@@ -32,6 +32,7 @@ from gi.repository import GLib
from enum import IntEnum, unique
import gajim
+from gajim.common.i18n import _
@unique
diff --git a/gajim/common/configpaths.py b/gajim/common/configpaths.py
index f3799b9a1..020e85244 100644
--- a/gajim/common/configpaths.py
+++ b/gajim/common/configpaths.py
@@ -19,82 +19,90 @@
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see .
+from typing import Dict # pylint: disable=unused-import
+from typing import List
+from typing import Generator
+from typing import Optional # pylint: disable=unused-import
+from typing import Tuple
+from typing import Union
+
import os
import sys
import tempfile
from pathlib import Path
import gajim
+from gajim.common.i18n import _
from gajim.common.const import PathType, PathLocation
+from gajim.common.types import PathTuple
-def get(key):
+def get(key: str) -> Union[str, List[str]]:
if key == 'PLUGINS_DIRS':
if gajim.IS_FLATPAK:
return ['/app/plugins',
_paths['PLUGINS_BASE']]
- else:
- return [_paths['PLUGINS_BASE'],
- _paths['PLUGINS_USER']]
+ return [_paths['PLUGINS_BASE'],
+ _paths['PLUGINS_USER']]
return _paths[key]
-def get_paths(type_):
+def get_paths(type_: PathType) -> Generator[str, None, None]:
for key, value in _paths.items():
- location, path, path_type = value
+ path_type = value[2]
if type_ != path_type:
continue
yield _paths[key]
def override_path(*args, **kwargs):
- _paths._add(*args, **kwargs)
+ _paths.add(*args, **kwargs)
-def set_separation(active: bool):
+def set_separation(active: bool) -> None:
_paths.profile_separation = active
-def set_profile(profile: str):
+def set_profile(profile: str) -> None:
_paths.profile = profile
-def set_config_root(config_root: str):
+def set_config_root(config_root: str) -> None:
_paths.custom_config_root = config_root
-def init():
+def init() -> None:
_paths.init()
-def create_paths():
+def create_paths() -> None:
for path in get_paths(PathType.FOLDER):
if not isinstance(path, Path):
- path = Path(path)
+ path_ = Path(path)
- if path.is_file():
- print(_('%s is a file but it should be a directory') % path)
+ if path_.is_file():
+ print(_('%s is a file but it should be a directory') % path_)
print(_('Gajim will now exit'))
sys.exit()
- if not path.exists():
- for parent_path in reversed(path.parents):
+ if not path_.exists():
+ for parent_path in reversed(path_.parents):
# Create all parent folders
# don't use mkdir(parent=True), as it ignores `mode`
# when creating the parents
if not parent_path.exists():
print(('creating %s directory') % parent_path)
parent_path.mkdir(mode=0o700)
- print(('creating %s directory') % path)
- path.mkdir(mode=0o700)
+ print(('creating %s directory') % path_)
+ path_.mkdir(mode=0o700)
class ConfigPaths:
- def __init__(self):
- self._paths = {}
+ def __init__(self) -> None:
+ self._paths = {} # type: Dict[str, PathTuple]
self.profile = ''
self.profile_separation = False
- self.custom_config_root = None
+ self.custom_config_root = None # type: Optional[str]
if os.name == 'nt':
try:
@@ -133,23 +141,23 @@ class ConfigPaths:
]
for path in source_paths:
- self._add(*path)
+ self.add(*path)
- def __getitem__(self, key):
+ def __getitem__(self, key: str) -> str:
location, path, _ = self._paths[key]
if location == PathLocation.CONFIG:
return os.path.join(self.config_root, path)
- elif location == PathLocation.CACHE:
+ if location == PathLocation.CACHE:
return os.path.join(self.cache_root, path)
- elif location == PathLocation.DATA:
+ if location == PathLocation.DATA:
return os.path.join(self.data_root, path)
return path
- def items(self):
+ def items(self) -> Generator[Tuple[str, PathTuple], None, None]:
for key, value in self._paths.items():
yield (key, value)
- def _prepare(self, path, unique):
+ def _prepare(self, path: str, unique: bool) -> str:
if os.name == 'nt':
path = path.capitalize()
if self.profile:
@@ -157,7 +165,12 @@ class ConfigPaths:
return '%s.%s' % (path, self.profile)
return path
- def _add(self, name, path, location=None, path_type=None, unique=False):
+ def add(self,
+ name: str,
+ path: str,
+ location: PathLocation = None,
+ path_type: PathType = None,
+ unique: bool = False) -> None:
if path and location is not None:
path = self._prepare(path, unique)
self._paths[name] = (location, path, path_type)
@@ -175,7 +188,7 @@ class ConfigPaths:
]
for path in user_dir_paths:
- self._add(*path)
+ self.add(*path)
# These paths are unique per profile
unique_profile_paths = [
@@ -191,7 +204,7 @@ class ConfigPaths:
]
for path in unique_profile_paths:
- self._add(*path, unique=True)
+ self.add(*path, unique=True)
# These paths are only unique per profile if the commandline arg
# `separate` is passed
@@ -219,7 +232,7 @@ class ConfigPaths:
]
for path in paths:
- self._add(*path)
+ self.add(*path)
_paths = ConfigPaths()
diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py
index 8b39da5a4..32373b8a4 100644
--- a/gajim/common/connection_handlers_events.py
+++ b/gajim/common/connection_handlers_events.py
@@ -176,7 +176,6 @@ class HelperEvent:
class IqErrorReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'iq-error-received'
- base_network_events = []
def generate(self):
self.get_id()
@@ -187,7 +186,6 @@ class IqErrorReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
class StreamReceivedEvent(nec.NetworkIncomingEvent):
name = 'stream-received'
- base_network_events = []
class StreamConflictReceivedEvent(nec.NetworkIncomingEvent):
name = 'stream-conflict-received'
@@ -321,7 +319,6 @@ PresenceHelperEvent):
class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent):
name = 'presence-received'
- base_network_events = []
def generate(self):
self.jid, self.resource = app.get_room_and_nick_from_fjid(self.fjid)
@@ -348,7 +345,6 @@ class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent):
class GcPresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'gc-presence-received'
- base_network_events = []
def generate(self):
self.ptype = self.presence_obj.ptype
@@ -436,15 +432,12 @@ class GcPresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
class OurShowEvent(nec.NetworkIncomingEvent):
name = 'our-show'
- base_network_events = []
class BeforeChangeShowEvent(nec.NetworkIncomingEvent):
name = 'before-change-show'
- base_network_events = []
class ChatstateReceivedEvent(nec.NetworkIncomingEvent):
name = 'chatstate-received'
- base_network_events = []
def generate(self):
self.stanza = self.msg_obj.stanza
@@ -456,7 +449,6 @@ class ChatstateReceivedEvent(nec.NetworkIncomingEvent):
class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
name = 'gc-message-received'
- base_network_events = []
def generate(self):
self.stanza = self.msg_obj.stanza
@@ -556,7 +548,6 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
class GcConfigChangedReceivedEvent(nec.NetworkIncomingEvent):
name = 'gc-config-changed-received'
- base_network_events = []
def generate(self):
self.conn = self.msg_event.conn
@@ -567,7 +558,6 @@ class GcConfigChangedReceivedEvent(nec.NetworkIncomingEvent):
class MessageSentEvent(nec.NetworkIncomingEvent):
name = 'message-sent'
- base_network_events = []
def generate(self):
if not self.automatic_message:
@@ -579,11 +569,9 @@ class MessageSentEvent(nec.NetworkIncomingEvent):
class MessageNotSentEvent(nec.NetworkIncomingEvent):
name = 'message-not-sent'
- base_network_events = []
class MessageErrorEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'message-error'
- base_network_events = []
def init(self):
self.zeroconf = False
@@ -600,11 +588,9 @@ class MessageErrorEvent(nec.NetworkIncomingEvent, HelperEvent):
class AnonymousAuthEvent(nec.NetworkIncomingEvent):
name = 'anonymous-auth'
- base_network_events = []
class JingleRequestReceivedEvent(nec.NetworkIncomingEvent):
name = 'jingle-request-received'
- base_network_events = []
def generate(self):
self.fjid = self.jingle_session.peerjid
@@ -614,7 +600,6 @@ class JingleRequestReceivedEvent(nec.NetworkIncomingEvent):
class JingleConnectedReceivedEvent(nec.NetworkIncomingEvent):
name = 'jingle-connected-received'
- base_network_events = []
def generate(self):
self.fjid = self.jingle_session.peerjid
@@ -624,7 +609,6 @@ class JingleConnectedReceivedEvent(nec.NetworkIncomingEvent):
class JingleDisconnectedReceivedEvent(nec.NetworkIncomingEvent):
name = 'jingle-disconnected-received'
- base_network_events = []
def generate(self):
self.fjid = self.jingle_session.peerjid
@@ -634,7 +618,6 @@ class JingleDisconnectedReceivedEvent(nec.NetworkIncomingEvent):
class JingleTransferCancelledEvent(nec.NetworkIncomingEvent):
name = 'jingleFT-cancelled-received'
- base_network_events = []
def generate(self):
self.fjid = self.jingle_session.peerjid
@@ -644,7 +627,6 @@ class JingleTransferCancelledEvent(nec.NetworkIncomingEvent):
class JingleErrorReceivedEvent(nec.NetworkIncomingEvent):
name = 'jingle-error-received'
- base_network_events = []
def generate(self):
self.fjid = self.jingle_session.peerjid
@@ -654,15 +636,12 @@ class JingleErrorReceivedEvent(nec.NetworkIncomingEvent):
class AccountCreatedEvent(nec.NetworkIncomingEvent):
name = 'account-created'
- base_network_events = []
class AccountNotCreatedEvent(nec.NetworkIncomingEvent):
name = 'account-not-created'
- base_network_events = []
class NewAccountConnectedEvent(nec.NetworkIncomingEvent):
name = 'new-account-connected'
- base_network_events = []
def generate(self):
try:
@@ -686,15 +665,12 @@ class NewAccountConnectedEvent(nec.NetworkIncomingEvent):
class NewAccountNotConnectedEvent(nec.NetworkIncomingEvent):
name = 'new-account-not-connected'
- base_network_events = []
class ConnectionTypeEvent(nec.NetworkIncomingEvent):
name = 'connection-type'
- base_network_events = []
class StanzaReceivedEvent(nec.NetworkIncomingEvent):
name = 'stanza-received'
- base_network_events = []
def init(self):
self.additional_data = {}
@@ -704,14 +680,12 @@ class StanzaReceivedEvent(nec.NetworkIncomingEvent):
class StanzaSentEvent(nec.NetworkIncomingEvent):
name = 'stanza-sent'
- base_network_events = []
def init(self):
self.additional_data = {}
class AgentRemovedEvent(nec.NetworkIncomingEvent):
name = 'agent-removed'
- base_network_events = []
def generate(self):
self.jid_list = []
@@ -722,7 +696,6 @@ class AgentRemovedEvent(nec.NetworkIncomingEvent):
class BadGPGPassphraseEvent(nec.NetworkIncomingEvent):
name = 'bad-gpg-passphrase'
- base_network_events = []
def generate(self):
self.account = self.conn.name
@@ -732,7 +705,6 @@ class BadGPGPassphraseEvent(nec.NetworkIncomingEvent):
class ConnectionLostEvent(nec.NetworkIncomingEvent):
name = 'connection-lost'
- base_network_events = []
def generate(self):
app.nec.push_incoming_event(OurShowEvent(None, conn=self.conn,
@@ -741,11 +713,9 @@ class ConnectionLostEvent(nec.NetworkIncomingEvent):
class GPGTrustKeyEvent(nec.NetworkIncomingEvent):
name = 'gpg-trust-key'
- base_network_events = []
class GPGPasswordRequiredEvent(nec.NetworkIncomingEvent):
name = 'gpg-password-required'
- base_network_events = []
def generate(self):
self.keyid = app.config.get_per('accounts', self.conn.name, 'keyid')
@@ -753,7 +723,6 @@ class GPGPasswordRequiredEvent(nec.NetworkIncomingEvent):
class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'pep-received'
- base_network_events = []
def generate(self):
if not self.stanza.getTag('event'):
@@ -778,72 +747,57 @@ class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
class PlainConnectionEvent(nec.NetworkIncomingEvent):
name = 'plain-connection'
- base_network_events = []
class InsecurePasswordEvent(nec.NetworkIncomingEvent):
name = 'insecure-password'
- base_network_events = []
class InsecureSSLConnectionEvent(nec.NetworkIncomingEvent):
name = 'insecure-ssl-connection'
- base_network_events = []
class SSLErrorEvent(nec.NetworkIncomingEvent):
name = 'ssl-error'
- base_network_events = []
class UniqueRoomIdSupportedEvent(nec.NetworkIncomingEvent):
name = 'unique-room-id-supported'
- base_network_events = []
class UniqueRoomIdNotSupportedEvent(nec.NetworkIncomingEvent):
name = 'unique-room-id-not-supported'
- base_network_events = []
class NonAnonymousServerErrorEvent(nec.NetworkIncomingEvent):
name = 'non-anonymous-server-error'
- base_network_events = []
class UpdateGCAvatarEvent(nec.NetworkIncomingEvent):
name = 'update-gc-avatar'
- base_network_events = []
def generate(self):
return True
class UpdateRosterAvatarEvent(nec.NetworkIncomingEvent):
name = 'update-roster-avatar'
- base_network_events = []
def generate(self):
return True
class UpdateRoomAvatarEvent(nec.NetworkIncomingEvent):
name = 'update-room-avatar'
- base_network_events = []
def generate(self):
return True
class ZeroconfNameConflictEvent(nec.NetworkIncomingEvent):
name = 'zeroconf-name-conflict'
- base_network_events = []
class PasswordRequiredEvent(nec.NetworkIncomingEvent):
name = 'password-required'
- base_network_events = []
class Oauth2CredentialsRequiredEvent(nec.NetworkIncomingEvent):
name = 'oauth2-credentials-required'
- base_network_events = []
class SignedInEvent(nec.NetworkIncomingEvent):
name = 'signed-in'
- base_network_events = []
class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'file-request-received'
- base_network_events = []
def init(self):
self.jingle_content = None
@@ -960,7 +914,6 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
class FileRequestErrorEvent(nec.NetworkIncomingEvent):
name = 'file-request-error'
- base_network_events = []
def generate(self):
self.jid = app.get_jid_without_resource(self.jid)
@@ -968,7 +921,6 @@ class FileRequestErrorEvent(nec.NetworkIncomingEvent):
class FileTransferCompletedEvent(nec.NetworkIncomingEvent):
name = 'file-transfer-completed'
- base_network_events = []
def generate(self):
jid = str(self.file_props.receiver)
@@ -977,7 +929,6 @@ class FileTransferCompletedEvent(nec.NetworkIncomingEvent):
class GatewayPromptReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'gateway-prompt-received'
- base_network_events = []
def generate(self):
self.get_jid_resource()
@@ -1251,7 +1202,6 @@ class NotificationEvent(nec.NetworkIncomingEvent):
class MessageOutgoingEvent(nec.NetworkOutgoingEvent):
name = 'message-outgoing'
- base_network_events = []
def init(self):
self.additional_data = {}
@@ -1297,21 +1247,18 @@ class MessageOutgoingEvent(nec.NetworkOutgoingEvent):
class StanzaMessageOutgoingEvent(nec.NetworkOutgoingEvent):
name='stanza-message-outgoing'
- base_network_events = []
def generate(self):
return True
class GcStanzaMessageOutgoingEvent(nec.NetworkOutgoingEvent):
name='gc-stanza-message-outgoing'
- base_network_events = []
def generate(self):
return True
class GcMessageOutgoingEvent(nec.NetworkOutgoingEvent):
name = 'gc-message-outgoing'
- base_network_events = []
def init(self):
self.additional_data = {}
@@ -1333,11 +1280,9 @@ class GcMessageOutgoingEvent(nec.NetworkOutgoingEvent):
class ClientCertPassphraseEvent(nec.NetworkIncomingEvent):
name = 'client-cert-passphrase'
- base_network_events = []
class InformationEvent(nec.NetworkIncomingEvent):
name = 'information'
- base_network_events = []
def init(self):
self.args = None
@@ -1355,7 +1300,6 @@ class InformationEvent(nec.NetworkIncomingEvent):
class StyleChanged(nec.NetworkIncomingEvent):
name = 'style-changed'
- base_network_events = []
def generate(self):
return True
diff --git a/gajim/common/const.py b/gajim/common/const.py
index 905743bec..20641381b 100644
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -1,6 +1,8 @@
from enum import IntEnum, Enum, unique
from collections import namedtuple
+from gajim.common.i18n import _
+
Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props')
Option.__new__.__defaults__ = (None,) * len(Option._fields)
@@ -168,13 +170,14 @@ class PEPHandlerType(IntEnum):
@unique
class PEPEventType(IntEnum):
- ACTIVITY = 0
- TUNE = 1
- MOOD = 2
- LOCATION = 3
- NICKNAME = 4
- AVATAR = 5
- ATOM = 6
+ ABSTRACT = 0
+ ACTIVITY = 1
+ TUNE = 2
+ MOOD = 3
+ LOCATION = 4
+ NICKNAME = 5
+ AVATAR = 6
+ ATOM = 7
ACTIVITIES = {
diff --git a/gajim/common/dbus_support.py b/gajim/common/dbus_support.py
index 1fe42871a..1f0e63ea0 100644
--- a/gajim/common/dbus_support.py
+++ b/gajim/common/dbus_support.py
@@ -25,6 +25,7 @@ import logging
from gajim.common import app
from gajim.common import exceptions
+from gajim.common.i18n import _
_GAJIM_ERROR_IFACE = 'org.gajim.dbus.Error'
diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py
index 9083f5fbf..d61277929 100644
--- a/gajim/common/helpers.py
+++ b/gajim/common/helpers.py
@@ -48,6 +48,7 @@ from string import Template
import nbxmpp
from gajim.common.i18n import Q_
+from gajim.common.i18n import _
from gajim.common.i18n import ngettext
from gajim.common import configpaths
diff --git a/gajim/common/i18n.py b/gajim/common/i18n.py
index 1ecd9c49e..f7e0bb59a 100644
--- a/gajim/common/i18n.py
+++ b/gajim/common/i18n.py
@@ -132,7 +132,7 @@ if os.name == 'nt':
_localedir = get_locale_dir()
if hasattr(locale, 'bindtextdomain'):
- locale.bindtextdomain(DOMAIN, _localedir)
+ locale.bindtextdomain(DOMAIN, _localedir) # type: ignore
gettext.textdomain(DOMAIN)
gettext.install(DOMAIN, _localedir)
@@ -142,7 +142,7 @@ try:
except OSError:
_ = gettext.gettext
-if gettext._translations:
- _translations = list(gettext._translations.values())[0]
+if gettext._translations: # type: ignore
+ _translations = list(gettext._translations.values())[0] # type: ignore
else:
_translations = gettext.NullTranslations()
diff --git a/gajim/common/modules/__init__.py b/gajim/common/modules/__init__.py
index 17beacd3b..89ad22af7 100644
--- a/gajim/common/modules/__init__.py
+++ b/gajim/common/modules/__init__.py
@@ -12,14 +12,18 @@
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see .
+from typing import Any
+from typing import Dict # pylint: disable=unused-import
+from typing import List
+from typing import Tuple
+
import logging
-from typing import List # noqa
-from typing import Dict # noqa
-from typing import Any # noqa
from importlib import import_module
from pathlib import Path
from unittest.mock import MagicMock
+from gajim.common.types import ConnectionT
+
log = logging.getLogger('gajim.c.m')
ZEROCONF_MODULES = ['adhoc_commands', 'receipts', 'discovery']
@@ -70,7 +74,7 @@ class ModuleMock:
return MagicMock()
-def register(con, *args, **kwargs):
+def register(con: ConnectionT, *args: Any, **kwargs: Any) -> None:
if con in _modules:
return
_modules[con.name] = {}
@@ -83,20 +87,20 @@ def register(con, *args, **kwargs):
_modules[con.name][name] = instance
-def register_single(con, instance, name):
+def register_single(con: ConnectionT, instance: Any, name: str) -> None:
if con.name not in _modules:
raise ValueError('Unknown account name: %s' % con.name)
_modules[con.name][name] = instance
-def unregister(con):
+def unregister(con: ConnectionT) -> None:
for instance in _modules[con.name].values():
if hasattr(instance, 'cleanup'):
instance.cleanup()
del _modules[con.name]
-def unregister_single(con, name):
+def unregister_single(con: ConnectionT, name: str) -> None:
if con.name not in _modules:
return
if name not in _modules[con.name]:
@@ -111,8 +115,8 @@ def get(account: str, name: str) -> Any:
return ModuleMock(name)
-def get_handlers(con):
- handlers = []
+def get_handlers(con: ConnectionT) -> List[Tuple[Any, ...]]:
+ handlers = [] # type: List[Tuple[Any, ...]]
for module in _modules[con.name].values():
handlers += module.handlers
return handlers
diff --git a/gajim/common/modules/annotations.py b/gajim/common/modules/annotations.py
index 8bf96df10..4eb8ed7e7 100644
--- a/gajim/common/modules/annotations.py
+++ b/gajim/common/modules/annotations.py
@@ -14,24 +14,30 @@
# XEP-0145: Annotations
+from typing import Any
+from typing import Dict # pylint: disable=unused-import
+from typing import List # pylint: disable=unused-import
+from typing import Tuple
+
import logging
import nbxmpp
from gajim.common import app
from gajim.common import helpers
+from gajim.common.types import ConnectionT
log = logging.getLogger('gajim.c.m.annotations')
class Annotations:
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
self._con = con
self._account = con.name
self._server = self._con.get_own_jid().getDomain()
- self.handlers = []
- self.annotations = {}
+ self.handlers = [] # type: List[Tuple[Any, ...]]
+ self.annotations = {} # type: Dict[str, str]
def get_annotations(self) -> None:
if not app.account_is_connected(self._account):
@@ -93,5 +99,5 @@ class Annotations:
log.info('Storing rosternotes successful')
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[Annotations, str]:
return Annotations(*args, **kwargs), 'Annotations'
diff --git a/gajim/common/modules/pep.py b/gajim/common/modules/pep.py
index 4434cba9a..f0cb83baf 100644
--- a/gajim/common/modules/pep.py
+++ b/gajim/common/modules/pep.py
@@ -14,6 +14,11 @@
# XEP-0163: Personal Eventing Protocol
+from typing import Any
+from typing import Dict
+from typing import List
+from typing import Tuple
+
import logging
import nbxmpp
@@ -22,12 +27,16 @@ from gajim.common import app
from gajim.common.exceptions import StanzaMalformed
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.const import PEPHandlerType, PEPEventType
+from gajim.common.types import ConnectionT
+from gajim.common.types import PEPHandlersDict # pylint: disable=unused-import
+from gajim.common.types import PEPNotifyCallback
+from gajim.common.types import PEPRetractCallback
log = logging.getLogger('gajim.c.m.pep')
class PEP:
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
self._con = con
self._account = con.name
@@ -37,29 +46,40 @@ class PEP:
]
self.supported = False
- self._pep_handlers = {}
- self._store_publish_modules = []
+ self._pep_handlers = {} # type: PEPHandlersDict
+ self._store_publish_modules = [] # type: List[Any]
- def pass_disco(self, from_, identities, _features, _data, _node):
+ def pass_disco(self,
+ from_: nbxmpp.JID,
+ identities: List[Dict[str, str]],
+ _features: List[str],
+ _data: List[nbxmpp.DataForm],
+ _node: str) -> None:
for identity in identities:
if identity['category'] == 'pubsub':
if identity.get('type') == 'pep':
log.info('Discovered PEP support: %s', from_)
self.supported = True
- def register_pep_handler(self, namespace, notify_handler, retract_handler):
+ def register_pep_handler(
+ self,
+ namespace: str,
+ notify_handler: PEPNotifyCallback,
+ retract_handler: PEPRetractCallback) -> None:
if namespace in self._pep_handlers:
self._pep_handlers[namespace].append(
(notify_handler, retract_handler))
else:
self._pep_handlers[namespace] = [(notify_handler, retract_handler)]
if notify_handler:
- module_instance = notify_handler.__self__
+ module_instance = notify_handler.__self__ # type: ignore
if module_instance.store_publish:
if module_instance not in self._store_publish_modules:
self._store_publish_modules.append(module_instance)
- def _pep_event_received(self, _con, stanza):
+ def _pep_event_received(self,
+ _con: ConnectionT,
+ stanza: nbxmpp.Message) -> None:
jid = stanza.getFrom()
event = stanza.getTag('event', namespace=nbxmpp.NS_PUBSUB_EVENT)
items = event.getTag('items')
@@ -98,17 +118,47 @@ class PEP:
handler[PEPHandlerType.NOTIFY](jid, items_[0])
raise nbxmpp.NodeProcessed
- def send_stored_publish(self):
+ def send_stored_publish(self) -> None:
for module in self._store_publish_modules:
module.send_stored_publish()
- def reset_stored_publish(self):
+ def reset_stored_publish(self) -> None:
for module in self._store_publish_modules:
module.reset_stored_publish()
+class AbstractPEPData:
+
+ type_ = PEPEventType.ABSTRACT
+
+ def __init__(self, data: Any) -> None:
+ self.data = data
+
+ def as_markup_text(self) -> str: # pylint: disable=no-self-use
+ '''SHOULD be implemented by subclasses'''
+ return ''
+
+ def __eq__(self, other: Any) -> bool:
+ return other == self.type_
+
+ def __bool__(self) -> bool:
+ return self.data is not None
+
+ def __str__(self) -> str:
+ return str(self.data)
+
+
class AbstractPEPModule:
- def __init__(self, con, account):
+
+ name = ''
+ namespace = ''
+ pep_class = AbstractPEPData
+ store_publish = True
+ _log = log
+
+ def __init__(self,
+ con: ConnectionT,
+ account: str) -> None:
self._account = account
self._con = con
@@ -119,7 +169,7 @@ class AbstractPEPModule:
self._pep_notify_received,
self._pep_retract_received)
- def _pep_notify_received(self, jid, item):
+ def _pep_notify_received(self, jid: nbxmpp.JID, item: nbxmpp.Node) -> None:
try:
data = self._extract_info(item)
except StanzaMalformed as error:
@@ -129,19 +179,19 @@ class AbstractPEPModule:
self._log.info('Received: %s %s', jid, data)
self._push_event(jid, self.pep_class(data))
- def _pep_retract_received(self, jid, id_):
+ def _pep_retract_received(self, jid: nbxmpp.JID, id_: str) -> None:
self._log.info('Retract: %s %s', jid, id_)
self._push_event(jid, self.pep_class(None))
- def _extract_info(self, item):
+ def _extract_info(self, item: nbxmpp.Node) -> Any:
'''To be implemented by subclasses'''
raise NotImplementedError
- def _build_node(self, data):
+ def _build_node(self, data: Any) -> nbxmpp.Node:
'''To be implemented by subclasses'''
raise NotImplementedError
- def _push_event(self, jid, user_pep):
+ def _push_event(self, jid: nbxmpp.JID, user_pep: Any) -> None:
self._notification_received(jid, user_pep)
app.nec.push_incoming_event(
PEPReceivedEvent(None, conn=self._con,
@@ -149,7 +199,7 @@ class AbstractPEPModule:
pep_type=self.name,
user_pep=user_pep))
- def _notification_received(self, jid, user_pep):
+ def _notification_received(self, jid: nbxmpp.JID, user_pep: Any) -> None:
for contact in app.contacts.get_contacts(self._account, str(jid)):
if user_pep:
contact.pep[self.name] = user_pep
@@ -162,17 +212,17 @@ class AbstractPEPModule:
else:
self._con.pep.pop(self.name, None)
- def send_stored_publish(self):
+ def send_stored_publish(self) -> None:
if self._stored_publish is not None:
self._log.info('Send stored publish')
self.send(self._stored_publish)
self._stored_publish = None
- def reset_stored_publish(self):
+ def reset_stored_publish(self) -> None:
self._log.info('Reset stored publish')
self._stored_publish = None
- def send(self, data):
+ def send(self, data: Any) -> None:
if not self._con.get_module('PEP').supported:
return
@@ -191,7 +241,7 @@ class AbstractPEPModule:
self._con.get_module('PubSub').send_pb_publish(
'', self.namespace, item, 'current')
- def retract(self):
+ def retract(self) -> None:
if not self._con.get_module('PEP').supported:
return
self.send(None)
@@ -199,27 +249,9 @@ class AbstractPEPModule:
'', self.namespace, 'current')
-class AbstractPEPData:
-
- type_ = PEPEventType
-
- def asMarkupText(self):
- '''SHOULD be implemented by subclasses'''
- return ''
-
- def __eq__(self, other):
- return other == self.type_
-
- def __bool__(self):
- return self.data is not None
-
- def __str__(self):
- return str(self.data)
-
-
class PEPReceivedEvent(NetworkIncomingEvent):
name = 'pep-received'
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[PEP, str]:
return PEP(*args, **kwargs), 'PEP'
diff --git a/gajim/common/modules/ping.py b/gajim/common/modules/ping.py
index 907d1d23b..0b7f7dc77 100644
--- a/gajim/common/modules/ping.py
+++ b/gajim/common/modules/ping.py
@@ -14,6 +14,9 @@
# XEP-0199: XMPP Ping
+from typing import Any
+from typing import Tuple
+
import logging
import time
@@ -21,12 +24,14 @@ import nbxmpp
from gajim.common import app
from gajim.common.nec import NetworkIncomingEvent
+from gajim.common.types import ConnectionT
+from gajim.common.types import ContactT
log = logging.getLogger('gajim.c.m.ping')
class Ping:
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
self._con = con
self._account = con.name
self._alarm_time = None
@@ -68,7 +73,7 @@ class Ping:
log.warning('No reply received for keepalive ping. Reconnecting...')
self._con.disconnectedReconnCB()
- def send_ping(self, contact):
+ def send_ping(self, contact: ContactT) -> None:
if not app.account_is_connected(self._account):
return
@@ -84,7 +89,11 @@ class Ping:
app.nec.push_incoming_event(
PingSentEvent(None, conn=self._con, contact=contact))
- def _pong_received(self, _con, stanza, ping_time, contact):
+ def _pong_received(self,
+ _con: ConnectionT,
+ stanza: nbxmpp.Iq,
+ ping_time: int,
+ contact: ContactT) -> None:
if not nbxmpp.isResultNode(stanza):
log.info('Error: %s', stanza.getError())
app.nec.push_incoming_event(
@@ -98,7 +107,9 @@ class Ping:
contact=contact,
seconds=diff))
- def _answer_request(self, _con, stanza):
+ def _answer_request(self,
+ _con: ConnectionT,
+ stanza: nbxmpp.Iq) -> None:
iq = stanza.buildReply('result')
ping = iq.getTag('ping')
if ping is not None:
@@ -120,5 +131,5 @@ class PingErrorEvent(NetworkIncomingEvent):
name = 'ping-error'
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[Ping, str]:
return Ping(*args, **kwargs), 'Ping'
diff --git a/gajim/common/modules/user_activity.py b/gajim/common/modules/user_activity.py
index 699cc96a4..8597a4ef6 100644
--- a/gajim/common/modules/user_activity.py
+++ b/gajim/common/modules/user_activity.py
@@ -33,7 +33,7 @@ class UserActivityData(AbstractPEPData):
def __init__(self, activity):
self.data = activity
- def asMarkupText(self):
+ def as_markup_text(self):
pep = self.data
activity = pep['activity']
subactivity = pep['subactivity'] if 'subactivity' in pep else None
diff --git a/gajim/common/modules/user_location.py b/gajim/common/modules/user_location.py
index 0429e8a7d..b55d1ac15 100644
--- a/gajim/common/modules/user_location.py
+++ b/gajim/common/modules/user_location.py
@@ -35,7 +35,7 @@ class UserLocationData(AbstractPEPData):
self._pep_specific_data = location
self.data = location
- def asMarkupText(self):
+ def as_markup_text(self):
location = self.data
location_string = ''
diff --git a/gajim/common/modules/user_mood.py b/gajim/common/modules/user_mood.py
index f687e7bea..07b1d64a2 100644
--- a/gajim/common/modules/user_mood.py
+++ b/gajim/common/modules/user_mood.py
@@ -14,6 +14,12 @@
# XEP-0107: User Mood
+from typing import Any
+from typing import Dict
+from typing import List # pylint: disable=unused-import
+from typing import Optional
+from typing import Tuple
+
import logging
import nbxmpp
@@ -22,6 +28,7 @@ from gi.repository import GLib
from gajim.common.const import PEPEventType, MOODS
from gajim.common.exceptions import StanzaMalformed
from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+from gajim.common.types import ConnectionT
log = logging.getLogger('gajim.c.m.user_mood')
@@ -30,10 +37,12 @@ class UserMoodData(AbstractPEPData):
type_ = PEPEventType.MOOD
- def __init__(self, mood):
+ def __init__(self, mood: Optional[Dict[str, str]]) -> None:
self.data = mood
- def asMarkupText(self):
+ def as_markup_text(self) -> str:
+ if self.data is None:
+ return ''
mood = self._translate_mood(self.data['mood'])
markuptext = '%s' % GLib.markup_escape_text(mood)
if 'text' in self.data:
@@ -42,7 +51,7 @@ class UserMoodData(AbstractPEPData):
return markuptext
@staticmethod
- def _translate_mood(mood):
+ def _translate_mood(mood: str) -> str:
if mood in MOODS:
return MOODS[mood]
return mood
@@ -56,12 +65,12 @@ class UserMood(AbstractPEPModule):
store_publish = True
_log = log
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
AbstractPEPModule.__init__(self, con, con.name)
- self.handlers = []
+ self.handlers = [] # type: List[Tuple[Any, ...]]
- def _extract_info(self, item):
+ def _extract_info(self, item: nbxmpp.Node) -> Optional[Dict[str, str]]:
mood_dict = {}
mood_tag = item.getTag('mood', namespace=nbxmpp.NS_MOOD)
if mood_tag is None:
@@ -76,7 +85,7 @@ class UserMood(AbstractPEPModule):
return mood_dict or None
- def _build_node(self, data):
+ def _build_node(self, data: Optional[Tuple[str, str]]) -> nbxmpp.Node:
item = nbxmpp.Node('mood', {'xmlns': nbxmpp.NS_MOOD})
if data is None:
return
@@ -88,5 +97,5 @@ class UserMood(AbstractPEPModule):
return item
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[UserMood, str]:
return UserMood(*args, **kwargs), 'UserMood'
diff --git a/gajim/common/modules/user_nickname.py b/gajim/common/modules/user_nickname.py
index 986bc074e..48ca8da3e 100644
--- a/gajim/common/modules/user_nickname.py
+++ b/gajim/common/modules/user_nickname.py
@@ -14,6 +14,11 @@
# XEP-0172: User Nickname
+from typing import Any
+from typing import List # pylint: disable=unused-import
+from typing import Optional
+from typing import Tuple
+
import logging
import nbxmpp
@@ -22,6 +27,7 @@ from gajim.common import app
from gajim.common.const import PEPEventType
from gajim.common.exceptions import StanzaMalformed
from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+from gajim.common.types import ConnectionT
log = logging.getLogger('gajim.c.m.user_nickname')
@@ -30,10 +36,10 @@ class UserNicknameData(AbstractPEPData):
type_ = PEPEventType.NICKNAME
- def __init__(self, nickname):
+ def __init__(self, nickname: Optional[str]) -> None:
self.data = nickname
- def get_nick(self):
+ def get_nick(self) -> str:
return self.data or ''
@@ -45,12 +51,12 @@ class UserNickname(AbstractPEPModule):
store_publish = True
_log = log
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
AbstractPEPModule.__init__(self, con, con.name)
- self.handlers = []
+ self.handlers = [] # type: List[Tuple[Any, ...]]
- def _extract_info(self, item):
+ def _extract_info(self, item: nbxmpp.Node) -> Optional[str]:
nick = ''
child = item.getTag('nick', namespace=nbxmpp.NS_NICK)
if child is None:
@@ -59,14 +65,16 @@ class UserNickname(AbstractPEPModule):
return nick or None
- def _build_node(self, data):
+ def _build_node(self, data: Optional[str]) -> Optional[nbxmpp.Node]:
item = nbxmpp.Node('nick', {'xmlns': nbxmpp.NS_NICK})
if data is None:
- return
+ return None
item.addData(data)
return item
- def _notification_received(self, jid, user_pep):
+ def _notification_received(self,
+ jid: nbxmpp.JID,
+ user_pep: UserNicknameData) -> None:
for contact in app.contacts.get_contacts(self._account, str(jid)):
contact.contact_name = user_pep.get_nick()
@@ -78,12 +86,12 @@ class UserNickname(AbstractPEPModule):
'accounts', self._account, 'name')
-def parse_nickname(stanza):
+def parse_nickname(stanza: nbxmpp.Node) -> str:
nick = stanza.getTag('nick', namespace=nbxmpp.NS_NICK)
if nick is None:
return ''
return nick.getData()
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[UserNickname, str]:
return UserNickname(*args, **kwargs), 'UserNickname'
diff --git a/gajim/common/modules/user_tune.py b/gajim/common/modules/user_tune.py
index cf0cfd983..55160c7f9 100644
--- a/gajim/common/modules/user_tune.py
+++ b/gajim/common/modules/user_tune.py
@@ -14,14 +14,23 @@
# XEP-0118: User Tune
+from typing import Any
+from typing import List # pylint: disable=unused-import
+from typing import Dict
+from typing import Optional
+from typing import Tuple
+
import logging
import nbxmpp
from gi.repository import GLib
+from gajim.common.i18n import _
from gajim.common.const import PEPEventType
from gajim.common.exceptions import StanzaMalformed
from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+from gajim.common.types import ConnectionT
+from gajim.common.types import UserTuneDataT
log = logging.getLogger('gajim.c.m.user_tune')
@@ -30,10 +39,13 @@ class UserTuneData(AbstractPEPData):
type_ = PEPEventType.TUNE
- def __init__(self, tune):
+ def __init__(self, tune: Optional[Dict[str, str]]) -> None:
self.data = tune
- def asMarkupText(self):
+ def as_markup_text(self) -> str:
+ if self.data is None:
+ return ''
+
tune = self.data
artist = tune.get('artist', _('Unknown Artist'))
@@ -60,12 +72,12 @@ class UserTune(AbstractPEPModule):
store_publish = True
_log = log
- def __init__(self, con):
+ def __init__(self, con: ConnectionT) -> None:
AbstractPEPModule.__init__(self, con, con.name)
- self.handlers = []
+ self.handlers = [] # type: List[Tuple[Any, ...]]
- def _extract_info(self, item):
+ def _extract_info(self, item: nbxmpp.Node) -> Optional[Dict[str, str]]:
tune_dict = {}
tune_tag = item.getTag('tune', namespace=self.namespace)
if tune_tag is None:
@@ -80,7 +92,7 @@ class UserTune(AbstractPEPModule):
return tune_dict or None
- def _build_node(self, data):
+ def _build_node(self, data: UserTuneDataT) -> nbxmpp.Node:
item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
if data is None:
return item
@@ -98,5 +110,5 @@ class UserTune(AbstractPEPModule):
return item
-def get_instance(*args, **kwargs):
+def get_instance(*args: Any, **kwargs: Any) -> Tuple[UserTune, str]:
return UserTune(*args, **kwargs), 'UserTune'
diff --git a/gajim/common/nec.py b/gajim/common/nec.py
index feeea5777..1f7351f26 100644
--- a/gajim/common/nec.py
+++ b/gajim/common/nec.py
@@ -22,11 +22,12 @@ Network Events Controller.
:license: GPL
'''
-#from plugins.helpers import log
+from typing import List # pylint: disable=unused-import
+
from gajim.common import app
-class NetworkEventsController(object):
+class NetworkEventsController:
def __init__(self):
self.incoming_events_generators = {}
'''
@@ -45,7 +46,7 @@ class NetworkEventsController(object):
for base_event_name in event_class.base_network_events:
event_list = self.incoming_events_generators.setdefault(
base_event_name, [])
- if not event_class in event_list:
+ if event_class not in event_list:
event_list.append(event_class)
def unregister_incoming_event(self, event_class):
@@ -58,7 +59,7 @@ class NetworkEventsController(object):
for base_event_name in event_class.base_network_events:
event_list = self.outgoing_events_generators.setdefault(
base_event_name, [])
- if not event_class in event_list:
+ if event_class not in event_list:
event_list.append(event_class)
def unregister_outgoing_event(self, event_class):
@@ -89,12 +90,12 @@ class NetworkEventsController(object):
base_event_name = event_object.name
if base_event_name in self.incoming_events_generators:
for new_event_class in self.incoming_events_generators[
- base_event_name]:
- new_event_object = new_event_class(None,
- base_event=event_object)
+ base_event_name]:
+ new_event_object = new_event_class(
+ None, base_event=event_object)
if new_event_object.generate():
if not app.ged.raise_event(new_event_object.name,
- new_event_object):
+ new_event_object):
self._generate_events_based_on_incoming_event(
new_event_object)
@@ -110,16 +111,17 @@ class NetworkEventsController(object):
base_event_name = event_object.name
if base_event_name in self.outgoing_events_generators:
for new_event_class in self.outgoing_events_generators[
- base_event_name]:
- new_event_object = new_event_class(None,
- base_event=event_object)
+ base_event_name]:
+ new_event_object = new_event_class(
+ None, base_event=event_object)
if new_event_object.generate():
if not app.ged.raise_event(new_event_object.name,
- new_event_object):
+ new_event_object):
self._generate_events_based_on_outgoing_event(
new_event_object)
-class NetworkEvent(object):
+
+class NetworkEvent:
name = ''
def __init__(self, new_name, **kwargs):
@@ -133,14 +135,14 @@ class NetworkEvent(object):
def init(self):
pass
-
def generate(self):
'''
Generates new event (sets it's attributes) based on event object.
Base event object name is one of those in `base_network_events`.
- Reference to base event object is stored in `self.base_event` attribute.
+ Reference to base event object is stored in `self.base_event`
+ attribute.
Note that this is a reference, so modifications to that event object
are possible before dispatching to Global Events Dispatcher.
@@ -159,15 +161,16 @@ class NetworkEvent(object):
if k not in ('name', 'base_network_events'):
setattr(self, k, v)
+
class NetworkIncomingEvent(NetworkEvent):
- base_network_events = []
+ base_network_events = [] # type: List[str]
'''
Names of base network events that new event is going to be generated on.
'''
class NetworkOutgoingEvent(NetworkEvent):
- base_network_events = []
+ base_network_events = [] # type: List[str]
'''
Names of base network events that new event is going to be generated on.
'''
diff --git a/gajim/common/pep.py b/gajim/common/pep.py
index 9d477e06a..a9d6cc785 100644
--- a/gajim/common/pep.py
+++ b/gajim/common/pep.py
@@ -67,7 +67,7 @@ class AbstractPEP(object):
else:
acc.pep[self.type_] = self
- def asMarkupText(self):
+ def as_markup_text(self):
'''SHOULD be implemented by subclasses'''
return ''
diff --git a/gajim/common/types.py b/gajim/common/types.py
new file mode 100644
index 000000000..408859cb0
--- /dev/null
+++ b/gajim/common/types.py
@@ -0,0 +1,47 @@
+# 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 .
+
+# Types for typechecking
+
+from typing import Callable
+from typing import Dict
+from typing import List
+from typing import Optional
+from typing import Tuple
+from typing import Union
+from typing import TYPE_CHECKING
+
+import nbxmpp
+
+from gajim.common.const import PathType, PathLocation
+
+if TYPE_CHECKING:
+ # pylint: disable=unused-import
+ from gajim.common.connection import Connection
+ from gajim.common.zeroconf.connection_zeroconf import ConnectionZeroconf
+ from gajim.common.contacts import Contact
+ from gajim.common.contacts import GC_Contact
+
+ConnectionT = Union['Connection', 'ConnectionZeroconf']
+ContactT = Union['Contact', 'GC_Contact']
+
+UserTuneDataT = Optional[Tuple[str, str, str, str, str]]
+
+# PEP
+PEPNotifyCallback = Callable[[nbxmpp.JID, nbxmpp.Node], None]
+PEPRetractCallback = Callable[[nbxmpp.JID, str], None]
+PEPHandlersDict = Dict[str, List[Tuple[PEPNotifyCallback, PEPRetractCallback]]]
+
+# Configpaths
+PathTuple = Tuple[Optional[PathLocation], str, Optional[PathType]]
diff --git a/gajim/dialog_messages.py b/gajim/dialog_messages.py
index b72bc251f..51951f95f 100644
--- a/gajim/dialog_messages.py
+++ b/gajim/dialog_messages.py
@@ -20,6 +20,7 @@ from collections import namedtuple
from gi.repository import GLib
from gajim.common.app import app
+from gajim.common.i18n import _
from gajim.gtk import ErrorDialog
from gajim.gtk import InformationDialog
diff --git a/gajim/dialogs.py b/gajim/dialogs.py
index 4b162260d..cb2a1b534 100644
--- a/gajim/dialogs.py
+++ b/gajim/dialogs.py
@@ -38,6 +38,7 @@ from gajim import dataforms_widget
from random import randrange
from gajim.common import ged
+from gajim.common.i18n import _
from gajim.common.const import ACTIVITIES
from gajim.common.const import MOODS
diff --git a/gajim/disco.py b/gajim/disco.py
index bab4fbdb5..60b27d474 100644
--- a/gajim/disco.py
+++ b/gajim/disco.py
@@ -42,11 +42,12 @@
import types
import weakref
+
+import nbxmpp
from gi.repository import GLib
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf
-from gi.repository import Pango
from gajim.gtk import ErrorDialog
from gajim.gtk import InformationDialog
@@ -54,13 +55,11 @@ from gajim import gtkgui_helpers
from gajim import groups
from gajim import adhoc_commands
from gajim import search_window
-from gajim import gui_menu_builder
from gajim.gtk import ServiceRegistration
from gajim.common import app
-import nbxmpp
+from gajim.common.i18n import _
from gajim.common import helpers
-from gajim.common import ged
from gajim.common.const import StyleAttr
LABELS = {
diff --git a/gajim/gajim_remote.py b/gajim/gajim_remote.py
index bc021c590..1bcaf7c09 100644
--- a/gajim/gajim_remote.py
+++ b/gajim/gajim_remote.py
@@ -28,13 +28,13 @@ import os
import sys
import locale
import signal
-signal.signal(signal.SIGINT, signal.SIG_DFL) # ^C exits the application
-
from gajim.common import exceptions
-from gajim.common import i18n # This installs _() function
+from gajim.common.i18n import _
from gajim.common.i18n import Q_
+signal.signal(signal.SIGINT, signal.SIG_DFL) # ^C exits the application
+
try:
PREFERRED_ENCODING = locale.getpreferredencoding()
except Exception:
diff --git a/gajim/gtk/add_contact.py b/gajim/gtk/add_contact.py
index 3fc53719d..4316a8fed 100644
--- a/gajim/gtk/add_contact.py
+++ b/gajim/gtk/add_contact.py
@@ -18,6 +18,7 @@ from gi.repository import Gtk
from gajim.common import app
from gajim.common import ged
from gajim.common import helpers
+from gajim.common.i18n import _
from gajim.gtk import ErrorDialog
from gajim.gtk.util import get_builder
diff --git a/gajim/gtk/filechoosers.py b/gajim/gtk/filechoosers.py
index ea16d7fbc..cf31be430 100644
--- a/gajim/gtk/filechoosers.py
+++ b/gajim/gtk/filechoosers.py
@@ -25,6 +25,7 @@ from gi.repository import GdkPixbuf
from gi.repository import GObject
from gajim.common import app
+from gajim.common.i18n import _
Filter = namedtuple('Filter', 'name pattern default')
diff --git a/gajim/gtk/service_registration.py b/gajim/gtk/service_registration.py
index dce48a191..7cf944020 100644
--- a/gajim/gtk/service_registration.py
+++ b/gajim/gtk/service_registration.py
@@ -19,6 +19,7 @@ from gi.repository import Gtk
from gajim.common import app
from gajim.common.modules import dataforms
+from gajim.common.i18n import _
from gajim.gtk.dataform import DataFormWidget
log = logging.getLogger('gajim.gtk.registration')
diff --git a/gajim/gtk/themes.py b/gajim/gtk/themes.py
index 94d3e1203..40cdfdce5 100644
--- a/gajim/gtk/themes.py
+++ b/gajim/gtk/themes.py
@@ -21,6 +21,7 @@ from gi.repository import Gtk
from gi.repository import Gdk
from gajim.common import app
+from gajim.common.i18n import _
from gajim.common.const import StyleAttr, DialogButton, ButtonAction
from gajim.common.connection_handlers_events import StyleChanged
from gajim.gtk import ErrorDialog
diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py
index 17e29594c..0fd112c85 100644
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -2127,7 +2127,7 @@ class Interface:
if app.connections[acct].music_track_info == music_track_info:
continue
app.connections[acct].get_module('UserTune').send(
- (artist, title, source, None, None))
+ (artist, title, source, '', ''))
app.connections[acct].music_track_info = music_track_info
def read_sleepy(self):
diff --git a/gajim/history_manager.py b/gajim/history_manager.py
index 0a5157016..bba23654f 100644
--- a/gajim/history_manager.py
+++ b/gajim/history_manager.py
@@ -79,6 +79,7 @@ if is_standalone():
configpaths.init()
from gajim.common import app
+from gajim.common.i18n import _
from gajim.common.const import JIDConstant, KindConstant
from gajim.common import helpers
from gajim.gtk import YesNoDialog
diff --git a/gajim/message_textview.py b/gajim/message_textview.py
index 99bf27b5b..21e51ad54 100644
--- a/gajim/message_textview.py
+++ b/gajim/message_textview.py
@@ -24,6 +24,7 @@ from gi.repository import GLib
from gi.repository import Pango
from gajim.common import app
+from gajim.common.i18n import _
from gajim import gtkgui_helpers
if app.is_installed('GSPELL'):
diff --git a/gajim/plugins/plugins_i18n.py b/gajim/plugins/plugins_i18n.py
index b71a31128..16860bc21 100644
--- a/gajim/plugins/plugins_i18n.py
+++ b/gajim/plugins/plugins_i18n.py
@@ -14,15 +14,18 @@
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see .
+from typing import cast
+
+import os
import locale
import gettext
-from os import path as os_path
-import os
+
from gajim.common import app
from gajim.common import configpaths
APP = 'gajim_plugins'
-plugins_locale_dir = os_path.join(configpaths.get('PLUGINS_USER'), 'locale')
+plugin_user_dir = cast(str, configpaths.get('PLUGINS_USER'))
+plugins_locale_dir = os.path.join(plugin_user_dir, 'locale')
if os.name != 'nt':
locale.setlocale(locale.LC_ALL, '')
diff --git a/gajim/tooltips.py b/gajim/tooltips.py
index 5ab0294fe..f0715a650 100644
--- a/gajim/tooltips.py
+++ b/gajim/tooltips.py
@@ -528,25 +528,25 @@ class RosterTooltip(Gtk.Window, StatusTable):
to the given property list.
"""
if 'mood' in contact.pep:
- mood = contact.pep['mood'].asMarkupText()
+ mood = contact.pep['mood'].as_markup_text()
self.mood.set_markup(mood)
self.mood.show()
self.mood_label.show()
if 'activity' in contact.pep:
- activity = contact.pep['activity'].asMarkupText()
+ activity = contact.pep['activity'].as_markup_text()
self.activity.set_markup(activity)
self.activity.show()
self.activity_label.show()
if 'tune' in contact.pep:
- tune = contact.pep['tune'].asMarkupText()
+ tune = contact.pep['tune'].as_markup_text()
self.tune.set_markup(tune)
self.tune.show()
self.tune_label.show()
if 'geoloc' in contact.pep:
- location = contact.pep['geoloc'].asMarkupText()
+ location = contact.pep['geoloc'].as_markup_text()
self.location.set_markup(location)
self.location.show()
self.location_label.show()