%PDF- %PDF-
Direktori : /lib/calibre/calibre/gui2/ |
Current File : //lib/calibre/calibre/gui2/author_mapper.py |
#!/usr/bin/env python3 # License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> from collections import OrderedDict from calibre.ebooks.metadata import authors_to_string, string_to_authors from calibre.ebooks.metadata.author_mapper import compile_rules, map_authors from calibre.gui2 import Application, elided_text from calibre.gui2.tag_mapper import ( RuleEdit as RuleEditBase, RuleEditDialog as RuleEditDialogBase, RuleItem as RuleItemBase, Rules as RulesBase, RulesDialog as RulesDialogBase, Tester as TesterBase ) from calibre.utils.config import JSONConfig author_maps = JSONConfig('author-mapping-rules') class RuleEdit(RuleEditBase): ACTION_MAP = OrderedDict(( ('replace', _('Change')), ('capitalize', _('Capitalize')), ('lower', _('Lower-case')), ('upper', _('Upper-case')), )) MATCH_TYPE_MAP = OrderedDict(( ('one_of', _('is one of')), ('not_one_of', _('is not one of')), ('has', _('contains')), ('matches', _('matches regex pattern')), ('not_matches', _('does not match regex pattern')), )) MSG = _('Create the rule below, the rule can be used to add or ignore files') SUBJECT = _('the author, if the author name') VALUE_ERROR = _('You must provide a value for the author name to match') REPLACE_TEXT = _('with the name:') @property def can_use_tag_editor(self): return False def update_state(self): a = self.action.currentData() replace = a == 'replace' self.la3.setVisible(replace), self.replace.setVisible(replace) m = self.match_type.currentData() is_match = 'matches' in m self.regex_help.setVisible(is_match) @property def rule(self): return { 'action': self.action.currentData(), 'match_type': self.match_type.currentData(), 'query': self.query.text().strip(), 'replace': self.replace.text().strip(), } @rule.setter def rule(self, rule): def sc(name): c = getattr(self, name) idx = c.findData(str(rule.get(name, ''))) if idx < 0: idx = 0 c.setCurrentIndex(idx) sc('match_type'), sc('action') self.query.setText(str(rule.get('query', '')).strip()) self.replace.setText(str(rule.get('replace', '')).strip()) class RuleEditDialog(RuleEditDialogBase): PREFS_NAME = 'edit-author-mapping-rule' RuleEditClass = RuleEdit class RuleItem(RuleItemBase): @staticmethod def text_from_rule(rule, parent): query = elided_text(rule['query'], font=parent.font(), width=200, pos='right') text = _( '<b>{action}</b> the author name, if it <i>{match_type}</i>: <b>{query}</b>').format( action=RuleEdit.ACTION_MAP[rule['action']], match_type=RuleEdit.MATCH_TYPE_MAP[rule['match_type']], query=query) if rule['action'] == 'replace': text += '<br>' + _('to the name') + ' <b>%s</b>' % rule['replace'] return '<div style="white-space: nowrap">' + text + '</div>' class Rules(RulesBase): RuleItemClass = RuleItem RuleEditDialogClass = RuleEditDialog MSG = _('You can specify rules to manipulate author names here.' ' Click the "Add Rule" button' ' below to get started. The rules will be processed in order for every author.') class Tester(TesterBase): DIALOG_TITLE = _('Test author mapping rules') PREFS_NAME = 'test-author-mapping-rules' LABEL = _('Enter an author name to test:') PLACEHOLDER = _('Enter author and click the "Test" button') EMPTY_RESULT = '<p> </p>' def do_test(self): authors = string_to_authors(self.value.strip()) ans = map_authors(authors, compile_rules(self.rules)) self.result.setText(authors_to_string(ans)) class RulesDialog(RulesDialogBase): DIALOG_TITLE = _('Edit author mapping rules') PREFS_NAME = 'edit-author-mapping-rules' RulesClass = Rules TesterClass = Tester PREFS_OBJECT = author_maps if __name__ == '__main__': app = Application([]) d = RulesDialog() d.rules = [ {'action':'replace', 'query':'alice B & alice bob', 'match_type':'one_of', 'replace':'Alice Bob'}, ] d.exec() from pprint import pprint pprint(d.rules) del d, app