The purpose of this module is to update the title and/or author sorting key, like the options in the Bulk Metadata dialog, options that are unavailable via Action Chains (I won't open the huge Bulk Metadata dialog just to check the same 2 options everytime => go on to make a non-interactive module)
Bonus: Normally translated into your language
EDIT: If your have Quality Check 1.14.3 and above installed, you can use directly the same action in "Imported From Other Plugin > Quality Check > Run Quality Check fix" and select "Check and repair book size"
Code:
import os, copy
try:
from qt.core import (QApplication, Qt, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout,
QGroupBox, QCheckBox)
except ImportError:
from PyQt5.Qt import (QApplication, Qt, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout,
QGroupBox, QCheckBox)
from calibre import prints
from calibre.constants import DEBUG
from calibre_plugins.action_chains.actions.base import ChainAction
class BulkSortKeyAction(ChainAction):
# the name of your action
name = 'Bulk Sort Key'
support_scopes = True
def run(self, gui, settings, chain):
cache = gui.current_db.new_api
self.ids = chain.scope().get_book_ids()
if not self.ids or len(self.ids) == 0:
return
if settings.get(KEY.SORT_TITLE, DEFAULT[KEY.SORT_TITLE]):
from calibre.ebooks.metadata import title_sort
lang_map = cache.all_field_for('languages', self.ids)
title_map = cache.all_field_for('title', self.ids)
def get_sort(book_id):
try:
lang = lang_map[book_id][0]
except (KeyError, IndexError, TypeError, AttributeError):
lang = None
return title_sort(title_map[book_id], lang=lang)
cache.set_field('sort', {bid:get_sort(bid) for bid in self.ids})
if settings.get(KEY.SORT_AUTHOR, DEFAULT[KEY.SORT_AUTHOR]):
author_sort_map = cache.author_sort_strings_for_books(self.ids)
cache.set_field('author_sort', {book_id: ' & '.join(author_sort_map[book_id]) for book_id in author_sort_map})
def config_widget(self):
return ConfigWidget
class KEY:
SORT_AUTHOR = 'sort_author'
SORT_TITLE = 'sort_title'
DEFAULT = {}
DEFAULT[KEY.SORT_AUTHOR] = True
DEFAULT[KEY.SORT_TITLE] = True
class ConfigWidget(QWidget):
def __init__(self, plugin_action):
QWidget.__init__(self)
self.plugin_action = plugin_action
self.gui = plugin_action.gui
self.db = self.gui.current_db
self._init_controls()
def _init_controls(self):
l = self.l = QVBoxLayout()
self.setLayout(l)
gb_opts = QGroupBox(_("Options"), self)
l.addWidget(gb_opts)
l_opts = QVBoxLayout()
gb_opts.setLayout(l_opts)
self.chk_sort_author = QCheckBox(_("A&utomatically set author sort"))
self.chk_sort_author.setChecked(DEFAULT[KEY.SORT_AUTHOR])
self.chk_sort_author.setToolTip(_("This will cause the author sort field to be automatically updated\n"
" based on the authors field for each selected book. Note that if\n"
" you use the control above to set authors in bulk, the author sort\n"
" field is updated anyway, regardless of the value of this checkbox."))
l_opts.addWidget(self.chk_sort_author)
self.chk_sort_title = QCheckBox(_("Update &title sort"))
self.chk_sort_title.setChecked(DEFAULT[KEY.SORT_TITLE])
self.chk_sort_title.setToolTip(_("Update title sort based on the current title. This will be applied only after other changes to title."))
l_opts.addWidget(self.chk_sort_title)
l.addStretch(1)
self.setMinimumSize(300,100)
def load_settings(self, settings):
if not settings:
settings = copy.deepcopy(DEFAULT)
self.chk_sort_author.setChecked(settings.get(KEY.SORT_AUTHOR, DEFAULT[KEY.SORT_AUTHOR]))
self.chk_sort_title.setChecked(settings.get(KEY.SORT_TITLE, DEFAULT[KEY.SORT_TITLE]))
def save_settings(self):
settings = {}
settings[KEY.SORT_AUTHOR] = self.chk_sort_author.isChecked()
settings[KEY.SORT_TITLE] = self.chk_sort_title.isChecked()
return settings