diff options
-rwxr-xr-x | launch.sh | 2 | ||||
-rw-r--r-- | poezio/args.py | 16 | ||||
-rw-r--r-- | poezio/connection.py | 2 | ||||
-rw-r--r-- | poezio/core/commands.py | 13 | ||||
-rw-r--r-- | poezio/core/handlers.py | 2 | ||||
-rw-r--r-- | poezio/core/tabs.py | 1 | ||||
-rw-r--r-- | poezio/logger.py | 1 | ||||
-rw-r--r-- | poezio/tabs/basetabs.py | 6 | ||||
-rw-r--r-- | poezio/tabs/privatetab.py | 14 | ||||
-rw-r--r-- | poezio/tabs/rostertab.py | 188 | ||||
-rw-r--r-- | poezio/version.py | 1 |
11 files changed, 149 insertions, 97 deletions
@@ -25,5 +25,5 @@ else fi $PYTHON3 -c 'import sys;(print("Python 3.5 or newer is required") and exit(1)) if sys.version_info < (3, 5) else exit(0)' || exit 1 -exec "$PYTHON3" -m poezio -v "$args" "$@" +exec "$PYTHON3" -m poezio --custom-version "$args" "$@" diff --git a/poezio/args.py b/poezio/args.py index d0005d82..e1ebe5e0 100644 --- a/poezio/args.py +++ b/poezio/args.py @@ -6,6 +6,8 @@ There is a fallback to the deprecated optparse if argparse is not found from pathlib import Path from argparse import ArgumentParser, SUPPRESS +from poezio.version import __version__ + def parse_args(CONFIG_PATH: Path): """ @@ -33,11 +35,17 @@ def parse_args(CONFIG_PATH: Path): help="The config file you want to use", metavar="CONFIG_FILE") parser.add_argument( - "-v", - "--version", - dest="version", + '-v', + '--version', + action='version', + version='Poezio v%s' % __version__, + ) + parser.add_argument( + "--custom-version", + dest="custom_version", help=SUPPRESS, metavar="VERSION", - default="0.13-dev") + default=__version__ + ) options = parser.parse_args() return options diff --git a/poezio/connection.py b/poezio/connection.py index 57254069..d56b6c52 100644 --- a/poezio/connection.py +++ b/poezio/connection.py @@ -177,7 +177,7 @@ class Connection(slixmpp.ClientXMPP): self.register_plugin('xep_0196') if config.get('send_poezio_info'): - info = {'name': 'poezio', 'version': options.version} + info = {'name': 'poezio', 'version': options.custom_version} if config.get('send_os_info'): info['os'] = common.get_os_info() self.plugin['xep_0030'].set_identities(identities={('client', diff --git a/poezio/core/commands.py b/poezio/core/commands.py index 2cb2b291..fd6279ec 100644 --- a/poezio/core/commands.py +++ b/poezio/core/commands.py @@ -9,6 +9,7 @@ log = logging.getLogger(__name__) import asyncio from xml.etree import cElementTree as ET +from slixmpp import JID, InvalidJID from slixmpp.exceptions import XMPPError from slixmpp.xmlstream.xmlstream import NotConnectedError from slixmpp.xmlstream.stanzabase import StanzaBase @@ -632,12 +633,18 @@ class CommandCore: def server_cycle(self, args): """ Do a /cycle on each room of the given server. - If none, do it on the current tab + If none, do it on the server of the current tab """ tab = self.core.tabs.current_tab message = "" if args: - domain = args[0] + try: + domain = JID(args[0]).domain + except InvalidJID: + return self.core.information( + "Invalid server domain: %s" % args[0], + "Error" + ) if len(args) == 2: message = args[1] else: @@ -646,7 +653,7 @@ class CommandCore: else: return self.core.information("No server specified", "Error") for tab in self.core.get_tabs(tabs.MucTab): - if tab.name.endswith(domain): + if JID(tab.name).domain == domain: tab.leave_room(message) tab.join() diff --git a/poezio/core/handlers.py b/poezio/core/handlers.py index 94d05ee2..9cdfb59a 100644 --- a/poezio/core/handlers.py +++ b/poezio/core/handlers.py @@ -1312,6 +1312,8 @@ class HandlerCore: """ Triggered when the topic is changed. """ + if message['body'] or message['thread']: + return nick_from = message['mucnick'] room_from = message.get_mucroom() tab = self.core.tabs.by_name_and_class(room_from, tabs.MucTab) diff --git a/poezio/core/tabs.py b/poezio/core/tabs.py index 3ced7a7e..3d4db8b0 100644 --- a/poezio/core/tabs.py +++ b/poezio/core/tabs.py @@ -233,6 +233,7 @@ class Tabs: self._previous_tab = None if is_current: self.restore_previous_tab() + self._previous_tab = None self._validate_current_index() def restore_previous_tab(self): diff --git a/poezio/logger.py b/poezio/logger.py index d43cc759..ca1f059f 100644 --- a/poezio/logger.py +++ b/poezio/logger.py @@ -196,6 +196,7 @@ class Logger: logged_msg = build_log_message(nick, msg, date=date, typ=typ) if not logged_msg: return True + jid = str(jid).replace('/', '\\') if jid in self._fds.keys(): fd = self._fds[jid] else: diff --git a/poezio/tabs/basetabs.py b/poezio/tabs/basetabs.py index 578668fc..f5a4ccf0 100644 --- a/poezio/tabs/basetabs.py +++ b/poezio/tabs/basetabs.py @@ -818,7 +818,7 @@ class OneToOneTab(ChatTab): msg += 'show: %s, ' % SHOW_NAME[status.show] self.add_message(msg[:-2], typ=2) - def ack_message(self, msg_id, msg_jid): + def ack_message(self, msg_id: str, msg_jid: JID): """ Ack a message """ @@ -827,9 +827,9 @@ class OneToOneTab(ChatTab): self.text_win.modify_message(msg_id, new_msg) self.core.refresh_window() - def nack_message(self, error, msg_id, msg_jid): + def nack_message(self, error: str, msg_id: str, msg_jid: JID): """ - Ack a message + Non-ack a message (e.g. timeout) """ new_msg = self._text_buffer.nack_message(error, msg_id, msg_jid) if new_msg: diff --git a/poezio/tabs/privatetab.py b/poezio/tabs/privatetab.py index 4811f14e..35e5feaa 100644 --- a/poezio/tabs/privatetab.py +++ b/poezio/tabs/privatetab.py @@ -14,6 +14,8 @@ import curses import logging from typing import Dict, Callable +from slixmpp import JID + from poezio.tabs import OneToOneTab, MucTab, Tab from poezio import windows @@ -85,6 +87,12 @@ class PrivateTab(OneToOneTab): def nick(self): return self.get_nick() + def ack_message(self, msg_id: str, msg_jid: JID): + # special case when talking to oneself + if msg_jid == self.core.xmpp.boundjid: + msg_jid = JID(self.name) + super().ack_message(msg_id, msg_jid) + @staticmethod def add_information_element(plugin_name, callback): """ @@ -141,6 +149,7 @@ class PrivateTab(OneToOneTab): def command_say(self, line, attention=False, correct=False): if not self.on: return + echo_message = JID(self.name).resource != self.own_nick msg = self.core.xmpp.make_message(self.name) msg['type'] = 'chat' msg['body'] = line @@ -157,7 +166,8 @@ class PrivateTab(OneToOneTab): replaced = False if correct or msg['replace']['id']: msg['replace']['id'] = self.last_sent_message['id'] - if config.get_by_tabname('group_corrections', self.name): + if (config.get_by_tabname('group_corrections', self.name) + and echo_message): try: self.modify_message( msg['body'], @@ -187,7 +197,7 @@ class PrivateTab(OneToOneTab): self.text_win.refresh() self.input.refresh() return - if not replaced: + if not replaced and echo_message: self.add_message( msg['body'], nickname=self.own_nick or self.core.own_nick, diff --git a/poezio/tabs/rostertab.py b/poezio/tabs/rostertab.py index 9f609f61..768963af 100644 --- a/poezio/tabs/rostertab.py +++ b/poezio/tabs/rostertab.py @@ -31,6 +31,17 @@ from poezio.tabs import Tab log = logging.getLogger(__name__) +def deny_anonymous(func: Callable) -> Callable: + def wrap(self: 'RosterInfoTab', *args, **kwargs): + if self.core.xmpp.anon: + return self.core.information( + 'This command is not available for anonymous accounts.', + 'Info' + ) + return func(self, *args, **kwargs) + return wrap + + class RosterInfoTab(Tab): """ A tab, splitted in two, containing the roster and infos @@ -71,89 +82,89 @@ class RosterInfoTab(Tab): self.key_func["s"] = self.start_search self.key_func["S"] = self.start_search_slow self.key_func["n"] = self.change_contact_name - self.register_command( - 'deny', - self.command_deny, - usage='[jid]', - desc='Deny your presence to the provided JID (or the ' - 'selected contact in your roster), who is asking' - 'you to be in his/here roster.', - shortdesc='Deny a user your presence.', - completion=self.completion_deny) - self.register_command( - 'accept', - self.command_accept, - usage='[jid]', - desc='Allow the provided JID (or the selected contact ' - 'in your roster), to see your presence.', - shortdesc='Allow a user your presence.', - completion=self.completion_deny) - self.register_command( - 'add', - self.command_add, - usage='<jid>', - desc='Add the specified JID to your roster, ask them to' - ' allow you to see his presence, and allow them to' - ' see your presence.', - shortdesc='Add a user to your roster.') - self.register_command( - 'name', - self.command_name, - usage='<jid> [name]', - shortdesc='Set the given JID\'s name.', - completion=self.completion_name) - self.register_command( - 'groupadd', - self.command_groupadd, - usage='[<jid> <group>]|<group>', - desc='Add the given JID or selected line to the given group.', - shortdesc='Add a user to a group', - completion=self.completion_groupadd) - self.register_command( - 'groupmove', - self.command_groupmove, - usage='<jid> <old group> <new group>', - desc='Move the given JID from the old group to the new group.', - shortdesc='Move a user to another group.', - completion=self.completion_groupmove) - self.register_command( - 'groupremove', - self.command_groupremove, - usage='<jid> <group>', - desc='Remove the given JID from the given group.', - shortdesc='Remove a user from a group.', - completion=self.completion_groupremove) - self.register_command( - 'remove', - self.command_remove, - usage='[jid]', - desc='Remove the specified JID from your roster. This ' - 'will unsubscribe you from its presence, cancel ' - 'its subscription to yours, and remove the item ' - 'from your roster.', - shortdesc='Remove a user from your roster.', - completion=self.completion_remove) - self.register_command( - 'export', - self.command_export, - usage='[/path/to/file]', - desc='Export your contacts into /path/to/file if ' - 'specified, or $HOME/poezio_contacts if not.', - shortdesc='Export your roster to a file.', - completion=partial(self.completion_file, 1)) - self.register_command( - 'import', - self.command_import, - usage='[/path/to/file]', - desc='Import your contacts from /path/to/file if ' - 'specified, or $HOME/poezio_contacts if not.', - shortdesc='Import your roster from a file.', - completion=partial(self.completion_file, 1)) - self.register_command( - 'password', - self.command_password, - usage='<password>', - shortdesc='Change your password') + self.register_command( + 'deny', + self.command_deny, + usage='[jid]', + desc='Deny your presence to the provided JID (or the ' + 'selected contact in your roster), who is asking' + 'you to be in his/here roster.', + shortdesc='Deny a user your presence.', + completion=self.completion_deny) + self.register_command( + 'accept', + self.command_accept, + usage='[jid]', + desc='Allow the provided JID (or the selected contact ' + 'in your roster), to see your presence.', + shortdesc='Allow a user your presence.', + completion=self.completion_deny) + self.register_command( + 'add', + self.command_add, + usage='<jid>', + desc='Add the specified JID to your roster, ask them to' + ' allow you to see his presence, and allow them to' + ' see your presence.', + shortdesc='Add a user to your roster.') + self.register_command( + 'name', + self.command_name, + usage='<jid> [name]', + shortdesc='Set the given JID\'s name.', + completion=self.completion_name) + self.register_command( + 'groupadd', + self.command_groupadd, + usage='[<jid> <group>]|<group>', + desc='Add the given JID or selected line to the given group.', + shortdesc='Add a user to a group', + completion=self.completion_groupadd) + self.register_command( + 'groupmove', + self.command_groupmove, + usage='<jid> <old group> <new group>', + desc='Move the given JID from the old group to the new group.', + shortdesc='Move a user to another group.', + completion=self.completion_groupmove) + self.register_command( + 'groupremove', + self.command_groupremove, + usage='<jid> <group>', + desc='Remove the given JID from the given group.', + shortdesc='Remove a user from a group.', + completion=self.completion_groupremove) + self.register_command( + 'remove', + self.command_remove, + usage='[jid]', + desc='Remove the specified JID from your roster. This ' + 'will unsubscribe you from its presence, cancel ' + 'its subscription to yours, and remove the item ' + 'from your roster.', + shortdesc='Remove a user from your roster.', + completion=self.completion_remove) + self.register_command( + 'export', + self.command_export, + usage='[/path/to/file]', + desc='Export your contacts into /path/to/file if ' + 'specified, or $HOME/poezio_contacts if not.', + shortdesc='Export your roster to a file.', + completion=partial(self.completion_file, 1)) + self.register_command( + 'import', + self.command_import, + usage='[/path/to/file]', + desc='Import your contacts from /path/to/file if ' + 'specified, or $HOME/poezio_contacts if not.', + shortdesc='Import your roster from a file.', + completion=partial(self.completion_file, 1)) + self.register_command( + 'password', + self.command_password, + usage='<password>', + shortdesc='Change your password') self.register_command( 'reconnect', @@ -652,6 +663,7 @@ class RosterInfoTab(Tab): self.core.information_buffer) self.refresh() + @deny_anonymous @command_args_parser.quoted(1) def command_password(self, args): """ @@ -670,6 +682,7 @@ class RosterInfoTab(Tab): self.core.xmpp.plugin['xep_0077'].change_password( args[0], callback=callback) + @deny_anonymous @command_args_parser.quoted(0, 1) def command_deny(self, args): """ @@ -695,6 +708,7 @@ class RosterInfoTab(Tab): self.core.information('Subscription to %s was revoked' % jid, 'Roster') + @deny_anonymous @command_args_parser.quoted(1) def command_add(self, args): """ @@ -715,6 +729,7 @@ class RosterInfoTab(Tab): roster.modified() self.core.information('%s was added to the roster' % jid, 'Roster') + @deny_anonymous @command_args_parser.quoted(1, 1) def command_name(self, args): """ @@ -747,6 +762,7 @@ class RosterInfoTab(Tab): subscription=subscription, callback=callback) + @deny_anonymous @command_args_parser.quoted(1, 1) def command_groupadd(self, args): """ @@ -801,6 +817,7 @@ class RosterInfoTab(Tab): subscription=subscription, callback=callback) + @deny_anonymous @command_args_parser.quoted(3) def command_groupmove(self, args): """ @@ -860,6 +877,7 @@ class RosterInfoTab(Tab): subscription=subscription, callback=callback) + @deny_anonymous @command_args_parser.quoted(2) def command_groupremove(self, args): """ @@ -905,6 +923,7 @@ class RosterInfoTab(Tab): subscription=subscription, callback=callback) + @deny_anonymous @command_args_parser.quoted(0, 1) def command_remove(self, args): """ @@ -923,6 +942,7 @@ class RosterInfoTab(Tab): roster.remove(jid) del roster[jid] + @deny_anonymous @command_args_parser.quoted(0, 1) def command_import(self, args): """ @@ -951,6 +971,7 @@ class RosterInfoTab(Tab): self.command_add(jid.lstrip('\n')) self.core.information('Contacts imported from %s' % filepath, 'Info') + @deny_anonymous @command_args_parser.quoted(0, 1) def command_export(self, args): """ @@ -1055,6 +1076,7 @@ class RosterInfoTab(Tab): if contact.pending_in) return Completion(the_input.new_completion, jids, 1, '', quotify=False) + @deny_anonymous @command_args_parser.quoted(0, 1) def command_accept(self, args): """ diff --git a/poezio/version.py b/poezio/version.py new file mode 100644 index 00000000..3543a785 --- /dev/null +++ b/poezio/version.py @@ -0,0 +1 @@ +__version__ = '0.13-dev' |