[teisenbe] Use the imp module to import modules.
Also add a simple translator module
This commit is contained in:
parent
e3b933445f
commit
f275567478
5 changed files with 118 additions and 23 deletions
|
@ -1,3 +1,4 @@
|
|||
from plugin import BasePlugin
|
||||
import os
|
||||
import stat
|
||||
import pyinotify
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from plugin import BasePlugin
|
||||
|
||||
class Plugin(BasePlugin):
|
||||
def init(self):
|
||||
self.add_command('plugintest', self.command_plugintest, 'Test command')
|
||||
self.add_event_handler('message', self.on_message)
|
||||
self.core.information("Plugin loaded")
|
||||
|
||||
def cleanup(self):
|
||||
|
|
33
plugins/translate.py
Normal file
33
plugins/translate.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
from plugin import BasePlugin
|
||||
import urllib.request
|
||||
from urllib.parse import urlencode
|
||||
import xhtml
|
||||
import json
|
||||
|
||||
TARGET_LANG = 'en'
|
||||
|
||||
def translate(s, target=TARGET_LANG, source=''):
|
||||
f = urllib.request.urlopen('http://ajax.googleapis.com/ajax/services/language/translate', urlencode({ 'v': '1.0', 'q': s, 'langpair': '%s|%s' % (source, target) }))
|
||||
response = json.loads(str(f.read(), 'utf-8'))['responseData']
|
||||
return (response['translatedText'], response['detectedSourceLanguage'])
|
||||
|
||||
class Plugin(BasePlugin):
|
||||
def init(self):
|
||||
self.add_event_handler('groupchat_message', self.on_groupchat_message)
|
||||
|
||||
def on_groupchat_message(self, message):
|
||||
try:
|
||||
room_from = message.getMucroom()
|
||||
if message['type'] == 'error':
|
||||
return
|
||||
|
||||
if room_from == 'poezio@kikoo.louiz.org':
|
||||
nick_from = message['mucnick']
|
||||
body = xhtml.get_body_from_message_stanza(message)
|
||||
room = self.core.get_room_by_name(room_from)
|
||||
text, lang = translate(body)
|
||||
if lang != TARGET_LANG:
|
||||
room.add_message(text, nickname=nick_from)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
self.core.information("Exception in translator! %s" % (traceback.format_exc(),))
|
|
@ -1,5 +1,3 @@
|
|||
import inspect
|
||||
|
||||
class BasePlugin(object):
|
||||
"""
|
||||
Class that all plugins derive from. Any methods beginning with command_
|
||||
|
@ -7,14 +5,9 @@ class BasePlugin(object):
|
|||
event handlers
|
||||
"""
|
||||
|
||||
def __init__(self, core):
|
||||
def __init__(self, plugin_manager, core):
|
||||
self.core = core
|
||||
for k, v in inspect.getmembers(self, inspect.ismethod):
|
||||
if k.startswith('on_'):
|
||||
core.xmpp.add_event_handler(k[3:], v)
|
||||
elif k.startswith('command_'):
|
||||
command = k[len('command_'):]
|
||||
core.commands[command] = (v, v.__doc__, None)
|
||||
self.plugin_manager = plugin_manager
|
||||
self.init()
|
||||
|
||||
def init(self):
|
||||
|
@ -24,10 +17,13 @@ class BasePlugin(object):
|
|||
pass
|
||||
|
||||
def unload(self):
|
||||
for k, v in inspect.getmembers(self, inspect.ismethod):
|
||||
if k.startswith('on_'):
|
||||
self.core.xmpp.del_event_handler(k[3:], v)
|
||||
elif k.startswith('command_'):
|
||||
command = k[len('command_'):]
|
||||
del self.core.commands[command]
|
||||
self.cleanup()
|
||||
|
||||
def add_command(self, name, handler, help, completion=None):
|
||||
return self.plugin_manager.add_command(self.__module__, name, handler, help, completion)
|
||||
|
||||
def add_event_handler(self, event_name, handler):
|
||||
return self.plugin_manager.add_event_handler(self.__module__, event_name, handler)
|
||||
|
||||
def del_event_handler(self, event_name, handler):
|
||||
return self.plugin_manager.del_event_handler(self.__module__, event_name, handler)
|
||||
|
|
|
@ -1,25 +1,86 @@
|
|||
import imp
|
||||
import os
|
||||
import sys
|
||||
from config import config
|
||||
from gettext import gettext as _
|
||||
|
||||
plugins_dir = config.get('plugins_dir', '')
|
||||
plugins_dir = plugins_dir or\
|
||||
os.path.join(os.environ.get('XDG_DATA_HOME') or\
|
||||
os.path.join(os.environ.get('HOME'), '.local', 'share'),
|
||||
'poezio', 'plugins')
|
||||
try:
|
||||
os.makedirs(plugins_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
sys.path.append(plugins_dir)
|
||||
|
||||
class PluginManager(object):
|
||||
def __init__(self, core):
|
||||
self.core = core
|
||||
self.plugins = {}
|
||||
self.modules = {} # module name -> module object
|
||||
self.plugins = {} # module name -> plugin object
|
||||
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
|
||||
|
||||
def load(self, name):
|
||||
if name in self.plugins:
|
||||
self.plugins[name].unload()
|
||||
|
||||
try:
|
||||
code = compile(open(name).read(), name, 'exec')
|
||||
from plugin import BasePlugin
|
||||
globals = { 'BasePlugin' : BasePlugin }
|
||||
exec(code, globals)
|
||||
self.plugins[name] = globals['Plugin'](self.core)
|
||||
if name in self.modules:
|
||||
imp.acquire_lock()
|
||||
module = imp.reload(self.modules[name])
|
||||
imp.release_lock()
|
||||
else:
|
||||
file, filename, info = imp.find_module(name, [plugins_dir])
|
||||
imp.acquire_lock()
|
||||
module = imp.load_module(name, file, filename, info)
|
||||
imp.release_lock()
|
||||
except Exception as e:
|
||||
self.core.information("Could not load plugin: %s" % (e,))
|
||||
import traceback
|
||||
self.core.information(_("Could not load plugin: ") + traceback.format_exc())
|
||||
return
|
||||
finally:
|
||||
if imp.lock_held():
|
||||
imp.release_lock()
|
||||
|
||||
self.modules[name] = module
|
||||
self.commands[name] = {}
|
||||
self.event_handlers[name] = []
|
||||
self.plugins[name] = module.Plugin(self, self.core)
|
||||
|
||||
def unload(self, name):
|
||||
if name in self.plugins:
|
||||
try:
|
||||
for command in self.commands[name].keys():
|
||||
del self.core.commands[command]
|
||||
for event_name, handler in self.event_handlers[name]:
|
||||
self.core.xmpp.del_event_handler(event_name, handler)
|
||||
|
||||
self.plugins[name].unload()
|
||||
del self.plugins[name]
|
||||
del self.commands[name]
|
||||
del self.event_handlers[name]
|
||||
except Exception as e:
|
||||
self.core.information("Could not unload plugin (may not be safe to try again): %s" % (e,))
|
||||
import traceback
|
||||
self.core.information(_("Could not unload plugin (may not be safe to try again): ") + traceback.format_exc())
|
||||
|
||||
def add_command(self, module_name, name, handler, help, completion=None):
|
||||
if name in self.core.commands:
|
||||
raise Exception(_("Command '%s' already exists") % (name,))
|
||||
|
||||
commands = self.commands[module_name]
|
||||
commands[name] = (handler, help, completion)
|
||||
self.core.commands[name] = (handler, help, completion)
|
||||
|
||||
def add_event_handler(self, module_name, event_name, handler):
|
||||
eh = self.event_handlers[module_name]
|
||||
eh.append((event_name, handler))
|
||||
self.core.xmpp.add_event_handler(event_name, handler)
|
||||
|
||||
def del_event_handler(self, module_name, event_name, handler):
|
||||
self.core.xmpp.del_event_handler(event_name, handler)
|
||||
eh = self.event_handlers[module_name]
|
||||
eh = list(filter(lambda e : e != (event_name, handler), eh))
|
||||
|
|
Loading…
Reference in a new issue