copy_to_library now preserves extra files in book folders

This commit is contained in:
Kovid Goyal 2023-04-17 12:11:03 +05:30
parent a041737b20
commit ce4238e8a1
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 43 additions and 17 deletions

View File

@ -1889,7 +1889,7 @@ class DB:
os.makedirs(tpath)
update_paths_in_db()
def iter_extra_files(self, book_id, book_path, formats_field):
def iter_extra_files(self, book_id, book_path, formats_field, yield_paths=False):
known_files = {COVER_FILE_NAME, METADATA_FILE_NAME}
for fmt in formats_field.for_book(book_id, default_value=()):
fname = formats_field.format_fname(book_id, fmt)
@ -1904,24 +1904,35 @@ class DB:
relpath = os.path.relpath(path, full_book_path)
relpath = relpath.replace(os.sep, '/')
if relpath not in known_files:
try:
src = open(path, 'rb')
except OSError:
if iswindows:
time.sleep(1)
src = open(path, 'rb')
with src:
yield relpath, src, os.path.getmtime(path)
mtime = os.path.getmtime(path)
if yield_paths:
yield relpath, path, mtime
else:
try:
src = open(path, 'rb')
except OSError:
if iswindows:
time.sleep(1)
src = open(path, 'rb')
with src:
yield relpath, src, mtime
def add_extra_file(self, relpath, stream, book_path):
dest = os.path.abspath(os.path.join(self.library_path, book_path, relpath))
try:
d = open(dest, 'wb')
except OSError:
os.makedirs(os.path.dirname(dest), exist_ok=True)
d = open(dest, 'wb')
with d:
shutil.copyfileobj(stream, d)
if isinstance(stream, str):
try:
shutil.copy2(stream, dest)
except FileNotFoundError:
os.makedirs(os.path.dirname(dest), exist_ok=True)
shutil.copy2(stream, dest)
else:
try:
d = open(dest, 'wb')
except FileNotFoundError:
os.makedirs(os.path.dirname(dest), exist_ok=True)
d = open(dest, 'wb')
with d:
shutil.copyfileobj(stream, d)
def write_backup(self, path, raw):
path = os.path.abspath(os.path.join(self.library_path, path, METADATA_FILE_NAME))

View File

@ -102,6 +102,12 @@ def copy_one_book(
new_book_id = newdb.add_books(
[(mi, format_map)], add_duplicates=True, apply_import_tags=tweaks['add_new_book_tags_when_importing_books'],
preserve_uuid=preserve_uuid, run_hooks=False)[0][0]
bp = db.field_for('path', book_id)
if bp:
for (relpath, src_path, mtime) in db.backend.iter_extra_files(book_id, bp, db.fields['formats'], yield_paths=True):
nbp = newdb.field_for('path', book_id)
if nbp:
newdb.backend.add_extra_file(relpath, src_path, nbp)
postprocess_copy(book_id, new_book_id, new_authors, db, newdb, identical_books_data, duplicate_action)
return_data['new_book_id'] = new_book_id
return return_data

View File

@ -377,6 +377,12 @@ class AddRemoveTest(BaseTest):
a(type='highlight', highlighted_text='text2', uuid='2', seq=3, notes='notes2 some word changed again'),
]
src_db.set_annotations_for_book(1, 'FMT1', annot_list)
bookdir = os.path.dirname(src_db.format_abspath(1, '__COVER_INTERNAL__'))
with open(os.path.join(bookdir, 'exf'), 'w') as f:
f.write('exf')
os.mkdir(os.path.join(bookdir, 'sub'))
with open(os.path.join(bookdir, 'sub', 'recurse'), 'w') as f:
f.write('recurse')
def make_rdata(book_id=1, new_book_id=None, action='add'):
return {
@ -416,5 +422,8 @@ class AddRemoveTest(BaseTest):
for new_book_id in (1, 4, 5):
self.assertEqual(dest_db.format(new_book_id, 'FMT1'), b'replaced')
self.assertEqual(dest_db.format(rdata['new_book_id'], 'FMT1'), b'second-round')
bookdir = os.path.dirname(dest_db.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())
# }}}

View File

@ -459,7 +459,7 @@ class CreateCustomColumn(QDialog):
l = QHBoxLayout()
self.composite_in_comments_box = cmc = QCheckBox(_("Show with comments in Book details"))
cmc.setToolTip('<p>' + _('If you check this box then the column contents '
'will show in the Comments section in Book details. '
'will show in the Comments section in the Book details. '
'You can indicate whether not to have a header or '
'to put a header above the column. If you want a '
"header beside the data, don't check this box. "