From 6e13b8b73572f9c0ac9b5c683b98a475afbeab38 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 15 Aug 2018 13:13:17 +0200 Subject: yapf -rip on plugins --- plugins/admin.py | 93 ++++++++++-------- plugins/alias.py | 51 ++++++---- plugins/amsg.py | 11 ++- plugins/autocorrect.py | 10 +- plugins/bob.py | 31 +++--- plugins/capslock.py | 1 + plugins/close_all.py | 8 +- plugins/code.py | 11 ++- plugins/csi.py | 23 +++-- plugins/cyber.py | 6 +- plugins/day_change.py | 4 +- plugins/dice.py | 30 ++++-- plugins/disco.py | 18 ++-- plugins/display_corrections.py | 22 +++-- plugins/double.py | 1 + plugins/embed.py | 11 ++- plugins/exec.py | 36 ++++--- plugins/figlet.py | 4 +- plugins/iq_show.py | 4 +- plugins/irc.py | 140 ++++++++++++++++----------- plugins/link.py | 28 ++++-- plugins/marquee.py | 36 ++++--- plugins/mirror.py | 11 ++- plugins/mpd_client.py | 28 ++++-- plugins/otr.py | 212 +++++++++++++++++++++++++--------------- plugins/pacokick.py | 17 ++-- plugins/ping.py | 68 ++++++++----- plugins/pipe_cmd.py | 6 +- plugins/pointpoint.py | 7 +- plugins/quote.py | 40 +++++--- plugins/rainbow.py | 15 ++- plugins/random_nick.py | 8 +- plugins/regex_admin.py | 29 +++--- plugins/reminder.py | 61 +++++++----- plugins/reorder.py | 22 +++-- plugins/replace.py | 8 +- plugins/replace_word.py | 1 + plugins/revstr.py | 1 + plugins/rstrip.py | 4 +- plugins/screen_detach.py | 15 ++- plugins/send_delayed.py | 24 +++-- plugins/server_part.py | 13 ++- plugins/shuffle.py | 1 + plugins/simple_notify.py | 24 ++++- plugins/spaces.py | 1 + plugins/spam.py | 4 +- plugins/status.py | 13 ++- plugins/stoi.py | 20 ++-- plugins/tell.py | 38 +++++--- plugins/test.py | 10 +- plugins/time_marker.py | 6 +- plugins/upload.py | 18 ++-- plugins/uptime.py | 17 +++- plugins/vcard.py | 213 +++++++++++++++++++++++++++++++---------- plugins/white.py | 1 + 55 files changed, 1006 insertions(+), 529 deletions(-) (limited to 'plugins') diff --git a/plugins/admin.py b/plugins/admin.py index 8c632532..7bbc01d6 100644 --- a/plugins/admin.py +++ b/plugins/admin.py @@ -50,11 +50,11 @@ For affiliations """ - from poezio.plugin import BasePlugin from poezio.tabs import MucTab from poezio.core.structs import Completion + class Plugin(BasePlugin): """ Adds several convenient aliases to /affiliation and /role: @@ -66,48 +66,66 @@ class Plugin(BasePlugin): /admin /noaffiliation """ + def init(self): - for role in ('visitor', 'participant' , 'moderator'): - self.api.add_tab_command(MucTab, role, self.role(role), - help='Set the role of a nick to %s' % role, - usage= '', - short='Set the role to %s' % role, - completion=self.complete_nick) + for role in ('visitor', 'participant', 'moderator'): + self.api.add_tab_command( + MucTab, + role, + self.role(role), + help='Set the role of a nick to %s' % role, + usage='', + short='Set the role to %s' % role, + completion=self.complete_nick) for aff in ('member', 'owner', 'admin'): - self.api.add_tab_command(MucTab, aff, self.affiliation(aff), - usage='', - help='Set the affiliation of a nick to %s' % aff, - short='Set the affiliation to %s' % aff, - completion=self.complete_nick) - - self.api.add_tab_command(MucTab, 'noaffiliation', self.affiliation('none'), - usage='', - help='Set the affiliation of a nick to none.', - short='Set the affiliation to none.', - completion=self.complete_nick) - self.api.add_tab_command(MucTab, 'voice', self.affiliation('member'), - usage='', - help='Set the affiliation of a nick to member.', - short='Set the affiliation to member.', - completion=self.complete_nick) - self.api.add_tab_command(MucTab, 'op', self.role('moderator'), - usage='', - help='Set the role of a nick to moderator.', - short='Set the role to moderator.', - completion=self.complete_nick) - self.api.add_tab_command(MucTab, 'mute', self.role('visitor'), - usage='', - help='Set the role of a nick to visitor.', - short='Set the role to visitor.', - completion=self.complete_nick) + self.api.add_tab_command( + MucTab, + aff, + self.affiliation(aff), + usage='', + help='Set the affiliation of a nick to %s' % aff, + short='Set the affiliation to %s' % aff, + completion=self.complete_nick) + + self.api.add_tab_command( + MucTab, + 'noaffiliation', + self.affiliation('none'), + usage='', + help='Set the affiliation of a nick to none.', + short='Set the affiliation to none.', + completion=self.complete_nick) + self.api.add_tab_command( + MucTab, + 'voice', + self.affiliation('member'), + usage='', + help='Set the affiliation of a nick to member.', + short='Set the affiliation to member.', + completion=self.complete_nick) + self.api.add_tab_command( + MucTab, + 'op', + self.role('moderator'), + usage='', + help='Set the role of a nick to moderator.', + short='Set the role to moderator.', + completion=self.complete_nick) + self.api.add_tab_command( + MucTab, + 'mute', + self.role('visitor'), + usage='', + help='Set the role of a nick to visitor.', + short='Set the role to visitor.', + completion=self.complete_nick) def role(self, role): - return lambda args: self.api.current_tab().command_role(args+' '+role) + return lambda args: self.api.current_tab().command_role(args + ' ' + role) def affiliation(self, affiliation): - return lambda args: self.api.current_tab().command_affiliation( - args+' '+affiliation) + return lambda args: self.api.current_tab().command_affiliation(args + ' ' + affiliation) def complete_nick(self, the_input): tab = self.api.current_tab() @@ -115,6 +133,3 @@ class Plugin(BasePlugin): word_list = [user.nick for user in sorted(tab.users, key=compare_users, reverse=True)\ if user.nick != tab.own_nick] return Completion(the_input.auto_completion, word_list, '') - - - diff --git a/plugins/alias.py b/plugins/alias.py index 108fde54..a10beb7c 100644 --- a/plugins/alias.py +++ b/plugins/alias.py @@ -71,15 +71,19 @@ from poezio.core.structs import Completion class Plugin(BasePlugin): def init(self): - self.api.add_command('alias', self.command_alias, - usage=' [args]', - short='Create an alias command', - help='Create an alias for with [args].') - self.api.add_command('unalias', self.command_unalias, - usage='', - help='Remove a previously created alias', - short='Remove an alias', - completion=self.completion_unalias) + self.api.add_command( + 'alias', + self.command_alias, + usage=' [args]', + short='Create an alias command', + help='Create an alias for with [args].') + self.api.add_command( + 'unalias', + self.command_unalias, + usage='', + help='Remove a previously created alias', + short='Remove an alias', + completion=self.completion_unalias) self.commands = {} self.load_conf() @@ -114,18 +118,18 @@ class Plugin(BasePlugin): self.config.set(alias, command + ' ' + args) self.commands[alias] = command_wrapper( - generic_command, lambda: self.get_command(command), args) + generic_command, lambda: self.get_command(command), args) self.api.del_command(alias) - self.api.add_command(alias, self.commands[alias], - 'This command is an alias for /%s %s' % - (alias, command)) + self.api.add_command( + alias, self.commands[alias], + 'This command is an alias for /%s %s' % (alias, command)) if not silent: if update: self.api.information('Alias /%s updated' % alias, 'Info') else: self.api.information('Alias /%s successfuly created' % alias, - 'Info') + 'Info') def command_unalias(self, alias): """ @@ -135,19 +139,23 @@ class Plugin(BasePlugin): del self.commands[alias] self.api.del_command(alias) self.config.remove(alias) - self.api.information('Alias /%s successfuly deleted' % alias, 'Info') + self.api.information('Alias /%s successfuly deleted' % alias, + 'Info') def completion_unalias(self, the_input): "Completion for /unalias" aliases = [alias for alias in self.commands] aliases.sort() - return Completion(the_input.auto_completion, aliases, '', quotify=False) + return Completion( + the_input.auto_completion, aliases, '', quotify=False) def get_command(self, name): """Returns the function associated with a command""" + def dummy(args): """Dummy function called if the command doesn’t exist""" pass + if name in self.commands: return dummy elif name in self.core.commands: @@ -156,6 +164,7 @@ class Plugin(BasePlugin): return self.api.current_tab().commands[name].func return dummy + def split_args(line): """ Extract the relevant vars from the command line @@ -165,16 +174,17 @@ def split_args(line): return None alias_pos = line.find(' ') alias = line[:alias_pos] - end = line[alias_pos+1:] + end = line[alias_pos + 1:] args_pos = end.find(' ') if args_pos == -1: command = end args = '' else: command = end[:args_pos] - args = end[args_pos+1:] + args = end[args_pos + 1:] return (alias, command, args) + def generic_command(command, extra_args, args): """ Function that will execute the command and set the relevant @@ -187,10 +197,11 @@ def generic_command(command, extra_args, args): new_extra_args += ' '.join(args) return command()(new_extra_args) + def command_wrapper(func, command, extra_args): "set the predefined arguments" + def wrapper(*args, **kwargs): return func(command, extra_args, *args, **kwargs) - return wrapper - + return wrapper diff --git a/plugins/amsg.py b/plugins/amsg.py index eea6a0c3..b8ac4e26 100644 --- a/plugins/amsg.py +++ b/plugins/amsg.py @@ -19,12 +19,15 @@ Command from poezio.plugin import BasePlugin from poezio.tabs import MucTab + class Plugin(BasePlugin): def init(self): - self.api.add_command('amsg', self.command_amsg, - usage='', - short='Broadcast a message', - help='Broadcast the message to all the joined rooms.') + self.api.add_command( + 'amsg', + self.command_amsg, + usage='', + short='Broadcast a message', + help='Broadcast the message to all the joined rooms.') def command_amsg(self, args): for room in self.core.tabs: diff --git a/plugins/autocorrect.py b/plugins/autocorrect.py index 32611483..6e83436d 100644 --- a/plugins/autocorrect.py +++ b/plugins/autocorrect.py @@ -49,7 +49,10 @@ from poezio.plugin import BasePlugin import re allowed_separators = '/#!:;' -sed_re = re.compile('^([sr])(?P[%s])(.+?)(?P=sep)(.*?)((?P=sep)|(?P=sep)g)?$' % allowed_separators) +sed_re = re.compile( + '^([sr])(?P[%s])(.+?)(?P=sep)(.*?)((?P=sep)|(?P=sep)g)?$' % + allowed_separators) + class Plugin(BasePlugin): def init(self): @@ -79,8 +82,9 @@ class Plugin(BasePlugin): else: new_body = re.sub(remove, put, body, count=1) except Exception as e: - self.api.information('Invalid regex for the autocorrect ' - 'plugin: %s' % e, 'Error') + self.api.information( + 'Invalid regex for the autocorrect ' + 'plugin: %s' % e, 'Error') return elif typ == 'r': if replace_all: diff --git a/plugins/bob.py b/plugins/bob.py index 527692b3..be56ef4a 100644 --- a/plugins/bob.py +++ b/plugins/bob.py @@ -34,36 +34,43 @@ from mimetypes import guess_type class Plugin(BasePlugin): - default_config = {'bob': {'max_size': 2048, - 'max_age': 86400}} + default_config = {'bob': {'max_size': 2048, 'max_age': 86400}} def init(self): for tab in tabs.ConversationTab, tabs.PrivateTab, tabs.MucTab: - self.api.add_tab_command(tab, 'bob', self.command_bob, - usage='', - help='Send image to the current discussion', - short='Send a short image', - completion=self.completion_bob) + self.api.add_tab_command( + tab, + 'bob', + self.command_bob, + usage='', + help='Send image to the current discussion', + short='Send a short image', + completion=self.completion_bob) def command_bob(self, filename): path = Path(expanduser(filename)) try: size = path.stat().st_size except OSError as exc: - self.api.information('Error sending “%s”: %s' % (path.name, exc), 'Error') + self.api.information('Error sending “%s”: %s' % (path.name, exc), + 'Error') return mime_type = guess_type(path.as_posix())[0] if mime_type is None or not mime_type.startswith('image/'): - self.api.information('Error sending “%s”, not an image file.' % path.name, 'Error') + self.api.information( + 'Error sending “%s”, not an image file.' % path.name, 'Error') return if size > self.config.get('max_size'): - self.api.information('Error sending “%s”, file too big.' % path.name, 'Error') + self.api.information( + 'Error sending “%s”, file too big.' % path.name, 'Error') return with open(path.as_posix(), 'rb') as file: data = file.read() max_age = self.config.get('max_age') - cid = self.core.xmpp.plugin['xep_0231'].set_bob(data, mime_type, max_age=max_age) - self.api.run_command('/xhtml %s' % (cid, path.name)) + cid = self.core.xmpp.plugin['xep_0231'].set_bob( + data, mime_type, max_age=max_age) + self.api.run_command( + '/xhtml %s' % (cid, path.name)) @staticmethod def completion_bob(the_input): diff --git a/plugins/capslock.py b/plugins/capslock.py index c315fcfa..7f960009 100644 --- a/plugins/capslock.py +++ b/plugins/capslock.py @@ -4,6 +4,7 @@ Once loaded, everything you will send will be IN CAPITAL LETTERS. from poezio.plugin import BasePlugin from poezio import xhtml + class Plugin(BasePlugin): def init(self): self.api.add_event_handler('muc_say', self.caps) diff --git a/plugins/close_all.py b/plugins/close_all.py index faf1d0ea..c1d1ec8b 100644 --- a/plugins/close_all.py +++ b/plugins/close_all.py @@ -18,8 +18,10 @@ from poezio.decorators import command_args_parser class Plugin(BasePlugin): def init(self): - self.api.add_command('closeall', self.command_closeall, - help='Close all non-chatroom tabs.') + self.api.add_command( + 'closeall', + self.command_closeall, + help='Close all non-chatroom tabs.') @command_args_parser.ignored def command_closeall(self): @@ -40,5 +42,3 @@ class Plugin(BasePlugin): self.core.close_tab(tab) self.api.information('%s tabs closed.' % length, 'Info') self.core.refresh_window() - - diff --git a/plugins/code.py b/plugins/code.py index 69fc79ec..1c0679f2 100644 --- a/plugins/code.py +++ b/plugins/code.py @@ -30,12 +30,15 @@ from pygments.lexers import get_lexer_by_name from pygments.formatters import HtmlFormatter FORMATTER = HtmlFormatter(nowrap=True, noclasses=True) + class Plugin(BasePlugin): def init(self): - self.api.add_command('code', self.command_code, - usage=' ', - short='Sends syntax-highlighted code', - help='Sends syntax-highlighted code in the current tab') + self.api.add_command( + 'code', + self.command_code, + usage=' ', + short='Sends syntax-highlighted code', + help='Sends syntax-highlighted code in the current tab') def command_code(self, args): language, code = args.split(None, 1) diff --git a/plugins/csi.py b/plugins/csi.py index 03a0d394..1bd6a928 100644 --- a/plugins/csi.py +++ b/plugins/csi.py @@ -22,23 +22,30 @@ Commands from poezio.plugin import BasePlugin + class Plugin(BasePlugin): def init(self): - self.api.add_command('csi_active', self.command_active, - help='Set the client state indication to “active”', - short='Manual set active') - self.api.add_command('csi_inactive', self.command_inactive, - help='Set the client state indication to “inactive”', - short='Manual set inactive') + self.api.add_command( + 'csi_active', + self.command_active, + help='Set the client state indication to “active”', + short='Manual set active') + self.api.add_command( + 'csi_inactive', + self.command_inactive, + help='Set the client state indication to “inactive”', + short='Manual set inactive') def command_active(self, args): if not self.core.xmpp.plugin['xep_0352'].enabled: - self.api.information('CSI is not enabled in this server', 'Warning') + self.api.information('CSI is not enabled in this server', + 'Warning') else: self.core.xmpp.plugin['xep_0352'].send_active() def command_inactive(self, args): if not self.core.xmpp.plugin['xep_0352'].enabled: - self.api.information('CSI is not enabled in this server', 'Warning') + self.api.information('CSI is not enabled in this server', + 'Warning') else: self.core.xmpp.plugin['xep_0352'].send_inactive() diff --git a/plugins/cyber.py b/plugins/cyber.py index cb6e0371..c7d4aba7 100644 --- a/plugins/cyber.py +++ b/plugins/cyber.py @@ -21,9 +21,9 @@ from poezio.plugin import BasePlugin from random import choice, randint import re - DEFAULT_CONFIG = {'cyber': {'frequency': 10}} + class Plugin(BasePlugin): default_config = DEFAULT_CONFIG @@ -34,7 +34,9 @@ class Plugin(BasePlugin): def cyberize(self, msg, tab): if randint(1, 100) > self.config.get('frequency'): return - words = [word for word in re.split('\W+', msg['body']) if len(word) > 3] + words = [ + word for word in re.split('\W+', msg['body']) if len(word) > 3 + ] if words: word = choice(words) msg['body'] = msg['body'].replace(word, 'cyber' + word) diff --git a/plugins/day_change.py b/plugins/day_change.py index 2bd56358..051b447b 100644 --- a/plugins/day_change.py +++ b/plugins/day_change.py @@ -10,6 +10,7 @@ import datetime from poezio import tabs from poezio import timed_events + class Plugin(BasePlugin): def init(self): self.schedule_event() @@ -18,7 +19,8 @@ class Plugin(BasePlugin): self.api.remove_timed_event(self.next_event) def schedule_event(self): - day_change = datetime.datetime.combine(datetime.date.today(), datetime.time()) + day_change = datetime.datetime.combine(datetime.date.today(), + datetime.time()) day_change += datetime.timedelta(1) self.next_event = timed_events.TimedEvent(day_change, self.day_change) self.api.add_timed_event(self.next_event) diff --git a/plugins/dice.py b/plugins/dice.py index 9fed11f9..376ed26a 100644 --- a/plugins/dice.py +++ b/plugins/dice.py @@ -36,10 +36,15 @@ from poezio.plugin import BasePlugin DICE = '\u2680\u2681\u2682\u2683\u2684\u2685' + class DiceRoll: - __slots__ = ['duration', 'total_duration', 'dice_number', 'msgtype', - 'jid', 'last_msgid', 'increments'] - def __init__(self, total_duration, dice_number, is_muc, jid, msgid, increments): + __slots__ = [ + 'duration', 'total_duration', 'dice_number', 'msgtype', 'jid', + 'last_msgid', 'increments' + ] + + def __init__(self, total_duration, dice_number, is_muc, jid, msgid, + increments): self.duration = 0 self.total_duration = total_duration self.dice_number = dice_number @@ -54,14 +59,18 @@ class DiceRoll: def is_finished(self): return self.duration >= self.total_duration + class Plugin(BasePlugin): default_config = {"dice": {"refresh": 0.5, "default_duration": 5}} def init(self): for tab_t in [tabs.MucTab, tabs.ConversationTab, tabs.PrivateTab]: - self.api.add_tab_command(tab_t, 'roll', self.command_dice, - help='Roll a die', - usage='[number] [duration]') + self.api.add_tab_command( + tab_t, + 'roll', + self.command_dice, + help='Roll a die', + usage='[number] [duration]') @command_args_parser.quoted(0, 2, ['', ''], True) def command_dice(self, args): @@ -86,8 +95,10 @@ class Plugin(BasePlugin): is_muctab = isinstance(tab, tabs.MucTab) msg_id = tab.last_sent_message["id"] increment = self.config.get('refresh') - roll = DiceRoll(duration, num_dice, is_muctab, tab.name, msg_id, increment) - event = self.api.create_delayed_event(increment, self.delayed_event, roll) + roll = DiceRoll(duration, num_dice, is_muctab, tab.name, msg_id, + increment) + event = self.api.create_delayed_event(increment, self.delayed_event, + roll) self.api.add_timed_event(event) def delayed_event(self, roll): @@ -96,7 +107,8 @@ class Plugin(BasePlugin): roll.reroll() message = self.core.xmpp.make_message(roll.jid) message["type"] = roll.msgtype - message["body"] = ''.join(random.choice(DICE) for _ in range(roll.dice_number)) + message["body"] = ''.join( + random.choice(DICE) for _ in range(roll.dice_number)) message["replace"]["id"] = roll.last_msgid message.send() roll.last_msgid = message['id'] diff --git a/plugins/disco.py b/plugins/disco.py index e2cdd0b0..f6769146 100644 --- a/plugins/disco.py +++ b/plugins/disco.py @@ -18,12 +18,15 @@ Usage from poezio.plugin import BasePlugin from slixmpp.jid import InvalidJID + class Plugin(BasePlugin): def init(self): - self.api.add_command('disco', self.command_disco, - usage='', - short='Get the disco#info of a JID', - help='Get the disco#info of a JID') + self.api.add_command( + 'disco', + self.command_disco, + usage='', + short='Get the disco#info of a JID', + help='Get the disco#info of a JID') def on_disco(self, iq): info = iq['disco_info'] @@ -40,14 +43,15 @@ class Plugin(BasePlugin): continue sep = '\n ' + len(var) * ' ' field_value = field.get_value(convert=False) - value = sep.join(field_value) if isinstance(field_value, list) else field_value + value = sep.join(field_value) if isinstance(field_value, + list) else field_value server_info.append('%s: %s' % (var, value)) if server_info: self.api.information('\n'.join(server_info), title) def command_disco(self, jid): try: - self.core.xmpp.plugin['xep_0030'].get_info(jid=jid, cached=False, - callback=self.on_disco) + self.core.xmpp.plugin['xep_0030'].get_info( + jid=jid, cached=False, callback=self.on_disco) except InvalidJID as e: self.api.information('Invalid JID “%s”: %s' % (jid, e), 'Error') diff --git a/plugins/display_corrections.py b/plugins/display_corrections.py index 8ed75e8b..22eb196d 100644 --- a/plugins/display_corrections.py +++ b/plugins/display_corrections.py @@ -26,14 +26,18 @@ from poezio.plugin import BasePlugin from poezio.common import shell_split from poezio import tabs + class Plugin(BasePlugin): def init(self): for tab_type in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab): - self.api.add_tab_command(tab_type, 'display_corrections', - handler=self.command_display_corrections, - usage='', - help='Display all the corrections of the number-th last corrected message.', - short='Display the corrections of a message') + self.api.add_tab_command( + tab_type, + 'display_corrections', + handler=self.command_display_corrections, + usage='', + help= + 'Display all the corrections of the number-th last corrected message.', + short='Display the corrections of a message') def find_corrected(self, nb): messages = self.api.get_conversation_messages() @@ -60,9 +64,13 @@ class Plugin(BasePlugin): if message: display = [] while message: - display.append('%s %s%s%s %s' % (message.str_time, '* ' if message.me else '', message.nickname, '' if message.me else '>', message.txt)) + display.append('%s %s%s%s %s' % + (message.str_time, '* ' + if message.me else '', message.nickname, '' + if message.me else '>', message.txt)) message = message.old_message - self.api.information('Older versions:\n' + '\n'.join(display[::-1]), 'Info') + self.api.information( + 'Older versions:\n' + '\n'.join(display[::-1]), 'Info') else: self.api.information('No corrected message found.', 'Warning') diff --git a/plugins/double.py b/plugins/double.py index 4f6a3401..88b7f4ce 100644 --- a/plugins/double.py +++ b/plugins/double.py @@ -3,6 +3,7 @@ Double the first word of any message you send in a :ref:`muctab`, making you app """ from poezio.plugin import BasePlugin + class Plugin(BasePlugin): def init(self): self.api.add_event_handler('muc_say', self.double) diff --git a/plugins/embed.py b/plugins/embed.py index 717fc3c5..726b1eb2 100644 --- a/plugins/embed.py +++ b/plugins/embed.py @@ -17,13 +17,16 @@ from poezio import tabs from poezio.plugin import BasePlugin from poezio.theming import get_theme -class Plugin(BasePlugin): +class Plugin(BasePlugin): def init(self): for tab_t in [tabs.MucTab, tabs.ConversationTab, tabs.PrivateTab]: - self.api.add_tab_command(tab_t, 'embed', self.embed_image_url, - help='Embed an image url into the contact\'s client', - usage='') + self.api.add_tab_command( + tab_t, + 'embed', + self.embed_image_url, + help='Embed an image url into the contact\'s client', + usage='') def embed_image_url(self, args): tab = self.api.current_tab() diff --git a/plugins/exec.py b/plugins/exec.py index 7869f233..0786c86f 100644 --- a/plugins/exec.py +++ b/plugins/exec.py @@ -40,34 +40,48 @@ from poezio import common import asyncio import subprocess + class Plugin(BasePlugin): def init(self): - self.api.add_command('exec', self.command_exec, - usage='[-o|-O] ', - help='Execute a shell command and prints the result in the information buffer. The command should be ONE argument, that means it should be between \"\". The first argument (before the command) can be -o or -O. If -o is specified, it sends the result in the current conversation. If -O is specified, it sends the command and its result in the current conversation.\nExample: /exec -O \"uptime\" will send “uptime\n20:36:19 up 3:47, 4 users, load average: 0.09, 0.13, 0.09” in the current conversation.', - short='Execute a command') + self.api.add_command( + 'exec', + self.command_exec, + usage='[-o|-O] ', + help= + 'Execute a shell command and prints the result in the information buffer. The command should be ONE argument, that means it should be between \"\". The first argument (before the command) can be -o or -O. If -o is specified, it sends the result in the current conversation. If -O is specified, it sends the command and its result in the current conversation.\nExample: /exec -O \"uptime\" will send “uptime\n20:36:19 up 3:47, 4 users, load average: 0.09, 0.13, 0.09” in the current conversation.', + short='Execute a command') async def async_exec(self, command, arg): - create = asyncio.create_subprocess_exec('sh', '-c', command, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + create = asyncio.create_subprocess_exec( + 'sh', + '-c', + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) try: process = await create except OSError as e: - self.api.information('Failed to execute command: %s' % (e,), 'Error') + self.api.information('Failed to execute command: %s' % (e, ), + 'Error') return stdout, stderr = await process.communicate() result = stdout.decode('utf-8') stderr = stderr.decode('utf-8') if arg == '-o': - if not self.api.send_message('%s' % (result,)): - self.api.information('Cannot send result (%s), this is not a conversation tab' % result, 'Error') + if not self.api.send_message('%s' % (result, )): + self.api.information( + 'Cannot send result (%s), this is not a conversation tab' % + result, 'Error') elif arg == '-O': if not self.api.send_message('%s:\n%s' % (command, result)): - self.api.information('Cannot send result (%s), this is not a conversation tab' % result, 'Error') + self.api.information( + 'Cannot send result (%s), this is not a conversation tab' % + result, 'Error') else: self.api.information('%s:\n%s' % (command, result), 'Info') if stderr: - self.api.information('stderr for %s:\n%s' % (command, stderr), 'Info') + self.api.information('stderr for %s:\n%s' % (command, stderr), + 'Info') await process.wait() def command_exec(self, args): diff --git a/plugins/figlet.py b/plugins/figlet.py index 6e82381b..b8fcb813 100644 --- a/plugins/figlet.py +++ b/plugins/figlet.py @@ -14,6 +14,7 @@ Say something in a Chat tab. from poezio.plugin import BasePlugin import subprocess + class Plugin(BasePlugin): def init(self): self.api.add_event_handler('muc_say', self.figletize) @@ -21,6 +22,7 @@ class Plugin(BasePlugin): self.api.add_event_handler('private_say', self.figletize) def figletize(self, msg, tab): - process = subprocess.Popen(['figlet', '--', msg['body']], stdout=subprocess.PIPE) + process = subprocess.Popen( + ['figlet', '--', msg['body']], stdout=subprocess.PIPE) result = process.communicate()[0].decode('utf-8') msg['body'] = result diff --git a/plugins/iq_show.py b/plugins/iq_show.py index 7e77a897..ad8f9e77 100644 --- a/plugins/iq_show.py +++ b/plugins/iq_show.py @@ -6,9 +6,11 @@ from poezio.plugin import BasePlugin from slixmpp.xmlstream.matcher import StanzaPath from slixmpp.xmlstream.handler import Callback + class Plugin(BasePlugin): def init(self): - self.core.xmpp.register_handler(Callback('Iq_show', StanzaPath('iq'), self.handle_iq)) + self.core.xmpp.register_handler( + Callback('Iq_show', StanzaPath('iq'), self.handle_iq)) def handle_iq(self, iq): self.api.information('%s' % iq, 'Iq') diff --git a/plugins/irc.py b/plugins/irc.py index 8a9f8946..10ff5bc9 100644 --- a/plugins/irc.py +++ b/plugins/irc.py @@ -135,48 +135,56 @@ from poezio.core.structs import Completion from poezio import common from poezio import tabs -class Plugin(BasePlugin): +class Plugin(BasePlugin): def init(self): if self.config.get('initial_connect', True): self.initial_connect() - self.api.add_command('irc_login', self.command_irc_login, - usage='[server] [server]…', - help=('Connect to the specified servers if they ' - 'exist in the configuration and the login ' - 'options are set. If not is given, the ' - 'plugin will try all the sections in the ' - 'configuration.'), - short='Login to irc servers with nickserv', - completion=self.completion_irc_login) - - self.api.add_command('irc_join', self.command_irc_join, - usage='', - help=('Join in the same server as the ' - 'current tab (if it is an IRC tab). Or ' - 'join all the preconfigured rooms in ' - ' '), - short='Join irc rooms more easily', - completion=self.completion_irc_join) - - self.api.add_command('irc_query', self.command_irc_query, - usage=' [message]', - help=('Open a private conversation with the ' - 'given , on the current IRC ' - 'server. Optionally immediately send ' - 'the given message. For example, if the ' - 'current tab is #foo%irc.example.com@' - 'biboumi.example.com, doing `/irc_query ' - 'nick "hi there"` is equivalent to ' - '`/message nick%irc.example.com@biboumi.' - 'example.com "hi there"`'), - short='Open a private conversation with an IRC user') + self.api.add_command( + 'irc_login', + self.command_irc_login, + usage='[server] [server]…', + help=('Connect to the specified servers if they ' + 'exist in the configuration and the login ' + 'options are set. If not is given, the ' + 'plugin will try all the sections in the ' + 'configuration.'), + short='Login to irc servers with nickserv', + completion=self.completion_irc_login) + + self.api.add_command( + 'irc_join', + self.command_irc_join, + usage='', + help=('Join in the same server as the ' + 'current tab (if it is an IRC tab). Or ' + 'join all the preconfigured rooms in ' + ' '), + short='Join irc rooms more easily', + completion=self.completion_irc_join) + + self.api.add_command( + 'irc_query', + self.command_irc_query, + usage=' [message]', + help=('Open a private conversation with the ' + 'given , on the current IRC ' + 'server. Optionally immediately send ' + 'the given message. For example, if the ' + 'current tab is #foo%irc.example.com@' + 'biboumi.example.com, doing `/irc_query ' + 'nick "hi there"` is equivalent to ' + '`/message nick%irc.example.com@biboumi.' + 'example.com "hi there"`'), + short='Open a private conversation with an IRC user') def join(self, gateway, server): "Join irc rooms on a server" - nick = self.config.get_by_tabname('nickname', server, default='') or self.core.own_nick - rooms = self.config.get_by_tabname('rooms', server, default='').split(':') + nick = self.config.get_by_tabname( + 'nickname', server, default='') or self.core.own_nick + rooms = self.config.get_by_tabname( + 'rooms', server, default='').split(':') for room in rooms: room = '{}%{}@{}/{}'.format(room, server, gateway, nick) self.core.command.join(room) @@ -195,23 +203,31 @@ class Plugin(BasePlugin): already_opened = True break - login_command = self.config.get_by_tabname('login_command', section, default='') - login_nick = self.config.get_by_tabname('login_nick', section, default='') - nick = self.config.get_by_tabname('nickname', section, default='') or self.core.own_nick + login_command = self.config.get_by_tabname( + 'login_command', section, default='') + login_nick = self.config.get_by_tabname( + 'login_nick', section, default='') + nick = self.config.get_by_tabname( + 'nickname', section, default='') or self.core.own_nick if login_command and login_nick: + def login(gw, sect, log_nick, log_cmd, room_suff): dest = '{}%{}'.format(log_nick, room_suff) - self.core.xmpp.send_message(mto=dest, mbody=log_cmd, mtype='chat') - delayed = self.api.create_delayed_event(5, self.join, gw, sect) + self.core.xmpp.send_message( + mto=dest, mbody=log_cmd, mtype='chat') + delayed = self.api.create_delayed_event( + 5, self.join, gw, sect) self.api.add_timed_event(delayed) + if not already_opened: self.core.command.join(room_suffix + '/' + nick) - delayed = self.api.create_delayed_event(5, login, gateway, section, - login_nick, login_command, - room_suffix[1:]) + delayed = self.api.create_delayed_event( + 5, login, gateway, section, login_nick, login_command, + room_suffix[1:]) self.api.add_timed_event(delayed) else: - login(gateway, section, login_nick, login_command, room_suffix[1:]) + login(gateway, section, login_nick, login_command, + room_suffix[1:]) elif not already_opened: self.join(gateway, section) @@ -228,32 +244,41 @@ class Plugin(BasePlugin): if section not in sections: not_present.append(section) continue - login_command = self.config.get_by_tabname('login_command', section, default='') - login_nick = self.config.get_by_tabname('login_nick', section, default='') + login_command = self.config.get_by_tabname( + 'login_command', section, default='') + login_nick = self.config.get_by_tabname( + 'login_nick', section, default='') if not login_command and not login_nick: not_present.append(section) continue room_suffix = '%{}@{}'.format(section, gateway) dest = '{}%{}'.format(login_nick, room_suffix[1:]) - self.core.xmpp.send_message(mto=dest, mbody=login_command, mtype='chat') + self.core.xmpp.send_message( + mto=dest, mbody=login_command, mtype='chat') if len(not_present) == 1: - self.api.information('Section %s does not exist or is not configured' % not_present[0], 'Warning') + self.api.information( + 'Section %s does not exist or is not configured' % + not_present[0], 'Warning') elif len(not_present) > 1: - self.api.information('Sections %s do not exist or are not configured' % ', '.join(not_present), 'Warning') + self.api.information( + 'Sections %s do not exist or are not configured' % + ', '.join(not_present), 'Warning') else: sections = self.config.sections() for section in (s for s in sections if s != 'irc'): - login_command = self.config.get_by_tabname('login_command', section, default='') - login_nick = self.config.get_by_tabname('login_nick', section, default='') + login_command = self.config.get_by_tabname( + 'login_command', section, default='') + login_nick = self.config.get_by_tabname( + 'login_nick', section, default='') if not login_nick and not login_command: continue room_suffix = '%{}@{}'.format(section, gateway) dest = '{}%{}'.format(login_nick, room_suffix[1:]) - self.core.xmpp.send_message(mto=dest, mbody=login_command, mtype='chat') - + self.core.xmpp.send_message( + mto=dest, mbody=login_command, mtype='chat') def completion_irc_login(self, the_input): """ @@ -283,7 +308,8 @@ class Plugin(BasePlugin): sections = self.config.sections() if 'irc' in sections: sections.remove('irc') - if args[0] in sections and self.config.get_by_tabname('rooms', args[0]): + if args[0] in sections and self.config.get_by_tabname( + 'rooms', args[0]): self.join_server_rooms(args[0]) else: self.join_room(args[0]) @@ -352,7 +378,8 @@ class Plugin(BasePlugin): current = self.core.current_tab() current_jid = common.safeJID(current.name) if not current_jid.server == gateway: - self.api.information('The current tab does not appear to be an IRC one', 'Warning') + self.api.information( + 'The current tab does not appear to be an IRC one', 'Warning') return None if isinstance(current, tabs.OneToOneTab): if '%' not in current_jid.node: @@ -365,7 +392,8 @@ class Plugin(BasePlugin): else: ignored, server = current_jid.node.rsplit('%', 1) else: - self.api.information('The current tab does not appear to be an IRC one', 'Warning') + self.api.information( + 'The current tab does not appear to be an IRC one', 'Warning') return None return server, gateway @@ -377,5 +405,3 @@ class Plugin(BasePlugin): if 'irc' in sections: sections.remove('irc') return Completion(the_input.new_completion, sections, 1) - - diff --git a/plugins/link.py b/plugins/link.py index c8c75918..352d403d 100644 --- a/plugins/link.py +++ b/plugins/link.py @@ -87,21 +87,27 @@ from poezio.xhtml import clean_text from poezio import common from poezio import tabs -url_pattern = re.compile(r'\b(?:http[s]?://(?:\S+))|(?:magnet:\?(?:\S+))\b', re.I|re.U) +url_pattern = re.compile(r'\b(?:http[s]?://(?:\S+))|(?:magnet:\?(?:\S+))\b', + re.I | re.U) app_mapping = { 'Linux': 'xdg-open', 'Darwin': 'open', } + class Plugin(BasePlugin): def init(self): for _class in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab): - self.api.add_tab_command(_class, 'link', self.command_link, - usage='[num] [command]', - help='Opens the last link from the conversation into a browser.\n\ + self.api.add_tab_command( + _class, + 'link', + self.command_link, + usage='[num] [command]', + help= + 'Opens the last link from the conversation into a browser.\n\ If [num] is given, then it will\open the num-th link displayed. \ Use a [command] argument to override the configured browser value.', - short='Open links into a browser') + short='Open links into a browser') def find_link(self, nb): messages = self.api.get_conversation_messages() @@ -140,20 +146,24 @@ class Plugin(BasePlugin): start = int(start) end = int(end) except ValueError: - return self.api.information('Invalid range: %s' % (args[0]), 'Error') + return self.api.information( + 'Invalid range: %s' % (args[0]), 'Error') command = None if len(args) == 2: command = args[1] - if len(args) == 1 and (not args[0][0].isnumeric() and args[0][0] != ":"): + if len(args) == 1 and (not args[0][0].isnumeric() + and args[0][0] != ":"): command = args[0] - for nb in range(start, end+1): + for nb in range(start, end + 1): link = self.find_link(nb) if not link: return self.api.information('No URL found.', 'Warning') default = app_mapping.get(platform.system(), 'firefox') if command is None: - self.core.exec_command([self.config.get('browser', default), link]) + self.core.exec_command( + [self.config.get('browser', default), link]) else: self.core.exec_command([command, link]) + def cleanup(self): del self.config diff --git a/plugins/marquee.py b/plugins/marquee.py index 6abaa344..bad06301 100644 --- a/plugins/marquee.py +++ b/plugins/marquee.py @@ -39,17 +39,27 @@ from poezio import tabs from poezio import xhtml from poezio.decorators import command_args_parser + def move(text, step, spacing): new_text = text + (" " * spacing) - return new_text[-(step % len(new_text)):] + new_text[:-(step % len(new_text))] + return new_text[-(step % len(new_text)):] + new_text[:-( + step % len(new_text))] + class Plugin(BasePlugin): - default_config = {"marquee": {"refresh": 1.0, "total_duration": 30, "padding": 20}} + default_config = { + "marquee": { + "refresh": 1.0, + "total_duration": 30, + "padding": 20 + } + } def init(self): for tab_t in [tabs.MucTab, tabs.ConversationTab, tabs.PrivateTab]: - self.add_tab_command(tab_t, 'marquee', self.command_marquee, - 'Replicate the behavior in a message') + self.add_tab_command( + tab_t, 'marquee', self.command_marquee, + 'Replicate the behavior in a message') @command_args_parser.raw def command_marquee(self, args): @@ -60,10 +70,9 @@ class Plugin(BasePlugin): msg_id = tab.last_sent_message["id"] jid = tab.name - event = self.api.create_delayed_event(self.config.get("refresh"), - self.delayed_event, - jid, args, msg_id, 1, 0, - is_muctab) + event = self.api.create_delayed_event( + self.config.get("refresh"), self.delayed_event, jid, args, msg_id, + 1, 0, is_muctab) self.api.add_timed_event(event) def delayed_event(self, jid, body, msg_id, step, duration, is_muctab): @@ -74,11 +83,8 @@ class Plugin(BasePlugin): message["body"] = move(body, step, self.config.get("padding")) message["replace"]["id"] = msg_id message.send() - event = self.api.create_delayed_event(self.config.get("refresh"), - self.delayed_event, jid, body, - message["id"], step + 1, - duration + self.config.get("refresh"), - is_muctab) + event = self.api.create_delayed_event( + self.config.get("refresh"), self.delayed_event, jid, body, + message["id"], step + 1, duration + self.config.get("refresh"), + is_muctab) self.api.add_timed_event(event) - - diff --git a/plugins/mirror.py b/plugins/mirror.py index b410422f..116d16b1 100644 --- a/plugins/mirror.py +++ b/plugins/mirror.py @@ -13,13 +13,16 @@ Command from poezio.plugin import BasePlugin from poezio import tabs + class Plugin(BasePlugin): def init(self): for tab_type in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab): - self.api.add_tab_command(tab_type, 'mirror', - handler=self.mirror, - help='Repeat the last message from the conversation.', - short='Repeat the last message from the conversation.') + self.api.add_tab_command( + tab_type, + 'mirror', + handler=self.mirror, + help='Repeat the last message from the conversation.', + short='Repeat the last message from the conversation.') def mirror(self, args): messages = self.api.get_conversation_messages() diff --git a/plugins/mpd_client.py b/plugins/mpd_client.py index 6115c0da..c5cd88b8 100644 --- a/plugins/mpd_client.py +++ b/plugins/mpd_client.py @@ -54,34 +54,44 @@ from os.path import basename as base from poezio import tabs import mpd + class Plugin(BasePlugin): def init(self): for _class in (tabs.ConversationTab, tabs.MucTab, tabs.PrivateTab): - self.api.add_tab_command(_class, 'mpd', self.command_mpd, - usage='[full]', - help='Sends a message showing the current song of an MPD instance. If full is provided, the message is more verbose.', - short='Send the MPD status', - completion=self.completion_mpd) + self.api.add_tab_command( + _class, + 'mpd', + self.command_mpd, + usage='[full]', + help= + 'Sends a message showing the current song of an MPD instance. If full is provided, the message is more verbose.', + short='Send the MPD status', + completion=self.completion_mpd) def command_mpd(self, args): args = shell_split(args) c = mpd.MPDClient() - c.connect(host=self.config.get('host', 'localhost'), port=self.config.get('port', '6600')) + c.connect( + host=self.config.get('host', 'localhost'), + port=self.config.get('port', '6600')) password = self.config.get('password', '') if password: c.password(password) current = c.currentsong() artist = current.get('artist', 'Unknown artist') album = current.get('album', 'Unknown album') - title = current.get('title', base(current.get('file', 'Unknown title'))) + title = current.get('title', base( + current.get('file', 'Unknown title'))) s = '%s - %s (%s)' % (artist, title, album) if 'full' in args: if 'elapsed' in current and 'time' in current: current_time = float(c.status()['elapsed']) percents = int(current_time / float(current['time']) * 10) - s += ' \x192}[\x191}' + '-'*(percents-1) + '\x193}+' + '\x191}' + '-' * (10-percents-1) + '\x192}]\x19o' - if not self.api.send_message('%s' % (s,)): + s += ' \x192}[\x191}' + '-' * ( + percents - 1) + '\x193}+' + '\x191}' + '-' * ( + 10 - percents - 1) + '\x192}]\x19o' + if not self.api.send_message('%s' % (s, )): self.api.information('Cannot send result (%s)' % s, 'Error') def completion_mpd(self, the_input): diff --git a/plugins/otr.py b/plugins/otr.py index d5e45384..1e5944a8 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -207,8 +207,8 @@ from poezio.decorators import command_args_parser from poezio.core.structs import Completion POLICY_FLAGS = { - 'ALLOW_V1':False, - 'ALLOW_V2':True, + 'ALLOW_V1': False, + 'ALLOW_V2': True, 'REQUIRE_ENCRYPTION': False, 'SEND_TAG': True, 'WHITESPACE_START_AKE': True, @@ -217,9 +217,7 @@ POLICY_FLAGS = { log = logging.getLogger(__name__) - -OTR_TUTORIAL = _( -"""%(info)sThis contact has not yet been verified. +OTR_TUTORIAL = _("""%(info)sThis contact has not yet been verified. You have several methods of authentication available: 1) Verify each other's fingerprints using a secure (and different) channel: @@ -259,8 +257,7 @@ OTR_OWN_FPR = _('%(info)sYour OTR key fingerprint is ' OTR_REMOTE_FPR = _('%(info)sThe key fingerprint for %(jid_c)s' '%(jid)s%(info)s is %(normal)s%(fpr)s%(info)s.') -OTR_NO_FPR = _('%(jid_c)s%(jid)s%(info)s has no' - ' key currently in use.') +OTR_NO_FPR = _('%(jid_c)s%(jid)s%(info)s has no' ' key currently in use.') OTR_START_TRUSTED = _('%(info)sStarted a \x19btrusted\x19o%(info)s ' 'OTR conversation with %(jid_c)s%(jid)s') @@ -315,7 +312,6 @@ POTR_ERROR = _('%(info)sAn unspecified error in the OTR plugin occured:\n' TRUST_ADDED = _('%(info)sYou added %(jid_c)s%(bare_jid)s%(info)s with key ' '\x19o%(key)s%(info)s to your trusted list.') - TRUST_REMOVED = _('%(info)sYou removed %(jid_c)s%(bare_jid)s%(info)s with ' 'key \x19o%(key)s%(info)s from your trusted list.') @@ -331,15 +327,18 @@ def hl(tab): conv_jid = safeJID(tab.name) if 'private' in config.get('beep_on', 'highlight private').split(): - if not config.get_by_tabname('disable_beep', conv_jid.bare, default=False): + if not config.get_by_tabname( + 'disable_beep', conv_jid.bare, default=False): curses.beep() + class PoezioContext(Context): """ OTR context, specific to a conversation with a contact Overrides methods from potr.context.Context """ + def __init__(self, account, peer, xmpp, core): super(PoezioContext, self).__init__(account, peer) self.xmpp = xmpp @@ -361,9 +360,8 @@ class PoezioContext(Context): self.smp_own = False def inject(self, msg, appdata=None): - message = self.xmpp.make_message(mto=self.peer, - mbody=msg.decode('ascii'), - mtype='chat') + message = self.xmpp.make_message( + mto=self.peer, mbody=msg.decode('ascii'), mtype='chat') message['eme']['namespace'] = 'urn:xmpp:otr:0' message.enable('carbon_private') message.enable('no-copy') @@ -404,15 +402,18 @@ class PoezioContext(Context): format_dict['our_fpr'] = self.user.getPrivkey() format_dict['remote_fpr'] = self.getCurrentKey() tab.add_message(OTR_TUTORIAL % format_dict, typ=0) - tab.add_message(OTR_START_UNTRUSTED % format_dict, typ=self.log) + tab.add_message( + OTR_START_UNTRUSTED % format_dict, typ=self.log) hl(tab) - log.debug('Set encryption state of %s to %s', self.peer, states[newstate]) + log.debug('Set encryption state of %s to %s', self.peer, + states[newstate]) super(PoezioContext, self).setState(newstate) if tab: self.core.refresh_window() self.core.doupdate() + class PoezioAccount(Account): """ OTR Account, keeps track of a specific account (ours) @@ -435,7 +436,8 @@ class PoezioAccount(Account): try: os.remove(self.key_dir + '.key3') except: - log.exception('Error in drop_privkey (removing %s)', self.key_dir + '.key3') + log.exception('Error in drop_privkey (removing %s)', + self.key_dir + '.key3') self.privkey = None def save_privkey(self): @@ -465,7 +467,8 @@ class PoezioAccount(Account): with open(self.key_dir + '.fpr', 'w') as fpr_fd: for uid, trusts in self.trusts.items(): for fpr, trustVal in trusts.items(): - fpr_fd.write('\t'.join((uid, self.name, 'xmpp', fpr, trustVal))) + fpr_fd.write('\t'.join((uid, self.name, 'xmpp', fpr, + trustVal))) fpr_fd.write('\n') except: log.exception('Error in save_trusts', exc_info=True) @@ -475,37 +478,46 @@ class PoezioAccount(Account): loadPrivkey = load_privkey savePrivkey = save_privkey + states = { STATE_PLAINTEXT: 'plaintext', STATE_ENCRYPTED: 'encrypted', STATE_FINISHED: 'finished', } -class Plugin(BasePlugin): +class Plugin(BasePlugin): def init(self): # set the default values from the config keys_dir = self.config.get('keys_dir', '') - otr_dir = Path(keys_dir).expanduser() if keys_dir else xdg.DATA_HOME / 'otr' + otr_dir = Path( + keys_dir).expanduser() if keys_dir else xdg.DATA_HOME / 'otr' try: otr_dir.mkdir(parents=True, exist_ok=True) except OSError as e: - self.api.information('The OTR-specific folder could not ' - 'be created: %s. Poezio will be unable ' - 'to save keys and trusts' % e, 'OTR') + self.api.information( + 'The OTR-specific folder could not ' + 'be created: %s. Poezio will be unable ' + 'to save keys and trusts' % e, 'OTR') except Exception as e: - self.api.information('The OTR-specific folder could not ' - 'be created. Poezio will be unable ' - 'to save keys and trusts', 'OTR') + self.api.information( + 'The OTR-specific folder could not ' + 'be created. Poezio will be unable ' + 'to save keys and trusts', 'OTR') - self.api.add_event_handler('conversation_msg', self.on_conversation_msg) + self.api.add_event_handler('conversation_msg', + self.on_conversation_msg) self.api.add_event_handler('private_msg', self.on_conversation_msg) - self.api.add_event_handler('conversation_say_after', self.on_conversation_say) - self.api.add_event_handler('private_say_after', self.on_conversation_say) + self.api.add_event_handler('conversation_say_after', + self.on_conversation_say) + self.api.add_event_handler('private_say_after', + self.on_conversation_say) - StaticConversationTab.add_information_element('otr', self.display_encryption_status) - PrivateTab.add_information_element('otr', self.display_encryption_status) + StaticConversationTab.add_information_element( + 'otr', self.display_encryption_status) + PrivateTab.add_information_element('otr', + self.display_encryption_status) self.core.xmpp.plugin['xep_0030'].add_feature('urn:xmpp:otr:0') @@ -524,24 +536,45 @@ class Plugin(BasePlugin): 'untrust: Remove the trust for the key of this contact\n') smp_usage = ' [question] [answer]' smp_short = 'Identify a contact' - smp_desc = ('Verify the identify of your contact by using a pre-defined secret.\n' - 'abort: Abort an ongoing verification\n' - 'ask: Start a verification, with a question or not\n' - 'answer: Finish a verification\n') - - self.api.add_tab_command(StaticConversationTab, 'otrsmp', self.command_smp, - help=smp_desc, usage=smp_usage, short=smp_short, - completion=self.completion_smp) - self.api.add_tab_command(PrivateTab, 'otrsmp', self.command_smp, - help=smp_desc, usage=smp_usage, short=smp_short, - completion=self.completion_smp) - - self.api.add_tab_command(StaticConversationTab, 'otr', self.command_otr, - help=desc, usage=usage, short=shortdesc, - completion=self.completion_otr) - self.api.add_tab_command(PrivateTab, 'otr', self.command_otr, - help=desc, usage=usage, short=shortdesc, - completion=self.completion_otr) + smp_desc = ( + 'Verify the identify of your contact by using a pre-defined secret.\n' + 'abort: Abort an ongoing verification\n' + 'ask: Start a verification, with a question or not\n' + 'answer: Finish a verification\n') + + self.api.add_tab_command( + StaticConversationTab, + 'otrsmp', + self.command_smp, + help=smp_desc, + usage=smp_usage, + short=smp_short, + completion=self.completion_smp) + self.api.add_tab_command( + PrivateTab, + 'otrsmp', + self.command_smp, + help=smp_desc, + usage=smp_usage, + short=smp_short, + completion=self.completion_smp) + + self.api.add_tab_command( + StaticConversationTab, + 'otr', + self.command_otr, + help=desc, + usage=usage, + short=shortdesc, + completion=self.completion_otr) + self.api.add_tab_command( + PrivateTab, + 'otr', + self.command_otr, + help=desc, + usage=usage, + short=shortdesc, + completion=self.completion_otr) def cleanup(self): for context in self.contexts.values(): @@ -559,11 +592,13 @@ class Plugin(BasePlugin): jid = safeJID(jid) if jid.full not in self.contexts: flags = POLICY_FLAGS.copy() - require = self.config.get_by_tabname('require_encryption', - jid.bare, default=False) + require = self.config.get_by_tabname( + 'require_encryption', jid.bare, default=False) flags['REQUIRE_ENCRYPTION'] = require - logging_policy = self.config.get_by_tabname('log', jid.bare , default=False) - self.contexts[jid.full] = PoezioContext(self.account, jid.full, self.core.xmpp, self.core) + logging_policy = self.config.get_by_tabname( + 'log', jid.bare, default=False) + self.contexts[jid.full] = PoezioContext(self.account, jid.full, + self.core.xmpp, self.core) self.contexts[jid.full].log = 1 if logging_policy else 0 self.contexts[jid.full].flags = flags return self.contexts[jid.full] @@ -574,7 +609,7 @@ class Plugin(BasePlugin): """ format_dict = { 'jid_c': '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID), - 'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT), + 'info': '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'jid': msg['from'] } try: @@ -594,13 +629,16 @@ class Plugin(BasePlugin): # if we expected an OTR message, we would have # got an UnencryptedMesssage # but do an additional check because of a bug with potr and py3k - if ctx.state != STATE_PLAINTEXT or ctx.getPolicy('REQUIRE_ENCRYPTION'): - self.unencrypted_message_received(err, ctx, msg, tab, format_dict) + if ctx.state != STATE_PLAINTEXT or ctx.getPolicy( + 'REQUIRE_ENCRYPTION'): + self.unencrypted_message_received(err, ctx, msg, tab, + format_dict) self.otr_start(tab, tab.name, format_dict) return except ErrorReceived as err: # Received an OTR error - format_dict['err'] = err.args[0].error.decode('utf-8', errors='replace') + format_dict['err'] = err.args[0].error.decode( + 'utf-8', errors='replace') tab.add_message(OTR_ERROR % format_dict, typ=0) del msg['body'] del msg['html'] @@ -658,9 +696,12 @@ class Plugin(BasePlugin): # Received an SMP request (with a question or not) if smp1q: try: - question = ' with question: \x19o' + smp1q.msg.decode('utf-8') + question = ' with question: \x19o' + smp1q.msg.decode( + 'utf-8') except UnicodeDecodeError: - self.api.information('The peer sent a question but it had a wrong encoding', 'Error') + self.api.information( + 'The peer sent a question but it had a wrong encoding', + 'Error') question = '' else: question = '' @@ -720,13 +761,12 @@ class Plugin(BasePlugin): nick_color = get_theme().COLOR_REMOTE_USER body = txt.decode() - decode_entities = self.config.get_by_tabname('decode_entities', - msg['from'].bare, - default=True) - decode_newlines = self.config.get_by_tabname('decode_newlines', - msg['from'].bare, - default=True) - if self.config.get_by_tabname('decode_xhtml', msg['from'].bare, default=True): + decode_entities = self.config.get_by_tabname( + 'decode_entities', msg['from'].bare, default=True) + decode_newlines = self.config.get_by_tabname( + 'decode_newlines', msg['from'].bare, default=True) + if self.config.get_by_tabname( + 'decode_xhtml', msg['from'].bare, default=True): try: body = xhtml.xhtml_to_poezio_colors(body, force=True) except Exception: @@ -739,9 +779,13 @@ class Plugin(BasePlugin): body = html.unescape(body) if decode_newlines: body = body.replace('
', '\n').replace('
', '\n') - tab.add_message(body, nickname=tab.nick, jid=msg['from'], - forced_user=user, typ=ctx.log, - nick_color=nick_color) + tab.add_message( + body, + nickname=tab.nick, + jid=msg['from'], + forced_user=user, + typ=ctx.log, + nick_color=nick_color) hl(tab) self.core.refresh_window() del msg['body'] @@ -751,7 +795,9 @@ class Plugin(BasePlugin): Find an OTR session from a bare JID. """ for ctx in self.contexts: - if safeJID(ctx).bare == bare_jid and self.contexts[ctx].state == STATE_ENCRYPTED: + if safeJID( + ctx + ).bare == bare_jid and self.contexts[ctx].state == STATE_ENCRYPTED: return self.contexts[ctx] return None @@ -779,12 +825,13 @@ class Plugin(BasePlugin): if not tab.send_chat_state('active'): tab.send_chat_state('inactive', always_send=True) - tab.add_message(msg['body'], - nickname=self.core.own_nick or tab.own_nick, - nick_color=get_theme().COLOR_OWN_NICK, - identifier=msg['id'], - jid=self.core.xmpp.boundjid, - typ=ctx.log) + tab.add_message( + msg['body'], + nickname=self.core.own_nick or tab.own_nick, + nick_color=get_theme().COLOR_OWN_NICK, + identifier=msg['id'], + jid=self.core.xmpp.boundjid, + typ=ctx.log) # remove everything from the message so that it doesn’t get sent del msg['body'] del msg['replace'] @@ -797,14 +844,16 @@ class Plugin(BasePlugin): del msg['html'] self.otr_start(tab, name, format_dict) elif not is_relevant(tab) and ctx and ( - ctx.state == STATE_ENCRYPTED or ctx.getPolicy('REQUIRE_ENCRYPTION')): + ctx.state == STATE_ENCRYPTED + or ctx.getPolicy('REQUIRE_ENCRYPTION')): contact = roster[tab.name] res = [] if contact: res = [resource.jid for resource in contact.resources] help_msg = '' if res: - help_msg = TAB_HELP_RESOURCE % ''.join(('\n - /message %s' % jid) for jid in res) + help_msg = TAB_HELP_RESOURCE % ''.join( + ('\n - /message %s' % jid) for jid in res) format_dict['help'] = help_msg warning_msg = INCOMPATIBLE_TAB % format_dict tab.add_message(warning_msg, typ=0) @@ -844,7 +893,7 @@ class Plugin(BasePlugin): 'bare_jid': safeJID(name).bare } - if action == 'end': # close the session + if action == 'end': # close the session context = self.get_context(name) context.disconnect() elif action == 'start' or action == 'refresh': @@ -898,6 +947,7 @@ class Plugin(BasePlugin): Start an otr conversation with a contact """ secs = self.config.get('timeout', 3) + def notify_otr_timeout(): tab_name = tab.name otr = self.find_encrypted_context_with_matching(tab_name) @@ -906,6 +956,7 @@ class Plugin(BasePlugin): text = OTR_NOT_ENABLED % format_dict tab.add_message(text, typ=0) self.core.refresh_window() + if secs > 0: event = self.api.create_delayed_event(secs, notify_otr_timeout) self.api.add_timed_event(event) @@ -974,7 +1025,11 @@ class Plugin(BasePlugin): def completion_smp(the_input): """Completion for /otrsmp""" if the_input.get_argument_position() == 1: - return Completion(the_input.new_completion, ['ask', 'answer', 'abort'], 1, quotify=False) + return Completion( + the_input.new_completion, ['ask', 'answer', 'abort'], + 1, + quotify=False) + def get_tlv(tlvs, cls): """Find the instance of a class in a list""" @@ -982,6 +1037,7 @@ def get_tlv(tlvs, cls): if isinstance(tlv, cls): return tlv + def is_relevant(tab): """Check if a tab should be concerned with OTR""" return isinstance(tab, (StaticConversationTab, PrivateTab)) diff --git a/plugins/pacokick.py b/plugins/pacokick.py index bf6bd844..4ec9d0af 100644 --- a/plugins/pacokick.py +++ b/plugins/pacokick.py @@ -17,21 +17,26 @@ from poezio.tabs import MucTab from poezio.plugin import BasePlugin + class Plugin(BasePlugin): def init(self): - self.api.add_command('pacokick', self.command_kick, - usage='', - help='Kick a random user.', - short='Kick a random user') + self.api.add_command( + 'pacokick', + self.command_kick, + usage='', + help='Kick a random user.', + short='Kick a random user') def command_kick(self, arg): tab = self.api.current_tab() if isinstance(tab, MucTab): - kickable = list(filter(lambda x: x.affiliation in ('none', 'member'), tab.users)) + kickable = list( + filter(lambda x: x.affiliation in ('none', 'member'), + tab.users)) if kickable: to_kick = choice(kickable) if to_kick: to_kick = to_kick.nick - tab.command_kick(to_kick + ' ' +arg) + tab.command_kick(to_kick + ' ' + arg) else: self.api.information('No one to kick :(', 'Info') diff --git a/plugins/ping.py b/plugins/ping.py index d373fc22..4868ccf9 100644 --- a/plugins/ping.py +++ b/plugins/ping.py @@ -34,27 +34,39 @@ import time class Plugin(BasePlugin): def init(self): - self.api.add_command('ping', self.command_ping, - usage='', - help='Send an XMPP ping to jid (see XEP-0199).', + self.api.add_command( + 'ping', + self.command_ping, + usage='', + help='Send an XMPP ping to jid (see XEP-0199).', + short='Send a ping', + completion=self.completion_ping) + self.api.add_tab_command( + tabs.MucTab, + 'ping', + self.command_muc_ping, + usage='', + help='Send an XMPP ping to jid or nick (see XEP-0199).', + short='Send a ping.', + completion=self.completion_muc_ping) + self.api.add_tab_command( + tabs.RosterInfoTab, + 'ping', + self.command_roster_ping, + usage='', + help='Send an XMPP ping to jid (see XEP-0199).', + short='Send a ping.', + completion=self.completion_ping) + for _class in (tabs.PrivateTab, tabs.ConversationTab): + self.api.add_tab_command( + _class, + 'ping', + self.command_private_ping, + usage='[jid]', + help= + 'Send an XMPP ping to the current interlocutor or the given JID.', short='Send a ping', completion=self.completion_ping) - self.api.add_tab_command(tabs.MucTab, 'ping', self.command_muc_ping, - usage='', - help='Send an XMPP ping to jid or nick (see XEP-0199).', - short='Send a ping.', - completion=self.completion_muc_ping) - self.api.add_tab_command(tabs.RosterInfoTab, 'ping', self.command_roster_ping, - usage='', - help='Send an XMPP ping to jid (see XEP-0199).', - short='Send a ping.', - completion=self.completion_ping) - for _class in (tabs.PrivateTab, tabs.ConversationTab): - self.api.add_tab_command(_class, 'ping', self.command_private_ping, - usage='[jid]', - help='Send an XMPP ping to the current interlocutor or the given JID.', - short='Send a ping', - completion=self.completion_ping) @command_args_parser.raw def command_ping(self, arg): @@ -62,6 +74,7 @@ class Plugin(BasePlugin): return self.core.command.help('ping') jid = safeJID(arg) start = time.time() + def callback(iq): delay = time.time() - start error = False @@ -72,7 +85,8 @@ class Plugin(BasePlugin): # These IQ errors are not ping errors: # 'service-unavailable': official "not supported" response as of RFC6120 (§8.4) and XEP-0199 (§4.1) # 'feature-not-implemented': inoffcial not-supported response from many clients - if error_condition not in ('service-unavailable', 'feature-not-implemented'): + if error_condition not in ('service-unavailable', + 'feature-not-implemented'): error = True error_text = iq['error']['text'] if error_text: @@ -81,12 +95,16 @@ class Plugin(BasePlugin): message = '%s did not respond to ping: %s' % (jid, reply) else: reply = ' (%s)' % reply if reply else '' - message = '%s responded to ping after %ss%s' % (jid, round(delay, 4), reply) + message = '%s responded to ping after %ss%s' % ( + jid, round(delay, 4), reply) self.api.information(message, 'Info') + def timeout(iq): - self.api.information('%s did not respond to ping after 10s: timeout' % jid, 'Info') + self.api.information( + '%s did not respond to ping after 10s: timeout' % jid, 'Info') - self.core.xmpp.plugin['xep_0199'].send_ping(jid=jid, callback=callback, timeout=10, timeout_callback=timeout) + self.core.xmpp.plugin['xep_0199'].send_ping( + jid=jid, callback=callback, timeout=10, timeout_callback=timeout) def completion_muc_ping(self, the_input): users = [user.nick for user in self.api.current_tab().users] @@ -133,5 +151,5 @@ class Plugin(BasePlugin): return l def completion_ping(self, the_input): - return Completion(the_input.auto_completion, self.resources(), '', quotify=False) - + return Completion( + the_input.auto_completion, self.resources(), '', quotify=False) diff --git a/plugins/pipe_cmd.py b/plugins/pipe_cmd.py index 186df216..28d6f874 100644 --- a/plugins/pipe_cmd.py +++ b/plugins/pipe_cmd.py @@ -18,7 +18,6 @@ Configuration """ - from poezio.plugin import BasePlugin import os import stat @@ -29,6 +28,7 @@ log = logging.getLogger(__name__) PIPENAME = "/tmp/poezio.fifo" + class Plugin(BasePlugin): def init(self): self.stop = False @@ -41,7 +41,7 @@ class Plugin(BasePlugin): if not stat.S_ISFIFO(os.stat(self.pipename).st_mode): raise TypeError("File %s is not a fifo file" % self.pipename) - self.fd = os.open(self.pipename, os.O_RDONLY|os.O_NONBLOCK) + self.fd = os.open(self.pipename, os.O_RDONLY | os.O_NONBLOCK) self.data = b"" asyncio.get_event_loop().add_reader(self.fd, self.read_from_fifo) @@ -52,7 +52,7 @@ class Plugin(BasePlugin): # EOF, close the fifo. And reopen it asyncio.get_event_loop().remove_reader(self.fd) os.close(self.fd) - self.fd = os.open(self.pipename, os.O_RDONLY|os.O_NONBLOCK) + self.fd = os.open(self.pipename, os.O_RDONLY | os.O_NONBLOCK) asyncio.get_event_loop().add_reader(self.fd, self.read_from_fifo) self.data = b'' else: diff --git a/plugins/pointpoint.py b/plugins/pointpoint.py index 88daae5f..dd1ae1c7 100644 --- a/plugins/pointpoint.py +++ b/plugins/pointpoint.py @@ -36,10 +36,13 @@ Command from poezio.plugin import BasePlugin from random import randrange + class Plugin(BasePlugin): def init(self): - self.api.add_command('pointpoint', self.command_pointpoint, - help='Insert a random number of dots in the input') + self.api.add_command( + 'pointpoint', + self.command_pointpoint, + help='Insert a random number of dots in the input') def command_pointpoint(self, args): for i in range(randrange(8, 25)): diff --git a/plugins/quote.py b/plugins/quote.py index a5ffd193..b412cd9a 100644 --- a/plugins/quote.py +++ b/plugins/quote.py @@ -53,14 +53,18 @@ from poezio import tabs import logging log = logging.getLogger(__name__) + class Plugin(BasePlugin): def init(self): for _class in (tabs.MucTab, tabs.ConversationTab, tabs.PrivateTab): - self.api.add_tab_command(_class, 'quote', self.command_quote, - usage='', - help='Quote the message you typed if it exists.', - short='Quote a message.', - completion=self.completion_quote) + self.api.add_tab_command( + _class, + 'quote', + self.command_quote, + usage='', + help='Quote the message you typed if it exists.', + short='Quote a message.', + completion=self.completion_quote) def command_quote(self, args): args = common.shell_split(args) @@ -70,13 +74,20 @@ class Plugin(BasePlugin): return self.api.run_command('/help quote') message = self.find_message(message) if message: - before = self.config.get('before_quote', '') % {'nick': message.nickname or '', - 'time': message.str_time} - after = self.config.get('after_quote', '') % {'nick': message.nickname or '', - 'time': message.str_time} - self.core.insert_input_text('%(before)s%(quote)s%(after)s' % {'before': before.replace('\\n', '\n').replace('[SP]', ' '), - 'quote': clean_text(message.txt), - 'after': after.replace('\\n', '\n').replace('[SP]', ' ')}) + before = self.config.get('before_quote', '') % { + 'nick': message.nickname or '', + 'time': message.str_time + } + after = self.config.get('after_quote', '') % { + 'nick': message.nickname or '', + 'time': message.str_time + } + self.core.insert_input_text( + '%(before)s%(quote)s%(after)s' % { + 'before': before.replace('\\n', '\n').replace('[SP]', ' '), + 'quote': clean_text(message.txt), + 'after': after.replace('\\n', '\n').replace('[SP]', ' ') + }) else: self.api.information('No message found', 'Warning') @@ -92,6 +103,7 @@ class Plugin(BasePlugin): def completion_quote(self, the_input): def message_match(msg): return input_message.lower() in clean_text(msg.txt).lower() + messages = self.api.get_conversation_messages() if not messages: return @@ -102,5 +114,5 @@ class Plugin(BasePlugin): messages = list(filter(message_match, messages)) elif len(args) > 1: return False - return Completion(the_input.auto_completion, [clean_text(msg.txt) for msg in messages[::-1]], '') - + return Completion(the_input.auto_completion, + [clean_text(msg.txt) for msg in messages[::-1]], '') diff --git a/plugins/rainbow.py b/plugins/rainbow.py index bb9ab8a3..4ab0b9ac 100644 --- a/plugins/rainbow.py +++ b/plugins/rainbow.py @@ -22,11 +22,15 @@ import random possible_colors = list(range(256)) # remove the colors that are almost white or almost black -for col in [16, 232, 233, 234, 235, 236, 237, 15, 231, 255, 254, 253, 252, 251]: +for col in [ + 16, 232, 233, 234, 235, 236, 237, 15, 231, 255, 254, 253, 252, 251 +]: possible_colors.remove(col) + def rand_color(): - return '\x19%s}' % (random.choice(possible_colors),) + return '\x19%s}' % (random.choice(possible_colors), ) + class Plugin(BasePlugin): def init(self): @@ -35,4 +39,9 @@ class Plugin(BasePlugin): self.api.add_event_handler('conversation_say', self.rainbowize) def rainbowize(self, msg, tab): - msg['body'] = ''.join(['%s%s' % (rand_color(),char,) for char in xhtml.clean_text(msg['body'])]) + msg['body'] = ''.join([ + '%s%s' % ( + rand_color(), + char, + ) for char in xhtml.clean_text(msg['body']) + ]) diff --git a/plugins/random_nick.py b/plugins/random_nick.py index 643c79f0..0f3f0272 100644 --- a/plugins/random_nick.py +++ b/plugins/random_nick.py @@ -14,6 +14,7 @@ automatically be changed to something random, for example: :: from poezio.plugin import BasePlugin from random import choice + class Plugin(BasePlugin): def init(self): self.api.add_event_handler('joining_muc', self.change_nick_to_random) @@ -25,8 +26,13 @@ class Plugin(BasePlugin): to.resource = gen_nick(3) presence["to"] = to + s = ["i", "ou", "ou", "on", "a", "o", "u", "i"] -c = ["b", "c", "d", "f", "g", "h", "j", "k", "m", "l", "n", "p", "r", "s", "t", "v", "z"] +c = [ + "b", "c", "d", "f", "g", "h", "j", "k", "m", "l", "n", "p", "r", "s", "t", + "v", "z" +] + def gen_nick(size): res = '' diff --git a/plugins/regex_admin.py b/plugins/regex_admin.py index b5ca3581..befbcac2 100644 --- a/plugins/regex_admin.py +++ b/plugins/regex_admin.py @@ -25,25 +25,29 @@ Those commands take a regular expression (as defined in the .. _re module documentation: http://docs.python.org/3/library/re.html """ - from poezio.plugin import BasePlugin from poezio.tabs import MucTab import re + class Plugin(BasePlugin): def init(self): - self.api.add_tab_command(MucTab, 'rkick', - self.command_rkick, - usage='', - help='Kick occupants of a room according to a regex', - short='Regex Kick') - - self.api.add_tab_command(MucTab, 'rban', - self.command_rban, - usage='', - help='Ban occupants of a room according to a regex', - short='Regex Ban') + self.api.add_tab_command( + MucTab, + 'rkick', + self.command_rkick, + usage='', + help='Kick occupants of a room according to a regex', + short='Regex Kick') + + self.api.add_tab_command( + MucTab, + 'rban', + self.command_rban, + usage='', + help='Ban occupants of a room according to a regex', + short='Regex Ban') def return_users(self, users, regex): try: @@ -69,4 +73,3 @@ class Plugin(BasePlugin): users = self.return_users(tab.users, regex) for user in users: tab.command_kick(user.nick) - diff --git a/plugins/reminder.py b/plugins/reminder.py index e3ba64cb..e5ed96c0 100644 --- a/plugins/reminder.py +++ b/plugins/reminder.py @@ -53,23 +53,29 @@ from poezio import timed_events from poezio import common import curses -class Plugin(BasePlugin): +class Plugin(BasePlugin): def init(self): - self.api.add_command('remind', self.command_remind, - usage=' ', - help='Remind you of every