diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 509f2a19a4..9a0713b09f 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -2272,15 +2272,27 @@ class KOBOTOUCH(KOBO): debug_print(f'KoboTouch:upload_books - {len(files)} books') debug_print('KoboTouch:upload_books - files=', files) - if self.modifying_epub(): - self.extra_sheet = self.get_extra_css() + modify_epub = self.modifying_epub() or self.get_pref('kepubify') + 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 - 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(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 - 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 self.report_progress(0, 'Working...') @@ -2317,6 +2329,18 @@ class KOBOTOUCH(KOBO): 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): 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_lower_template', default=None) + c.add_opt('kepubify', default=True) 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. diff --git a/src/calibre/devices/kobo/kobotouch_config.py b/src/calibre/devices/kobo/kobotouch_config.py index f32773c6f5..ad9d906ee0 100644 --- a/src/calibre/devices/kobo/kobotouch_config.py +++ b/src/calibre/devices/kobo/kobotouch_config.py @@ -201,10 +201,18 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox): self.options_layout.setObjectName('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( _('Modify 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. ' '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), @@ -221,8 +229,9 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox): device.get_pref('override_kobo_replace_existing') ) - self.options_layout.addWidget(self.modify_css_checkbox, 0, 0, 1, 2) - self.options_layout.addWidget(self.override_kobo_replace_existing_checkbox, 1, 0, 1, 2) + self.options_layout.addWidget(self.kepubify_checkbox, 0, 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 def modify_css(self):