7from os
import listdir, makedirs, remove, stat, utime
8from os.path
import abspath, basename, dirname, exists, join
54def sync_resource(base_path, resource_path, name, target_dir, plugin_dir):
55 dep_path = join(base_path, resource_path)
56 file_name = basename(dep_path)
57 resource_path = join(target_dir, file_name)
58 if not exists(resource_path)
or sha_sum(dep_path) !=
sha_sum(resource_path):
60 copyfile(dep_path, resource_path)
63 dep_stat = stat(dep_path)
64 utime(resource_path, ns=(dep_stat.st_atime_ns, dep_stat.st_mtime_ns))
66 logger.critical(
"failed to copy plugin resource {0} for plugin {1}".
format(file_name, name))
70 return join(
"plugins/external_plugins", plugin_dir, file_name)
74 plugin_base_path = dirname(abspath(plugin.__file__))
76 plugin_dir = plugin_module_name
77 target_dir = join(settings[
"ui"][
"static_path"],
"plugins/external_plugins", plugin_dir)
79 makedirs(target_dir, exist_ok=
True)
81 logger.critical(
"failed to create resource directory {0} for plugin {1}".
format(target_dir, plugin_module_name))
86 if hasattr(plugin,
"js_dependencies"):
87 resources.extend(map(basename, plugin.js_dependencies))
88 plugin.js_dependencies = [
89 sync_resource(plugin_base_path, x, plugin_module_name, target_dir, plugin_dir)
90 for x
in plugin.js_dependencies
93 if hasattr(plugin,
"css_dependencies"):
94 resources.extend(map(basename, plugin.css_dependencies))
95 plugin.css_dependencies = [
96 sync_resource(plugin_base_path, x, plugin_module_name, target_dir, plugin_dir)
97 for x
in plugin.css_dependencies
100 for f
in listdir(target_dir):
101 if basename(f)
not in resources:
102 resource_path = join(target_dir, basename(f))
104 remove(resource_path)
107 "failed to remove unused resource file {0} for plugin {1}".
format(resource_path, plugin_module_name)
115 plugin = import_module(plugin_module_name)
124 logger.critical(
"%s: fatal exception", plugin_module_name, exc_info=e)
126 except BaseException:
127 logger.exception(
"%s: exception while loading, the plugin is disabled", plugin_module_name)
131 plugin.id = plugin_module_name
134 plugin.logger = getLogger(plugin_module_name)
136 for plugin_attr, plugin_attr_type
in required_attrs:
137 if not hasattr(plugin, plugin_attr):
138 logger.critical(
'%s: missing attribute "%s", cannot load plugin', plugin, plugin_attr)
140 attr = getattr(plugin, plugin_attr)
141 if not isinstance(attr, plugin_attr_type):
142 type_attr = str(type(attr))
144 '{1}: attribute "{0}" is of type {2}, must be of type {3}, cannot load plugin'.
format(
145 plugin, plugin_attr, type_attr, plugin_attr_type
150 for plugin_attr, plugin_attr_type
in optional_attrs:
151 if not hasattr(plugin, plugin_attr)
or not isinstance(getattr(plugin, plugin_attr), plugin_attr_type):
152 setattr(plugin, plugin_attr, plugin_attr_type())
154 if not hasattr(plugin,
"preference_section"):
155 plugin.preference_section =
"general"
158 if plugin.preference_section ==
"query":
159 for plugin_attr
in (
"query_keywords",
"query_examples"):
160 if not hasattr(plugin, plugin_attr):
161 logger.critical(
'missing attribute "{0}", cannot load plugin: {1}'.
format(plugin_attr, plugin))
164 if settings.get(
"enabled_plugins"):
166 plugin.default_on = plugin.name
in settings[
"enabled_plugins"]
or plugin.id
in settings[
"enabled_plugins"]
172 logger.debug(
"%s: loaded", plugin_module_name)