View Single Post
Old 05-10-2022, 04:14 PM   #26
un_pogaz
Chalut o/
un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.un_pogaz ought to be getting tired of karma fortunes by now.
 
un_pogaz's Avatar
 
Posts: 676
Karma: 720026
Join Date: Dec 2017
Device: Kobo
Bulk Sort Key

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
Attached Thumbnails
Click image for larger version

Name:	Capture d’écran 2022-05-10 221043.png
Views:	1060
Size:	7.3 KB
ID:	193754  
Attached Files
File Type: py Bulk Sort Key.py (3.9 KB, 563 views)

Last edited by un_pogaz; 10-05-2025 at 03:18 AM.
un_pogaz is offline   Reply With Quote