Merge branch 'plugins' of /home/louiz/git/poezio into plugins
Conflicts: src/core.py
This commit is contained in:
commit
54962e6796
5 changed files with 43 additions and 66 deletions
11
plugins/figlet.py
Normal file
11
plugins/figlet.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from plugin import BasePlugin
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
class Plugin(BasePlugin):
|
||||||
|
def init(self):
|
||||||
|
self.add_poezio_event_handler('muc_say', self.figletize)
|
||||||
|
|
||||||
|
def figletize(self, msg):
|
||||||
|
process = subprocess.Popen(['figlet', msg['body']], stdout=subprocess.PIPE)
|
||||||
|
result = process.communicate()[0].decode('utf-8')
|
||||||
|
msg['body'] = result
|
60
src/core.py
60
src/core.py
|
@ -33,6 +33,7 @@ import multiuserchat as muc
|
||||||
import tabs
|
import tabs
|
||||||
|
|
||||||
import xhtml
|
import xhtml
|
||||||
|
import events
|
||||||
import pubsub
|
import pubsub
|
||||||
import windows
|
import windows
|
||||||
import connection
|
import connection
|
||||||
|
@ -80,12 +81,6 @@ class Core(object):
|
||||||
User interface using ncurses
|
User interface using ncurses
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# dict containing the name of the internal events
|
|
||||||
# used with the plugins, the key is the name of the event
|
|
||||||
# and the value is the number of arguments the handler must take
|
|
||||||
internal_events = {
|
|
||||||
'enter': 2,
|
|
||||||
}
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# All uncaught exception are given to this callback, instead
|
# All uncaught exception are given to this callback, instead
|
||||||
# of being displayed on the screen and exiting the program.
|
# of being displayed on the screen and exiting the program.
|
||||||
|
@ -93,6 +88,7 @@ class Core(object):
|
||||||
self.status = Status(show=None, message='')
|
self.status = Status(show=None, message='')
|
||||||
sys.excepthook = self.on_exception
|
sys.excepthook = self.on_exception
|
||||||
self.running = True
|
self.running = True
|
||||||
|
self.events = events.EventHandler()
|
||||||
self.xmpp = singleton.Singleton(connection.Connection)
|
self.xmpp = singleton.Singleton(connection.Connection)
|
||||||
self.remote_fifo = None
|
self.remote_fifo = None
|
||||||
# a unique buffer used to store global informations
|
# a unique buffer used to store global informations
|
||||||
|
@ -180,6 +176,7 @@ class Core(object):
|
||||||
self.timed_events = set()
|
self.timed_events = set()
|
||||||
|
|
||||||
self.connected_events = {}
|
self.connected_events = {}
|
||||||
|
|
||||||
self.autoload_plugins()
|
self.autoload_plugins()
|
||||||
|
|
||||||
def autoload_plugins(self):
|
def autoload_plugins(self):
|
||||||
|
@ -213,57 +210,6 @@ class Core(object):
|
||||||
))
|
))
|
||||||
self.refresh_window()
|
self.refresh_window()
|
||||||
|
|
||||||
def connect(self, event, handler):
|
|
||||||
"""
|
|
||||||
Connect an handler to an internal event of poezio
|
|
||||||
(eg "enter pressed in a chattab")
|
|
||||||
"""
|
|
||||||
# Fail if the method doesn’t take at least the good number of arguments
|
|
||||||
# or if the event is unknown
|
|
||||||
if not event in self.internal_events \
|
|
||||||
or len(getargspec(handler).args) < self.internal_events[event]:
|
|
||||||
return False
|
|
||||||
|
|
||||||
module_name = handler.__module__
|
|
||||||
if not event in self.connected_events:
|
|
||||||
self.connected_events[event] = {}
|
|
||||||
if not module_name in self.connected_events[event]:
|
|
||||||
self.connected_events[event][module_name] = []
|
|
||||||
|
|
||||||
self.connected_events[event][module_name].append(handler)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def run_event(self, event, **kwargs):
|
|
||||||
"""
|
|
||||||
Call the handlers associated with an event
|
|
||||||
"""
|
|
||||||
if event in self.connected_events:
|
|
||||||
for module in self.connected_events[event]:
|
|
||||||
for handler in self.connected_events[event][module]:
|
|
||||||
try:
|
|
||||||
handler(**kwargs)
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
tp = traceback.format_exc()
|
|
||||||
module_name = handler.__name__
|
|
||||||
log.debug('ERROR: in plugin %s, \n%s' % (module_name, tp))
|
|
||||||
|
|
||||||
def disconnect(self, event, handler):
|
|
||||||
"""
|
|
||||||
Disconnect a handler from an event
|
|
||||||
"""
|
|
||||||
if not event in self.internal_events:
|
|
||||||
return False
|
|
||||||
|
|
||||||
module_name = getmodule(handler).__name__
|
|
||||||
if not event in self.connected_events:
|
|
||||||
return False
|
|
||||||
if not module_name in self.connected_events[event]:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.connected_events[event][module_name].remove(handler)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def resize_global_information_win(self):
|
def resize_global_information_win(self):
|
||||||
"""
|
"""
|
||||||
Resize the global_information_win only once at each resize.
|
Resize the global_information_win only once at each resize.
|
||||||
|
|
|
@ -84,3 +84,9 @@ class BasePlugin(object, metaclass=SafetyMetaclass):
|
||||||
|
|
||||||
def del_event_handler(self, event_name, handler):
|
def del_event_handler(self, event_name, handler):
|
||||||
return self.plugin_manager.del_event_handler(self.__module__, event_name, handler)
|
return self.plugin_manager.del_event_handler(self.__module__, event_name, handler)
|
||||||
|
|
||||||
|
def add_poezio_event_handler(self, event_name, handler, first=True, last=False, position=None):
|
||||||
|
return self.plugin_manager.add_poezio_event_handler(self.__module__, event_name, handler, first, last, position)
|
||||||
|
|
||||||
|
def del_poezio_event_handler(self, event_name, handler):
|
||||||
|
return self.plugin_manager.del_poezio_event_handler(self.__module__, event_name, handler)
|
||||||
|
|
|
@ -34,6 +34,7 @@ class PluginManager(object):
|
||||||
self.plugins = {} # module name -> plugin object
|
self.plugins = {} # module name -> plugin object
|
||||||
self.commands = {} # module name -> dict of commands loaded for the module
|
self.commands = {} # module name -> dict of commands loaded for the module
|
||||||
self.event_handlers = {} # module name -> list of event_name/handler pairs loaded for the module
|
self.event_handlers = {} # module name -> list of event_name/handler pairs loaded for the module
|
||||||
|
self.poezio_event_handlers = {}
|
||||||
|
|
||||||
def load(self, name):
|
def load(self, name):
|
||||||
if name in self.plugins:
|
if name in self.plugins:
|
||||||
|
@ -60,6 +61,7 @@ class PluginManager(object):
|
||||||
self.modules[name] = module
|
self.modules[name] = module
|
||||||
self.commands[name] = {}
|
self.commands[name] = {}
|
||||||
self.event_handlers[name] = []
|
self.event_handlers[name] = []
|
||||||
|
self.poezio_event_handlers[name] = []
|
||||||
self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir)
|
self.plugins[name] = module.Plugin(self, self.core, plugins_conf_dir)
|
||||||
|
|
||||||
def unload(self, name):
|
def unload(self, name):
|
||||||
|
@ -69,14 +71,14 @@ class PluginManager(object):
|
||||||
del self.core.commands[command]
|
del self.core.commands[command]
|
||||||
for event_name, handler in self.event_handlers[name]:
|
for event_name, handler in self.event_handlers[name]:
|
||||||
self.core.xmpp.del_event_handler(event_name, handler)
|
self.core.xmpp.del_event_handler(event_name, handler)
|
||||||
for event_name in self.core.internal_events:
|
for handler in self.poezio_event_handlers[name]:
|
||||||
if name in event_name:
|
self.core.events.del_event_handler(None, handler)
|
||||||
del event_name[name]
|
|
||||||
|
|
||||||
self.plugins[name].unload()
|
self.plugins[name].unload()
|
||||||
del self.plugins[name]
|
del self.plugins[name]
|
||||||
del self.commands[name]
|
del self.commands[name]
|
||||||
del self.event_handlers[name]
|
del self.event_handlers[name]
|
||||||
|
del self.poezio_event_handlers[name]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
import traceback
|
import traceback
|
||||||
self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc())
|
self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc())
|
||||||
|
@ -105,6 +107,16 @@ class PluginManager(object):
|
||||||
eh = self.event_handlers[module_name]
|
eh = self.event_handlers[module_name]
|
||||||
eh = list(filter(lambda e : e != (event_name, handler), eh))
|
eh = list(filter(lambda e : e != (event_name, handler), eh))
|
||||||
|
|
||||||
|
def add_poezio_event_handler(self, module_name, event_name, handler, first, last, position):
|
||||||
|
eh = self.poezio_event_handlers[module_name]
|
||||||
|
eh.append(handler)
|
||||||
|
self.core.events.add_event_handler(event_name, handler, first, last, position)
|
||||||
|
|
||||||
|
def del_poezio_event_handler(self, module_name, event_name, handler):
|
||||||
|
self.core.events.del_event_handler(None, handler)
|
||||||
|
eh = self.poezio_event_handlers[module_name]
|
||||||
|
eh = list(filter(lambda e : e != handler, eh))
|
||||||
|
|
||||||
def completion_load(self, the_input):
|
def completion_load(self, the_input):
|
||||||
"""
|
"""
|
||||||
completion function that completes the name of the plugins, from
|
completion function that completes the name of the plugins, from
|
||||||
|
|
14
src/tabs.py
14
src/tabs.py
|
@ -323,8 +323,7 @@ class ChatTab(Tab):
|
||||||
if not self.execute_command(clean_text):
|
if not self.execute_command(clean_text):
|
||||||
if txt.startswith('//'):
|
if txt.startswith('//'):
|
||||||
txt = txt[1:]
|
txt = txt[1:]
|
||||||
self.core.run_event('enter', line=txt)
|
self.command_say(xhtml.convert_simple_to_full_colors(txt))
|
||||||
self.command_say(txt)
|
|
||||||
self.cancel_paused_delay()
|
self.cancel_paused_delay()
|
||||||
|
|
||||||
def send_chat_state(self, state, always_send=False):
|
def send_chat_state(self, state, always_send=False):
|
||||||
|
@ -602,7 +601,7 @@ class MucTab(ChatTab):
|
||||||
r = self.core.open_private_window(self.name, user.nick)
|
r = self.core.open_private_window(self.name, user.nick)
|
||||||
if r and len(args) > 1:
|
if r and len(args) > 1:
|
||||||
msg = arg[len(nick)+1:]
|
msg = arg[len(nick)+1:]
|
||||||
self.core.current_tab().command_say(msg)
|
self.core.current_tab().command_say(xhtml.convert_simple_to_full_colors(msg))
|
||||||
if not r:
|
if not r:
|
||||||
self.core.information(_("Cannot find user: %s" % nick), 'Error')
|
self.core.information(_("Cannot find user: %s" % nick), 'Error')
|
||||||
|
|
||||||
|
@ -719,10 +718,11 @@ class MucTab(ChatTab):
|
||||||
if line.find('\x19') == -1:
|
if line.find('\x19') == -1:
|
||||||
msg['body'] = line
|
msg['body'] = line
|
||||||
else:
|
else:
|
||||||
msg['body'] = xhtml.clean_text_simple(line)
|
msg['body'] = xhtml.clean_text(line)
|
||||||
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
||||||
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
||||||
msg['chat_state'] = needed
|
msg['chat_state'] = needed
|
||||||
|
self.core.events.trigger('muc_say', msg)
|
||||||
self.cancel_paused_delay()
|
self.cancel_paused_delay()
|
||||||
msg.send()
|
msg.send()
|
||||||
self.chat_state = needed
|
self.chat_state = needed
|
||||||
|
@ -1211,11 +1211,12 @@ class PrivateTab(ChatTab):
|
||||||
if line.find('\x19') == -1:
|
if line.find('\x19') == -1:
|
||||||
msg['body'] = line
|
msg['body'] = line
|
||||||
else:
|
else:
|
||||||
msg['body'] = xhtml.clean_text_simple(line)
|
msg['body'] = xhtml.clean_text(line)
|
||||||
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
||||||
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
||||||
needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active'
|
needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active'
|
||||||
msg['chat_state'] = needed
|
msg['chat_state'] = needed
|
||||||
|
self.core.events.trigger('private_say', msg)
|
||||||
msg.send()
|
msg.send()
|
||||||
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick or self.own_nick)
|
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick or self.own_nick)
|
||||||
self.cancel_paused_delay()
|
self.cancel_paused_delay()
|
||||||
|
@ -1874,11 +1875,12 @@ class ConversationTab(ChatTab):
|
||||||
if line.find('\x19') == -1:
|
if line.find('\x19') == -1:
|
||||||
msg['body'] = line
|
msg['body'] = line
|
||||||
else:
|
else:
|
||||||
msg['body'] = xhtml.clean_text_simple(line)
|
msg['body'] = xhtml.clean_text(line)
|
||||||
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
msg['xhtml_im'] = xhtml.poezio_colors_to_html(line)
|
||||||
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False:
|
||||||
needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active'
|
needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active'
|
||||||
msg['chat_state'] = needed
|
msg['chat_state'] = needed
|
||||||
|
self.core.events.trigger('conversation_say', msg)
|
||||||
msg.send()
|
msg.send()
|
||||||
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick)
|
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick)
|
||||||
logger.log_message(JID(self.get_name()).bare, self.core.own_nick, line)
|
logger.log_message(JID(self.get_name()).bare, self.core.own_nick, line)
|
||||||
|
|
Loading…
Reference in a new issue