Kobo driver: Automatically convert EPUB to KEPUB when sending to device. Can be turned off via an option in the device configuration

This commit is contained in:
Kovid Goyal 2025-02-22 15:45:19 +05:30
parent c2d52efbcd
commit c40f271c4b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 42 additions and 8 deletions

View File

@ -2272,15 +2272,27 @@ 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)
if self.modifying_epub(): modify_epub = self.modifying_epub() or self.get_pref('kepubify')
self.extra_sheet = self.get_extra_css() def should_modify(name: str) -> bool:
ext = name.rpartition('.')[-1].lower()
return ext == 'epub' and modify_epub
self.extra_sheet = self.get_extra_css()
modifiable = {x for x in names if should_modify(x)}
if modifiable:
names, files = list(names), list(files)
i = 0 i = 0
for file, n, mi in zip(files, names, metadata): for idx, (file, n, mi) in enumerate(zip(files, names, metadata)):
if n not in modifiable:
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(files)), '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 mi.kte_calibre_name = n
self._modify_epub(file, mi) if self.get_pref('kepubify'):
names[idx] = n = self._kepubify(file, n, mi, self.extra_sheet)
else:
self._modify_epub(file, mi)
i += 1 i += 1
self.report_progress(0, 'Working...') self.report_progress(0, 'Working...')
@ -2317,6 +2329,18 @@ class KOBOTOUCH(KOBO):
return result return result
def _kepubify(self, path, name, mi, extra_css) -> None:
from calibre.ebooks.oeb.polish.errors import DRMError
from calibre.ebooks.oeb.polish.kepubify import kepubify_path
debug_print(f'Converting {name} to kepub')
try:
kepubify_path(path, outpath=path, allow_overwrite=True)
except DRMError:
debug_print(f'Not converting {name} to KEPUB as it is DRMed')
else:
debug_print(f'Conversion of {name} to KEPUB succeeded')
return name.rpartition('.')[0] + '.kepub'
def _modify_epub(self, book_file, metadata, container=None): def _modify_epub(self, book_file, metadata, container=None):
debug_print(f'KoboTouch:_modify_epub:Processing {metadata.author_sort} - {metadata.title}') debug_print(f'KoboTouch:_modify_epub:Processing {metadata.author_sort} - {metadata.title}')
@ -3606,6 +3630,7 @@ class KOBOTOUCH(KOBO):
c.add_opt('bookstats_timetoread_upper_template', default=None) c.add_opt('bookstats_timetoread_upper_template', default=None)
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('modify_css', default=False) c.add_opt('modify_css', default=False)
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.

View File

@ -201,10 +201,18 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
self.options_layout.setObjectName('options_layout') self.options_layout.setObjectName('options_layout')
self.setLayout(self.options_layout) self.setLayout(self.options_layout)
self.kepubify_checkbox = create_checkbox(
_('Use Kobo viewer for EPUB books'), _(
'Kobo devices have two viewer programs for EPUB files on their devices. An older one from Adobe and'
' the Kobo one. The Kobo one has much better performance and features and so, by default,'
' calibre will auto-convert EPUB books to the Kobo KEPUB format so that they are viewed by'
' the Kobo viewer. If you would rather use the legacy viewer for EPUB, disable this option.'
), device.get_pref('kepubify'))
self.modify_css_checkbox = create_checkbox( self.modify_css_checkbox = create_checkbox(
_('Modify CSS'), _('Modify CSS'),
_('This allows addition of user CSS rules and removal of some CSS. ' _('This allows addition of user CSS rules and removal of some CSS. '
'When sending a book, the driver adds the contents of {0} to all stylesheets in the EPUB. ' 'When sending a book, the driver adds the contents of {0} to all stylesheets in the book. '
'This file is searched for in the root folder of the main memory of the device. ' 'This file is searched for in the root folder of the main memory of the device. '
'As well as this, if the file contains settings for the "orphans" or "widows", ' 'As well as this, if the file contains settings for the "orphans" or "widows", '
'these are removed for all styles in the original stylesheet.').format(device.KOBO_EXTRA_CSSFILE), 'these are removed for all styles in the original stylesheet.').format(device.KOBO_EXTRA_CSSFILE),
@ -221,8 +229,9 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
device.get_pref('override_kobo_replace_existing') device.get_pref('override_kobo_replace_existing')
) )
self.options_layout.addWidget(self.modify_css_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.modify_css_checkbox, 1, 0, 1, 2)
self.options_layout.addWidget(self.override_kobo_replace_existing_checkbox, 2, 0, 1, 2)
@property @property
def modify_css(self): def modify_css(self):