mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-10-31 02:27:01 -04:00 
			
		
		
		
	GR Catalog Plugin implementation
This commit is contained in:
		
							parent
							
								
									2673542326
								
							
						
					
					
						commit
						00b4b1194a
					
				| @ -48,7 +48,7 @@ class Plugin(object): | ||||
|     #: the plugins are run in order of decreasing priority | ||||
|     #: i.e. plugins with higher priority will be run first. | ||||
|     #: The highest possible priority is ``sys.maxint``. | ||||
|     #: Default pririty is 1. | ||||
|     #: Default priority is 1. | ||||
|     priority = 1 | ||||
| 
 | ||||
|     #: The earliest version of calibre this plugin requires | ||||
| @ -226,4 +226,55 @@ class MetadataWriterPlugin(Plugin): | ||||
|         ''' | ||||
|         pass | ||||
| 
 | ||||
| class CatalogPlugin(Plugin): | ||||
|     ''' | ||||
|     A plugin that implements a catalog generator. | ||||
|     ''' | ||||
|      | ||||
|     #: Output file type for which this plugin should be run | ||||
|     #: For example: 'epub' or 'xml' | ||||
|     file_types = set([]) | ||||
| 
 | ||||
|     type = _('Catalog generator') | ||||
|      | ||||
|     #: CLI parser options specific to this plugin, declared as namedtuple Option | ||||
|     #: | ||||
|     #: from collections import namedtuple | ||||
|     #: Option = namedtuple('Option', 'option, default, dest, help') | ||||
|     #: cli_options = [Option('--catalog-title', | ||||
|     #:                       default = 'My Catalog', | ||||
|     #:                       dest = 'catalog_title', | ||||
|     #:                       help = (_('Title of generated catalog. \nDefault:') + " '" +  | ||||
|     #:                       '%default' + "'"))] | ||||
| 
 | ||||
|     cli_options = [] | ||||
| 
 | ||||
|     def run(self, path_to_output, opts, log): | ||||
|         ''' | ||||
|         Run the plugin. Must be implemented in subclasses. | ||||
|         It should generate the catalog in the format specified | ||||
|         in file_types, returning the absolute path to the | ||||
|         generated catalog file. If an error is encountered | ||||
|         it should raise an Exception and return None. The default  | ||||
|         implementation simply returns None. | ||||
| 
 | ||||
|         The generated catalog file should be created with the | ||||
|         :meth:`temporary_file` method. | ||||
| 
 | ||||
|         :param path_to_output: Absolute path to the generated catalog file. | ||||
|         :param opts: A dictionary of keyword arguments | ||||
| 
 | ||||
|         :return: Absolute path to the modified ebook. | ||||
|          | ||||
|         Access the opts object as a dictionary with this code: | ||||
|         opts_dict = vars(opts) | ||||
|         keys = opts_dict.keys() | ||||
|         keys.sort() | ||||
|         print "opts:" | ||||
|         for key in keys: | ||||
|             print "\t%s: %s" % (key, opts_dict[key]) | ||||
| 
 | ||||
|         ''' | ||||
|         # Default implementation does nothing | ||||
|         print "CatalogPlugin.generate_catalog() default method, should be overridden in subclass" | ||||
|         return None | ||||
|  | ||||
| @ -5,8 +5,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' | ||||
| import os, shutil, traceback, functools, sys, re | ||||
| from contextlib import closing | ||||
| 
 | ||||
| from calibre.customize import Plugin, FileTypePlugin, MetadataReaderPlugin, \ | ||||
|                               MetadataWriterPlugin | ||||
| from calibre.customize import Plugin, CatalogPlugin, FileTypePlugin, \ | ||||
|                               MetadataReaderPlugin, MetadataWriterPlugin | ||||
| from calibre.customize.conversion import InputFormatPlugin, OutputFormatPlugin | ||||
| from calibre.customize.profiles import InputProfile, OutputProfile | ||||
| from calibre.customize.builtins import plugins as builtin_plugins | ||||
| @ -300,6 +300,7 @@ def find_plugin(name): | ||||
|         if plugin.name == name: | ||||
|             return plugin | ||||
| 
 | ||||
| 
 | ||||
| def input_format_plugins(): | ||||
|     for plugin in _initialized_plugins: | ||||
|         if isinstance(plugin, InputFormatPlugin): | ||||
| @ -328,6 +329,7 @@ def available_input_formats(): | ||||
|     formats.add('zip'), formats.add('rar') | ||||
|     return formats | ||||
| 
 | ||||
| 
 | ||||
| def output_format_plugins(): | ||||
|     for plugin in _initialized_plugins: | ||||
|         if isinstance(plugin, OutputFormatPlugin): | ||||
| @ -347,6 +349,27 @@ def available_output_formats(): | ||||
|             formats.add(plugin.file_type) | ||||
|     return formats | ||||
| 
 | ||||
| 
 | ||||
| def catalog_plugins(): | ||||
|     for plugin in _initialized_plugins: | ||||
|         if isinstance(plugin, CatalogPlugin): | ||||
|             yield plugin | ||||
|              | ||||
| def available_catalog_formats(): | ||||
|     formats = set([]) | ||||
|     for plugin in catalog_plugins(): | ||||
|         if not is_disabled(plugin): | ||||
|             for format in plugin.file_types: | ||||
|                 formats.add(format) | ||||
|     return formats     | ||||
| 
 | ||||
| def plugin_for_catalog_format(fmt): | ||||
|     for plugin in catalog_plugins(): | ||||
|         if fmt.lower() in plugin.file_types: | ||||
|             return plugin | ||||
|     else: | ||||
|         return None | ||||
| 
 | ||||
| def device_plugins(): | ||||
|     for plugin in _initialized_plugins: | ||||
|         if isinstance(plugin, DevicePlugin): | ||||
|  | ||||
| @ -583,8 +583,121 @@ def command_export(args, dbpath): | ||||
|     do_export(get_db(dbpath, opts), ids, dir, opts) | ||||
|     return 0 | ||||
| 
 | ||||
| 
 | ||||
| #   GR additions | ||||
| 
 | ||||
| def catalog_option_parser(args): | ||||
|     from calibre.customize.ui import available_catalog_formats, plugin_for_catalog_format | ||||
|     from calibre.utils.logging import Log | ||||
| 
 | ||||
|     def add_plugin_parser_options(fmt, parser, log): | ||||
|      | ||||
|         # Fetch the extension-specific CLI options from the plugin | ||||
|         plugin = plugin_for_catalog_format(fmt) | ||||
|         for option in plugin.cli_options: | ||||
|             parser.add_option(option.option,  | ||||
|                               default=option.default,  | ||||
|                               dest=option.dest,  | ||||
|                               help=option.help)             | ||||
| 
 | ||||
|         # print_help(parser, log) | ||||
|         return plugin | ||||
| 
 | ||||
|     def print_help(parser, log): | ||||
|         help = parser.format_help().encode(preferred_encoding, 'replace') | ||||
|         log(help) | ||||
| 
 | ||||
|     def validate_command_line(parser, args, log): | ||||
|         # calibredb catalog path/to/destination.[epub|csv|xml|...] [options] | ||||
|          | ||||
|         # Validate form | ||||
|         if not len(args) or args[0].startswith('-'): | ||||
|             print_help(parser, log) | ||||
|             log.error("\n\nYou must specify a catalog output file of the form 'path/to/destination.extension'\n" | ||||
|             "To review options for an output format, type 'calibredb catalog <.extension> --help'\n" | ||||
|             "For example, 'calibredb catalog .xml --help'\n") | ||||
|             raise SystemExit(1) | ||||
|      | ||||
|         # Validate plugin exists for specified output format | ||||
|         output = os.path.abspath(args[0]) | ||||
|         file_extension = output[output.rfind('.') + 1:] | ||||
|          | ||||
|         if not file_extension in available_catalog_formats(): | ||||
|             print_help(parser, log) | ||||
|             log.error("No catalog plugin available for extension '%s'.\n" % file_extension + | ||||
|                       "Catalog plugins available for %s\n" % ', '.join(available_catalog_formats()) ) | ||||
|             raise SystemExit(1) | ||||
|          | ||||
|         return output, file_extension | ||||
| 
 | ||||
|     # Entry point | ||||
|     log = Log() | ||||
|     parser = get_parser(_( | ||||
|     ''' | ||||
|     %prog catalog /path/to/destination.(epub|csv|xml|...) [options] | ||||
|      | ||||
|     Export a catalog in format specified by path/to/destination extension. | ||||
|     Options control how entries are displayed in the generated catalog ouput. | ||||
|     ''')) | ||||
| 
 | ||||
|     # Confirm that a plugin handler exists for specified output file extension | ||||
|     # Will raise SystemExit(1) if no plugin matching file_extension | ||||
|     output, fmt = validate_command_line(parser, args, log) | ||||
|      | ||||
|     # Add options common to all catalog plugins | ||||
|     parser.add_option('-s', '--search', default=None, dest='search_text', | ||||
|                       help=_("Filter the results by the search query.  For the format of the search query, please see the search-related documentation in the User Manual.\n"+ | ||||
|                       "Default: no filtering")) | ||||
|     parser.add_option('-v','--verbose', default=False, action='store_true', | ||||
|                       dest='verbose',  | ||||
|                       help=_('Show detailed output information. Useful for debugging')) | ||||
| 
 | ||||
|     # Add options specific to fmt plugin | ||||
|     plugin = add_plugin_parser_options(fmt, parser, log) | ||||
|      | ||||
|     # Merge options from GUI Preferences | ||||
|     ''' | ||||
|     from calibre.library.save_to_disk import config | ||||
|     c = config() | ||||
|     for pref in ['asciiize', 'update_metadata', 'write_opf', 'save_cover']: | ||||
|         opt = c.get_option(pref) | ||||
|         switch = '--dont-'+pref.replace('_', '-') | ||||
|         parser.add_option(switch, default=True, action='store_false', | ||||
|                 help=opt.help+' '+_('Specifying this switch will turn ' | ||||
|                     'this behavior off.'), dest=pref) | ||||
| 
 | ||||
|     for pref in ['timefmt', 'template', 'formats']: | ||||
|         opt = c.get_option(pref) | ||||
|         switch = '--'+pref | ||||
|         parser.add_option(switch, default=opt.default, | ||||
|                 help=opt.help, dest=pref) | ||||
| 
 | ||||
|     for pref in ('replace_whitespace', 'to_lowercase'): | ||||
|         opt = c.get_option(pref) | ||||
|         switch = '--'+pref.replace('_', '-') | ||||
|         parser.add_option(switch, default=False, action='store_true', | ||||
|                 help=opt.help) | ||||
|     ''' | ||||
|      | ||||
|     return parser, plugin, log | ||||
| 
 | ||||
| def command_catalog(args, dbpath): | ||||
|     parser, plugin, log = catalog_option_parser(args) | ||||
|     opts, args = parser.parse_args(sys.argv[1:]) | ||||
|     if len(args) < 2: | ||||
|         parser.print_help() | ||||
|         print | ||||
|         print >>sys.stderr, _('Error: You must specify a catalog output file') | ||||
|         return 1 | ||||
|     if opts.verbose: | ||||
|         log("library.cli:command_catalog dispatching to plugin %s" % plugin.name) | ||||
|     plugin.run(args[1], opts) | ||||
|     return 0 | ||||
| 
 | ||||
| # end of GR additions     | ||||
| 
 | ||||
| COMMANDS = ('list', 'add', 'remove', 'add_format', 'remove_format', | ||||
|                 'show_metadata', 'set_metadata', 'export') | ||||
|                 'show_metadata', 'set_metadata', 'export', 'catalog') | ||||
| 
 | ||||
| 
 | ||||
| def option_parser(): | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user