mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
copy_to_library now preserves extra files in book folders
This commit is contained in:
parent
a041737b20
commit
ce4238e8a1
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
||||
# }}}
|
||||
|
@ -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. "
|
||||
|
Loading…
x
Reference in New Issue
Block a user