MTP driver: Use APNX config values from the Kindle plugin

This means APNX settings will be shared across all Kindle devices in one
place. They will apply the same to both USBMS and MTP based Kindles.
This commit is contained in:
Kovid Goyal 2025-07-17 13:53:51 +05:30
parent aa2aef48f8
commit 6d3af52614
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 53 additions and 36 deletions

View File

@ -13,6 +13,7 @@ import hashlib
import json
import os
import re
from typing import NamedTuple
from calibre import fsync, prints, strftime
from calibre.constants import DEBUG, filesystem_encoding
@ -366,6 +367,18 @@ class KINDLE(USBMS):
db.add_books([bm.value['path']], ['txt'], [mi])
class APNXOpts(NamedTuple):
send_apnx: bool = True
apnx_method: str = 'fast'
custom_col_name: str = ''
method_col_name: str = ''
overwrite: bool = True
def get_apnx_opts() -> APNXOpts:
return APNXOpts(*KINDLE2.settings().extra_customization)
class KINDLE2(KINDLE):
name = 'Kindle 2/3/4/Touch/PaperWhite/Voyage Device Interface'

View File

@ -86,13 +86,6 @@ class MTP_DEVICE(BASE):
p.defaults['history'] = {}
p.defaults['rules'] = []
p.defaults['ignored_folders'] = {}
p.defaults['apnx'] = {
'send': False,
'method': 'fast',
'custom_column_page_count': None,
'custom_column_method': None,
}
return self._prefs
@property
@ -551,10 +544,13 @@ class MTP_DEVICE(BASE):
try:
self.upload_cover(parent, relpath, storage, mi, stream)
# Upload the apnx file
if self.is_kindle and self.get_pref('apnx').get('send', False):
if self.is_kindle:
from calibre.devices.kindle.driver import get_apnx_opts
apnx_opts = get_apnx_opts()
if apnx_opts.send_apnx:
name = path[-1].rpartition('.')[0]
debug('Uploading APNX file for', name)
self.upload_apnx(parent, name, storage, mi, infile)
self.upload_apnx(parent, name, storage, mi, infile, apnx_opts)
except Exception:
import traceback
traceback.print_exc()
@ -643,7 +639,7 @@ class MTP_DEVICE(BASE):
debug(f'Restored {count} cover thumbnails that were destroyed by Amazon')
# }}}
def upload_apnx(self, parent, name, storage, mi, filepath):
def upload_apnx(self, parent, name, storage, mi, filepath, apnx_opts):
debug('upload_apnx() called')
from calibre.devices.kindle.apnx import APNXBuilder
from calibre.ptempfile import PersistentTemporaryFile
@ -653,18 +649,17 @@ class MTP_DEVICE(BASE):
apnx_local_file.close()
try:
pref = self.get_pref('apnx')
custom_page_count = 0
cust_col_name = pref.get('custom_column_page_count')
cust_col_name = apnx_opts.custom_col_name
if cust_col_name:
try:
custom_page_count = int(mi.get(cust_col_name, 0))
except Exception:
pass
method = pref.get('method', 'fast')
method = apnx_opts.apnx_method
cust_col_method = pref.get('custom_column_method')
cust_col_method = apnx_opts.method_col_name
if cust_col_method:
try:
method = str(mi.get(cust_col_method)).lower()

View File

@ -354,7 +354,10 @@ class FormatRules(QGroupBox):
class APNX(QWidget): # {{{
def __init__(self, apnx):
def __init__(self):
from calibre.devices.kindle.apnx import APNXBuilder
from calibre.devices.kindle.driver import KINDLE2, get_apnx_opts
apnx_opts = get_apnx_opts()
QWidget.__init__(self)
self.layout = l = QVBoxLayout()
self.setLayout(l)
@ -362,17 +365,19 @@ class APNX(QWidget): # {{{
self.layout.setAlignment(Qt.AlignTop)
self.send = f1 = QCheckBox(_('Send page number information when sending books'))
f1.setChecked(bool(apnx.get('send')))
f1.setChecked(bool(apnx_opts.send_apnx))
l.addWidget(f1)
f1.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX])
label2 = QLabel('<p>' + _('Page count calculation method') + '</p>')
label2.setWordWrap(True)
l.addWidget(label2)
self.method = f2 = QComboBox(self)
f2.addItem(_('fast'), 'fast')
f2.addItem(_('accurate'), 'accurate')
f2.addItem(_('page break'), 'pagebreak')
if (idx := f2.findData(apnx.get('method') or 'fast')) > -1:
label2.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_METHOD])
f2.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_METHOD])
for key in sorted(APNXBuilder.generators.keys()):
f2.addItem(key, key)
if (idx := f2.findData(apnx_opts.apnx_method)) > -1:
f2.setCurrentIndex(idx)
l.addWidget(f2)
@ -380,25 +385,30 @@ class APNX(QWidget): # {{{
label3.setWordWrap(True)
l.addWidget(label3)
self.column_page_count = f3 = QLineEdit(self)
f3.setText(apnx.get('custom_column_page_count') or '')
f3.setText(apnx_opts.custom_col_name)
label3.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_CUST_COL])
f3.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_CUST_COL])
l.addWidget(f3)
label4 = QLabel('<p>' + _('Custom column name to retrieve calculation method from') + '</p>')
label4.setWordWrap(True)
l.addWidget(label4)
self.column_method = f4 = QLineEdit(self)
f4.setText(apnx.get('custom_column_method') or '')
f4.setText(apnx_opts.method_col_name)
label4.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_METHOD_COL])
f4.setToolTip(KINDLE2.EXTRA_CUSTOMIZATION_MESSAGE[KINDLE2.OPT_APNX_METHOD_COL])
l.addWidget(f4)
l.addWidget(QLabel(_('Note that these settings apply to all Kindle devices not just this particular one')))
@property
def apnx(self):
result = {
'send': bool(self.send.isChecked()),
'method': str(self.method.currentData()).strip(),
'custom_column_page_count': str(self.column_page_count.text()).strip(),
'custom_column_method': str(self.column_method.text()).strip(),
}
return result
def commit(self):
from calibre.devices.kindle.driver import KINDLE2
vals = list(KINDLE2.EXTRA_CUSTOMIZATION_DEFAULT)
vals[KINDLE2.OPT_APNX] = bool(self.send.isChecked())
vals[KINDLE2.OPT_APNX_METHOD] = str(self.method.currentData()).strip()
vals[KINDLE2.OPT_APNX_CUST_COL] = str(self.column_page_count.text()).strip()
vals[KINDLE2.OPT_APNX_METHOD_COL] = str(self.column_method.text()).strip()
p = KINDLE2._configProxy()
p['extra_customization'] = vals
# }}}
@ -472,7 +482,7 @@ class MTPConfig(QTabWidget):
l.setRowStretch(7, 100)
if device.is_kindle:
self.apnx_tab = APNX(self.get_pref('apnx') or {})
self.apnx_tab = APNX()
self.addTab(self.apnx_tab, _('Page numbering (APNX)'))
self.igntab = IgnoredDevices(self.device.prefs['history'],
@ -563,9 +573,8 @@ class MTPConfig(QTabWidget):
if self.current_ignored_folders != self.initial_ignored_folders:
p['ignored_folders'] = self.current_ignored_folders
p.pop('apnx', None)
if hasattr(self, 'apnx_tab'):
p['apnx'] = self.apnx_tab.apnx
self.apnx_tab.commit()
if self.current_device_key is not None:
self.device.prefs[self.current_device_key] = p