Refactor the plugin_manager.py

This commit is contained in:
Gobinath 2020-04-15 17:52:14 -04:00
parent fbaed596aa
commit 9128e8b1fb
3 changed files with 64 additions and 62 deletions

View File

@ -42,7 +42,6 @@ The plugin.py can have following methods but all are optional:
"""
import importlib
import inspect
import logging
import os
import sys
@ -60,7 +59,7 @@ class PluginManager:
Imports the Safe Eyes plugins and calls the methods defined in those plugins.
"""
def __init__(self, context, config):
def __init__(self):
logging.info('Load all the plugins')
self.__plugins = {}
self.__plugins_on_init = []
@ -79,12 +78,12 @@ class PluginManager:
def init(self, context, config):
"""
Initialize all the plugins with init(context, safeeyes_config, plugin_config) function.
Initialize all the plugins with init(context, safe_eyes_config, plugin_config) function.
"""
# Load the plugins
for plugin in config.get('plugins'):
try:
self.__load_plugin(plugin, context)
self.__load_plugin(plugin)
except BaseException:
logging.error('Error in loading the plugin: %s', plugin['id'])
continue
@ -196,23 +195,7 @@ class PluginManager:
return actions
def __has_method(self, module, method_name, no_of_args=0):
"""
Check whether the given function is defined in the module or not.
"""
if hasattr(module, method_name):
if len(inspect.getargspec(getattr(module, method_name)).args) == no_of_args:
return True
return False
def __remove_if_exists(self, list_of_items, item):
"""
Remove the item from the list_of_items it it exists.
"""
if item in list_of_items:
list_of_items.remove(item)
def __load_plugin(self, plugin, context):
def __load_plugin(self, plugin):
"""
Load the given plugin.
"""
@ -223,29 +206,28 @@ class PluginManager:
if plugin_obj['enabled']:
# Previously enabled but now disabled
plugin_obj['enabled'] = False
self.__remove_if_exists(self.__plugins_on_start, plugin_obj)
self.__remove_if_exists(self.__plugins_on_stop, plugin_obj)
self.__remove_if_exists(self.__plugins_on_exit, plugin_obj)
self.__remove_if_exists(self.__plugins_update_next_break, plugin_obj)
utility.remove_if_exists(self.__plugins_on_start, plugin_obj)
utility.remove_if_exists(self.__plugins_on_stop, plugin_obj)
utility.remove_if_exists(self.__plugins_on_exit, plugin_obj)
utility.remove_if_exists(self.__plugins_update_next_break, plugin_obj)
# Call the plugin.disable method if available
if self.__has_method(plugin_obj['module'], 'disable'):
if utility.has_method(plugin_obj['module'], 'disable'):
plugin_obj['module'].disable()
logging.info("Successfully unloaded the plugin '%s'", plugin['id'])
if not plugin_obj['break_override_allowed']:
# Remaining methods also should be removed
self.__remove_if_exists(self.__plugins_on_init, plugin_obj)
self.__remove_if_exists(self.__plugins_on_pre_break, plugin_obj)
self.__remove_if_exists(self.__plugins_on_start_break, plugin_obj)
self.__remove_if_exists(self.__plugins_on_stop_break, plugin_obj)
self.__remove_if_exists(self.__plugins_on_countdown, plugin_obj)
self.__remove_if_exists(self.__widget_plugins, plugin_obj)
self.__remove_if_exists(self.__tray_actions_plugins, plugin_obj)
utility.remove_if_exists(self.__plugins_on_init, plugin_obj)
utility.remove_if_exists(self.__plugins_on_pre_break, plugin_obj)
utility.remove_if_exists(self.__plugins_on_start_break, plugin_obj)
utility.remove_if_exists(self.__plugins_on_stop_break, plugin_obj)
utility.remove_if_exists(self.__plugins_on_countdown, plugin_obj)
utility.remove_if_exists(self.__widget_plugins, plugin_obj)
utility.remove_if_exists(self.__tray_actions_plugins, plugin_obj)
del self.__plugins[plugin['id']]
return
# Look for plugin.py
plugin_dir = None
if os.path.isfile(os.path.join(utility.SYSTEM_PLUGINS_DIR, plugin['id'], 'plugin.py')):
plugin_dir = utility.SYSTEM_PLUGINS_DIR
elif os.path.isfile(os.path.join(utility.USER_PLUGINS_DIR, plugin['id'], 'plugin.py')):
@ -263,12 +245,12 @@ class PluginManager:
if plugin_config is None:
return
if (plugin_enabled or plugin_config.get('break_override_allowed', False)):
if plugin_enabled or plugin_config.get('break_override_allowed', False):
if plugin['id'] in self.__plugins:
# The plugin is already enabled or partially loaded due to break_override_allowed
# Use the existing plugin object
plugin_obj = self.__plugins[plugin['id']]
# Update the config
plugin_obj['config'] = dict(plugin.get('settings', {}))
plugin_obj['config']['path'] = os.path.join(plugin_dir, plugin['id'])
@ -281,14 +263,7 @@ class PluginManager:
# Load the rest of the methods
plugin_obj['enabled'] = True
module = plugin_obj['module']
if self.__has_method(module, 'on_start'):
self.__plugins_on_start.append(plugin_obj)
if self.__has_method(module, 'on_stop'):
self.__plugins_on_stop.append(plugin_obj)
if self.__has_method(module, 'on_exit'):
self.__plugins_on_exit.append(plugin_obj)
if self.__has_method(module, 'update_next_break', 2):
self.__plugins_update_next_break.append(plugin_obj)
self.__init_plugin(module, plugin_obj)
else:
# This is the first time to load the plugin
# Check for dependencies
@ -299,32 +274,40 @@ class PluginManager:
module = importlib.import_module((plugin['id'] + '.plugin'))
logging.info("Successfully loaded %s", str(module))
plugin_obj = {'id': plugin['id'], 'module': module, 'config': dict(plugin.get(
'settings', {})), 'enabled': plugin_enabled, 'break_override_allowed': plugin_config.get('break_override_allowed', False)}
'settings', {})), 'enabled': plugin_enabled,
'break_override_allowed': plugin_config.get('break_override_allowed', False)}
# Inject the plugin directory into the config
plugin_obj['config']['path'] = os.path.join(plugin_dir, plugin['id'])
self.__plugins[plugin['id']] = plugin_obj
if self.__has_method(module, 'enable'):
if utility.has_method(module, 'enable'):
module.enable()
if plugin_enabled:
if self.__has_method(module, 'on_start'):
self.__plugins_on_start.append(plugin_obj)
if self.__has_method(module, 'on_stop'):
self.__plugins_on_stop.append(plugin_obj)
if self.__has_method(module, 'on_exit'):
self.__plugins_on_exit.append(plugin_obj)
if self.__has_method(module, 'update_next_break', 2):
self.__plugins_update_next_break.append(plugin_obj)
if self.__has_method(module, 'init', 3):
self.__init_plugin(module, plugin_obj)
if utility.has_method(module, 'init', 3):
self.__plugins_on_init.append(plugin_obj)
if self.__has_method(module, 'on_pre_break', 1):
if utility.has_method(module, 'on_pre_break', 1):
self.__plugins_on_pre_break.append(plugin_obj)
if self.__has_method(module, 'on_start_break', 1):
if utility.has_method(module, 'on_start_break', 1):
self.__plugins_on_start_break.append(plugin_obj)
if self.__has_method(module, 'on_stop_break', 0):
if utility.has_method(module, 'on_stop_break', 0):
self.__plugins_on_stop_break.append(plugin_obj)
if self.__has_method(module, 'on_countdown', 2):
if utility.has_method(module, 'on_countdown', 2):
self.__plugins_on_countdown.append(plugin_obj)
if self.__has_method(module, 'get_widget_title', 1) and self.__has_method(module, 'get_widget_content', 1):
if utility.has_method(module, 'get_widget_title', 1) and utility.has_method(module,
'get_widget_content', 1):
self.__widget_plugins.append(plugin_obj)
if self.__has_method(module, 'get_tray_action', 1):
if utility.has_method(module, 'get_tray_action', 1):
self.__tray_actions_plugins.append(plugin_obj)
def __init_plugin(self, module, plugin_obj):
"""
Collect mandatory methods from the plugin and add them to the life cycle methods list.
"""
if utility.has_method(module, 'on_start'):
self.__plugins_on_start.append(plugin_obj)
if utility.has_method(module, 'on_stop'):
self.__plugins_on_stop.append(plugin_obj)
if utility.has_method(module, 'on_exit'):
self.__plugins_on_exit.append(plugin_obj)
if utility.has_method(module, 'update_next_break', 2):
self.__plugins_update_next_break.append(plugin_obj)

View File

@ -84,7 +84,7 @@ class SafeEyes:
self.break_screen = BreakScreen(
self.context, self.on_skipped, self.on_postponed, utility.STYLE_SHEET_PATH)
self.break_screen.initialize(self.config)
self.plugins_manager = PluginManager(self.context, self.config)
self.plugins_manager = PluginManager()
self.safe_eyes_core = SafeEyesCore(self.context)
self.safe_eyes_core.on_pre_break += self.plugins_manager.pre_break
self.safe_eyes_core.on_start_break += self.on_start_break

View File

@ -22,6 +22,7 @@ This module contains utility functions for Safe Eyes and its plugins.
import errno
import imp
import inspect
import importlib
import json
import locale
@ -554,3 +555,21 @@ def load_and_scale_image(path, width, height):
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
return image
def has_method(module, method_name, no_of_args=0):
"""
Check whether the given function is defined in the module or not.
"""
if hasattr(module, method_name):
if len(inspect.getargspec(getattr(module, method_name)).args) == no_of_args:
return True
return False
def remove_if_exists(list_of_items, item):
"""
Remove the item from the list_of_items it it exists.
"""
if item in list_of_items:
list_of_items.remove(item)