From dc9da6b2e8e835cb0cc39e78f637572c441b9390 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 18 Apr 2023 22:31:58 +0530 Subject: [PATCH] Allow adding arbitrary files to a book record stored as auxiliary data by right clicking the add books button and choosing "Add data files" --- manual/gui.rst | 14 +++++++++++++- src/calibre/db/cache.py | 6 ++++++ src/calibre/gui2/actions/add.py | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/manual/gui.rst b/manual/gui.rst index 19b57869a1..0d6960e664 100644 --- a/manual/gui.rst +++ b/manual/gui.rst @@ -57,7 +57,9 @@ Add books 6. **Add files to selected book records**: Allows you to add or update the files associated with an existing book in your library. - 7. **Add an empty file to selected book records**: Allows you to add an empty file of the specified format to the selected book records. + 7. **Add data files to selected book records**: Allows you to add any number of extra files that will be stored in a :file:`data` sub-directory in the book directory + + 8. **Add an empty file to selected book records**: Allows you to add an empty file of the specified format to the selected book records. The :guilabel:`Add books` action can read metadata from a wide variety of e-book formats. In addition, it tries to guess metadata from the filename. See the :ref:`config_filename_metadata` section, to learn how to configure this. @@ -70,6 +72,16 @@ To add an additional format for an existing book you can do any of three things: 3. Click the :guilabel:`Add books` button in the top right area of the :guilabel:`Edit metadata` dialog, accessed by the :ref:`edit_meta_information` action. +.. note:: + The extra data files added to a book will be managed by calibre, as part of + the book. However, they cannot be viewed directly or used as conversion + sources. Nor are they indexed by the Full text search engine in calibre. To + view them select the book and press the :kbd:`O` key which will open up the + book folder in your file manager, from where the extra files can be viewed + using any program you like. They are most useful to store any ancilliary + data associated with a book such as supplementary reading material, digital + resources, etc. + .. _edit_meta_information: Edit metadata diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 51ed62aff4..f7776cd830 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -3049,6 +3049,12 @@ class Cache: def reindex_annotations(self): self.backend.reindex_annotations() + @write_api + def add_extra_files(self, book_id, map_of_relpath_to_stream_or_path): + path = self._field_for('path', book_id).replace('/', os.sep) + for relpath, stream_or_path in map_of_relpath_to_stream_or_path.items(): + self.backend.add_extra_file(relpath, stream_or_path, path) + def import_library(library_key, importer, library_path, progress=None, abort=None): from calibre.db.backend import DB diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py index fdc1e4ce07..f163785382 100644 --- a/src/calibre/gui2/actions/add.py +++ b/src/calibre/gui2/actions/add.py @@ -71,6 +71,8 @@ class AddAction(InterfaceAction): triggered=self.add_formats, shortcut='Shift+A') ma('add-formats-clipboard', _('Add files to selected book records from clipboard'), triggered=self.add_formats_from_clipboard, shortcut='Shift+Alt+A', icon='edit-paste.png') + ma('add-extra-files-to-books', _( + 'Add data files to selected book records')).triggered.connect(self.add_extra_files) ma('add-empty-format-to-books', _( 'Add an empty file to selected book records')).triggered.connect(self.add_empty_format_choose) self.add_menu.addSeparator() @@ -145,6 +147,18 @@ class AddAction(InterfaceAction): if books: self._add_formats(books, ids) + def add_extra_files(self): + ids = self._check_add_formats_ok() + if not ids: + return + books = choose_files_and_remember_all_files(self.gui, 'add extra data files dialog dir', + _('Select extra data files'), filters=get_filters()) + if books: + rmap = {'data/' + os.path.basename(x): x for x in books} + db = self.gui.current_db.new_api + for book_id in ids: + db.add_extra_files(book_id, rmap) + def _add_formats(self, paths, ids): if len(ids) > 1 and not question_dialog( self.gui,