From 2f6cd98741ff97b34513397f909c5b33976c9eeb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 19 Apr 2023 17:39:47 +0530 Subject: [PATCH] calibredb add_format: Add support for adding extra data files --- src/calibre/db/backend.py | 5 ++++- src/calibre/db/cache.py | 6 ++++-- src/calibre/db/cli/cmd_add_format.py | 24 +++++++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 535027cc8f..59c9b22294 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -1936,8 +1936,10 @@ class DB: with src: yield relpath, src, mtime - def add_extra_file(self, relpath, stream, book_path): + def add_extra_file(self, relpath, stream, book_path, replace=True): dest = os.path.abspath(os.path.join(self.library_path, book_path, relpath)) + if not replace and os.path.exists(dest): + return False if isinstance(stream, str): try: shutil.copy2(stream, dest) @@ -1952,6 +1954,7 @@ class DB: d = open(dest, 'wb') with d: shutil.copyfileobj(stream, d) + return True def write_backup(self, path, raw): path = os.path.abspath(os.path.join(self.library_path, path, METADATA_FILE_NAME)) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 6081fcd5ca..3bc6eaa47d 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -3050,11 +3050,13 @@ class Cache: self.backend.reindex_annotations() @write_api - def add_extra_files(self, book_id, map_of_relpath_to_stream_or_path): + def add_extra_files(self, book_id, map_of_relpath_to_stream_or_path, replace=True): ' Add extra data files ' path = self._field_for('path', book_id).replace('/', os.sep) + added = {} for relpath, stream_or_path in map_of_relpath_to_stream_or_path.items(): - self.backend.add_extra_file(relpath, stream_or_path, path) + added[relpath] = self.backend.add_extra_file(relpath, stream_or_path, path, replace) + return added @read_api def list_extra_files_matching(self, book_id, pattern=''): diff --git a/src/calibre/db/cli/cmd_add_format.py b/src/calibre/db/cli/cmd_add_format.py index f180846a0a..ccc1456734 100644 --- a/src/calibre/db/cli/cmd_add_format.py +++ b/src/calibre/db/cli/cmd_add_format.py @@ -15,8 +15,14 @@ def implementation(db, notify_changes, book_id, data, fmt, replace): is_remote = notify_changes is not None if is_remote: data = BytesIO(data[1]) - added = db.add_format(book_id, fmt, data, replace=replace) - if is_remote and added: + relpath = '' + if fmt.startswith('.EXTRA_DATA_FILE:'): + relpath = fmt[len('.EXTRA_DATA_FILE:'):] + if relpath: + added = db.add_extra_files(book_id, {relpath: data}, replace=replace)[relpath] + else: + added = db.add_format(book_id, fmt, data, replace=replace) + if is_remote and added and not relpath: notify_changes(formats_added({book_id: (fmt,)})) return added @@ -40,6 +46,13 @@ it is replaced, unless the do not replace option is specified.\ action='store_false', help=_('Do not replace the format if it already exists') ) + parser.add_option( + '--as-extra-data-file', + default=False, + action='store_true', + help=_('Add the file as an extra data file to the book, not an ebook format') + ) + return parser @@ -48,9 +61,14 @@ def main(opts, args, dbctx): raise SystemExit(_('You must specify an id and an e-book file')) id, path, fmt = int(args[0]), args[1], os.path.splitext(args[1])[-1] + if opts.as_extra_data_file: + fmt = '.EXTRA_DATA_FILE:' + 'data/' + os.path.basename(args[1]) + else: + fmt = fmt[1:].upper() if not fmt: raise SystemExit(_('e-book file must have an extension')) - fmt = fmt[1:].upper() if not dbctx.run('add_format', id, dbctx.path(path), fmt, opts.replace): + if opts.as_extra_data_file: + raise SystemExit(f'An extra data file with the filename {os.path.basename(args[1])} already exists') raise SystemExit(_('A %(fmt)s file already exists for book: %(id)d, not replacing')%dict(fmt=fmt, id=id)) return 0