diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 3bc6eaa47d..5e64164b8b 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -1515,6 +1515,15 @@ class Cache: return random.choice(tuple(self.dirtied_cache)) return None + def _metadata_as_object_for_dump(self, book_id): + mi = self._get_metadata(book_id) + # Always set cover to cover.jpg. Even if cover doesn't exist, + # no harm done. This way no need to call dirtied when + # cover is set/removed + mi.cover = 'cover.jpg' + mi.all_annotations = self._all_annotations_for_book(book_id) + return mi + @read_api def get_metadata_for_dump(self, book_id): mi = None @@ -1527,12 +1536,7 @@ class Cache: # While a book is being created, the path is empty. Don't bother to # try to write the opf, because it will go to the wrong folder. if self._field_for('path', book_id): - mi = self._get_metadata(book_id) - # Always set cover to cover.jpg. Even if cover doesn't exist, - # no harm done. This way no need to call dirtied when - # cover is set/removed - mi.cover = 'cover.jpg' - mi.all_annotations = self._all_annotations_for_book(book_id) + mi = self._metadata_as_object_for_dump(book_id) except: # This almost certainly means that the book has been deleted while # the backup operation sat in the queue. @@ -2052,9 +2056,15 @@ class Cache: except Exception: path = None path_map[book_id] = path - # ensure metadata.opf is written so we can restore the book - if not permanent: - self._dump_metadata(book_ids=tuple(bid for bid, path in path_map.items() if path)) + if not permanent and path: + # ensure metadata.opf is written and up-to-date so we can restore the book + try: + mi = self._metadata_as_object_for_dump(book_id) + raw = metadata_to_opf(mi) + self.backend.write_backup(path, raw) + except Exception: + import traceback + traceback.print_exc() self.backend.remove_books(path_map, permanent=permanent) for field in itervalues(self.fields): try: diff --git a/src/calibre/db/tests/add_remove.py b/src/calibre/db/tests/add_remove.py index 8e08f58146..2afbb97a5b 100644 --- a/src/calibre/db/tests/add_remove.py +++ b/src/calibre/db/tests/add_remove.py @@ -7,10 +7,12 @@ __docformat__ = 'restructuredtext en' import glob import os +from contextlib import suppress from datetime import timedelta from io import BytesIO from tempfile import NamedTemporaryFile +from calibre.db.backend import METADATA_FILE_NAME from calibre.db.tests.base import IMG, BaseTest from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.date import UNDEFINED_DATE, now, utcnow @@ -298,6 +300,8 @@ class AddRemoveTest(BaseTest): fm_before = cache.format_metadata(1, 'FMT1', allow_cache=False), cache.format_metadata(1, 'FMT2', allow_cache=False) os.mkdir(os.path.join(bookpath, 'xyz')) open(os.path.join(bookpath, 'xyz', 'abc'), 'w').close() + with suppress(FileNotFoundError): + os.remove(os.path.join(bookpath, METADATA_FILE_NAME)) cache.remove_books((1,)) cache.move_book_from_trash(1) b, f = cache.list_trash_entries()