mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Port calibredb export
This commit is contained in:
parent
dc86b78001
commit
4b09406136
@ -4,19 +4,140 @@
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
readonly = False
|
||||
import os
|
||||
|
||||
from calibre.db.cli import integers_from_string
|
||||
from calibre.db.errors import NoSuchFormat
|
||||
from calibre.library.save_to_disk import (
|
||||
config, do_save_book_to_disk, get_formats, sanitize_args
|
||||
)
|
||||
from calibre.utils.formatter_functions import load_user_template_functions
|
||||
|
||||
readonly = True
|
||||
version = 0 # change this if you change signature of implementation()
|
||||
|
||||
|
||||
def implementation(db, notify_changes, *args):
|
||||
def implementation(db, notify_changes, action, *args):
|
||||
is_remote = notify_changes is not None
|
||||
is_remote
|
||||
if action == 'all_ids':
|
||||
return db.all_book_ids()
|
||||
if action == 'setup':
|
||||
book_id, formats = args
|
||||
mi = db.get_metadata(book_id)
|
||||
plugboards = db.pref('plugboards', {})
|
||||
formats = get_formats(db.formats(book_id), formats)
|
||||
return mi, plugboards, formats, db.library_id, db.pref(
|
||||
'user_template_functions', []
|
||||
)
|
||||
if action == 'cover':
|
||||
return db.cover(args[0])
|
||||
if action == 'fmt':
|
||||
book_id, fmt, dest = args
|
||||
if is_remote:
|
||||
return db.format(book_id, fmt)
|
||||
db.copy_format_to(book_id, fmt, dest)
|
||||
|
||||
|
||||
def option_parser(get_parser):
|
||||
pass
|
||||
parser = get_parser(
|
||||
_(
|
||||
'''\
|
||||
%prog export [options] ids
|
||||
|
||||
Export the books specified by ids (a comma separated list) to the filesystem.
|
||||
The export operation saves all formats of the book, its cover and metadata (in
|
||||
an opf file). You can get id numbers from the search command.
|
||||
'''
|
||||
)
|
||||
)
|
||||
parser.add_option(
|
||||
'--all',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Export all books in database, ignoring the list of ids.')
|
||||
)
|
||||
parser.add_option(
|
||||
'--to-dir',
|
||||
default='.',
|
||||
help=(
|
||||
_('Export books to the specified directory. Default is') + ' %default'
|
||||
)
|
||||
)
|
||||
parser.add_option(
|
||||
'--single-dir',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Export all books into a single directory')
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
class DBProxy(object):
|
||||
|
||||
# Proxy to allow do_save_book_to_disk() to work with remote database
|
||||
|
||||
def __init__(self, dbctx):
|
||||
self.dbctx = dbctx
|
||||
|
||||
def cover(self, book_id):
|
||||
return self.dbctx.run('export', 'cover', book_id)
|
||||
|
||||
def copy_format_to(self, book_id, fmt, path):
|
||||
fdata = self.dbctx.run('export', 'fmt', book_id, fmt, path)
|
||||
if self.dbctx.is_remote:
|
||||
if fdata is None:
|
||||
raise NoSuchFormat(fmt)
|
||||
with lopen(path, 'wb') as f:
|
||||
f.write(fdata)
|
||||
|
||||
|
||||
def export(opts, dbctx, book_id, dest, dbproxy, length, first):
|
||||
mi, plugboards, formats, library_id, template_funcs = dbctx.run(
|
||||
'export', 'setup', book_id, opts.formats
|
||||
)
|
||||
if dbctx.is_remote and first:
|
||||
load_user_template_functions(library_id, template_funcs)
|
||||
return do_save_book_to_disk(
|
||||
dbproxy, book_id, mi, plugboards, formats, dest, opts, length
|
||||
)
|
||||
|
||||
|
||||
def main(opts, args, dbctx):
|
||||
raise NotImplementedError('TODO: implement this')
|
||||
if len(args) < 1 and not opts.all:
|
||||
raise SystemExit(_('You must specify some ids or the %s option') % '--all')
|
||||
if opts.all:
|
||||
book_ids = dbctx.run('export', 'all_ids')
|
||||
else:
|
||||
book_ids = set()
|
||||
for arg in args:
|
||||
book_ids |= set(integers_from_string(arg))
|
||||
dest = os.path.abspath(os.path.expanduser(opts.to_dir))
|
||||
dbproxy = DBProxy(dbctx)
|
||||
dest, opts, length = sanitize_args(dest, opts)
|
||||
for i, book_id in enumerate(book_ids):
|
||||
export(opts, dbctx, book_id, dest, dbproxy, length, i == 0)
|
||||
return 0
|
||||
|
@ -7,7 +7,6 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, traceback, re, errno
|
||||
from io import BytesIO
|
||||
|
||||
from calibre.constants import DEBUG
|
||||
from calibre.db.errors import NoSuchFormat
|
||||
@ -258,12 +257,12 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
||||
return shorten_components_to(length, components, last_has_extension=last_has_extension)
|
||||
|
||||
|
||||
def get_formats(available_formats, opts):
|
||||
def get_formats(available_formats, formats):
|
||||
available_formats = {x.lower().strip() for x in available_formats}
|
||||
if opts.formats == 'all':
|
||||
if formats == 'all':
|
||||
asked_formats = available_formats
|
||||
else:
|
||||
asked_formats = {x.lower().strip() for x in opts.formats.split(',')}
|
||||
asked_formats = {x.lower().strip() for x in formats.split(',')}
|
||||
return available_formats & asked_formats
|
||||
|
||||
|
||||
@ -271,7 +270,7 @@ def save_book_to_disk(book_id, db, root, opts, length):
|
||||
db = db.new_api
|
||||
mi = db.get_metadata(book_id, index_is_id=True)
|
||||
plugboards = db.pref('plugboards', {})
|
||||
formats = get_formats(db.formats(book_id), opts)
|
||||
formats = get_formats(db.formats(book_id), opts.formats)
|
||||
return do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||
formats, root, opts, length)
|
||||
|
||||
@ -342,9 +341,8 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||
|
||||
cdata = None
|
||||
if opts.save_cover or formats:
|
||||
cbuf = BytesIO()
|
||||
if db.copy_cover_to(book_id, cbuf):
|
||||
cdata = cbuf.getvalue()
|
||||
cdata = db.cover(book_id)
|
||||
if cdata:
|
||||
cpath = base_path + '.jpg'
|
||||
with lopen(cpath, 'wb') as f:
|
||||
f.write(cdata)
|
||||
@ -368,7 +366,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||
except NoSuchFormat:
|
||||
continue
|
||||
if opts.update_metadata:
|
||||
with lopen(fmt_path, 'rb') as stream:
|
||||
with lopen(fmt_path, 'r+b') as stream:
|
||||
update_metadata(mi, fmt, stream, plugboards, cdata)
|
||||
|
||||
return not formats_written, book_id, mi.title
|
||||
|
Loading…
x
Reference in New Issue
Block a user