mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Preserve notes resource mtimes when importing notes db
This commit is contained in:
parent
53f20a2ce6
commit
1e9a543e54
@ -989,8 +989,8 @@ class DB:
|
||||
id_val = self.tables[field].id_map[item_id]
|
||||
return self.notes.unretire(self.conn, field, item_id, id_val)
|
||||
|
||||
def add_notes_resource(self, path_or_stream, name) -> int:
|
||||
return self.notes.add_resource(self.conn, path_or_stream, name)
|
||||
def add_notes_resource(self, path_or_stream, name, mtime=None) -> int:
|
||||
return self.notes.add_resource(self.conn, path_or_stream, name, mtime=mtime)
|
||||
|
||||
def get_notes_resource(self, resource_hash) -> Optional[dict]:
|
||||
return self.notes.get_resource_data(self.conn, resource_hash)
|
||||
|
@ -20,7 +20,7 @@ from functools import partial, wraps
|
||||
from io import DEFAULT_BUFFER_SIZE, BytesIO
|
||||
from queue import Queue
|
||||
from threading import Lock
|
||||
from time import monotonic, sleep, time
|
||||
from time import mktime, monotonic, sleep, time
|
||||
from typing import NamedTuple, Optional, Tuple
|
||||
|
||||
from calibre import as_unicode, detect_ncpus, isbytestring
|
||||
@ -724,9 +724,9 @@ class Cache:
|
||||
return self.backend.set_notes_for(field, item_id, doc, searchable_text, resource_hashes, remove_unused_resources)
|
||||
|
||||
@write_api
|
||||
def add_notes_resource(self, path_or_stream_or_data, name: str) -> int:
|
||||
def add_notes_resource(self, path_or_stream_or_data, name: str, mtime: float = None) -> int:
|
||||
' Add the specified resource so it can be referenced by notes and return its content hash '
|
||||
return self.backend.add_notes_resource(path_or_stream_or_data, name)
|
||||
return self.backend.add_notes_resource(path_or_stream_or_data, name, mtime)
|
||||
|
||||
@read_api
|
||||
def get_notes_resource(self, resource_hash) -> Optional[dict]:
|
||||
@ -3460,7 +3460,10 @@ def import_library(library_key, importer, library_path, progress=None, abort=Non
|
||||
with closing(importer.start_file(metadata['notes.db'], 'notes.db for ' + library_path)) as stream:
|
||||
stream.check_hash = False
|
||||
with zipfile.ZipFile(stream) as zf:
|
||||
zf.extractall(notes_dir)
|
||||
for zi in zf.infolist():
|
||||
tpath = zf._extract_member(zi, notes_dir, None)
|
||||
date_time = mktime(zi.date_time + (0, 0, -1))
|
||||
os.utime(tpath, (date_time, date_time))
|
||||
if abort is not None and abort.is_set():
|
||||
return
|
||||
cache = Cache(DB(library_path, load_user_formatter_functions=False))
|
||||
|
@ -306,7 +306,7 @@ class Notes:
|
||||
for path in items[:extra]:
|
||||
remove_with_retry(path, is_dir=True)
|
||||
|
||||
def add_resource(self, conn, path_or_stream_or_data, name, update_name=True):
|
||||
def add_resource(self, conn, path_or_stream_or_data, name, update_name=True, mtime=None):
|
||||
if isinstance(path_or_stream_or_data, bytes):
|
||||
data = path_or_stream_or_data
|
||||
elif isinstance(path_or_stream_or_data, str):
|
||||
@ -332,6 +332,9 @@ class Notes:
|
||||
f = open(path, 'wb')
|
||||
with f:
|
||||
f.write(data)
|
||||
if mtime is not None:
|
||||
os.utime(f.name, (mtime, mtime))
|
||||
|
||||
name = sanitize_file_name(name)
|
||||
base_name, ext = os.path.splitext(name)
|
||||
c = 0
|
||||
|
@ -264,8 +264,8 @@ class FilesystemTest(BaseTest):
|
||||
bookdir = os.path.dirname(ic.format_abspath(1, '__COVER_INTERNAL__'))
|
||||
self.assertEqual('exf', open(os.path.join(bookdir, 'exf')).read())
|
||||
self.assertEqual('recurse', open(os.path.join(bookdir, 'sub', 'recurse')).read())
|
||||
r1 = cache.add_notes_resource(b'res1', 'res.jpg')
|
||||
r2 = cache.add_notes_resource(b'res2', 'res.jpg')
|
||||
r1 = cache.add_notes_resource(b'res1', 'res.jpg', mtime=time.time()-113)
|
||||
r2 = cache.add_notes_resource(b'res2', 'res.jpg', mtime=time.time()-1115)
|
||||
cache.set_notes_for('authors', 2, 'some notes', resource_hashes=(r1, r2))
|
||||
cache.add_format(1, 'TXT', BytesIO(b'testing exim'))
|
||||
cache.fts_indexing_sleep_time = 0.001
|
||||
@ -285,7 +285,10 @@ class FilesystemTest(BaseTest):
|
||||
ic = import_library('l', importer, idir)
|
||||
self.assertEqual(ic.fts_search('exim')[0]['id'], 1)
|
||||
self.assertEqual(cache.notes_for('authors', 2), ic.notes_for('authors', 2))
|
||||
self.assertEqual(cache.get_notes_resource(r1), ic.get_notes_resource(r1))
|
||||
a, b = cache.get_notes_resource(r1), ic.get_notes_resource(r1)
|
||||
at, bt, = a.pop('mtime'), b.pop('mtime')
|
||||
self.assertEqual(a, b)
|
||||
self.assertLess(abs(at-bt), 2)
|
||||
|
||||
def test_find_books_in_directory(self):
|
||||
from calibre.db.adding import find_books_in_directory, compile_rule
|
||||
|
@ -151,6 +151,10 @@ def test_cache_api(self: 'NotesTest'):
|
||||
self.assertGreater(note_id, 0)
|
||||
self.assertIn('<p>test simple exim <img', cache.notes_for('authors', author_id))
|
||||
res2 = tuple(cache.get_notes_resource(x) for x in cache.notes_resources_used_by('authors', author_id))
|
||||
for x in res:
|
||||
del x['mtime']
|
||||
for x in res2:
|
||||
del x['mtime']
|
||||
self.ae(sorted(res, key=itemgetter('name')), sorted(res2, key=itemgetter('name')))
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user