mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Ensure metadata.opf is always written when deleting book even if it is not sequenced for backup. Fixes #2017217 [Trash Bin not working](https://bugs.launchpad.net/calibre/+bug/2017217)
This commit is contained in:
parent
46406ca9a7
commit
f7fb20e431
@ -1515,6 +1515,15 @@ class Cache:
|
|||||||
return random.choice(tuple(self.dirtied_cache))
|
return random.choice(tuple(self.dirtied_cache))
|
||||||
return None
|
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
|
@read_api
|
||||||
def get_metadata_for_dump(self, book_id):
|
def get_metadata_for_dump(self, book_id):
|
||||||
mi = None
|
mi = None
|
||||||
@ -1527,12 +1536,7 @@ class Cache:
|
|||||||
# While a book is being created, the path is empty. Don't bother to
|
# 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.
|
# try to write the opf, because it will go to the wrong folder.
|
||||||
if self._field_for('path', book_id):
|
if self._field_for('path', book_id):
|
||||||
mi = self._get_metadata(book_id)
|
mi = self._metadata_as_object_for_dump(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)
|
|
||||||
except:
|
except:
|
||||||
# This almost certainly means that the book has been deleted while
|
# This almost certainly means that the book has been deleted while
|
||||||
# the backup operation sat in the queue.
|
# the backup operation sat in the queue.
|
||||||
@ -2052,9 +2056,15 @@ class Cache:
|
|||||||
except Exception:
|
except Exception:
|
||||||
path = None
|
path = None
|
||||||
path_map[book_id] = path
|
path_map[book_id] = path
|
||||||
# ensure metadata.opf is written so we can restore the book
|
if not permanent and path:
|
||||||
if not permanent:
|
# ensure metadata.opf is written and up-to-date so we can restore the book
|
||||||
self._dump_metadata(book_ids=tuple(bid for bid, path in path_map.items() if path))
|
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)
|
self.backend.remove_books(path_map, permanent=permanent)
|
||||||
for field in itervalues(self.fields):
|
for field in itervalues(self.fields):
|
||||||
try:
|
try:
|
||||||
|
@ -7,10 +7,12 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
|
from contextlib import suppress
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
|
from calibre.db.backend import METADATA_FILE_NAME
|
||||||
from calibre.db.tests.base import IMG, BaseTest
|
from calibre.db.tests.base import IMG, BaseTest
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.utils.date import UNDEFINED_DATE, now, utcnow
|
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)
|
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'))
|
os.mkdir(os.path.join(bookpath, 'xyz'))
|
||||||
open(os.path.join(bookpath, 'xyz', 'abc'), 'w').close()
|
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.remove_books((1,))
|
||||||
cache.move_book_from_trash(1)
|
cache.move_book_from_trash(1)
|
||||||
b, f = cache.list_trash_entries()
|
b, f = cache.list_trash_entries()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user