Commit 2b3cde23 authored by mathieui's avatar mathieui

fix: improve typing

preliminary to more typing added to slixmpp, fix things in advance
parent 26505c32
......@@ -40,10 +40,10 @@ from typing import (
from slixmpp import (
InvalidJID,
JID,
ClientXMPP,
)
from slixmpp.exceptions import IqError, IqTimeout
from slixmpp.plugins.xep_0048 import Bookmarks, Conference, URL
from poezio.connection import Connection
from poezio.config import config
log = logging.getLogger(__name__)
......@@ -223,7 +223,7 @@ class BookmarkList:
self.preferred = value
config.set_and_save('use_bookmarks_method', value)
async def save_remote(self, xmpp: ClientXMPP):
async def save_remote(self, xmpp: Connection):
"""Save the remote bookmarks."""
if not any(self.available_storage.values()):
return
......@@ -241,7 +241,7 @@ class BookmarkList:
if bookmark.method == 'local')
config.set_and_save('rooms', local)
async def save(self, xmpp: ClientXMPP, core=None):
async def save(self, xmpp: Connection, core=None):
"""Save all the bookmarks."""
self.save_local()
if config.getbool('use_remote_bookmarks'):
......@@ -258,7 +258,7 @@ class BookmarkList:
)
raise
async def get_pep(self, xmpp: ClientXMPP):
async def get_pep(self, xmpp: Connection):
"""Add the remotely stored bookmarks via pep to the list."""
iq = await xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0223')
for conf in iq['pubsub']['items']['item']['bookmarks'][
......@@ -269,7 +269,7 @@ class BookmarkList:
self.append(bookm)
return iq
async def get_privatexml(self, xmpp: ClientXMPP):
async def get_privatexml(self, xmpp: Connection):
"""
Fetch the remote bookmarks stored via privatexml.
"""
......@@ -280,7 +280,7 @@ class BookmarkList:
self.append(bookm)
return iq
async def get_remote(self, xmpp: ClientXMPP, information: Callable):
async def get_remote(self, xmpp: Connection, information: Callable):
"""Add the remotely stored bookmarks to the list."""
if xmpp.anon or not any(self.available_storage.values()):
information('No remote bookmark storage available', 'Warning')
......
......@@ -249,7 +249,7 @@ class Config:
def get_by_tabname(self,
option,
tabname: str,
tabname: JID,
fallback=True,
fallback_server=True,
default=''):
......@@ -259,14 +259,12 @@ class Config:
in the section, we search for the global option if fallback is
True. And we return `default` as a fallback as a last resort.
"""
if isinstance(tabname, JID):
tabname = tabname.full
if self.default and (not default) and fallback:
default = self.default.get(DEFSECTION, {}).get(option, '')
if tabname in self.sections():
if option in self.options(tabname):
# We go the tab-specific option
return self.get(option, default, tabname)
return self.get(option, default, tabname.full)
if fallback_server:
return self.get_by_servname(tabname, option, default, fallback)
if fallback:
......
......@@ -1011,7 +1011,7 @@ class CommandCore:
jid = None
if args:
try:
jid = JID(args[0]).full
jid = JID(args[0])
except InvalidJID:
self.core.information('Invalid JID %s' % args, 'Error')
return
......@@ -1027,7 +1027,7 @@ class CommandCore:
if isinstance(item, Contact):
jid = item.bare_jid
elif isinstance(item, Resource):
jid = item.jid
jid = JID(item.jid)
chattabs = (
tabs.ConversationTab,
......@@ -1035,7 +1035,7 @@ class CommandCore:
tabs.DynamicConversationTab,
)
if isinstance(current_tab, chattabs):
jid = current_tab.jid.bare
jid = JID(current_tab.jid.bare)
if jid is None:
self.core.information('No specified JID to block', 'Error')
......@@ -1066,7 +1066,7 @@ class CommandCore:
jid = None
if args:
try:
jid = JID(args[0]).full
jid = JID(args[0])
except InvalidJID:
self.core.information('Invalid JID %s' % args, 'Error')
return
......@@ -1082,7 +1082,7 @@ class CommandCore:
if isinstance(item, Contact):
jid = item.bare_jid
elif isinstance(item, Resource):
jid = item.jid
jid = JID(item.jid)
chattabs = (
tabs.ConversationTab,
......@@ -1090,7 +1090,7 @@ class CommandCore:
tabs.DynamicConversationTab,
)
if isinstance(current_tab, chattabs):
jid = current_tab.jid.bare
jid = JID(current_tab.jid.bare)
if jid is not None:
asyncio.ensure_future(
......@@ -1158,6 +1158,7 @@ class CommandCore:
else:
self.core.information('Room %s destroyed' % room, 'Info')
room: Optional[JID]
if not args[0] and isinstance(self.core.tabs.current_tab, tabs.MucTab):
room = self.core.tabs.current_tab.general_jid
else:
......
......@@ -466,11 +466,11 @@ class CompletionCore:
tabs.StaticConversationTab,
tabs.DynamicConversationTab,
)
tabjid: List[JID] = []
tabjid: List[str] = []
if isinstance(current_tab, chattabs):
tabjid = [current_tab.jid.bare]
jids = roster.jids()
jids = [str(i) for i in roster.jids()]
jids += tabjid
return Completion(
the_input.new_completion, jids, 1, '', quotify=False)
......
......@@ -930,14 +930,17 @@ class Core:
pass
supports_direct = 'jabber:x:conference' in features
if supports_direct:
invite = self.xmpp.plugin['xep_0249'].send_invitation
self.xmpp.plugin['xep_0249'].send_invitation(
jid=jid,
roomjid=room,
reason=reason
)
else: # fallback
invite = self.xmpp.plugin['xep_0045'].invite
invite(
jid=jid,
room=room,
reason=reason
)
self.xmpp.plugin['xep_0045'].invite(
jid=jid,
room=room,
reason=reason or '',
)
return True
def _impromptu_room_form(self, room):
......@@ -1259,7 +1262,7 @@ class Core:
return tab
def open_new_room(self,
room: str,
room: JID,
nick: str,
*,
password: Optional[str] = None,
......@@ -1773,7 +1776,7 @@ class Core:
remote_bookmarks = self.bookmarks.remote()
self.join_initial_rooms(remote_bookmarks)
def room_error(self, error: IqError, room_name: str) -> None:
def room_error(self, error, room_name: str) -> None:
"""
Display the error in the tab
"""
......
......@@ -171,12 +171,17 @@ class Tabs:
return any_matched, candidate
def by_name_and_class(self, name: str,
def by_name_and_class(self, name: Union[str, JID],
cls: Type[T]) -> Optional[T]:
"""Get a tab with its name and class"""
if isinstance(name, JID):
str_name = name.full
else:
str_name = name
str
cls_tabs = self._tab_types.get(cls, [])
for tab in cls_tabs:
if tab.name == name:
if tab.name == str_name:
return cast(T, tab)
return None
......
......@@ -194,7 +194,7 @@ class Logger:
:param open_fd: if the file should be opened after creating the dir
:returns: the opened fd or None
"""
if not config.get_by_tabname('use_log', jid):
if not config.get_by_tabname('use_log', JID(jid)):
return None
try:
self.log_dir.mkdir(parents=True, exist_ok=True)
......@@ -225,7 +225,7 @@ class Logger:
:param msg: Message to log
:returns: True if no error was encountered
"""
if not config.get_by_tabname('use_log', jid):
if not config.get_by_tabname('use_log', JID(jid)):
return True
if not isinstance(msg, LoggableTrait):
return True
......@@ -290,7 +290,7 @@ class Logger:
:param message: message to log
:returns: True if no error happened
"""
if not config.get_by_tabname('use_log', jid):
if not config.get_by_tabname('use_log', JID(jid)):
return True
self._check_and_create_log_dir('', open_fd=False)
filename = self.log_dir / 'roster.log'
......
......@@ -92,7 +92,7 @@ async def get_mam_iterator(
start: Optional[str] = None,
end: Optional[str] = None,
before: Optional[str] = None,
) -> AsyncIterable[Message]:
) -> AsyncIterable[SMessage]:
"""Get an async iterator for this mam query"""
try:
query_jid = remote_jid if groupchat else JID(core.xmpp.boundjid.bare)
......
......@@ -16,6 +16,7 @@ import asyncio
from xml.etree import ElementTree as ET
from typing import (
Optional,
Union,
TYPE_CHECKING,
)
......@@ -23,6 +24,7 @@ from slixmpp import (
JID,
ClientXMPP,
Iq,
Presence,
)
import logging
......@@ -45,7 +47,7 @@ def change_show(
Change our 'Show'
"""
jid = JID(jid)
pres = xmpp.make_presence(pto='%s/%s' % (jid, own_nick))
pres: Presence = xmpp.make_presence(pto='%s/%s' % (jid, own_nick))
if show: # if show is None, don't put a <show /> tag. It means "available"
pres['type'] = show
if status:
......@@ -55,7 +57,7 @@ def change_show(
def change_nick(
core: Core,
jid: JID,
jid: Union[JID, str],
nick: str,
status: Optional[str] = None,
show: Optional[str] = None
......@@ -64,7 +66,7 @@ def change_nick(
Change our own nick in a room
"""
xmpp = core.xmpp
presence = xmpp.make_presence(
presence: Presence = xmpp.make_presence(
pshow=show, pstatus=status, pto=JID('%s/%s' % (jid, nick)))
core.events.trigger('changing_nick', presence)
presence.send()
......@@ -81,7 +83,7 @@ def join_groupchat(
tab: Optional['MucTab'] = None
) -> None:
xmpp = core.xmpp
stanza = xmpp.make_presence(
stanza: Presence = xmpp.make_presence(
pto='%s/%s' % (jid, nick), pstatus=status, pshow=show)
x = ET.Element('{http://jabber.org/protocol/muc}x')
if passwd:
......
......@@ -591,7 +591,7 @@ class ChatTab(Tab):
if value.domain:
self._jid = value
except InvalidJID:
self._name = value
self._name = str(value)
else:
raise TypeError("Name %r must be of type JID or str." % value)
......@@ -687,9 +687,9 @@ class ChatTab(Tab):
if message:
message.send()
def generate_xhtml_message(self, arg: str) -> SMessage:
def generate_xhtml_message(self, arg: str) -> Optional[SMessage]:
if not arg:
return
return None
try:
body = xhtml.clean_text(
xhtml.xhtml_to_poezio_colors(arg, force=True))
......@@ -697,9 +697,9 @@ class ChatTab(Tab):
except SAXParseException:
self.core.information('Could not send custom xhtml', 'Error')
log.error('/xhtml: Unable to send custom xhtml')
return
return None
msg = self.core.xmpp.make_message(self.get_dest_jid())
msg: SMessage = self.core.xmpp.make_message(self.get_dest_jid())
msg['body'] = body
msg.enable('html')
msg['html']['body'] = arg
......@@ -731,7 +731,7 @@ class ChatTab(Tab):
'gone') and self.inactive and not always_send:
return
if config.get_by_tabname('send_chat_states', self.general_jid):
msg = self.core.xmpp.make_message(self.get_dest_jid())
msg: SMessage = self.core.xmpp.make_message(self.get_dest_jid())
msg['type'] = self.message_type
msg['chat_state'] = state
self.chat_state = state
......
......@@ -173,7 +173,7 @@ class ConversationTab(OneToOneTab):
@refresh_wrapper.always
@command_args_parser.raw
def command_say(self, line: str, attention: bool = False, correct: bool = False):
msg = self.core.xmpp.make_message(
msg: SMessage = self.core.xmpp.make_message(
mto=self.get_dest_jid(),
mfrom=self.core.xmpp.boundjid
)
......@@ -210,7 +210,8 @@ class ConversationTab(OneToOneTab):
return
self.set_last_sent_message(msg, correct=correct)
self.core.handler.on_normal_message(msg)
msg._add_receipt = True
# Our receipts slixmpp hack
msg._add_receipt = True # type: ignore
msg.send()
self.cancel_paused_delay()
......
......@@ -34,7 +34,7 @@ from typing import (
TYPE_CHECKING,
)
from slixmpp import InvalidJID, JID, Presence, Iq
from slixmpp import InvalidJID, JID, Presence, Iq, Message as SMessage
from slixmpp.exceptions import IqError, IqTimeout
from poezio.tabs import ChatTab, Tab, SHOW_NAME
......@@ -154,14 +154,14 @@ class MucTab(ChatTab):
"""
The user do not want to send their config, send an iq cancel
"""
asyncio.ensure_future(self.core.xmpp['xep_0045'].cancel_config(self.jid.bare))
asyncio.ensure_future(self.core.xmpp['xep_0045'].cancel_config(self.jid))
self.core.close_tab()
def send_config(self, form: Form) -> None:
"""
The user sends their config to the server
"""
asyncio.ensure_future(self.core.xmpp['xep_0045'].set_room_config(self.jid.bare, form))
asyncio.ensure_future(self.core.xmpp['xep_0045'].set_room_config(self.jid, form))
self.core.close_tab()
def join(self) -> None:
......@@ -185,7 +185,7 @@ class MucTab(ChatTab):
self.mam_filler = MAMFiller(logger, self, limit)
muc.join_groupchat(
self.core,
self.jid.bare,
self.jid,
self.own_nick,
self.password or '',
status=status.message,
......@@ -229,11 +229,11 @@ class MucTab(ChatTab):
}
self.add_message(MucOwnLeaveMessage(msg))
self.disconnect()
muc.leave_groupchat(self.core.xmpp, self.jid.bare, self.own_nick,
muc.leave_groupchat(self.core.xmpp, self.jid, self.own_nick,
message)
self.core.disable_private_tabs(self.jid.bare, reason=msg)
else:
muc.leave_groupchat(self.core.xmpp, self.jid.bare, self.own_nick,
muc.leave_groupchat(self.core.xmpp, self.jid, self.own_nick,
message)
async def change_affiliation(
......@@ -275,7 +275,7 @@ class MucTab(ChatTab):
if affiliation != 'member':
nick = None
await self.core.xmpp['xep_0045'].set_affiliation(
self.jid.bare,
self.jid,
jid=jid,
nick=nick,
affiliation=affiliation,
......@@ -312,7 +312,7 @@ class MucTab(ChatTab):
try:
await self.core.xmpp['xep_0045'].set_role(
self.jid.bare, nick, role=role, reason=reason
self.jid, nick, role=role, reason=reason
)
self.core.information(
f'Role of {nick} changed to {role} successfully.'
......@@ -357,7 +357,7 @@ class MucTab(ChatTab):
def change_topic(self, topic: str) -> None:
"""Change the current topic"""
self.core.xmpp.plugin['xep_0045'].set_subject(self.jid.bare, topic)
self.core.xmpp.plugin['xep_0045'].set_subject(self.jid, topic)
@refresh_wrapper.always
def show_topic(self) -> None:
......@@ -416,7 +416,7 @@ class MucTab(ChatTab):
user.change_color(color)
config.set_and_save(nick, color, 'muc_colors')
nick_color_aliases = config.get_by_tabname('nick_color_aliases',
self.jid.bare)
self.jid)
if nick_color_aliases:
# if any user in the room has a nick which is an alias of the
# nick, update its color
......@@ -443,12 +443,12 @@ class MucTab(ChatTab):
def get_nick(self) -> str:
if config.getbool('show_muc_jid'):
return cast(str, self.jid.bare)
bookmark = self.core.bookmarks[self.jid.bare]
return cast(str, self.jid)
bookmark = self.core.bookmarks[self.jid]
if bookmark is not None and bookmark.name:
return bookmark.name
# TODO: send the disco#info identity name here, if it exists.
return self.jid.user
return self.jid.node
def get_text_window(self) -> windows.TextWin:
return self.text_win
......@@ -555,8 +555,8 @@ class MucTab(ChatTab):
self.own_nick = from_nick
self.own_user = new_user
self.joined = True
if self.jid.bare in self.core.initial_joins:
self.core.initial_joins.remove(self.jid.bare)
if self.jid in self.core.initial_joins:
self.core.initial_joins.remove(self.jid)
self._state = 'normal'
elif self != self.core.tabs.current_tab:
self._state = 'joined'
......@@ -637,7 +637,7 @@ class MucTab(ChatTab):
self.on_user_join(from_nick, affiliation, show, status, role, jid,
user_color)
elif user is None:
log.error('BUG: User %s in %s is None', from_nick, self.jid.bare)
log.error('BUG: User %s in %s is None', from_nick, self.jid)
return
elif change_nick:
self.core.events.trigger('muc_nickchange', presence, self)
......@@ -661,7 +661,7 @@ class MucTab(ChatTab):
# user quit
elif typ == 'unavailable':
self.on_user_leave_groupchat(user, jid, status, from_nick,
from_room, server_initiated)
JID(from_room), server_initiated)
# status change
else:
self.on_user_change_status(user, from_nick, from_room, affiliation,
......@@ -732,9 +732,13 @@ class MucTab(ChatTab):
self.core.on_user_rejoined_private_conversation(self.jid.bare, from_nick)
def on_user_nick_change(self, presence: Presence, user: User, from_nick: str) -> None:
new_nick = presence.xml.find(
new_nick_elt = presence.xml.find(
'{%s}x/{%s}item' % (NS_MUC_USER, NS_MUC_USER)
).attrib['nick']
)
if new_nick_elt is not None:
new_nick = new_nick_elt.attrib['nick']
else:
return # should not happen
old_color_tuple = user.color
if user.nick == self.own_nick:
self.own_nick = new_nick
......@@ -780,10 +784,9 @@ class MucTab(ChatTab):
(NS_MUC_USER, NS_MUC_USER, NS_MUC_USER))
reason = presence.xml.find('{%s}x/{%s}item/{%s}reason' %
(NS_MUC_USER, NS_MUC_USER, NS_MUC_USER))
by_repr: Union[JID, str, None] = None
if by:
by = by.get('jid') or by.get('nick') or None
else:
by = None
by_repr = by.get('jid') or by.get('nick') or None
theme = get_theme()
info_col = dump_tuple(theme.COLOR_INFORMATION_TEXT)
......@@ -795,7 +798,7 @@ class MucTab(ChatTab):
kick_msg = ('\x191}%(spec)s \x193}You\x19%(info_col)s}'
' have been banned by \x194}%(by)s') % {
'spec': char_kick,
'by': by,
'by': by_repr,
'info_col': info_col
}
else:
......@@ -813,11 +816,11 @@ class MucTab(ChatTab):
self.general_jid)
delay = common.parse_str_to_secs(delay)
if delay <= 0:
muc.join_groupchat(self.core, self.jid.bare, self.own_nick)
muc.join_groupchat(self.core, self.jid, self.own_nick)
else:
self.core.add_timed_event(
timed_events.DelayedEvent(delay, muc.join_groupchat,
self.core, self.jid.bare,
self.core, self.jid,
self.own_nick))
else:
......@@ -895,11 +898,11 @@ class MucTab(ChatTab):
self.general_jid)
delay = common.parse_str_to_secs(delay)
if delay <= 0:
muc.join_groupchat(self.core, self.jid.bare, self.own_nick)
muc.join_groupchat(self.core, self.jid, self.own_nick)
else:
self.core.add_timed_event(
timed_events.DelayedEvent(delay, muc.join_groupchat,
self.core, self.jid.bare,
self.core, self.jid,
self.own_nick))
else:
if config.get_by_tabname('display_user_color_in_join_part',
......@@ -948,7 +951,7 @@ class MucTab(ChatTab):
# We are now out of the room.
# Happens with some buggy (? not sure) servers
self.disconnect()
self.core.disable_private_tabs(from_room)
self.core.disable_private_tabs(from_room.bare)
self.refresh_tab_win()
hide_exit_join = config.get_by_tabname('hide_exit_join',
......@@ -997,7 +1000,7 @@ class MucTab(ChatTab):
if status:
leave_msg += ' (\x19o%s\x19%s})' % (status, info_col)
self.add_message(PersistentInfoMessage(leave_msg))
self.core.on_user_left_private_conversation(from_room, user, status)
self.core.on_user_left_private_conversation(from_room.bare, user, status)
def on_user_change_status(self, user: User, from_nick: str, from_room: str, affiliation: str,
role: str, show: str, status: str) -> None:
......@@ -1057,7 +1060,8 @@ class MucTab(ChatTab):
# display the message in the room
self.add_message(InfoMessage(msg))
self.core.on_user_changed_status_in_private(
'%s/%s' % (from_room, from_nick), Status(show, status))
JID('%s/%s' % (from_room, from_nick)), Status(show, status)
)
self.users.remove(user)
# finally, effectively change the user status
user.update(affiliation, show, status, role)
......@@ -1100,7 +1104,7 @@ class MucTab(ChatTab):
return
if msg.user:
msg.user.set_last_talked(msg.time)
if config.get_by_tabname('notify_messages', self.jid.bare) and self.state != 'current':
if config.get_by_tabname('notify_messages', self.jid) and self.state != 'current':
if msg.nickname != self.own_nick and not msg.history:
self.state = 'message'
if msg.txt and msg.nickname:
......@@ -1133,7 +1137,7 @@ class MucTab(ChatTab):
return False
def matching_names(self) -> List[Tuple[int, str]]:
return [(1, self.jid.user), (3, self.jid.full)]
return [(1, self.jid.node), (3, self.jid.full)]
def enable_self_ping_event(self) -> None:
delay = config.get_by_tabname(
......@@ -1159,7 +1163,7 @@ class MucTab(ChatTab):
"self_ping_timeout", self.general_jid, default=60)
to = self.jid.bare + "/" + self.own_nick
self.core.xmpp.plugin['xep_0199'].send_ping(
jid=to,
jid=JID(to),
callback=self.on_self_ping_result,
timeout_callback=self.on_self_ping_failed,
timeout=timeout)
......@@ -1185,7 +1189,7 @@ class MucTab(ChatTab):
if color != '':
return color
nick_color_aliases = config.get_by_tabname('nick_color_aliases',
self.jid.bare)
self.jid)
if nick_color_aliases:
nick_alias = re.sub('^_*(.*?)_*$', '\\1', nick)
color = config.getstr(nick_alias, section='muc_colors')
......@@ -1359,7 +1363,7 @@ class MucTab(ChatTab):
self.state = 'highlight'
beep_on = config.getstr('beep_on').split()
if 'highlight' in beep_on and 'message' not in beep_on:
if not config.get_by_tabname('disable_beep', self.jid.bare):
if not config.get_by_tabname('disable_beep', self.jid):
curses.beep()
return True
return False
......@@ -1373,7 +1377,7 @@ class MucTab(ChatTab):
self.core.command.help('invite')
return
jid, reason = args
await self.core.command.invite('%s %s "%s"' % (jid, self.jid.bare, reason))
await self.core.command.invite('%s %s "%s"' % (jid, self.jid, reason))
@command_args_parser.quoted(1)
def command_info(self, args: List[str]) -> None:
......@@ -1395,7 +1399,7 @@ class MucTab(ChatTab):