97 lines
2.7 KiB
Python
97 lines
2.7 KiB
Python
|
#!/usr/bin/python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
|
||
|
import sys
|
||
|
import logging
|
||
|
logging = logging.getLogger()
|
||
|
import os.path
|
||
|
import importlib
|
||
|
from os import listdir
|
||
|
|
||
|
|
||
|
class Plugin(object):
|
||
|
|
||
|
'''
|
||
|
Proto type of plugin class. Only subclasses are valid plugins.
|
||
|
'''
|
||
|
|
||
|
__command = ''
|
||
|
|
||
|
@staticmethod
|
||
|
def get_module():
|
||
|
return Plugin.__module
|
||
|
|
||
|
@staticmethod
|
||
|
def get_command():
|
||
|
return Plugin.__command
|
||
|
|
||
|
@staticmethod
|
||
|
def get_description():
|
||
|
return Plugin.__description
|
||
|
|
||
|
def __init__(self, callback):
|
||
|
self.callback = callback
|
||
|
|
||
|
def help(self):
|
||
|
return 'Sorry ... Help is unavailable at the moment'
|
||
|
|
||
|
def run(self, msg):
|
||
|
self.callback('Sorry ... Run is unavailable at the moment')
|
||
|
|
||
|
|
||
|
class PluginManager():
|
||
|
|
||
|
'''
|
||
|
Handles the plugins. Optional becomes a directory for search plugins.
|
||
|
'''
|
||
|
|
||
|
def __init__(self, plug_dir=None):
|
||
|
'''
|
||
|
Initialize callback function and plugin directory. If no callback is
|
||
|
given it returns imediality. If no plugin directory is given it uses
|
||
|
actual directory.
|
||
|
'''
|
||
|
if plug_dir is None:
|
||
|
self.plugin_dir = './plugins'
|
||
|
else: self.plugin_dir = plug_dir
|
||
|
|
||
|
def collect_plugins(self):
|
||
|
'''
|
||
|
Find all files in plugin directory and grabs filename, provided
|
||
|
command and short description.
|
||
|
'''
|
||
|
self.plugins = {}
|
||
|
search_dir = os.path.realpath(self.plugin_dir)
|
||
|
sys.path.insert(0, search_dir)
|
||
|
logging.debug('Search plugins in {}'.format(search_dir))
|
||
|
files = [x[:-3] for x in os.listdir(search_dir) if x.endswith('.py')]
|
||
|
for filename in files:
|
||
|
plugin = self.import_plugin(filename)
|
||
|
if plugin is False:
|
||
|
continue
|
||
|
command = plugin.Plugin.get_command()
|
||
|
self.plugins[command] = plugin
|
||
|
return self.plugins
|
||
|
|
||
|
def import_plugin(self, filename):
|
||
|
'''
|
||
|
Imports or reimports a module depending its known or not. It's
|
||
|
tested by the command provided by the plugin. (Not best praxis but
|
||
|
the easyst way. And i dont know, what a trouble is causes, if a
|
||
|
module ist moved.)
|
||
|
param 1: string
|
||
|
'''
|
||
|
try:
|
||
|
plugin = importlib.import_module(filename)
|
||
|
except Exception as e:
|
||
|
logging.error('Cant import module: {}'.format(filename))
|
||
|
logging.error('Exception: {}'.format(e))
|
||
|
return False
|
||
|
if not issubclass(plugin.Plugin, Plugin):
|
||
|
logging.error('Not a valid plugin: {}'.format(filename))
|
||
|
return False
|
||
|
logging.debug('Found plugin {}.'.format(filename))
|
||
|
return plugin
|
||
|
|