def __init__(cls, name, bases, dct): try: if not name.endswith("HPlugin"): raise exceptions.PluginNameError( name, "Main plugin class should end with name HPlugin") if not hasattr(cls, "ID"): raise exceptions.PluginAttributeError( name, "ID attribute is missing") cls.ID = cls.ID.replace('-', '') if not hasattr(cls, "NAME"): raise exceptions.PluginAttributeError( name, "NAME attribute is missing") if not hasattr(cls, "VERSION"): raise exceptions.PluginAttributeError( name, "VERSION attribute is missing") if not hasattr(cls, "AUTHOR"): raise exceptions.PluginAttributeError( name, "AUTHOR attribute is missing") if not hasattr(cls, "DESCRIPTION"): raise exceptions.PluginAttributeError( name, "DESCRIPTION attribute is missing") try: val = uuid.UUID(cls.ID, version=4) assert val.hex == cls.ID except ValueError: raise exceptions.PluginIDError( name, "Invalid plugin id. UUID4 is required.") except AssertionError: raise exceptions.PluginIDError( name, "Invalid plugin id. A valid UUID4 is required.") if not isinstance(cls.NAME, str): raise exceptions.PluginAttributeError( name, "Plugin name should be a string") if not isinstance(cls.VERSION, tuple): raise exceptions.PluginAttributeError( name, "Plugin version should be a tuple with 3 integers") if not isinstance(cls.AUTHOR, str): raise exceptions.PluginAttributeError( name, "Plugin author should be a string") if not isinstance(cls.DESCRIPTION, str): raise exceptions.PluginAttributeError( name, "Plugin description should be a string") except exceptions.PluginError: return super().__init__(name, bases, dct) setattr(cls, "connectPlugin", cls.connectPlugin) setattr(cls, "newHook", cls.createHook) setattr(cls, "connectHook", cls.connectHook) setattr(cls, "__getattr__", cls.__getattr__) registered.register(cls)
def get_logger(cls): """ Return a logger for plugin """ node = registered._nodes.get(cls.ID) if not node: raise exceptions.PluginIDError( cls.NAME, "No plugin found with ID: {}".format(cls.ID)) return node.logger
def __init__(cls, name, bases, dct): plugin_requires = ("ID", "NAME", "VERSION", "AUTHOR", "DESCRIPTION") for pr in plugin_requires: if not hasattr(cls, pr): raise exceptions.PluginAttributeError( name, "{} attribute is missing".format(pr)) try: uid = cls.ID.replace('-', '') val = uuid.UUID(uid, version=4) assert val.hex == uid except ValueError: raise exceptions.PluginIDError( name, "Invalid plugin id. UUID4 is required.") except AssertionError: raise exceptions.PluginIDError( name, "Invalid plugin id. A valid UUID4 is required.") if not isinstance(cls.NAME, str): raise exceptions.PluginAttributeError( name, "Plugin name should be a string") if not isinstance(cls.VERSION, tuple) or not len(cls.VERSION) == 3: raise exceptions.PluginAttributeError( name, "Plugin version should be a tuple with 3 integers") if not isinstance(cls.AUTHOR, str): raise exceptions.PluginAttributeError( name, "Plugin author should be a string") if not isinstance(cls.DESCRIPTION, str): raise exceptions.PluginAttributeError( name, "Plugin description should be a string") super().__init__(name, bases, dct) # set attributes attrs = inspect.getmembers(HPluginMeta) for n, a in attrs: if not n.startswith('_'): setattr(cls, n, a)
def __getattr__(self, key): try: plugin = registered._plugins[self._id] except KeyError: raise exceptions.PluginIDError( name, "No plugin found with ID: " + self._id) pluginmethod = registered.hooks[self.ID].get(key) if pluginmethod: return pluginmethod else: raise exceptions.PluginMethodError( name, "Plugin {}:{} has no such method: {}".format( plugin.ID, plugin.NAME, key))
def on_command(cls, command_name, handler, **kwargs): """ Attach handler to command Params: - command_name -- Name of the Class.command you want to connect to. Eg.: GalleryRename.rename - handler -- Your custom method that should be executed when command is invoked """ node = registered._nodes.get(cls.ID) if not node: raise exceptions.PluginIDError( cls.NAME, "No plugin found with ID: {}".format(cls.ID)) registered._ensure_before_init(node) registered.attach_to_command(node, command_name, handler)
def connectHook(cls, pluginid, hook_name, handler): """ Connect to other plugins' hooks Params: pluginid -- PluginID of the plugin that has the hook you want to connect to hook_name -- Exact name of the hook you want to connect to handler -- Your custom method that should be executed when the other plugin uses its hook. """ assert isinstance(pluginid, str) and isinstance( hook_name, str) and callable(handler), "" if not registered._plugins[pluginid]: raise exceptions.PluginIDError( "No plugin found with ID: {}".format(pluginid)) if not registered.hooks[pluginid][hook_name]: raise exceptions.PluginHookError( "No hook with name '{}' found on plugin with ID: {}".format( hook_name, pluginid)) registered._connections.append( (cls.ID, pluginid.replace('-', ''), hook_name, handler))
def __getattr__(self, key): try: return self._plugins[key] except KeyError: raise exceptions.PluginIDError( "No plugin found with ID: {}".format(key))
def __init__(self, pluginid): self._id = pluginid.replace('-', '') if not registered._plugins.get(self._id): raise exceptions.PluginIDError( name, "No plugin found with ID: " + self._id)
def __init__(cls, name, bases, dct): plugin_requires = ("ID", "NAME", "SHORTNAME", "VERSION", "AUTHOR", "DESCRIPTION") for pr in plugin_requires: if not hasattr(cls, pr): raise exceptions.PluginAttributeError( name, "{} attribute is missing".format(pr)) for pr in plugin_requires: if not getattr(cls, pr): raise exceptions.PluginAttributeError( name, "{} attribute cannot be empty".format(pr)) try: uid = cls.ID.replace('-', '') val = uuid.UUID(uid, version=4) assert val.hex == uid except ValueError: raise exceptions.PluginIDError( name, "Invalid plugin id. UUID4 is required.") except AssertionError: raise exceptions.PluginIDError( name, "Invalid plugin id. A valid UUID4 is required.") if not isinstance(cls.NAME, str): raise exceptions.PluginAttributeError( name, "Plugin name should be a string") if not isinstance(cls.SHORTNAME, str): raise exceptions.PluginAttributeError( name, "Plugin shortname should be a string") if len(cls.SHORTNAME) > 10: raise exceptions.PluginAttributeError( name, "Plugin shortname cannot exceed {} characters".format( constants.plugin_shortname_length)) if not isinstance(cls.VERSION, tuple) or not len(cls.VERSION) == 3: raise exceptions.PluginAttributeError( name, "Plugin version should be a tuple with 3 integers") if not isinstance(cls.AUTHOR, str): raise exceptions.PluginAttributeError( name, "Plugin author should be a string") if not isinstance(cls.DESCRIPTION, str): raise exceptions.PluginAttributeError( name, "Plugin description should be a string") if hasattr(cls, "WEBSITE"): if not isinstance(cls.WEBSITE, str): raise exceptions.PluginAttributeError( name, "Plugin website should be a string") if hasattr(cls, "REQUIRE"): e = None if cls.REQUIRE: # invalid list if not isinstance(cls.REQUIRE, (tuple, list)): e = exceptions.PluginAttributeError( cls.NAME, "REQUIRE attribute must be a tuple/list") if not e: # wrong list e_x = exceptions.PluginAttributeError( cls.NAME, "REQUIRE should look like this: [ ( ID, (0,0,0), (0,0,0) ) ]" ) if not all( isinstance(x, (tuple, list)) for x in cls.REQUIRE): e = e_x if not e: e = e_x for x in cls.REQUIRE: if not x: break if len(x) < 2: break if not isinstance(x[0], str): break if not isinstance(x[1], tuple): break try: if not isinstance(x[2], tuple): break except IndexError: pass else: e = None if e: raise e else: cls.REQUIRE = None if hasattr(cls, "OPTIONS"): pass super().__init__(name, bases, dct) # set attributes attrs = inspect.getmembers(HPluginMeta) for n, a in attrs: if not n.startswith('_'): setattr(cls, n, a)