mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Refactor the code to embed metadata into format files to enable re-use
This commit is contained in:
parent
5036b68d8a
commit
542658a85f
@ -1214,6 +1214,13 @@ class DB(object):
|
||||
shutil.copyfile(candidates[0], fmt_path)
|
||||
return fmt_path
|
||||
|
||||
def apply_to_format(self, book_id, path, fname, fmt, func, missing_value=None):
|
||||
path = self.format_abspath(book_id, fmt, fname, path)
|
||||
if path is None:
|
||||
return missing_value
|
||||
with lopen(path, 'r+b') as f:
|
||||
return func(f)
|
||||
|
||||
def format_hash(self, book_id, fmt, fname, path):
|
||||
path = self.format_abspath(book_id, fmt, fname, path)
|
||||
if path is None:
|
||||
|
@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import os, traceback, random, shutil, re, operator
|
||||
from io import BytesIO
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
from functools import wraps, partial
|
||||
from future_builtins import zip
|
||||
|
||||
from calibre import isbytestring
|
||||
@ -1685,8 +1685,7 @@ class Cache(object):
|
||||
identical_book_ids = set()
|
||||
if mi.authors:
|
||||
try:
|
||||
quathors = mi.authors[:20] # Too many authors causes parsing of
|
||||
# the search expression to fail
|
||||
quathors = mi.authors[:20] # Too many authors causes parsing of the search expression to fail
|
||||
query = ' and '.join('authors:"=%s"'%(a.replace('"', '')) for a in quathors)
|
||||
qauthors = mi.authors[20:]
|
||||
except ValueError:
|
||||
@ -1797,5 +1796,44 @@ class Cache(object):
|
||||
ans[book].append(lib)
|
||||
return {k:tuple(sorted(v, key=sort_key)) for k, v in ans.iteritems()}
|
||||
|
||||
@write_api
|
||||
def embed_metadata(self, book_ids, only_fmts=None):
|
||||
''' Update metadata in all formats of the specified book_ids to current metadata in the database. '''
|
||||
field = self.fields['formats']
|
||||
from calibre.ebooks.metadata.opf2 import pretty_print
|
||||
from calibre.customize.ui import apply_null_metadata
|
||||
from calibre.ebooks.metadata.meta import set_metadata
|
||||
if only_fmts:
|
||||
only_fmts = {f.lower() for f in only_fmts}
|
||||
|
||||
def doit(fmt, mi, stream):
|
||||
with apply_null_metadata, pretty_print:
|
||||
set_metadata(stream, mi, stream_type=fmt)
|
||||
stream.seek(0, os.SEEK_END)
|
||||
return stream.tell()
|
||||
|
||||
for book_id in book_ids:
|
||||
fmts = field.table.book_col_map.get(book_id, ())
|
||||
if not fmts:
|
||||
continue
|
||||
mi = self.get_metadata(book_id, get_cover=True, cover_as_data=True)
|
||||
try:
|
||||
path = self._field_for('path', book_id).replace('/', os.sep)
|
||||
except:
|
||||
continue
|
||||
for fmt in fmts:
|
||||
if only_fmts is not None and fmt.lower() not in only_fmts:
|
||||
continue
|
||||
try:
|
||||
name = self.fields['formats'].format_fname(book_id, fmt)
|
||||
except:
|
||||
continue
|
||||
if name and path:
|
||||
new_size = self.backend.apply_to_format(book_id, path, name, fmt, partial(doit, fmt, mi))
|
||||
if new_size is not None:
|
||||
self.format_metadata_cache[book_id].get(fmt, {})['size'] = new_size
|
||||
max_size = self.fields['formats'].table.update_fmt(book_id, fmt, name, new_size, self.backend)
|
||||
self.fields['size'].table.update_sizes({book_id: max_size})
|
||||
|
||||
# }}}
|
||||
|
||||
|
@ -131,16 +131,11 @@ class TweakEpubAction(InterfaceAction):
|
||||
'The %s format is missing from the calibre library. You should run'
|
||||
' library maintenance.') % fmt, show=True)
|
||||
tweak = 'ebook-edit'
|
||||
try:
|
||||
self.gui.setCursor(Qt.BusyCursor)
|
||||
if tprefs['update_metadata_from_calibre']:
|
||||
from calibre.ebooks.metadata.opf2 import pretty_print
|
||||
from calibre.ebooks.metadata.meta import set_metadata
|
||||
from calibre.customize.ui import apply_null_metadata
|
||||
mi = db.new_api.get_metadata(book_id, get_cover=True)
|
||||
with pretty_print, apply_null_metadata, open(path, 'r+b') as f:
|
||||
set_metadata(f, mi, stream_type=fmt.lower())
|
||||
db.new_api.embed_metadata((book_id,), only_fmts={fmt})
|
||||
notify = '%d:%s:%s:%s' % (book_id, fmt, db.library_id, db.library_path)
|
||||
try:
|
||||
self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(path=path, notify=notify))
|
||||
time.sleep(2)
|
||||
finally:
|
||||
|
Loading…
x
Reference in New Issue
Block a user