View Single Post
Old 03-15-2021, 03:32 PM   #389
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,088
Karma: 1948136
Join Date: Aug 2015
Device: Kindle
Experimental API

Action chains provides an experimental API that enables other plugins to communicate with it. At this point it is unstable and is meant mainly for testing. Two main things that can be done are:
  1. API For other plugins to provide resources to Action Chains

    Using this, other plugins can provide Action Chains with different resources: actions, events and template functions.

    All you need to do is to define the resources you want in a module called action_chains.py in the root directory of your plugin. Action chains will read this module and import relevant resources based on their type (ChainAction, ChainEvent, TemplateFunction)

    All the resources imported to Action Chains can be used the same as their builtin counter parts.

  2. A fuction to allow other plugins to access Action Chains Modules for their own user defined objects

    This can be useful if you want to give users of you plugin to define their own objects that can be used in your plugin (e.g. user define algorithms in the Find Duplicates plugin)

    Fuction: on_modules_update(user_modules)

    This function should be implemented in a file called action_chains.py in the root of your plugin. A plugin that implements this function will have access to the action chains module manager. It passes user_modules instance which allows plugins to access different objects and classes defined in the module editor. Using this, plugins can give users the option to implement custom classes or functions.

    The user_modules provides the following methods:
    • get_objects(self, module_filters=[], type_filters=[])
    • get_classes(self, module_filters=[], class_filters=[])
    • get_namespace(self, module_name)

    Will start with an example of how action chains gets its custom actions from the user_modules instance:
    Code:
    user_actions = {}
    for cls in user_modules.get_classes(class_filters=[ChainAction]):
        name = cls.name
        if name in ['', 'Chain Action']:
            continue
        user_actions[name] = cls
    The above example will get all classes of type ChainAction form all modules. You can filter by module name by passing a list of filters to the module_list argument. The members of this list can be: string, compiled regex pattern, function.

    The second example is used by a custom version of Find Duplicates to get user defined algorithms (defined as functions not as classes):

    Code:
    user_algorithms = {}
    for module_name in user_modules.module_names:
        module_algos = user_modules.get_namespace(module_name).get('FIND_DUPLICATES_ALGORITHMS', {})
        user_algorithms.update(module_algos)
    The above code deal with functions that are defined in the modules and then added to a dictionary called 'FIND_DUPLICATES_ALGORITHMS'. It gets the 'FIND_DUPLICATES_ALGORITHMS' dictionary and uses it to added the functions to the plugin.

    Notes:
    • The get_namespace(module_name) method returns a dictionary of name : object for the specified module.
    • All methods above will return all objects including imported objects. So if you import a builtin class it will included with the user defined objects. Imported classes will only be excluded if the define the following attribute:
      Code:
      exclude_from_modules = True
      This will affect the class only and will not affect any other class the inherits from it.

      Another way to deal with this is to define a dictionary of objects you want to include as illustrated in the second example above.
    • on_modules_update() is called whenever the modules are updated + at calibre startup + library change.

Last edited by capink; 07-17-2023 at 02:11 PM.
capink is online now   Reply With Quote