Quote:
Originally Posted by un_pogaz
Hey, a make a module.
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).
I remember you had created a thread to reference different user modules (and other event managers), but I couldn't find it.
If it exists, it would be nice to have an explicit link in the description (so that we can look for it before breaking our heads to do things ourselves, especially if we don't understand anything in code)
Here is the code of the module:
EDIT: code moved into the dedicated thread
|
Thanks for your contribution. I added a link to your module in the
first post of the Action Chains Scripts thread.
One suggestion I have is to make the action support the
scopes feature as illustrated in the code below (modifications
highlighted in blue)
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()
#self.ids = gui.current_view().selectionModel().selectedRows()
if not self.ids or len(self.ids) == 0:
return
#self.ids = gui.library_view.get_selected_ids()
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 = DEFAULT_LANG
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
#set DEFAULT_LANG title sort to the user interface
def get_iso_language():
from calibre.utils.localization import set_translators, _load_iso639
iso639 = _load_iso639()
rslt = 'eng'
lang = set_translators.lang.split('_')[0].lower()
if len(lang) == 3:
if lang in iso639['codes3']:
rslt = lang
elif len(lang) == 2:
rslt = iso639['2to3'].get(lang, rslt)
elif len(lang) > 3:
rslt = iso639['name_map'].get(lang, rslt)
return rslt
DEFAULT_LANG = get_iso_language()
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