mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -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
|
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()
|
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 = 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):
|
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):
|
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
|
return 0
|
||||||
|
@ -7,7 +7,6 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import os, traceback, re, errno
|
import os, traceback, re, errno
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
from calibre.constants import DEBUG
|
from calibre.constants import DEBUG
|
||||||
from calibre.db.errors import NoSuchFormat
|
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)
|
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}
|
available_formats = {x.lower().strip() for x in available_formats}
|
||||||
if opts.formats == 'all':
|
if formats == 'all':
|
||||||
asked_formats = available_formats
|
asked_formats = available_formats
|
||||||
else:
|
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
|
return available_formats & asked_formats
|
||||||
|
|
||||||
|
|
||||||
@ -271,7 +270,7 @@ def save_book_to_disk(book_id, db, root, opts, length):
|
|||||||
db = db.new_api
|
db = db.new_api
|
||||||
mi = db.get_metadata(book_id, index_is_id=True)
|
mi = db.get_metadata(book_id, index_is_id=True)
|
||||||
plugboards = db.pref('plugboards', {})
|
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,
|
return do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||||
formats, root, opts, length)
|
formats, root, opts, length)
|
||||||
|
|
||||||
@ -342,9 +341,8 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
|
|||||||
|
|
||||||
cdata = None
|
cdata = None
|
||||||
if opts.save_cover or formats:
|
if opts.save_cover or formats:
|
||||||
cbuf = BytesIO()
|
cdata = db.cover(book_id)
|
||||||
if db.copy_cover_to(book_id, cbuf):
|
if cdata:
|
||||||
cdata = cbuf.getvalue()
|
|
||||||
cpath = base_path + '.jpg'
|
cpath = base_path + '.jpg'
|
||||||
with lopen(cpath, 'wb') as f:
|
with lopen(cpath, 'wb') as f:
|
||||||
f.write(cdata)
|
f.write(cdata)
|
||||||
@ -368,7 +366,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
|
|||||||
except NoSuchFormat:
|
except NoSuchFormat:
|
||||||
continue
|
continue
|
||||||
if opts.update_metadata:
|
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)
|
update_metadata(mi, fmt, stream, plugboards, cdata)
|
||||||
|
|
||||||
return not formats_written, book_id, mi.title
|
return not formats_written, book_id, mi.title
|
||||||
|
Loading…
x
Reference in New Issue
Block a user