mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Refactor the old save to disk code to use the new db api
This commit is contained in:
parent
ad5ba94f3a
commit
bafc949526
@ -6,9 +6,11 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import os, traceback, re, shutil
|
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.utils.config import Config, StringConfig, tweaks
|
from calibre.utils.config import Config, StringConfig, tweaks
|
||||||
from calibre.utils.formatter import TemplateFormatter
|
from calibre.utils.formatter import TemplateFormatter
|
||||||
from calibre.utils.filenames import shorten_components_to, supports_long_names, ascii_filename
|
from calibre.utils.filenames import shorten_components_to, supports_long_names, ascii_filename
|
||||||
@ -17,7 +19,6 @@ from calibre.ebooks.metadata import fmt_sidx
|
|||||||
from calibre.ebooks.metadata import title_sort
|
from calibre.ebooks.metadata import title_sort
|
||||||
from calibre.utils.date import as_local_time
|
from calibre.utils.date import as_local_time
|
||||||
from calibre import strftime, prints, sanitize_file_name_unicode
|
from calibre import strftime, prints, sanitize_file_name_unicode
|
||||||
from calibre.ptempfile import SpooledTemporaryFile
|
|
||||||
from calibre.db.lazy import FormatsList
|
from calibre.db.lazy import FormatsList
|
||||||
|
|
||||||
plugboard_any_device_value = 'any device'
|
plugboard_any_device_value = 'any device'
|
||||||
@ -257,35 +258,22 @@ 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 save_book_to_disk(id_, db, root, opts, length):
|
def get_formats(available_formats, opts):
|
||||||
mi = db.get_metadata(id_, index_is_id=True)
|
available_formats = {x.lower().strip() for x in available_formats}
|
||||||
cover = db.cover(id_, index_is_id=True)
|
if opts.formats == 'all':
|
||||||
plugboards = db.prefs.get('plugboards', {})
|
asked_formats = available_formats
|
||||||
|
|
||||||
available_formats = db.formats(id_, index_is_id=True)
|
|
||||||
if not available_formats:
|
|
||||||
available_formats = []
|
|
||||||
else:
|
else:
|
||||||
available_formats = [x.lower().strip() for x in
|
asked_formats = {x.lower().strip() for x in opts.formats.split(',')}
|
||||||
available_formats.split(',')]
|
return available_formats & asked_formats
|
||||||
formats = {}
|
|
||||||
fmts = db.formats(id_, index_is_id=True, verify_formats=False)
|
|
||||||
if fmts:
|
|
||||||
fmts = fmts.split(',')
|
|
||||||
for fmt in fmts:
|
|
||||||
fpath = db.format(id_, fmt, index_is_id=True, as_path=True)
|
|
||||||
if fpath is not None:
|
|
||||||
formats[fmt.lower()] = fpath
|
|
||||||
|
|
||||||
try:
|
|
||||||
return do_save_book_to_disk(id_, mi, cover, plugboards,
|
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)
|
||||||
|
return do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||||
formats, root, opts, length)
|
formats, root, opts, length)
|
||||||
finally:
|
|
||||||
for temp in formats.itervalues():
|
|
||||||
try:
|
|
||||||
os.remove(temp)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def get_path_components(opts, mi, book_id, path_length):
|
def get_path_components(opts, mi, book_id, path_length):
|
||||||
@ -332,70 +320,58 @@ def update_metadata(mi, fmt, stream, plugboards, cdata, error_report=None, plugb
|
|||||||
error_report(fmt, traceback.format_exc())
|
error_report(fmt, traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
def do_save_book_to_disk(id_, mi, cover, plugboards,
|
def do_save_book_to_disk(db, book_id, mi, plugboards,
|
||||||
format_map, root, opts, length):
|
formats, root, opts, length):
|
||||||
available_formats = [x.lower().strip() for x in format_map.keys()]
|
originals = mi.cover, mi.pubdate, mi.timestamp
|
||||||
|
formats_written = False
|
||||||
|
try:
|
||||||
if mi.pubdate:
|
if mi.pubdate:
|
||||||
mi.pubdate = as_local_time(mi.pubdate)
|
mi.pubdate = as_local_time(mi.pubdate)
|
||||||
if mi.timestamp:
|
if mi.timestamp:
|
||||||
mi.timestamp = as_local_time(mi.timestamp)
|
mi.timestamp = as_local_time(mi.timestamp)
|
||||||
|
|
||||||
if opts.formats == 'all':
|
components = get_path_components(opts, mi, book_id, length)
|
||||||
asked_formats = available_formats
|
|
||||||
else:
|
|
||||||
asked_formats = [x.lower().strip() for x in opts.formats.split(',')]
|
|
||||||
formats = set(available_formats).intersection(set(asked_formats))
|
|
||||||
if not formats:
|
|
||||||
return True, id_, mi.title
|
|
||||||
|
|
||||||
components = get_path_components(opts, mi, id_, length)
|
|
||||||
base_path = os.path.join(root, *components)
|
base_path = os.path.join(root, *components)
|
||||||
base_name = os.path.basename(base_path)
|
base_name = os.path.basename(base_path)
|
||||||
dirpath = os.path.dirname(base_path)
|
dirpath = os.path.dirname(base_path)
|
||||||
# Don't test for existence first as the test could fail but
|
|
||||||
# another worker process could create the directory before
|
|
||||||
# the call to makedirs
|
|
||||||
try:
|
try:
|
||||||
os.makedirs(dirpath)
|
os.makedirs(dirpath)
|
||||||
except BaseException:
|
except EnvironmentError as err:
|
||||||
if not os.path.exists(dirpath):
|
if err.errno != errno.EEXIST:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
ocover = mi.cover
|
cdata = None
|
||||||
if opts.save_cover and cover:
|
if opts.save_cover or formats:
|
||||||
with open(base_path+'.jpg', 'wb') as f:
|
cbuf = BytesIO()
|
||||||
f.write(cover)
|
if db.copy_cover_to(book_id, cbuf):
|
||||||
|
cdata = cbuf.getvalue()
|
||||||
|
cpath = base_path + '.jpg'
|
||||||
|
with lopen(cpath, 'wb') as f:
|
||||||
|
f.write(cdata)
|
||||||
mi.cover = base_name+'.jpg'
|
mi.cover = base_name+'.jpg'
|
||||||
else:
|
|
||||||
mi.cover = None
|
|
||||||
|
|
||||||
if opts.write_opf:
|
if opts.write_opf:
|
||||||
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
||||||
opf = metadata_to_opf(mi)
|
opf = metadata_to_opf(mi)
|
||||||
with open(base_path+'.opf', 'wb') as f:
|
with lopen(base_path+'.opf', 'wb') as f:
|
||||||
f.write(opf)
|
f.write(opf)
|
||||||
|
finally:
|
||||||
|
mi.cover, mi.pubdate, mi.timestamp = originals
|
||||||
|
|
||||||
mi.cover = ocover
|
if not formats:
|
||||||
|
return not formats_written, book_id, mi.title
|
||||||
|
|
||||||
written = False
|
|
||||||
for fmt in formats:
|
for fmt in formats:
|
||||||
fp = format_map.get(fmt, None)
|
|
||||||
if fp is None:
|
|
||||||
continue
|
|
||||||
stream = SpooledTemporaryFile(20*1024*1024, '_save_to_disk.'+(fmt or
|
|
||||||
'tmp'))
|
|
||||||
with open(fp, 'rb') as f:
|
|
||||||
shutil.copyfileobj(f, stream)
|
|
||||||
stream.seek(0)
|
|
||||||
written = True
|
|
||||||
if opts.update_metadata:
|
|
||||||
update_metadata(mi, fmt, stream, plugboards, cover)
|
|
||||||
stream.seek(0)
|
|
||||||
fmt_path = base_path+'.'+str(fmt)
|
fmt_path = base_path+'.'+str(fmt)
|
||||||
with open(fmt_path, 'wb') as f:
|
try:
|
||||||
shutil.copyfileobj(stream, f)
|
db.copy_format_to(book_id, fmt, fmt_path)
|
||||||
|
formats_written = True
|
||||||
|
except NoSuchFormat:
|
||||||
|
continue
|
||||||
|
if opts.update_metadata:
|
||||||
|
with lopen(fmt_path, 'rb') as stream:
|
||||||
|
update_metadata(mi, fmt, stream, plugboards, cdata)
|
||||||
|
|
||||||
return not written, id_, mi.title
|
return not formats_written, book_id, mi.title
|
||||||
|
|
||||||
|
|
||||||
def sanitize_args(root, opts):
|
def sanitize_args(root, opts):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user