mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge branch 'master' of https://github.com/j-howell/calibre
This commit is contained in:
commit
732f09cd2b
@ -114,8 +114,9 @@ class MTP_DEVICE(BASE):
|
|||||||
'pictures', 'ringtones', 'samsung', 'sony', 'htc', 'bluetooth', 'fonts',
|
'pictures', 'ringtones', 'samsung', 'sony', 'htc', 'bluetooth', 'fonts',
|
||||||
'games', 'lost.dir', 'video', 'whatsapp', 'image', 'com.zinio.mobile.android.reader'}:
|
'games', 'lost.dir', 'video', 'whatsapp', 'image', 'com.zinio.mobile.android.reader'}:
|
||||||
return True
|
return True
|
||||||
if lpath[0].startswith('.') and lpath[0] != '.tolino':
|
if lpath[0].startswith('.') and lpath[0] != '.tolino' and lpath[0] != '.notebooks':
|
||||||
# apparently the Tolino for some reason uses a hidden folder for its library, sigh.
|
# apparently the Tolino for some reason uses a hidden folder for its library, sigh.
|
||||||
|
# Kindle Scribe stores user notebooks in subfolders of '.notebooks'
|
||||||
return True
|
return True
|
||||||
if lpath[0] == 'system' and not self.is_kindle:
|
if lpath[0] == 'system' and not self.is_kindle:
|
||||||
# on Kindles we need the system/thumbnails folder for the amazon cover bug workaround
|
# on Kindles we need the system/thumbnails folder for the amazon cover bug workaround
|
||||||
@ -349,6 +350,21 @@ class MTP_DEVICE(BASE):
|
|||||||
from calibre.customize.ui import quick_metadata
|
from calibre.customize.ui import quick_metadata
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
ext = mtp_file.name.rpartition('.')[-1].lower()
|
ext = mtp_file.name.rpartition('.')[-1].lower()
|
||||||
|
if self.is_kindle and ext == 'kfx' and mtp_file.name != 'metadata.kfx':
|
||||||
|
# locate the actual file containing KFX book metadata
|
||||||
|
stream = BytesIO()
|
||||||
|
try:
|
||||||
|
self.get_file_by_name(stream, mtp_file.parent, *(mtp_file.name[:-4] + '.sdr', 'assets', 'metadata.kfx'))
|
||||||
|
except Exception:
|
||||||
|
pass # expect failure for sideloaded books and personal documents
|
||||||
|
else:
|
||||||
|
stream.name = 'metadata.kfx'
|
||||||
|
with quick_metadata:
|
||||||
|
metadata = get_metadata(stream, stream_type=ext,
|
||||||
|
force_read_metadata=True,
|
||||||
|
pattern=self.build_template_regexp())
|
||||||
|
if metadata.title != 'metadata' and metadata.title != 'Unknown':
|
||||||
|
return metadata
|
||||||
stream = self.get_mtp_file(mtp_file)
|
stream = self.get_mtp_file(mtp_file)
|
||||||
with quick_metadata:
|
with quick_metadata:
|
||||||
return get_metadata(stream, stream_type=ext,
|
return get_metadata(stream, stream_type=ext,
|
||||||
@ -417,7 +433,26 @@ class MTP_DEVICE(BASE):
|
|||||||
ans.append((path, e, traceback.format_exc()))
|
ans.append((path, e, traceback.format_exc()))
|
||||||
else:
|
else:
|
||||||
ans.append(out.name)
|
ans.append(out.name)
|
||||||
|
if self.is_kindle and path.endswith('.kfx'):
|
||||||
|
# copy additional KFX files from the associated .sdr folder
|
||||||
|
try:
|
||||||
|
sdr_folder_name = f.name[:-4] + '.sdr'
|
||||||
|
new_sdr_path = os.path.join(os.path.split(out.name)[0], sdr_folder_name)
|
||||||
|
os.mkdir(new_sdr_path)
|
||||||
|
self.scan_sdr_for_kfx_files(f.parent, (sdr_folder_name, 'assets'), new_sdr_path)
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def scan_sdr_for_kfx_files(self, parent, folders, new_sdr_path):
|
||||||
|
for ff in self.list_folder_by_name(parent, *folders):
|
||||||
|
if ff.is_folder:
|
||||||
|
self.scan_sdr_for_kfx_files(parent, folders + (ff.name,), new_sdr_path)
|
||||||
|
elif ff.name.endswith('.kfx') or ff.name == 'voucher':
|
||||||
|
name = ''.join(shorten_components_to(245 - len(new_sdr_path), [ff.name])) if iswindows else ff.name
|
||||||
|
with open(os.path.join(new_sdr_path, name), 'wb') as out:
|
||||||
|
self.get_file_by_name(out, parent, *(folders + (ff.name,)))
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Sending files to the device {{{
|
# Sending files to the device {{{
|
||||||
|
@ -97,6 +97,13 @@ class FileOrFolder:
|
|||||||
self.is_ebook = (not self.is_folder and not self.is_storage and
|
self.is_ebook = (not self.is_folder and not self.is_storage and
|
||||||
self.name.rpartition('.')[-1].lower() in bexts and not self.name.startswith('._'))
|
self.name.rpartition('.')[-1].lower() in bexts and not self.name.startswith('._'))
|
||||||
|
|
||||||
|
# allow Kindle Scribe notebooks to be imported and preserve the notebook name
|
||||||
|
if self.name == 'nbk' and not (self.is_folder or self.is_storage):
|
||||||
|
if len(self.full_path) >= 3 and self.full_path[-3] == '.notebooks':
|
||||||
|
nbk_name = self.full_path[-2].replace('!!notebook', '').replace('!!', ' ')
|
||||||
|
self.name = f'Scribe {nbk_name} Notebook.kfx'
|
||||||
|
self.is_ebook = True
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.is_storage:
|
if self.is_storage:
|
||||||
name = 'Storage'
|
name = 'Storage'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user