From 2bb5f7af796a26a457dbf6e1a02cf744cace59b7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 8 Feb 2017 16:07:11 +0530 Subject: [PATCH] Allow file type plugins to specify that they should be run for all file types --- src/calibre/customize/__init__.py | 3 ++- src/calibre/customize/ui.py | 37 ++++++++++++++----------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index ff81ee0572..d75ef63063 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -320,6 +320,7 @@ class FileTypePlugin(Plugin): # {{{ ''' #: Set of file types for which this plugin should be run. + #: Use '*' for all file types. #: For example: ``{'lit', 'mobi', 'prc'}`` file_types = set() @@ -389,7 +390,7 @@ class FileTypePlugin(Plugin): # {{{ :param fmt_map: Map of file format to path from which the file format was added. Note that this might or might not point to an actual existing file, as sometimes files are added as streams. In which case - it might be a dummy value or an on-existent path. + it might be a dummy value or a non-existent path. :param db: Library database ''' pass # Default implementation does nothing diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index 7dcd4f6e9e..9b5eb17fb8 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -4,6 +4,7 @@ __copyright__ = '2008, Kovid Goyal ' import os, shutil, traceback, functools, sys from collections import defaultdict +from itertools import chain from calibre.customize import (CatalogPlugin, FileTypePlugin, PluginNotFound, MetadataReaderPlugin, MetadataWriterPlugin, @@ -122,11 +123,7 @@ _on_postadd = [] def reread_filetype_plugins(): - global _on_import - global _on_postimport - global _on_preprocess - global _on_postprocess - global _on_postadd + global _on_import, _on_postimport, _on_preprocess, _on_postprocess, _on_postadd _on_import = defaultdict(list) _on_postimport = defaultdict(list) _on_preprocess = defaultdict(list) @@ -147,16 +144,21 @@ def reread_filetype_plugins(): _on_postprocess[ft].append(plugin) +def plugins_for_ft(ft, occasion): + op = { + 'import':_on_import, 'preprocess':_on_preprocess, 'postprocess':_on_postprocess, 'postimport':_on_postimport, + }[occasion] + for p in chain(op.get(ft, ()), op.get('*', ())): + if not is_disabled(p): + yield p + + def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'): - occasion_plugins = {'import':_on_import, 'preprocess':_on_preprocess, - 'postprocess':_on_postprocess}[occasion] customization = config['plugin_customization'] if ft is None: ft = os.path.splitext(path_to_file)[-1].lower().replace('.', '') nfp = path_to_file - for plugin in occasion_plugins.get(ft, []): - if is_disabled(plugin): - continue + for plugin in plugins_for_ft(ft, occasion): plugin.site_customization = customization.get(plugin.name, '') oo, oe = sys.stdout, sys.stderr # Some file type plugins out there override the output streams with buggy implementations with plugin: @@ -170,27 +172,22 @@ def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'): print >>oe, 'Running file type plugin %s failed with traceback:'%plugin.name traceback.print_exc(file=oe) sys.stdout, sys.stderr = oo, oe - x = lambda j : os.path.normpath(os.path.normcase(j)) + x = lambda j: os.path.normpath(os.path.normcase(j)) if occasion == 'postprocess' and x(nfp) != x(path_to_file): shutil.copyfile(nfp, path_to_file) nfp = path_to_file return nfp -run_plugins_on_import = functools.partial(_run_filetype_plugins, - occasion='import') -run_plugins_on_preprocess = functools.partial(_run_filetype_plugins, - occasion='preprocess') -run_plugins_on_postprocess = functools.partial(_run_filetype_plugins, - occasion='postprocess') +run_plugins_on_import = functools.partial(_run_filetype_plugins, occasion='import') +run_plugins_on_preprocess = functools.partial(_run_filetype_plugins, occasion='preprocess') +run_plugins_on_postprocess = functools.partial(_run_filetype_plugins, occasion='postprocess') def run_plugins_on_postimport(db, book_id, fmt): customization = config['plugin_customization'] fmt = fmt.lower() - for plugin in _on_postimport.get(fmt, []): - if is_disabled(plugin): - continue + for plugin in plugins_for_ft(fmt, 'postimport'): plugin.site_customization = customization.get(plugin.name, '') with plugin: try: