summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/admin.py93
-rw-r--r--plugins/alias.py51
-rw-r--r--plugins/amsg.py11
-rw-r--r--plugins/autocorrect.py10
-rw-r--r--plugins/bob.py31
-rw-r--r--plugins/capslock.py1
-rw-r--r--plugins/close_all.py8
-rw-r--r--plugins/code.py11
-rw-r--r--plugins/csi.py23
-rw-r--r--plugins/cyber.py6
-rw-r--r--plugins/day_change.py4
-rw-r--r--plugins/dice.py30
-rw-r--r--plugins/disco.py18
-rw-r--r--plugins/display_corrections.py22
-rw-r--r--plugins/double.py1
-rw-r--r--plugins/embed.py11
-rw-r--r--plugins/exec.py36
-rw-r--r--plugins/figlet.py4
-rw-r--r--plugins/iq_show.py4
-rw-r--r--plugins/irc.py140
-rw-r--r--plugins/link.py28
-rw-r--r--plugins/marquee.py36
-rw-r--r--plugins/mirror.py11
-rw-r--r--plugins/mpd_client.py28
-rw-r--r--plugins/otr.py212
-rw-r--r--plugins/pacokick.py17
-rw-r--r--plugins/ping.py68
-rw-r--r--plugins/pipe_cmd.py6
-rw-r--r--plugins/pointpoint.py7
-rw-r--r--plugins/quote.py40
-rw-r--r--plugins/rainbow.py15
-rw-r--r--plugins/random_nick.py8
-rw-r--r--plugins/regex_admin.py29
-rw-r--r--plugins/reminder.py61
-rw-r--r--plugins/reorder.py22
-rw-r--r--plugins/replace.py8
-rw-r--r--plugins/replace_word.py1
-rw-r--r--plugins/revstr.py1
-rw-r--r--plugins/rstrip.py4
-rw-r--r--plugins/screen_detach.py15
-rw-r--r--plugins/send_delayed.py24
-rw-r--r--plugins/server_part.py13
-rw-r--r--plugins/shuffle.py1
-rw-r--r--plugins/simple_notify.py24
-rw-r--r--plugins/spaces.py1
-rw-r--r--plugins/spam.py4
-rw-r--r--plugins/status.py13
-rw-r--r--plugins/stoi.py20
-rw-r--r--plugins/tell.py38
-rw-r--r--plugins/test.py10
-rw-r--r--plugins/time_marker.py6
-rw-r--r--plugins/upload.py18
-rw-r--r--plugins/uptime.py17
-rw-r--r--plugins/vcard.py213
-rw-r--r--plugins/white.py1
55 files changed, 1006 insertions, 529 deletions
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= '<nick>',
- 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='<nick>',
+ 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='<nick>',
- 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='<nick>',
- 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='<nick>',
- 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='<nick>',
- 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='<nick>',
- 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='<nick>',
+ 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='<nick>',
+ 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='<nick>',
+ 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='<nick>',
+ 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='<nick>',
+ 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='<alias> <command> [args]',
- short='Create an alias command',
- help='Create an alias for <command> with [args].')
- self.api.add_command('unalias', self.command_unalias,
- usage='<alias>',
- help='Remove a previously created alias',
- short='Remove an alias',
- completion=self.completion_unalias)
+ self.api.add_command(
+ 'alias',
+ self.command_alias,
+ usage='<alias> <command> [args]',
+ short='Create an alias command',
+ help='Create an alias for <command> with [args].')
+ self.api.add_command(
+ 'unalias',
+ self.command_unalias,
+ usage='<alias>',
+ 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='<message>',
- short='Broadcast a message',
- help='Broadcast the message to all the joined rooms.')
+ self.api.add_command(
+ 'amsg',
+ self.command_amsg,
+ usage='<message>',
+ 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<sep>[%s])(.+?)(?P=sep)(.*?)((?P=sep)|(?P=sep)g)?$' % allowed_separators)
+sed_re = re.compile(
+ '^([sr])(?P<sep>[%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='<image>',
- help='Send image <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='<image>',
+ help='Send image <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 <img src="cid:%s" alt="%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 <img src="cid:%s" alt="%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='<language> <code>',
- short='Sends syntax-highlighted code',
- help='Sends syntax-highlighted code in the current tab')
+ self.api.add_command(
+ 'code',
+ self.command_code,
+ usage='<language> <code>',
+ 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='<JID>',
- 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='<JID>',
+ 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='<number>',
- 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='<number>',
+ 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='<image_url>')
+ self.api.add_tab_command(
+ tab_t,
+ 'embed',
+ self.embed_image_url,
+ help='Embed an image url into the contact\'s client',
+ usage='<image_url>')
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] <command>',
- 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] <command>',
+ 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='<room or server>',
- help=('Join <room> in the same server as the '
- 'current tab (if it is an IRC tab). Or '
- 'join all the preconfigured rooms in '
- '<server> '),
- short='Join irc rooms more easily',
- completion=self.completion_irc_join)
-
- self.api.add_command('irc_query', self.command_irc_query,
- usage='<nickname> [message]',
- help=('Open a private conversation with the '
- 'given <nickname>, 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='<room or server>',
+ help=('Join <room> in the same server as the '
+ 'current tab (if it is an IRC tab). Or '
+ 'join all the preconfigured rooms in '
+ '<server> '),
+ short='Join irc rooms more easily',
+ completion=self.completion_irc_join)
+
+ self.api.add_command(
+ 'irc_query',
+ self.command_irc_query,
+ usage='<nickname> [message]',
+ help=('Open a private conversation with the '
+ 'given <nickname>, 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 <marquee/> behavior in a message')
+ self.add_tab_command(
+ tab_t, 'marquee', self.command_marquee,
+ 'Replicate the <marquee/> 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 = '<abort|ask|answer> [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('<br/>', '\n').replace('<br>', '\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='<jid>',
- help='Send an XMPP ping to jid (see XEP-0199).',
+ self.api.add_command(
+ 'ping',
+ self.command_ping,
+ usage='<jid>',
+ 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='<jid|nick>',
+ 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='<jid>',
+ 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='<jid|nick>',
- 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='<jid>',
- 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='<message>',
- 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='<message>',
+ 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='<regex>',
- help='Kick occupants of a room according to a regex',
- short='Regex Kick')
-
- self.api.add_tab_command(MucTab, 'rban',
- self.command_rban,
- usage='<regex>',
- help='Ban occupants of a room according to a regex',
- short='Regex Ban')
+ self.api.add_tab_command(
+ MucTab,
+ 'rkick',
+ self.command_rkick,
+ usage='<regex>',
+ help='Kick occupants of a room according to a regex',
+ short='Regex Kick')
+
+ self.api.add_tab_command(
+ MucTab,
+ 'rban',
+ self.command_rban,
+ usage='<regex>',
+ 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='<seconds> <todo>',
- help='Remind you of <todo> every <time> seconds.',
- short='Remind you of a task',
- completion=self.completion_remind)
- self.api.add_command('done', self.command_done,
- usage='<id>',
- help='Stop reminding you do the task identified by <id>.',
- short='Remove a task',
- completion=self.completion_done)
- self.api.add_command('tasks', self.command_tasks,
- usage='',
- help='List all the current tasks and their ids.',
- short='List current tasks')
+ self.api.add_command(
+ 'remind',
+ self.command_remind,
+ usage='<seconds> <todo>',
+ help='Remind you of <todo> every <time> seconds.',
+ short='Remind you of a task',
+ completion=self.completion_remind)
+ self.api.add_command(
+ 'done',
+ self.command_done,
+ usage='<id>',
+ help='Stop reminding you do the task identified by <id>.',
+ short='Remove a task',
+ completion=self.completion_done)
+ self.api.add_command(
+ 'tasks',
+ self.command_tasks,
+ usage='',
+ help='List all the current tasks and their ids.',
+ short='List current tasks')
self.tasks = {}
self.count = 0
@@ -97,8 +103,10 @@ class Plugin(BasePlugin):
self.tasks[self.count] = (time, args[1])
timed_event = timed_events.DelayedEvent(time, self.remind, self.count)
self.api.add_timed_event(timed_event)
- self.api.information('Task %s added: %s every %s.' % (self.count, args[1],
- common.parse_secs_to_str(time)), 'Info')
+ self.api.information(
+ 'Task %s added: %s every %s.' % (self.count, args[1],
+ common.parse_secs_to_str(time)),
+ 'Info')
self.count += 1
def completion_remind(self, the_input):
@@ -108,10 +116,13 @@ class Plugin(BasePlugin):
if txt.endswith(' '):
n += 1
if n == 2:
- return Completion(the_input.auto_completion, ["60", "5m", "15m", "30m", "1h", "10h", "1d"], '')
+ return Completion(the_input.auto_completion,
+ ["60", "5m", "15m", "30m", "1h", "10h", "1d"],
+ '')
def completion_done(self, the_input):
- return Completion(the_input.auto_completion, ["%s" % key for key in self.tasks], '')
+ return Completion(the_input.auto_completion,
+ ["%s" % key for key in self.tasks], '')
def command_done(self, arg="0"):
try:
@@ -121,7 +132,8 @@ class Plugin(BasePlugin):
if id_ not in self.tasks:
return
- self.api.information('Task %s: %s [DONE]' % (id_, self.tasks[id_][1]), 'Info')
+ self.api.information('Task %s: %s [DONE]' % (id_, self.tasks[id_][1]),
+ 'Info')
del self.tasks[id_]
def command_tasks(self, arg, nocommand=None):
@@ -131,7 +143,8 @@ class Plugin(BasePlugin):
s = 'The following tasks are active:\n'
for key in self.tasks:
s += 'Task %s: %s every %s.\n' % (key, repr(self.tasks[key][1]),
- common.parse_secs_to_str(self.tasks[key][0]))
+ common.parse_secs_to_str(
+ self.tasks[key][0]))
if s:
self.api.information(s, 'Info')
@@ -141,7 +154,8 @@ class Plugin(BasePlugin):
self.api.information('Task %s: %s' % (id_, self.tasks[id_][1]), 'Info')
if self.config.get('beep', '') == 'true':
curses.beep()
- timed_event = timed_events.DelayedEvent(self.tasks[id_][0], self.remind, id_)
+ timed_event = timed_events.DelayedEvent(self.tasks[id_][0],
+ self.remind, id_)
self.api.add_timed_event(timed_event)
def cleanup(self):
@@ -149,5 +163,6 @@ class Plugin(BasePlugin):
self.config.remove_section(self.__module__)
self.config.add_section(self.__module__)
for task in self.tasks:
- self.config.set('%s,%s' % (task, self.tasks[task][0]), self.tasks[task][1])
+ self.config.set('%s,%s' % (task, self.tasks[task][0]),
+ self.tasks[task][1])
self.config.write()
diff --git a/plugins/reorder.py b/plugins/reorder.py
index 5ba23c59..7308196d 100644
--- a/plugins/reorder.py
+++ b/plugins/reorder.py
@@ -80,6 +80,7 @@ TAB_TO_TEXT = {
tabs.GapTab: 'empty'
}
+
def parse_config(tab_config):
result = {}
for option in tab_config.options('reorder'):
@@ -96,12 +97,14 @@ def parse_config(tab_config):
return result
+
def check_tab(tab):
for cls, rep in TAB_TO_TEXT.items():
if isinstance(tab, cls):
return rep
return ''
+
def parse_runtime_tablist(tablist):
props = []
i = 0
@@ -112,13 +115,18 @@ def parse_runtime_tablist(tablist):
props.append((i, '%s:%s' % (result, tab.name)))
return props
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_command('reorder', self.command_reorder,
- help='Reorder all tabs using the pre-defined'
- ' layout from the configuration file.')
- self.api.add_command('save_order', self.command_save_order,
- help='Save the current tab layout')
+ self.api.add_command(
+ 'reorder',
+ self.command_reorder,
+ help='Reorder all tabs using the pre-defined'
+ ' layout from the configuration file.')
+ self.api.add_command(
+ 'save_order',
+ self.command_save_order,
+ help='Save the current tab layout')
@command_args_parser.ignored
def command_save_order(self):
@@ -145,7 +153,9 @@ class Plugin(BasePlugin):
last = 0
for pos in sorted(tabs_spec):
if create_gaps and pos > last + 1:
- new_tabs += [tabs.GapTab(self.core) for i in range(pos - last - 1)]
+ new_tabs += [
+ tabs.GapTab(self.core) for i in range(pos - last - 1)
+ ]
cls, name = tabs_spec[pos]
tab = self.core.tabs.by_name_and_class(name, cls=cls)
if tab and tab in old_tabs:
diff --git a/plugins/replace.py b/plugins/replace.py
index 1949bd6a..3202721c 100644
--- a/plugins/replace.py
+++ b/plugins/replace.py
@@ -60,6 +60,7 @@ import random
import re
from slixmpp.xmlstream.stanzabase import JID
+
class Plugin(BasePlugin):
def init(self):
self.patterns = {}
@@ -81,20 +82,22 @@ class Plugin(BasePlugin):
for pattern in self.patterns:
new = body
body = re.sub('%%%s%%' % pattern,
- lambda x: self.patterns[pattern](message, tab),
- body)
+ lambda x: self.patterns[pattern](message, tab), body)
message['body'] = body
def replace_time(message, tab):
return datetime.datetime.now().strftime("%X")
+
def replace_date(message, tab):
return datetime.datetime.now().strftime("%x")
+
def replace_datetime(message, tab):
return datetime.datetime.now().strftime("%c")
+
def replace_random_user(message, tab):
if isinstance(tab, tabs.MucTab):
return random.choice(tab.users).nick
@@ -105,5 +108,6 @@ def replace_random_user(message, tab):
# ConversationTab anyway?
return str(tab.name)
+
def replace_dice(message, tab):
return str(random.randrange(1, 7))
diff --git a/plugins/replace_word.py b/plugins/replace_word.py
index ce66dff4..41e1da23 100644
--- a/plugins/replace_word.py
+++ b/plugins/replace_word.py
@@ -19,6 +19,7 @@ Just use the word in a message. It will be replaced automatically.
from poezio.plugin import BasePlugin
import re
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('conversation_say', self.replace_pattern)
diff --git a/plugins/revstr.py b/plugins/revstr.py
index 0fa93bb1..561b87fe 100644
--- a/plugins/revstr.py
+++ b/plugins/revstr.py
@@ -5,6 +5,7 @@ Reverse everything you say (``Je proteste énergiquement`` will become
from poezio.plugin import BasePlugin
from poezio import xhtml
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.revstr)
diff --git a/plugins/rstrip.py b/plugins/rstrip.py
index 3661cf2a..efbbe9d4 100644
--- a/plugins/rstrip.py
+++ b/plugins/rstrip.py
@@ -3,6 +3,7 @@ Once loaded, every line of your messages will be stripped of their trailing spac
"""
from poezio.plugin import BasePlugin
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.rstrip)
@@ -10,4 +11,5 @@ class Plugin(BasePlugin):
self.api.add_event_handler('private_say', self.rstrip)
def rstrip(self, msg, tab):
- msg['body'] = '\n'.join(line.rstrip() for line in msg['body'].split('\n'))
+ msg['body'] = '\n'.join(
+ line.rstrip() for line in msg['body'].split('\n'))
diff --git a/plugins/screen_detach.py b/plugins/screen_detach.py
index 8a00d90f..0a2514c4 100644
--- a/plugins/screen_detach.py
+++ b/plugins/screen_detach.py
@@ -40,7 +40,6 @@ DEFAULT_CONFIG = {
}
}
-
# overload if this is not how your stuff
# is configured
try:
@@ -53,6 +52,7 @@ except Exception:
SCREEN_DIR = '/var/run/screens/S-%s' % LOGIN
TMUX_DIR = '/tmp/tmux-%s' % LOGIN_TMUX
+
def find_screen(path):
if not os.path.isdir(path):
return
@@ -61,9 +61,11 @@ def find_screen(path):
if screen_attached(path):
return path
+
def screen_attached(socket):
return (os.stat(socket).st_mode & stat.S_IXUSR) != 0
+
class Plugin(BasePlugin, pyinotify.Notifier):
default_config = DEFAULT_CONFIG
@@ -79,12 +81,14 @@ class Plugin(BasePlugin, pyinotify.Notifier):
if sock_path:
self.attached = True
wm = pyinotify.WatchManager()
- wm.add_watch(sock_path, pyinotify.EventsCodes.ALL_FLAGS['IN_ATTRIB'])
- pyinotify.Notifier.__init__(self, wm, default_proc_fun=HandleScreen(plugin=self))
+ wm.add_watch(sock_path,
+ pyinotify.EventsCodes.ALL_FLAGS['IN_ATTRIB'])
+ pyinotify.Notifier.__init__(
+ self, wm, default_proc_fun=HandleScreen(plugin=self))
asyncio.get_event_loop().add_reader(self._fd, self.process)
else:
- self.api.information('screen_detach plugin: No tmux or screen found',
- 'Warning')
+ self.api.information(
+ 'screen_detach plugin: No tmux or screen found', 'Warning')
self.attached = False
def process(self):
@@ -106,6 +110,7 @@ class Plugin(BasePlugin, pyinotify.Notifier):
else:
self.core.xmpp.plugin['xep_0352'].send_inactive()
+
class HandleScreen(pyinotify.ProcessEvent):
def my_init(self, **kwargs):
self.plugin = kwargs['plugin']
diff --git a/plugins/send_delayed.py b/plugins/send_delayed.py
index 7a3ddc60..846fccd1 100644
--- a/plugins/send_delayed.py
+++ b/plugins/send_delayed.py
@@ -25,15 +25,18 @@ from poezio import tabs
from poezio import common
from poezio import timed_events
-class Plugin(BasePlugin):
+class Plugin(BasePlugin):
def init(self):
for _class in (tabs.PrivateTab, tabs.ConversationTab, tabs.MucTab):
- self.api.add_tab_command(_class, 'send_delayed', self.command_delayed,
- usage='<delay> <message>',
- help='Send <message> with a delay of <delay> seconds.',
- short='Send a message later',
- completion=self.completion_delay)
+ self.api.add_tab_command(
+ _class,
+ 'send_delayed',
+ self.command_delayed,
+ usage='<delay> <message>',
+ help='Send <message> with a delay of <delay> seconds.',
+ short='Send a message later',
+ completion=self.completion_delay)
@command_args_parser.quoted(2)
def command_delayed(self, args):
@@ -49,8 +52,9 @@ class Plugin(BasePlugin):
tab = self.api.current_tab()
timed_event = timed_events.DelayedEvent(delay, self.say, (tab, txt))
self.api.add_timed_event(timed_event)
- self.api.information('Delayed message will be sent in %ds (%s).'
- % (delay, delay_str), 'Info')
+ self.api.information(
+ 'Delayed message will be sent in %ds (%s).' % (delay, delay_str),
+ 'Info')
def completion_delay(self, the_input):
txt = the_input.get_text()
@@ -59,7 +63,9 @@ class Plugin(BasePlugin):
if txt.endswith(' '):
n += 1
if n == 2:
- return Completion(the_input.auto_completion, ["60", "5m", "15m", "30m", "1h", "10h", "1d"], '')
+ return Completion(the_input.auto_completion,
+ ["60", "5m", "15m", "30m", "1h", "10h", "1d"],
+ '')
def say(self, args=None):
if not args:
diff --git a/plugins/server_part.py b/plugins/server_part.py
index 08aa663b..7a71d94b 100644
--- a/plugins/server_part.py
+++ b/plugins/server_part.py
@@ -22,13 +22,16 @@ from poezio.decorators import command_args_parser
from poezio.common import safeJID
from poezio.core.structs import Completion
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_command('server_part', self.command_server_part,
- usage='[<server> [message]]',
- short='Leave all the rooms on a server',
- help='Leave all the rooms on a sever.',
- completion=self.completion_server_part)
+ self.api.add_command(
+ 'server_part',
+ self.command_server_part,
+ usage='[<server> [message]]',
+ short='Leave all the rooms on a server',
+ help='Leave all the rooms on a sever.',
+ completion=self.completion_server_part)
@command_args_parser.quoted(0, 2, defaults=[])
def command_server_part(self, args):
diff --git a/plugins/shuffle.py b/plugins/shuffle.py
index 1c5cfeb5..895c052c 100644
--- a/plugins/shuffle.py
+++ b/plugins/shuffle.py
@@ -6,6 +6,7 @@ from poezio.plugin import BasePlugin
from random import shuffle
from poezio import xhtml
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.shuffle)
diff --git a/plugins/simple_notify.py b/plugins/simple_notify.py
index 60482101..cfb65e9b 100644
--- a/plugins/simple_notify.py
+++ b/plugins/simple_notify.py
@@ -94,7 +94,8 @@ from poezio import common
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('private_msg', self.on_private_msg)
- self.api.add_event_handler('conversation_msg', self.on_conversation_msg)
+ self.api.add_event_handler('conversation_msg',
+ self.on_conversation_msg)
if self.config.get('muc_too', False):
self.api.add_event_handler('muc_msg', self.on_muc_msg)
self.api.add_event_handler('highlight', self.on_highlight)
@@ -138,13 +139,26 @@ class Plugin(BasePlugin):
return
command_str = self.config.get('command', '').strip()
if not command_str:
- self.api.information('No notification command was provided in the configuration file', 'Warning')
+ self.api.information(
+ 'No notification command was provided in the configuration file',
+ 'Warning')
return
- command = [arg % {'body': body.replace('\n', ' '), 'from': fro} for arg in shlex.split(command_str)]
+ command = [
+ arg % {
+ 'body': body.replace('\n', ' '),
+ 'from': fro
+ } for arg in shlex.split(command_str)
+ ]
self.core.exec_command(command)
after_command_str = self.config.get('after_command', '').strip()
if not after_command_str:
return
- after_command = [arg % {'body': body.replace('\n', ' '), 'from': fro} for arg in shlex.split(after_command_str)]
- delayed_event = DelayedEvent(self.config.get('delay', 1), self.core.exec_command, after_command)
+ after_command = [
+ arg % {
+ 'body': body.replace('\n', ' '),
+ 'from': fro
+ } for arg in shlex.split(after_command_str)
+ ]
+ delayed_event = DelayedEvent(
+ self.config.get('delay', 1), self.core.exec_command, after_command)
self.api.add_timed_event(delayed_event)
diff --git a/plugins/spaces.py b/plugins/spaces.py
index b0730b62..1d0f6e0e 100644
--- a/plugins/spaces.py
+++ b/plugins/spaces.py
@@ -5,6 +5,7 @@ them horrible to read.
from poezio.plugin import BasePlugin
from poezio import xhtml
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.add_spaces)
diff --git a/plugins/spam.py b/plugins/spam.py
index ee1e57cd..de4fa7a2 100644
--- a/plugins/spam.py
+++ b/plugins/spam.py
@@ -13,6 +13,7 @@ Configuration
from poezio.plugin import BasePlugin
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.advert)
@@ -20,4 +21,5 @@ class Plugin(BasePlugin):
self.api.add_event_handler('private_say', self.advert)
def advert(self, msg, tab):
- msg['body'] = "%s\n\n%s" % (msg['body'], self.config.get("ad", "Sent from poezio"))
+ msg['body'] = "%s\n\n%s" % (msg['body'],
+ self.config.get("ad", "Sent from poezio"))
diff --git a/plugins/status.py b/plugins/status.py
index b14e5cab..fd50481b 100644
--- a/plugins/status.py
+++ b/plugins/status.py
@@ -27,14 +27,17 @@ Aliases
"""
from poezio.plugin import BasePlugin
+
class Plugin(BasePlugin):
"""
Adds several convenient aliases to /status command
"""
+
def init(self):
for st in ('dnd', 'busy', 'afk', 'chat', 'xa', 'away', 'available'):
- self.api.add_command(st,
- lambda line,st=st: self.api.run_command('/status ' + st + ' "'+line+'"'),
- usage='[status message]',
- short='Set your status as %s' % st,
- help='Set your status as %s' % st)
+ self.api.add_command(
+ st,
+ lambda line, st=st: self.api.run_command('/status ' + st + ' "' + line + '"'),
+ usage='[status message]',
+ short='Set your status as %s' % st,
+ help='Set your status as %s' % st)
diff --git a/plugins/stoi.py b/plugins/stoi.py
index f3881879..04d84881 100644
--- a/plugins/stoi.py
+++ b/plugins/stoi.py
@@ -23,18 +23,21 @@ import string
from poezio import xhtml
import random
-char_we_dont_want = string.punctuation+' ’„“”…«»'
+char_we_dont_want = string.punctuation + ' ’„“”…«»'
+
class Plugin(BasePlugin):
def init(self):
for tab_type in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab):
- self.api.add_tab_command(tab_type, 'stoi',
- handler=self.stoi,
- help="Repeats the last word of the last "
- "message in the conversation, and "
- "use it in an annoying “C’est toi "
- "le” sentence.",
- short='C’est toi le stoi.')
+ self.api.add_tab_command(
+ tab_type,
+ 'stoi',
+ handler=self.stoi,
+ help="Repeats the last word of the last "
+ "message in the conversation, and "
+ "use it in an annoying “C’est toi "
+ "le” sentence.",
+ short='C’est toi le stoi.')
def stoi(self, args):
messages = self.api.get_conversation_messages()
@@ -55,4 +58,3 @@ class Plugin(BasePlugin):
else:
msg = intro + ('le %s' % last_word)
self.api.send_message(msg)
-
diff --git a/plugins/tell.py b/plugins/tell.py
index 870fc12e..43a91d8b 100644
--- a/plugins/tell.py
+++ b/plugins/tell.py
@@ -30,20 +30,30 @@ from poezio.core.structs import Completion
from poezio.decorators import command_args_parser
from poezio import tabs
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_tab_command(tabs.MucTab, 'tell', self.command_tell,
- usage='<nick> <message>',
- help='Will tell <nick> of <message> when he next joins.',
- short='Send a message when someone joins')
- self.api.add_tab_command(tabs.MucTab, 'untell', self.command_untell,
- usage='<nick>',
- help='Remove the planned messages from /tell.',
- short='Cancel a /tell message',
- completion=self.completion_untell)
- self.api.add_tab_command(tabs.MucTab, 'list_tell', self.command_list_tell,
- usage='',
- help='List currently queued messages')
+ self.api.add_tab_command(
+ tabs.MucTab,
+ 'tell',
+ self.command_tell,
+ usage='<nick> <message>',
+ help='Will tell <nick> of <message> when he next joins.',
+ short='Send a message when someone joins')
+ self.api.add_tab_command(
+ tabs.MucTab,
+ 'untell',
+ self.command_untell,
+ usage='<nick>',
+ help='Remove the planned messages from /tell.',
+ short='Cancel a /tell message',
+ completion=self.completion_untell)
+ self.api.add_tab_command(
+ tabs.MucTab,
+ 'list_tell',
+ self.command_list_tell,
+ usage='',
+ help='List currently queued messages')
self.api.add_event_handler('muc_join', self.on_join)
self.api.add_event_handler('muc_nickchange', self.on_join)
# {tab -> {nick -> [messages]}
@@ -102,5 +112,5 @@ class Plugin(BasePlugin):
tab = self.api.current_tab()
if tab not in self.tabs:
return Completion(the_input.auto_completion, [], '')
- return Completion(the_input.auto_completion, list(self.tabs[tab]), '', quotify=False)
-
+ return Completion(
+ the_input.auto_completion, list(self.tabs[tab]), '', quotify=False)
diff --git a/plugins/test.py b/plugins/test.py
index a518984f..72924c91 100644
--- a/plugins/test.py
+++ b/plugins/test.py
@@ -1,10 +1,13 @@
from poezio.plugin import BasePlugin
from poezio import tabs
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_command('plugintest', self.command_plugintest, 'Test command')
- self.api.add_tab_command(tabs.MucTab, 'plugintest', self.command_tab_plugintest, 'Test command')
+ self.api.add_command('plugintest', self.command_plugintest,
+ 'Test command')
+ self.api.add_tab_command(tabs.MucTab, 'plugintest',
+ self.command_tab_plugintest, 'Test command')
self.api.add_slix_event_handler('message', self.on_message)
self.api.information("Plugin loaded")
@@ -12,7 +15,8 @@ class Plugin(BasePlugin):
self.api.information("Plugin unloaded")
def on_message(self, message):
- self.api.information("Test plugin received message: {}".format(message))
+ self.api.information(
+ "Test plugin received message: {}".format(message))
def command_tab_plugintest(self, args):
self.api.information("Command for MucTabs! With args {}".format(args))
diff --git a/plugins/time_marker.py b/plugins/time_marker.py
index 43ec11e0..bd6af1c4 100644
--- a/plugins/time_marker.py
+++ b/plugins/time_marker.py
@@ -32,6 +32,7 @@ Messages like “2 hours, 25 minutes passed…” are automatically displayed in
from poezio.plugin import BasePlugin
from datetime import datetime, timedelta
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler("muc_msg", self.on_muc_msg)
@@ -70,6 +71,5 @@ class Plugin(BasePlugin):
if last_message_date:
delta = datetime.now() - last_message_date
if delta >= timedelta(0, self.config.get('delay', 900)):
- tab.add_message("%s passed…" % (format_timedelta(delta),), str_time='')
-
-
+ tab.add_message(
+ "%s passed…" % (format_timedelta(delta), ), str_time='')
diff --git a/plugins/upload.py b/plugins/upload.py
index 3b2b4075..4013243a 100644
--- a/plugins/upload.py
+++ b/plugins/upload.py
@@ -26,24 +26,28 @@ from poezio.core.structs import Completion
from poezio.decorators import command_args_parser
from poezio import tabs
-class Plugin(BasePlugin):
+class Plugin(BasePlugin):
def init(self):
if not self.core.xmpp['xep_0363']:
raise Exception('slixmpp XEP-0363 plugin failed to load')
for _class in (tabs.PrivateTab, tabs.ConversationTab, tabs.MucTab):
- self.api.add_tab_command(_class, 'upload', self.command_upload,
- usage='<filename>',
- help='Upload a file and auto-complete the input with its URL.',
- short='Upload a file',
- completion=self.completion_filename)
+ self.api.add_tab_command(
+ _class,
+ 'upload',
+ self.command_upload,
+ usage='<filename>',
+ help='Upload a file and auto-complete the input with its URL.',
+ short='Upload a file',
+ completion=self.completion_filename)
async def async_upload(self, filename):
try:
url = await self.core.xmpp['xep_0363'].upload_file(filename)
except Exception:
exception = traceback.format_exc()
- self.api.information('Failed to upload file: %s' % exception, 'Error')
+ self.api.information('Failed to upload file: %s' % exception,
+ 'Error')
return
self.core.insert_input_text(url)
diff --git a/plugins/uptime.py b/plugins/uptime.py
index 0c471e1a..d5a07b7b 100644
--- a/plugins/uptime.py
+++ b/plugins/uptime.py
@@ -15,19 +15,26 @@ from poezio.plugin import BasePlugin
from poezio.common import parse_secs_to_str, safeJID
from slixmpp.xmlstream import ET
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_command('uptime', self.command_uptime,
- usage='<jid>',
- help='Ask for the uptime of a server or component (see XEP-0012).',
- short='Get the uptime')
+ self.api.add_command(
+ 'uptime',
+ self.command_uptime,
+ usage='<jid>',
+ help='Ask for the uptime of a server or component (see XEP-0012).',
+ short='Get the uptime')
def command_uptime(self, arg):
def callback(iq):
for query in iq.xml.getiterator('{jabber:iq:last}query'):
- self.api.information('Server %s online since %s' % (iq['from'], parse_secs_to_str(int(query.attrib['seconds']))), 'Info')
+ self.api.information(
+ 'Server %s online since %s' %
+ (iq['from'], parse_secs_to_str(
+ int(query.attrib['seconds']))), 'Info')
return
self.api.information('Could not retrieve uptime', 'Error')
+
jid = safeJID(arg)
if not jid.server:
return
diff --git a/plugins/vcard.py b/plugins/vcard.py
index 759c9929..643dd569 100644
--- a/plugins/vcard.py
+++ b/plugins/vcard.py
@@ -35,29 +35,42 @@ from poezio.core.structs import Completion
from poezio import tabs
from slixmpp.jid import JID, InvalidJID
+
class Plugin(BasePlugin):
def init(self):
- self.api.add_command('vcard', self.command_vcard,
- usage='<jid>',
- help='Send an XMPP vcard request to jid (see XEP-0054).',
+ self.api.add_command(
+ 'vcard',
+ self.command_vcard,
+ usage='<jid>',
+ help='Send an XMPP vcard request to jid (see XEP-0054).',
+ short='Send a vcard request',
+ completion=self.completion_vcard)
+ self.api.add_tab_command(
+ tabs.MucTab,
+ 'vcard',
+ self.command_muc_vcard,
+ usage='<jid|nick>',
+ help='Send an XMPP vcard request to jid or nick (see XEP-0054).',
+ short='Send a vcard request.',
+ completion=self.completion_muc_vcard)
+ self.api.add_tab_command(
+ tabs.RosterInfoTab,
+ 'vcard',
+ self.command_roster_vcard,
+ usage='<jid>',
+ help='Send an XMPP vcard request to jid (see XEP-0054).',
+ short='Send a vcard request.',
+ completion=self.completion_vcard)
+ for _class in (tabs.PrivateTab, tabs.ConversationTab):
+ self.api.add_tab_command(
+ _class,
+ 'vcard',
+ self.command_private_vcard,
+ usage='[jid]',
+ help=
+ 'Send an XMPP vcard request to the current interlocutor or the given JID.',
short='Send a vcard request',
completion=self.completion_vcard)
- self.api.add_tab_command(tabs.MucTab, 'vcard', self.command_muc_vcard,
- usage='<jid|nick>',
- help='Send an XMPP vcard request to jid or nick (see XEP-0054).',
- short='Send a vcard request.',
- completion=self.completion_muc_vcard)
- self.api.add_tab_command(tabs.RosterInfoTab, 'vcard', self.command_roster_vcard,
- usage='<jid>',
- help='Send an XMPP vcard request to jid (see XEP-0054).',
- short='Send a vcard request.',
- completion=self.completion_vcard)
- for _class in (tabs.PrivateTab, tabs.ConversationTab):
- self.api.add_tab_command(_class, 'vcard', self.command_private_vcard,
- usage='[jid]',
- help='Send an XMPP vcard request to the current interlocutor or the given JID.',
- short='Send a vcard request',
- completion=self.completion_vcard)
def _handle_vcard(self, iq):
'''Retrieves a vCard from vcard-temp and present it as a DataFormsTab.
@@ -65,71 +78,163 @@ class Plugin(BasePlugin):
jid = iq['from']
if iq['type'] == 'error':
- self.api.information('Error retrieving vCard for %s: %s: %s' % (jid, iq['error']['type'], iq['error']['condition']), 'Error')
+ self.api.information(
+ 'Error retrieving vCard for %s: %s: %s' %
+ (jid, iq['error']['type'], iq['error']['condition']), 'Error')
return
vcard = iq['vcard_temp']
- form = self.core.xmpp['xep_0004'].make_form(ftype='result', title='vCard of %s' % jid)
+ form = self.core.xmpp['xep_0004'].make_form(
+ ftype='result', title='vCard of %s' % jid)
# TODO: implement the other fields.
- form.add_field(var='FN', ftype='text-single', label='Name', value=vcard['FN'])
- form.add_field(var='NICKNAME', ftype='text-multi', label='Nicknames', value=vcard['NICKNAME'])
+ form.add_field(
+ var='FN', ftype='text-single', label='Name', value=vcard['FN'])
+ form.add_field(
+ var='NICKNAME',
+ ftype='text-multi',
+ label='Nicknames',
+ value=vcard['NICKNAME'])
# TODO: find a way to detect whether this is present or not.
form.add_field(ftype='fixed', value='Full Name')
- form.add_field(var='N/GIVEN', ftype='text-single', label='Given', value=vcard['N']['GIVEN'])
- form.add_field(var='N/MIDDLE', ftype='text-single', label='Middle', value=vcard['N']['MIDDLE'])
- form.add_field(var='N/FAMILY', ftype='text-single', label='Family', value=vcard['N']['FAMILY'])
- form.add_field(var='N/PREFIX', ftype='text-single', label='Prefix', value=vcard['N']['PREFIX'])
- form.add_field(var='N/SUFFIX', ftype='text-single', label='Suffix', value=vcard['N']['SUFFIX'])
+ form.add_field(
+ var='N/GIVEN',
+ ftype='text-single',
+ label='Given',
+ value=vcard['N']['GIVEN'])
+ form.add_field(
+ var='N/MIDDLE',
+ ftype='text-single',
+ label='Middle',
+ value=vcard['N']['MIDDLE'])
+ form.add_field(
+ var='N/FAMILY',
+ ftype='text-single',
+ label='Family',
+ value=vcard['N']['FAMILY'])
+ form.add_field(
+ var='N/PREFIX',
+ ftype='text-single',
+ label='Prefix',
+ value=vcard['N']['PREFIX'])
+ form.add_field(
+ var='N/SUFFIX',
+ ftype='text-single',
+ label='Suffix',
+ value=vcard['N']['SUFFIX'])
for i, addr in enumerate(vcard['addresses']):
form.add_field(ftype='fixed', value='Address')
values = [type_ for type_ in addr.bool_interfaces if addr[type_]]
- addr_type = form.add_field(var='ADR %d/TYPE' % i, ftype='list-multi', label='Type', value=values)
+ addr_type = form.add_field(
+ var='ADR %d/TYPE' % i,
+ ftype='list-multi',
+ label='Type',
+ value=values)
addr_type.add_option(label='Home', value='HOME')
for type_ in addr.bool_interfaces:
addr_type.add_option(label=type_, value=type_)
- form.add_field(var='ADR %d/POBOX' % i, ftype='text-single', label='Pobox', value=addr['POBOX'])
- form.add_field(var='ADR %d/EXTADD' % i, ftype='text-single', label='Extended Address', value=addr['EXTADD'])
- form.add_field(var='ADR %d/STREET' % i, ftype='text-single', label='Street', value=addr['STREET'])
- form.add_field(var='ADR %d/LOCALITY' % i, ftype='text-single', label='Locality', value=addr['LOCALITY'])
- form.add_field(var='ADR %d/REGION' % i, ftype='text-single', label='Region', value=addr['REGION'])
- form.add_field(var='ADR %d/PCODE' % i, ftype='text-single', label='Post Code', value=addr['PCODE'])
- form.add_field(var='ADR %d/CTRY' % i, ftype='text-single', label='Country', value=addr['CTRY'])
+ form.add_field(
+ var='ADR %d/POBOX' % i,
+ ftype='text-single',
+ label='Pobox',
+ value=addr['POBOX'])
+ form.add_field(
+ var='ADR %d/EXTADD' % i,
+ ftype='text-single',
+ label='Extended Address',
+ value=addr['EXTADD'])
+ form.add_field(
+ var='ADR %d/STREET' % i,
+ ftype='text-single',
+ label='Street',
+ value=addr['STREET'])
+ form.add_field(
+ var='ADR %d/LOCALITY' % i,
+ ftype='text-single',
+ label='Locality',
+ value=addr['LOCALITY'])
+ form.add_field(
+ var='ADR %d/REGION' % i,
+ ftype='text-single',
+ label='Region',
+ value=addr['REGION'])
+ form.add_field(
+ var='ADR %d/PCODE' % i,
+ ftype='text-single',
+ label='Post Code',
+ value=addr['PCODE'])
+ form.add_field(
+ var='ADR %d/CTRY' % i,
+ ftype='text-single',
+ label='Country',
+ value=addr['CTRY'])
for i, tel in enumerate(vcard['telephone_numbers']):
form.add_field(ftype='fixed', value='Telephone')
values = [type_ for type_ in tel.bool_interfaces if tel[type_]]
- tel_type = form.add_field(var='TEL %d/TYPE' % i, ftype='list-multi', label='Type', value=values)
+ tel_type = form.add_field(
+ var='TEL %d/TYPE' % i,
+ ftype='list-multi',
+ label='Type',
+ value=values)
for type_ in tel.bool_interfaces:
tel_type.add_option(label=type_, value=type_)
- form.add_field(var='TEL %d/NUMBER' % i, ftype='text-single', label='Number', value=tel['NUMBER'])
+ form.add_field(
+ var='TEL %d/NUMBER' % i,
+ ftype='text-single',
+ label='Number',
+ value=tel['NUMBER'])
for i, email in enumerate(vcard['emails']):
form.add_field(ftype='fixed', value='Email address')
values = [type_ for type_ in email.bool_interfaces if email[type_]]
- email_type = form.add_field(var='EMAIL %d/TYPE' % i, ftype='list-multi', label='Type', value=values)
+ email_type = form.add_field(
+ var='EMAIL %d/TYPE' % i,
+ ftype='list-multi',
+ label='Type',
+ value=values)
for type_ in email.bool_interfaces:
email_type.add_option(label=type_, value=type_)
- form.add_field(var='EMAIL %d/USERID' % i, ftype='text-single', label='Email Address', value=email['USERID'])
+ form.add_field(
+ var='EMAIL %d/USERID' % i,
+ ftype='text-single',
+ label='Email Address',
+ value=email['USERID'])
form.add_field(ftype='fixed', value='Misc')
- form.add_field(var='BDAY', ftype='text-single', label='Birthday', value=str(vcard['BDAY']))
+ form.add_field(
+ var='BDAY',
+ ftype='text-single',
+ label='Birthday',
+ value=str(vcard['BDAY']))
for i, jabberid in enumerate(vcard['jids']):
form.add_field(ftype='fixed', value='URL')
- form.add_field(var='JABBERID %d' % i, ftype='jid-single', label='URL', value=jabberid['JABBERID'])
+ form.add_field(
+ var='JABBERID %d' % i,
+ ftype='jid-single',
+ label='URL',
+ value=jabberid['JABBERID'])
for i, url in enumerate(vcard['urls']):
form.add_field(ftype='fixed', value='URL')
- form.add_field(var='URL %d' % i, ftype='text-single', label='URL', value=url['URL'])
+ form.add_field(
+ var='URL %d' % i,
+ ftype='text-single',
+ label='URL',
+ value=url['URL'])
for i, desc in enumerate(vcard['descriptions']):
form.add_field(ftype='fixed', value='Description')
- form.add_field(var='DESC %d' % i, ftype='text-multi', label='Description', value=desc['DESC'])
+ form.add_field(
+ var='DESC %d' % i,
+ ftype='text-multi',
+ label='Description',
+ value=desc['DESC'])
on_validate = lambda form: self.core.close_tab()
on_cancel = lambda form: self.core.close_tab()
@@ -137,13 +242,17 @@ class Plugin(BasePlugin):
def _get_vcard(self, jid):
'''Send an iq to ask the vCard.'''
+
def timeout_cb(iq):
- self.api.information('Timeout while retrieving vCard for %s' % jid, 'Error')
+ self.api.information('Timeout while retrieving vCard for %s' % jid,
+ 'Error')
return
- self.core.xmpp.plugin['xep_0054'].get_vcard(jid=jid, timeout=30,
- callback=self._handle_vcard,
- timeout_callback=timeout_cb)
+ self.core.xmpp.plugin['xep_0054'].get_vcard(
+ jid=jid,
+ timeout=30,
+ callback=self._handle_vcard,
+ timeout_callback=timeout_cb)
@command_args_parser.raw
def command_vcard(self, arg):
@@ -192,9 +301,13 @@ class Plugin(BasePlugin):
def completion_vcard(self, the_input):
contacts = [contact.bare_jid for contact in roster.get_contacts()]
- return Completion(the_input.auto_completion, contacts, '', quotify=False)
+ return Completion(
+ the_input.auto_completion, contacts, '', quotify=False)
def completion_muc_vcard(self, the_input):
users = [user.nick for user in self.api.current_tab().users]
- users.extend([resource.jid for contact in roster.get_contacts() for resource in contact.resources])
+ users.extend([
+ resource.jid for contact in roster.get_contacts()
+ for resource in contact.resources
+ ])
return Completion(the_input.auto_completion, users, '', quotify=False)
diff --git a/plugins/white.py b/plugins/white.py
index bb28c512..69796373 100644
--- a/plugins/white.py
+++ b/plugins/white.py
@@ -17,6 +17,7 @@ assuming everyone is using a white background. Black backgrounds matter too!
from poezio.plugin import BasePlugin
from poezio import xhtml
+
class Plugin(BasePlugin):
def init(self):
self.api.add_event_handler('muc_say', self.whiteify)