From 9885203c6799c121f5bc8a733dc1937fe8c1b4d6 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 8 Mar 2013 22:53:35 +0100 Subject: Update the plugins to use the PluginAPI Also: - Add get_conversation_messages() to PluginAPI - Make plugins_autoload colon-separated instead of space-separated (for consistency) - Replace a JID() with a safeJID() in the uptime plugin --- data/default_config.cfg | 2 +- doc/en/configure.txt | 2 +- plugins/admin.py | 18 +++++++++--------- plugins/alias.py | 11 ++++++----- plugins/amsg.py | 2 +- plugins/day_change.py | 4 ++-- plugins/display_corrections.py | 10 +++++----- plugins/double.py | 2 +- plugins/exec.py | 16 ++++++++-------- plugins/figlet.py | 6 +++--- plugins/iq_show.py | 2 +- plugins/link.py | 8 ++++---- plugins/mpd_client.py | 6 +++--- plugins/otr.py | 24 ++++++++++++------------ plugins/pacokick.py | 6 +++--- plugins/ping.py | 18 +++++++++--------- plugins/quote.py | 12 ++++++------ plugins/rainbow.py | 6 +++--- plugins/reminder.py | 18 +++++++++--------- plugins/replace.py | 6 +++--- plugins/revstr.py | 2 +- plugins/send_delayed.py | 6 +++--- plugins/shuffle.py | 2 +- plugins/simple_notify.py | 10 +++++----- plugins/status.py | 4 ++-- plugins/tell.py | 16 ++++++++-------- plugins/test.py | 18 +++++++++--------- plugins/time_marker.py | 2 +- plugins/uptime.py | 11 +++++------ src/core.py | 8 ++++++-- src/plugin.py | 12 +++++++++++- 31 files changed, 142 insertions(+), 128 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index 681d4dd5..abafe4ae 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -222,7 +222,7 @@ plugins_dir = # $XDG_CONFIG_HOME/poezio/plugins. You can specify another directory here. plugins_conf_dir = -# Space separated list of plugins to load on startup +# Colon-separated list of plugins to load on startup plugins_autoload = # the full path to the photo (avatar) you want to use diff --git a/doc/en/configure.txt b/doc/en/configure.txt index 02cd454d..6eff81a5 100644 --- a/doc/en/configure.txt +++ b/doc/en/configure.txt @@ -253,7 +253,7 @@ section of this documentation. *plugins_autoload*:: [empty] - Space separated list of plugins to load on startup. + Colon-separated list of plugins to load on startup. *plugins_conf_dir*:: [empty] diff --git a/plugins/admin.py b/plugins/admin.py index 0f61007b..fac34fdb 100644 --- a/plugins/admin.py +++ b/plugins/admin.py @@ -14,49 +14,49 @@ class Plugin(BasePlugin): """ def init(self): for role in ('visitor', 'participant' , 'moderator'): - self.add_tab_command(MucTab, role, self.role(role), + self.api.add_tab_command(MucTab, role, self.role(role), help='Set the role of a nick to %s' % role, usage= '', short='Set the role to %s' % role, completion=self.complete_nick) for aff in ('member', 'owner', 'admin'): - self.add_tab_command(MucTab, aff, self.affiliation(aff), + self.api.add_tab_command(MucTab, aff, self.affiliation(aff), usage='', help='Set the affiliation of a nick to %s' % aff, short='Set the affiliation to %s' % aff, completion=self.complete_nick) - self.add_tab_command(MucTab, 'noaffiliation', self.affiliation('none'), + self.api.add_tab_command(MucTab, 'noaffiliation', self.affiliation('none'), usage='', help='Set the affiliation of a nick to none.', short='Set the affiliation to none.', completion=self.complete_nick) - self.add_tab_command(MucTab, 'voice', self.affiliation('member'), + self.api.add_tab_command(MucTab, 'voice', self.affiliation('member'), usage='', help='Set the affiliation of a nick to member.', short='Set the affiliation to member.', completion=self.complete_nick) - self.add_tab_command(MucTab, 'op', self.role('moderator'), + self.api.add_tab_command(MucTab, 'op', self.role('moderator'), usage='', help='Set the role of a nick to moderator.', short='Set the role to moderator.', completion=self.complete_nick) - self.add_tab_command(MucTab, 'mute', self.role('visitor'), + self.api.add_tab_command(MucTab, 'mute', self.role('visitor'), usage='', help='Set the role of a nick to visitor.', short='Set the role to visitor.', completion=self.complete_nick) def role(self, role): - return lambda args: self.core.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.core.current_tab().command_affiliation( + return lambda args: self.api.current_tab().command_affiliation( args+' '+affiliation) def complete_nick(self, the_input): - tab = self.core.current_tab() + tab = self.api.current_tab() compare_users = lambda x: x.last_talked word_list = [user.nick for user in sorted(tab.users, key=compare_users, reverse=True)\ if user.nick != tab.own_nick] diff --git a/plugins/alias.py b/plugins/alias.py index 4d4a3bf4..a3843f35 100644 --- a/plugins/alias.py +++ b/plugins/alias.py @@ -10,11 +10,11 @@ from common import shell_split class Plugin(BasePlugin): def init(self): - self.add_command('alias', self.command_alias, + self.api.add_command('alias', self.command_alias, usage=' [args]', short='Create an alias command', help='Create an alias for with [args].') - self.add_command('unalias', self.command_unalias, + self.api.add_command('unalias', self.command_unalias, usage='', help='Remove a previously created alias', short='Remove an alias', @@ -36,8 +36,9 @@ class Plugin(BasePlugin): if alias in self.core.commands or alias in self.commands: self.api.information('Alias: command already exists', 'Error') return - self.commands[alias] = lambda arg: self.get_command(command)(tmp_args.format(*shell_split(arg))) - self.add_command(alias, self.commands[alias], 'This command is an alias for /%s %s' %( command, tmp_args)) + + self.commands[alias] = lambda arg: self.get_command(command)(tmp_args + arg) + self.api.add_command(alias, self.commands[alias], 'This command is an alias for /%s %s' %( command, tmp_args)) self.api.information('Alias /%s successfuly created' % alias, 'Info') def command_unalias(self, alias): @@ -46,7 +47,7 @@ class Plugin(BasePlugin): """ if alias in self.commands: del self.commands[alias] - self.del_command(alias) + self.api.del_command(alias) self.api.information('Alias /%s successfuly deleted' % alias, 'Info') def completion_unalias(self, the_input): diff --git a/plugins/amsg.py b/plugins/amsg.py index a002b11e..57a37255 100644 --- a/plugins/amsg.py +++ b/plugins/amsg.py @@ -5,7 +5,7 @@ from tabs import MucTab class Plugin(BasePlugin): def init(self): - self.add_command('amsg', self.command_amsg, + self.api.add_command('amsg', self.command_amsg, usage='', short='Broadcast a message', help='Broadcast the message to all the joined rooms.') diff --git a/plugins/day_change.py b/plugins/day_change.py index 14924684..179bfd98 100644 --- a/plugins/day_change.py +++ b/plugins/day_change.py @@ -9,13 +9,13 @@ class Plugin(BasePlugin): self.schedule_event() def cleanup(self): - self.core.remove_timed_event(self.next_event) + 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.timedelta(1) self.next_event = timed_events.TimedEvent(day_change, self.day_change) - self.core.add_timed_event(self.next_event) + self.api.add_timed_event(self.next_event) def day_change(self): msg = datetime.date.today().strftime(_("Day changed to %x")) diff --git a/plugins/display_corrections.py b/plugins/display_corrections.py index 6e122bfe..cad5a327 100644 --- a/plugins/display_corrections.py +++ b/plugins/display_corrections.py @@ -8,14 +8,14 @@ import tabs class Plugin(BasePlugin): def init(self): for tab_type in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab): - self.add_tab_command(tab_type, 'display_corrections', + self.api.add_tab_command(tab_type, 'display_corrections', handler=self.command_display_corrections, usage='', help='Display all the corrections of the number-th last corrected message.', short='Display the corrections of a message') def find_corrected(self, nb): - messages = self.core.get_conversation_messages() + messages = self.api.get_conversation_messages() if not messages: return None for message in messages[::-1]: @@ -32,7 +32,7 @@ class Plugin(BasePlugin): try: nb = int(args[0]) except: - return self.core.command_help('display_corrections') + return self.api.run_command('/help display_corrections') else: nb = 1 message = self.find_corrected(nb) @@ -41,9 +41,9 @@ class Plugin(BasePlugin): while message: 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.core.information('Older versions:\n' + '\n'.join(display[::-1]), 'Info') + self.api.information('Older versions:\n' + '\n'.join(display[::-1]), 'Info') else: - self.core.information('No corrected message found.', 'Warning') + self.api.information('No corrected message found.', 'Warning') def cleanup(self): del self.config diff --git a/plugins/double.py b/plugins/double.py index 04728bbf..597ab242 100644 --- a/plugins/double.py +++ b/plugins/double.py @@ -2,7 +2,7 @@ from plugin import BasePlugin class Plugin(BasePlugin): def init(self): - self.add_event_handler('muc_say', self.double) + self.api.add_event_handler('muc_say', self.double) def double(self, msg, tab): split = msg['body'].split() diff --git a/plugins/exec.py b/plugins/exec.py index bf7d7c38..4dbe9590 100644 --- a/plugins/exec.py +++ b/plugins/exec.py @@ -8,7 +8,7 @@ import subprocess class Plugin(BasePlugin): def init(self): - self.add_command('exec', self.command_exec, + self.api.add_command('exec', self.command_exec, usage='[-o|-O] ', help='Execute a shell command and prints the result in the information buffer. The command should be ONE argument, that means it should be between \"\". The first argument (before the command) can be -o or -O. If -o is specified, it sends the result in the current conversation. If -O is specified, it sends the command and its result in the current conversation.\nExample: /exec -O \"uptime\" will send “uptime\n20:36:19 up 3:47, 4 users, load average: 0.09, 0.13, 0.09” in the current conversation.', short='Execute a command') @@ -22,20 +22,20 @@ class Plugin(BasePlugin): command = args[1] arg = args[0] else: - self.core.command_help('exec') + self.api.run_command('/help exec') return try: process = subprocess.Popen(['sh', '-c', command], stdout=subprocess.PIPE) except OSError as e: - self.core.information('Failed to execute command: %s' % (e,), 'Error') + self.api.information('Failed to execute command: %s' % (e,), 'Error') return result = process.communicate()[0].decode('utf-8') if arg and arg == '-o': - if not self.core.send_message('%s' % (result,)): - self.core.information('Cannot send result (%s), this is not a conversation tab' % result) + if not self.api.send_message('%s' % (result,)): + self.api.information('Cannot send result (%s), this is not a conversation tab' % result) elif arg and arg == '-O': - if not self.core.send_message('%s:\n%s' % (command, result)): - self.core.information('Cannot send result (%s), this is not a conversation tab' % result) + 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) else: - self.core.information('%s:\n%s' % (command, result), 'Info') + self.api.information('%s:\n%s' % (command, result), 'Info') return diff --git a/plugins/figlet.py b/plugins/figlet.py index 0fda098e..eaf8dab3 100644 --- a/plugins/figlet.py +++ b/plugins/figlet.py @@ -3,9 +3,9 @@ import subprocess class Plugin(BasePlugin): def init(self): - self.add_event_handler('muc_say', self.figletize) - self.add_event_handler('conversation_say', self.figletize) - self.add_event_handler('private_say', self.figletize) + self.api.add_event_handler('muc_say', self.figletize) + self.api.add_event_handler('conversation_say', self.figletize) + self.api.add_event_handler('private_say', self.figletize) def figletize(self, msg, tab): process = subprocess.Popen(['figlet', '--', msg['body']], stdout=subprocess.PIPE) diff --git a/plugins/iq_show.py b/plugins/iq_show.py index 77d50d6c..06d06d8e 100644 --- a/plugins/iq_show.py +++ b/plugins/iq_show.py @@ -7,7 +7,7 @@ class Plugin(BasePlugin): self.core.xmpp.register_handler(Callback('Iq_show', StanzaPath('iq'), self.handle_iq)) def handle_iq(self, iq): - self.core.information('%s' % iq, 'Iq') + self.api.information('%s' % iq, 'Iq') def cleanup(self): self.core.xmpp.remove_handler('Iq_show') diff --git a/plugins/link.py b/plugins/link.py index 0d88fba2..9e8b6f97 100644 --- a/plugins/link.py +++ b/plugins/link.py @@ -13,13 +13,13 @@ url_pattern = re.compile(r'\b(http[s]?://(?:\S+))\b', re.I|re.U) class Plugin(BasePlugin): def init(self): for _class in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab): - self.add_tab_command(_class, 'link', self.command_link, + self.api.add_tab_command(_class, 'link', self.command_link, usage='[num]', help='Opens the last link from the conversation into a browser.\nIf [num] is given, then it will open the num-th link displayed.', short='Open links into a browser') def find_link(self, nb): - messages = self.core.get_conversation_messages() + messages = self.api.get_conversation_messages() if not messages: return None for message in messages[::-1]: @@ -38,14 +38,14 @@ class Plugin(BasePlugin): try: nb = int(args[0]) except: - return self.core.command_help('link') + return self.api.run_command('/help link') else: nb = 1 link = self.find_link(nb) if link: self.core.exec_command([self.config.get('browser', 'firefox'), link]) else: - self.core.information('No URL found.', 'Warning') + self.api.information('No URL found.', 'Warning') def cleanup(self): del self.config diff --git a/plugins/mpd_client.py b/plugins/mpd_client.py index 47bbdf29..c215e971 100644 --- a/plugins/mpd_client.py +++ b/plugins/mpd_client.py @@ -9,7 +9,7 @@ import mpd class Plugin(BasePlugin): def init(self): for _class in (tabs.ConversationTab, tabs.MucTab, tabs.PrivateTab): - self.add_tab_command(_class, 'mpd', self.command_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', @@ -34,8 +34,8 @@ class Plugin(BasePlugin): current_time = float(c.status()['elapsed']) pourcentage = int(current_time / float(current['time']) * 10) s += ' \x192}[\x191}' + '-'*(pourcentage-1) + '\x193}+' + '\x191}' + '-' * (10-pourcentage-1) + '\x192}]\x19o' - if not self.core.send_message('%s' % (s,)): - self.core.information('Cannot send result (%s)' % s, 'Error') + if not self.api.send_message('%s' % (s,)): + self.api.information('Cannot send result (%s)' % s, 'Error') def completion_mpd(self, the_input): return the_input.auto_completion(['full'], quotify=False) diff --git a/plugins/otr.py b/plugins/otr.py index f3a1d7a2..4e900b84 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -13,10 +13,10 @@ class Plugin(BasePlugin): def init(self): self.contacts = {} # a dict of {full-JID: OTR object} - self.add_event_handler('conversation_say_after', self.on_conversation_say) - self.add_event_handler('conversation_msg', self.on_conversation_msg) + self.api.add_event_handler('conversation_say_after', self.on_conversation_say) + self.api.add_event_handler('conversation_msg', self.on_conversation_msg) - self.add_tab_command(ConversationTab, 'otr', self.command_otr, + self.api.add_tab_command(ConversationTab, 'otr', self.command_otr, usage='', help='Start or stop OTR for the current conversation.', short='Manage OTR status', @@ -113,27 +113,27 @@ class Plugin(BasePlugin): """ args = args.split() if not args: - return self.core.command_help("otr") - if isinstance(self.core.current_tab(), ConversationTab): - jid = JID(self.core.current_tab().get_name()) + return self.api.run_command("/help otr") + if isinstance(self.api.current_tab(), ConversationTab): + jid = JID(self.api.current_tab().get_name()) command = args[0] if command == 'start': - otr_state = self.get_otr(self.core.current_tab()) - self.otr_say(self.core.current_tab(), otr_state.start().decode()) + otr_state = self.get_otr(self.api.current_tab()) + self.otr_say(self.api.current_tab(), otr_state.start().decode()) elif command == 'end': - otr_state = self.get_otr(self.core.current_tab()) + otr_state = self.get_otr(self.api.current_tab()) msg = otr_state.end() if msg is not None: - self.otr_say(self.core.current_tab(), msg.decode()) + self.otr_say(self.api.current_tab(), msg.decode()) elif command == 'fpr': - otr_state = self.get_otr(self.core.current_tab()) + otr_state = self.get_otr(self.api.current_tab()) our = otr_state.our_fpr if our: our = hex(int.from_bytes(our, 'big'))[2:].ljust(40).upper() their = otr_state.their_fpr if their: their = hex(int.from_bytes(their, 'big'))[2:].ljust(40).upper() - self.core.current_tab().add_message('Your: %s Their: %s' % (our, their)) + self.api.current_tab().add_message('Your: %s Their: %s' % (our, their)) self.core.refresh_window() def otr_completion(self, the_input): diff --git a/plugins/pacokick.py b/plugins/pacokick.py index 053e6c22..358df013 100644 --- a/plugins/pacokick.py +++ b/plugins/pacokick.py @@ -5,13 +5,13 @@ from plugin import BasePlugin class Plugin(BasePlugin): def init(self): - self.add_command('pacokick', self.command_kick, + 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.core.current_tab() + tab = self.api.current_tab() if isinstance(tab, MucTab): kickable = list(filter(lambda x: x.affiliation in ('none', 'member'), tab.users)) if kickable: @@ -20,4 +20,4 @@ class Plugin(BasePlugin): to_kick = to_kick.nick tab.command_kick(to_kick + ' ' +arg) else: - self.core.information('No one to kick :(', 'Info') + self.api.information('No one to kick :(', 'Info') diff --git a/plugins/ping.py b/plugins/ping.py index 22401a25..faf3e97d 100644 --- a/plugins/ping.py +++ b/plugins/ping.py @@ -8,18 +8,18 @@ import tabs class Plugin(BasePlugin): def init(self): self.core.xmpp.register_plugin('xep_0199') - self.add_command('ping', self.command_ping, + self.api.add_command('ping', self.command_ping, usage='', help='Send a XMPP ping to jid (see XEP-0199).', short='Send a ping', completion=self.completion_ping) - self.add_tab_command(tabs.MucTab, 'ping', self.command_muc_ping, + self.api.add_tab_command(tabs.MucTab, 'ping', self.command_muc_ping, usage='', help='Send a XMPP ping to jid or nick (see XEP-0199).', short='Send a ping.', completion=self.completion_muc_ping) for _class in (tabs.PrivateTab, tabs.ConversationTab): - self.add_tab_command(_class, 'ping', self.command_private_ping, + self.api.add_tab_command(_class, 'ping', self.command_private_ping, usage='[jid]', help='Send a XMPP ping to the current interlocutor or the given JID.', short='Send a ping', @@ -34,12 +34,12 @@ class Plugin(BasePlugin): except: delay = None if delay is not None: - self.core.information('%s responded to ping after %s s' % (jid, round(delay, 4)), 'Info') + self.api.information('%s responded to ping after %s s' % (jid, round(delay, 4)), 'Info') else: - self.core.information('%s did not respond to ping' % jid, 'Info') + self.api.information('%s did not respond to ping' % jid, 'Info') def completion_muc_ping(self, the_input): - users = [user.nick for user in self.core.current_tab().users] + users = [user.nick for user in self.api.current_tab().users] l = [contact.bare_jid for contact in roster.get_contacts()] users.extend(l) return the_input.auto_completion(users, '', quotify=False) @@ -47,14 +47,14 @@ class Plugin(BasePlugin): def command_private_ping(self, arg): if arg: return self.command_ping(arg) - self.command_ping(self.core.current_tab().get_name()) + self.command_ping(self.api.current_tab().get_name()) def command_muc_ping(self, arg): if not arg.strip(): return - user = self.core.current_tab().get_user_by_name(arg) + user = self.api.current_tab().get_user_by_name(arg) if user: - jid = safeJID(self.core.current_tab().get_name()) + jid = safeJID(self.api.current_tab().get_name()) jid.resource = user.nick else: jid = safeJID(arg) diff --git a/plugins/quote.py b/plugins/quote.py index ebd9b15e..9b1fd9ad 100644 --- a/plugins/quote.py +++ b/plugins/quote.py @@ -13,7 +13,7 @@ log = logging.getLogger(__name__) class Plugin(BasePlugin): def init(self): for _class in (tabs.MucTab, tabs.ConversationTab, tabs.PrivateTab): - self.add_tab_command(_class, 'quote', self.command_quote, + self.api.add_tab_command(_class, 'quote', self.command_quote, usage='', help='Takes the message received at and insert it in the input, to quote it.', short='Quote a message from a timestamp', @@ -24,9 +24,9 @@ class Plugin(BasePlugin): if len(args) in (1, 2): timestamp = args[-1] else: - return self.core.command_help('quote') + return self.api.run_command('/help quote') if re.match(timestamp_re, timestamp) is None: - return self.core.information('Timestamp has a wrong format.', 'Warning') + return self.api.information('Timestamp has a wrong format.', 'Warning') message = self.find_message_with_timestamp(timestamp) if message: before = self.config.get('before_quote', '') % {'nick': message.nickname or '', @@ -37,12 +37,12 @@ class Plugin(BasePlugin): 'quote': clean_text(message.txt), 'after': after.replace('\\n', '\n').replace('[SP]', ' ')}) else: - self.core.information('No message found for timestamp %s.' % timestamp, 'Warning') + self.api.information('No message found for timestamp %s.' % timestamp, 'Warning') def find_message_with_timestamp(self, timestamp): # TODO: handle messages with the same # timestamp but not the same day - messages = self.core.get_conversation_messages() + messages = self.api.get_conversation_messages() if not messages: return None for message in messages[::-1]: @@ -57,7 +57,7 @@ class Plugin(BasePlugin): return msg.nickname.lower().startswith(nick.lower()) def time_match(msg): return msg.str_time.endswith(time) - messages = self.core.get_conversation_messages() + messages = self.api.get_conversation_messages() if not messages: return text = the_input.get_text() diff --git a/plugins/rainbow.py b/plugins/rainbow.py index 3c4813d0..4a188b33 100644 --- a/plugins/rainbow.py +++ b/plugins/rainbow.py @@ -12,9 +12,9 @@ def rand_color(): class Plugin(BasePlugin): def init(self): - self.add_event_handler('muc_say', self.rainbowize) - self.add_event_handler('private_say', self.rainbowize) - self.add_event_handler('conversation_say', self.rainbowize) + self.api.add_event_handler('muc_say', self.rainbowize) + self.api.add_event_handler('private_say', self.rainbowize) + 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'])]) diff --git a/plugins/reminder.py b/plugins/reminder.py index 03711906..16a3f710 100644 --- a/plugins/reminder.py +++ b/plugins/reminder.py @@ -6,17 +6,17 @@ import timed_events class Plugin(BasePlugin): def init(self): - self.add_command('remind', self.command_remind, + self.api.add_command('remind', self.command_remind, usage=' ', help='Remind you of every