Kobo: add an option to change the SeriesIndex_Text value using a template. The text value is what the Kobo displays for series_index. It sorts on the float value.

This commit is contained in:
Charles Haley 2025-06-16 12:02:57 +01:00
parent f3b203d905
commit ca0f1187a9
2 changed files with 60 additions and 1 deletions

View File

@ -3429,7 +3429,12 @@ class KOBOTOUCH(KOBO):
if newmi.series is not None:
new_series = newmi.series
try:
new_series_number = f'{newmi.series_index:g}'
if self.use_series_index_template:
from calibre.ebooks.metadata.book.formatter import SafeFormat
new_series_number = SafeFormat().safe_format(
self.series_index_template, newmi, 'Kobo series number template', newmi)
else:
new_series_number = f'{newmi.series_index:g}'
except:
new_series_number = None
else:
@ -3640,6 +3645,8 @@ class KOBOTOUCH(KOBO):
c.add_opt('collections_columns', default='')
c.add_opt('use_collections_template', default=False)
c.add_opt('collections_template', default='')
c.add_opt('use_series_index_template', default=False)
c.add_opt('series_index_template', default='')
c.add_opt('create_collections', default=False)
c.add_opt('delete_empty_collections', default=False)
c.add_opt('ignore_collections_names', default='')
@ -3986,6 +3993,14 @@ class KOBOTOUCH(KOBO):
def collections_template(self):
return self.get_pref('collections_template') if self.use_collections_template else ''
@property
def use_series_index_template(self):
return self.get_pref('use_series_index_template')
@property
def series_index_template(self):
return self.get_pref('series_index_template') if self.use_series_index_template else ''
def get_collections_attributes(self):
collections_str = self.collections_columns
collections = [x.lower().strip() for x in collections_str.split(',')] if collections_str else []

View File

@ -127,6 +127,8 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
p['collections_columns'] = self.collections_columns
p['use_collections_template'] = self.use_collections_template
p['collections_template'] = self.collections_template
p['use_series_index_template'] = self.use_series_index_template
p['series_index_template'] = self.series_index_template
p['ignore_collections_names'] = self.ignore_collections_names
p['delete_empty_collections'] = self.delete_empty_collections
@ -889,6 +891,32 @@ class MetadataGroupBox(DeviceOptionsGroupBox):
'in a series to the same value.'),
device.get_pref('force_series_id')
)
self.use_series_index_template_checkbox = create_checkbox(
_('Series number template:'),
_('Use a template to generate what the Kobo displays for the series number.'),
device.get_pref('use_series_index_template')
)
self.series_index_template_edit = TemplateConfig(
self.use_series_index_template_checkbox.text(),
device.get_pref('series_index_template'),
tooltip='<p>' +
_('The Kobo can display a series number (book number) '
'when books are in a series. To do this, the Kobo uses '
'two values, the "series number" (a floating point value) '
'and the "series text" (a string). The series number is '
'used for sorting. The series text is what is displayed. '
'Normally the series text is the same as the series '
'number. This option lets you choose a different value '
'for the series text.</p><p>'
'A common use is to change the series text to the '
'empty string when the series number is zero. This General '
'Program Mode template does that: {0}'
'You can do more complicated things such as have an omnibus '
'display "5 to 9". How you do this depends on how you have set '
'up the series in calibre.').format(
'<pre style="white-space: nowrap;">program: if $series_index !=# 0 then $series_index else "" fi</pre>')
+ '</p>'
)
self.update_core_metadata_checkbox = create_checkbox(
_('Update metadata on Book Details pages'),
_('This will update the metadata in the device database when the device is connected. '
@ -967,6 +995,9 @@ class MetadataGroupBox(DeviceOptionsGroupBox):
hbl.addStretch(1)
self.options_layout.addLayout(hbl, line, 0, 1, 4)
line += 1
self.options_layout.addWidget(self.use_series_index_template_checkbox, line, 0, 1, 2)
self.options_layout.addWidget(self.series_index_template_edit, line, 2, 1, 2)
line += 1
self.options_layout.addWidget(self.update_core_metadata_checkbox, line, 0, 1, 4)
line += 1
self.options_layout.addWidget(self.update_subtitle_checkbox, line, 0, 1, 2)
@ -990,12 +1021,17 @@ class MetadataGroupBox(DeviceOptionsGroupBox):
self.update_core_metadata_checkbox_clicked(device.get_pref('update_core_metadata'))
self.update_subtitle_checkbox_clicked(device.get_pref('update_subtitle'))
self.update_bookstats_checkbox_clicked(device.get_pref('update_bookstats'))
self.use_series_index_template_checkbox.clicked.connect(self.use_series_index_template_checkbox_clicked)
self.use_series_index_template_checkbox_clicked(device.get_pref('use_series_index_template'))
def update_series_checkbox_clicked(self, checked):
self.force_series_id_checkbox.setEnabled(checked)
if not checked:
self.force_series_id_checkbox.setChecked(False)
def use_series_index_template_checkbox_clicked(self, checked):
self.series_index_template_edit.setEnabled(checked)
def update_core_metadata_checkbox_clicked(self, checked):
self.update_series_checkbox.setEnabled(not checked)
self.force_series_id_checkbox.setEnabled(self.update_series)
@ -1043,6 +1079,14 @@ class MetadataGroupBox(DeviceOptionsGroupBox):
def force_series_id(self):
return self.update_series and self.force_series_id_checkbox.isChecked()
@property
def use_series_index_template(self):
return self.use_series_index_template_checkbox.isChecked()
@property
def series_index_template(self):
return self.series_index_template_edit.template
@property
def update_core_metadata(self):
return self.update_core_metadata_checkbox.isChecked()