mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #2100559 [KePubify: Restore 'template for kepubification'](https://bugs.launchpad.net/calibre/+bug/2100559)
This commit is contained in:
parent
882dc07eec
commit
1526cdb906
@ -2294,24 +2294,43 @@ class KOBOTOUCH(KOBO):
|
|||||||
debug_print(f'KoboTouch:upload_books - {len(files)} books')
|
debug_print(f'KoboTouch:upload_books - {len(files)} books')
|
||||||
debug_print('KoboTouch:upload_books - files=', files)
|
debug_print('KoboTouch:upload_books - files=', files)
|
||||||
|
|
||||||
modify_epub = self.modifying_epub() or self.get_pref('kepubify')
|
do_kepubify = self.get_pref('kepubify')
|
||||||
def should_modify(name: str) -> bool:
|
template = self.get_pref('template_for_kepubify')
|
||||||
ext = '.' + name.rpartition('.')[-1].lower()
|
modify_css = self.modifying_epub()
|
||||||
return ext == EPUB_EXT and modify_epub
|
entries = tuple(zip(files, names, metadata))
|
||||||
|
kepubifiable = set()
|
||||||
|
|
||||||
|
def should_modify(name: str, mi) -> bool:
|
||||||
|
mi.kte_calibre_name = name
|
||||||
|
if not name.lower().endswith(EPUB_EXT):
|
||||||
|
return False
|
||||||
|
if do_kepubify:
|
||||||
|
if not template:
|
||||||
|
kepubifiable.add(mi.uuid)
|
||||||
|
return True
|
||||||
|
from calibre.ebooks.metadata.book.formatter import SafeFormat
|
||||||
|
kepubify = SafeFormat().safe_format(template, mi, 'Open With template error', mi)
|
||||||
|
debug_print(f'kepubify_template_result for {mi.title}:', kepubify)
|
||||||
|
if kepubify is not None and kepubify.startswith('PLUGBOARD TEMPLATE ERROR'):
|
||||||
|
import sys
|
||||||
|
print(f'kepubify template: {template} returned error', file=sys.stderr)
|
||||||
|
kepubifiable.add(mi.uuid)
|
||||||
|
return True
|
||||||
|
return kepubify and kepubify != 'false'
|
||||||
|
return modify_css
|
||||||
|
|
||||||
self.extra_css, self.extra_sheet = self.get_extra_css()
|
self.extra_css, self.extra_sheet = self.get_extra_css()
|
||||||
modifiable = {x for x in names if should_modify(x)}
|
modifiable = {mi.uuid for _, name, mi in entries if should_modify(name, mi)}
|
||||||
self.files_to_rename_to_kepub = set()
|
self.files_to_rename_to_kepub = set()
|
||||||
if modifiable:
|
if modifiable:
|
||||||
i = 0
|
i = 0
|
||||||
for idx, (file, n, mi) in enumerate(zip(files, names, metadata)):
|
for idx, (file, n, mi) in enumerate(entries):
|
||||||
if n not in modifiable:
|
if mi.uuid not in modifiable:
|
||||||
continue
|
continue
|
||||||
debug_print('KoboTouch:upload_books: Processing book: {} by {}'.format(mi.title, ' and '.join(mi.authors)))
|
debug_print('KoboTouch:upload_books: Processing book: {} by {}'.format(mi.title, ' and '.join(mi.authors)))
|
||||||
debug_print(f'KoboTouch:upload_books: file={file}, name={n}')
|
debug_print(f'KoboTouch:upload_books: file={file}, name={n}')
|
||||||
self.report_progress(i / float(len(modifiable)), 'Processing book: {} by {}'.format(mi.title, ' and '.join(mi.authors)))
|
self.report_progress(i / float(len(modifiable)), 'Processing book: {} by {}'.format(mi.title, ' and '.join(mi.authors)))
|
||||||
mi.kte_calibre_name = n
|
if mi.uuid in kepubifiable:
|
||||||
if self.get_pref('kepubify'):
|
|
||||||
self._kepubify(file, n, mi)
|
self._kepubify(file, n, mi)
|
||||||
else:
|
else:
|
||||||
self._modify_epub(file, mi)
|
self._modify_epub(file, mi)
|
||||||
@ -3663,6 +3682,7 @@ class KOBOTOUCH(KOBO):
|
|||||||
c.add_opt('bookstats_timetoread_lower_template', default=None)
|
c.add_opt('bookstats_timetoread_lower_template', default=None)
|
||||||
|
|
||||||
c.add_opt('kepubify', default=True)
|
c.add_opt('kepubify', default=True)
|
||||||
|
c.add_opt('template_for_kepubify', default=None)
|
||||||
c.add_opt('modify_css', default=False)
|
c.add_opt('modify_css', default=False)
|
||||||
c.add_opt('per_device_css', default='{}')
|
c.add_opt('per_device_css', default='{}')
|
||||||
c.add_opt('override_kobo_replace_existing', default=True) # Overriding the replace behaviour is how the driver has always worked.
|
c.add_opt('override_kobo_replace_existing', default=True) # Overriding the replace behaviour is how the driver has always worked.
|
||||||
|
@ -155,6 +155,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
|
|||||||
p['modify_css'] = self.modify_css
|
p['modify_css'] = self.modify_css
|
||||||
p['per_device_css'] = self.per_device_css
|
p['per_device_css'] = self.per_device_css
|
||||||
p['kepubify'] = self.kepubify
|
p['kepubify'] = self.kepubify
|
||||||
|
p['template_for_kepubify'] = self.template_for_kepubify
|
||||||
p['override_kobo_replace_existing'] = self.override_kobo_replace_existing
|
p['override_kobo_replace_existing'] = self.override_kobo_replace_existing
|
||||||
|
|
||||||
p['support_newer_firmware'] = self.support_newer_firmware
|
p['support_newer_firmware'] = self.support_newer_firmware
|
||||||
@ -359,6 +360,20 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
|
|||||||
' the Kobo viewer. If you would rather use the legacy viewer for EPUB, disable this option.'
|
' the Kobo viewer. If you would rather use the legacy viewer for EPUB, disable this option.'
|
||||||
), device.get_pref('kepubify'))
|
), device.get_pref('kepubify'))
|
||||||
|
|
||||||
|
self.template_la = la = QLabel('\xa0\xa0' + _('Template to decide conversion:'))
|
||||||
|
self.kepubify_template_edit = TemplateConfig(
|
||||||
|
device.get_pref('template_for_kepubify'),
|
||||||
|
tooltip=_(
|
||||||
|
'Enter a template to decide if an EPUB book is to be auto converted to KEPUB. '
|
||||||
|
'If the template returns false or no result, the book will not be '
|
||||||
|
'converted to KEPUB. For example to only kepubify books that have the tag "as_kepub", use the template: {0}'
|
||||||
|
' or to only convert books that do not have the tag as_epub, use the template: {1}'
|
||||||
|
'\n\nIf no template is specified conversion to KEPUB is controlled only by the setting above to use the Kobo viewer. '
|
||||||
|
'Note that the setting above must be enabled for the template to be checked.'
|
||||||
|
).format(r'{tags:str_in_list(\,,as_kepub,true,false)}', r'{tags:str_in_list(\,,as_epub,false,true)}')
|
||||||
|
)
|
||||||
|
la.setBuddy(self.kepubify_template_edit)
|
||||||
|
|
||||||
self.override_kobo_replace_existing_checkbox = create_checkbox(
|
self.override_kobo_replace_existing_checkbox = create_checkbox(
|
||||||
_('Do not treat replacements as new books'),
|
_('Do not treat replacements as new books'),
|
||||||
_('When a new book is side-loaded, the Kobo firmware imports details of the book into the internal database. '
|
_('When a new book is side-loaded, the Kobo firmware imports details of the book into the internal database. '
|
||||||
@ -371,7 +386,14 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.options_layout.addWidget(self.kepubify_checkbox, 0, 0, 1, 2)
|
self.options_layout.addWidget(self.kepubify_checkbox, 0, 0, 1, 2)
|
||||||
self.options_layout.addWidget(self.override_kobo_replace_existing_checkbox, 1, 0, 1, 2)
|
self.options_layout.addWidget(self.template_la, 1, 0, 1, 1)
|
||||||
|
self.options_layout.addWidget(self.kepubify_template_edit, 1, 1, 1, 1)
|
||||||
|
self.options_layout.addWidget(self.override_kobo_replace_existing_checkbox, 2, 0, 1, 2)
|
||||||
|
self.update_template_state()
|
||||||
|
self.kepubify_checkbox.toggled.connect(self.update_template_state)
|
||||||
|
|
||||||
|
def update_template_state(self):
|
||||||
|
self.kepubify_template_edit.setEnabled(self.kepubify)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def override_kobo_replace_existing(self):
|
def override_kobo_replace_existing(self):
|
||||||
@ -381,6 +403,10 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
|
|||||||
def kepubify(self):
|
def kepubify(self):
|
||||||
return self.kepubify_checkbox.isChecked()
|
return self.kepubify_checkbox.isChecked()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template_for_kepubify(self):
|
||||||
|
return (self.kepubify_template_edit.template or '').strip()
|
||||||
|
|
||||||
|
|
||||||
class HyphenationGroupBox(DeviceOptionsGroupBox):
|
class HyphenationGroupBox(DeviceOptionsGroupBox):
|
||||||
|
|
||||||
|
@ -553,11 +553,12 @@ def unkepubify_path(path, outpath='', max_workers=0, allow_overwrite=False):
|
|||||||
|
|
||||||
def check_if_css_needs_modification(extra_css: str) -> tuple[bool, bool]:
|
def check_if_css_needs_modification(extra_css: str) -> tuple[bool, bool]:
|
||||||
remove_widows_and_orphans = remove_at_page_rules = False
|
remove_widows_and_orphans = remove_at_page_rules = False
|
||||||
|
sheet = None
|
||||||
if extra_css:
|
if extra_css:
|
||||||
try:
|
try:
|
||||||
sheet = css_parser().parseString(extra_css)
|
sheet = css_parser().parseString(extra_css)
|
||||||
except Exception:
|
except Exception:
|
||||||
sheet = None
|
pass
|
||||||
else:
|
else:
|
||||||
for rule in sheet.cssRules:
|
for rule in sheet.cssRules:
|
||||||
if rule.type == CSSRule.PAGE_RULE:
|
if rule.type == CSSRule.PAGE_RULE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user