mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -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