diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index b3b1b39ea1..40532d250f 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -24,10 +24,10 @@ class InvalidPlugin(ValueError): pass -class PluginInstallationType(enum.Enum): - BUILTIN = enum.auto() - SYSTEM = enum.auto() - EXTERNAL = enum.auto() +class PluginInstallationType(enum.IntEnum): + EXTERNAL = 1 + SYSTEM = 2 + BUILTIN = 3 class Plugin(object): # {{{ diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index ee49a18235..b11af101c3 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -348,15 +348,7 @@ def reread_metadata_plugins(): # Ensure the following metadata plugin preference is used: # external > system > builtin def key(plugin): - installation_type = plugin.installation_type - if installation_type is PluginInstallationType.BUILTIN: - order = 2 - elif installation_type is PluginInstallationType.SYSTEM: - order = 1 - elif installation_type is PluginInstallationType.EXTERNAL: - order = 0 - else: - raise ValueError(installation_type) + order = sys.maxsize if plugin.installation_type is None else plugin.installation_type return order, plugin.name for group in (_metadata_readers, _metadata_writers): @@ -486,7 +478,7 @@ def add_plugin(path_to_zip_file): if plugin.name in builtin_names: raise NameConflict( 'A builtin plugin with the name %r already exists' % plugin.name) - if plugin.name in _list_system_plugins(): + if plugin.name in get_system_plugins(): raise NameConflict( 'A system plugin with the name %r already exists' % plugin.name) plugin = initialize_plugin(plugin, path_to_zip_file, PluginInstallationType.EXTERNAL) @@ -693,29 +685,30 @@ def has_external_plugins(): return bool(config['plugins']) -@functools.lru_cache(maxsize=None) -def _list_system_plugins(): +@functools.lru_cache(maxsize=2) +def get_system_plugins(): if not system_plugins_loc: - return + return {} try: plugin_file_names = os.listdir(system_plugins_loc) except OSError: - return + return {} + ans = [] for plugin_file_name in plugin_file_names: plugin_path = os.path.join(system_plugins_loc, plugin_file_name) if os.path.isfile(plugin_path) and plugin_file_name.endswith('.zip'): - yield (os.path.splitext(plugin_file_name)[0], plugin_path) + ans.append((os.path.splitext(plugin_file_name)[0], plugin_path)) + return dict(ans) def initialize_plugins(perf=False): - global _initialized_plugins, _system_plugins + global _initialized_plugins _initialized_plugins = [] - _system_plugins = [] - system_plugins = dict(_list_system_plugins()) - conflicts = [name for name in config['plugins'] if name in - builtin_names or name in system_plugins] + system_plugins = get_system_plugins().copy() + conflicts = {name for name in config['plugins'] if name in + builtin_names or name in system_plugins} for p in conflicts: remove_plugin(p) system_conflicts = [name for name in system_plugins if name in diff --git a/src/calibre/debug.py b/src/calibre/debug.py index d4398162e8..2f7fb6bee4 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -207,7 +207,9 @@ def print_basic_debug_info(out=None): out('Interface language:', unicode_type(set_translators.lang)) from calibre.customize.ui import has_external_plugins, initialized_plugins if has_external_plugins(): - names = ('{0} {1}'.format(p.name, p.version) for p in initialized_plugins() if getattr(p, 'plugin_path', None) is not None) + from calibre.customize import PluginInstallationType + names = ('{0} {1}'.format(p.name, p.version) for p in initialized_plugins() + if getattr(p, 'installation_type', None) is not PluginInstallationType.BUILTIN) out('Successfully initialized third party plugins:', ' && '.join(names)) diff --git a/src/calibre/gui2/dialogs/catalog.py b/src/calibre/gui2/dialogs/catalog.py index 781753691b..84166111e2 100644 --- a/src/calibre/gui2/dialogs/catalog.py +++ b/src/calibre/gui2/dialogs/catalog.py @@ -6,14 +6,18 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, sys, importlib, weakref +import importlib +import os +import sys +import weakref +from qt.core import ( + QApplication, QCoreApplication, QDialog, QDialogButtonBox, QScrollArea, QSize +) -from qt.core import QDialog, QCoreApplication, QSize, QScrollArea, QApplication, QDialogButtonBox - -from calibre.customize.ui import config -from calibre.gui2.dialogs.catalog_ui import Ui_Dialog +from calibre.customize import PluginInstallationType +from calibre.customize.ui import catalog_plugins, config from calibre.gui2 import dynamic, info_dialog -from calibre.customize.ui import catalog_plugins +from calibre.gui2.dialogs.catalog_ui import Ui_Dialog from polyglot.builtins import unicode_type @@ -23,9 +27,10 @@ class Catalog(QDialog, Ui_Dialog): def __init__(self, parent, dbspec, ids, db): import re - from calibre import prints as info from PyQt5.uic import compileUi + from calibre import prints as info + QDialog.__init__(self, parent) self.setupUi(self) self.dbspec, self.ids = dbspec, ids @@ -44,7 +49,7 @@ class Catalog(QDialog, Ui_Dialog): continue name = plugin.name.lower().replace(' ', '_') - if getattr(plugin, 'plugin_path', None) is None: + if getattr(plugin, 'installation_type', None) is PluginInstallationType.BUILTIN: try: catalog_widget = importlib.import_module('calibre.gui2.catalog.'+name) pw = catalog_widget.PluginWidget() @@ -68,6 +73,7 @@ class Catalog(QDialog, Ui_Dialog): # Compile the .ui form provided in plugin.zip if not os.path.exists(compiled_form): from polyglot.io import PolyglotStringIO + # info('\tCompiling form', form) buf = PolyglotStringIO() compileUi(form, buf) diff --git a/src/calibre/gui2/dialogs/plugin_updater.py b/src/calibre/gui2/dialogs/plugin_updater.py index 77ed0c95ae..8bd193aa05 100644 --- a/src/calibre/gui2/dialogs/plugin_updater.py +++ b/src/calibre/gui2/dialogs/plugin_updater.py @@ -198,7 +198,7 @@ class DisplayPlugin(object): self.uninstall_plugins = plugin['uninstall'] or [] self.has_changelog = plugin['history'] self.is_deprecated = plugin['deprecated'] - self.installation_type = plugin['installation_type'] + self.installation_type = PluginInstallationType.EXTERNAL def is_disabled(self): if self.plugin is None: diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index c6b635c5c8..65457012d5 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -54,7 +54,7 @@ class PluginModel(QAbstractItemModel, AdaptSQP): # {{{ def populate(self): self._data = {} for plugin in initialized_plugins(): - if (getattr(plugin, 'plugin_path', None) is None and self.show_only_user_plugins): + if (getattr(plugin, 'installation_type', None) is not PluginInstallationType.EXTERNAL and self.show_only_user_plugins): continue if plugin.type not in self._data: self._data[plugin.type] = [plugin] diff --git a/src/calibre/gui2/tweak_book/plugin.py b/src/calibre/gui2/tweak_book/plugin.py index 57e0257fdf..5cccbf7d62 100644 --- a/src/calibre/gui2/tweak_book/plugin.py +++ b/src/calibre/gui2/tweak_book/plugin.py @@ -10,6 +10,7 @@ import sys from qt.core import QToolButton from calibre import prints +from calibre.customize import PluginInstallationType from calibre.customize.ui import all_edit_book_tool_plugins from calibre.gui2.tweak_book import current_container, tprefs from calibre.gui2.tweak_book.boss import get_boss @@ -171,7 +172,7 @@ def create_plugin_actions(actions, toolbar_actions, plugin_menu_actions): try: tools = tuple(load_plugin_tools(plugin)) except Exception: - if not plugin.plugin_path: + if plugin.installation_type is PluginInstallationType.BUILTIN: raise print('Failed to load third-party plugin:', plugin.name, file=sys.stderr) import traceback diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 6e51eb5a9f..0ab27d3ff8 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -217,7 +217,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ # Ignore errors in third party plugins import traceback traceback.print_exc() - if getattr(ac, 'plugin_path', None) is None: + if getattr(ac, 'installation_type', None) is PluginInstallationType.BUILTIN: raise self.donate_action = QAction(QIcon(I('donate.png')), _('&Donate to support calibre'), self)