#!/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