summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlaunch.sh2
-rw-r--r--poezio/args.py16
-rw-r--r--poezio/connection.py2
-rw-r--r--poezio/core/commands.py13
-rw-r--r--poezio/core/handlers.py2
-rw-r--r--poezio/core/tabs.py1
-rw-r--r--poezio/logger.py1
-rw-r--r--poezio/tabs/basetabs.py6
-rw-r--r--poezio/tabs/privatetab.py14
-rw-r--r--poezio/tabs/rostertab.py188
-rw-r--r--poezio/version.py1
11 files changed, 149 insertions, 97 deletions
diff --git a/launch.sh b/launch.sh
index b049a7af..44b8074c 100755
--- a/launch.sh
+++ b/launch.sh
@@ -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'