mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Tool to test tag mapper rules easily
This commit is contained in:
parent
f8f9b2a0cd
commit
f01a5ce349
53
src/calibre/ebooks/metadata/tag_mapper.py
Normal file
53
src/calibre/ebooks/metadata/tag_mapper.py
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
import regex
|
||||
REGEX_FLAGS = regex.VERSION1 | regex.WORD | regex.FULLCASE | regex.IGNORECASE | regex.UNICODE
|
||||
|
||||
|
||||
def matcher(rule):
|
||||
mt = rule['match_type']
|
||||
if mt == 'one_of':
|
||||
tags = {icu_lower(x.strip()) for x in rule['query'].split(',')}
|
||||
return lambda x: x in tags
|
||||
|
||||
if mt == 'not_one_of':
|
||||
tags = {icu_lower(x.strip()) for x in rule['query'].split(',')}
|
||||
return lambda x: x not in tags
|
||||
|
||||
if mt == 'matches':
|
||||
pat = regex.compile(rule['query'], flags=REGEX_FLAGS)
|
||||
return lambda x: pat.match(x) is not None
|
||||
|
||||
if mt == 'not_matches':
|
||||
pat = regex.compile(rule['query'], flags=REGEX_FLAGS)
|
||||
return lambda x: pat.match(x) is None
|
||||
|
||||
return lambda x: False
|
||||
|
||||
|
||||
def apply_rules(tag, rules):
|
||||
for rule, matches in rules:
|
||||
ltag = icu_lower(tag)
|
||||
if matches(ltag):
|
||||
ac = rule['action']
|
||||
if ac == 'remove':
|
||||
return None
|
||||
if ac == 'keep':
|
||||
return tag
|
||||
if ac == 'replace':
|
||||
tag = regex.sub(rule['query'], rule['replace'], flags=REGEX_FLAGS)
|
||||
return tag
|
||||
|
||||
|
||||
def map_tags(tags, rules=()):
|
||||
if not tags:
|
||||
return []
|
||||
if not rules:
|
||||
return list(tags)
|
||||
rules = [(r, matcher(r)) for r in rules]
|
||||
return [x for x in (apply_rules(t, rules) for t in tags) if x]
|
@ -14,6 +14,7 @@ from PyQt5.Qt import (
|
||||
QStaticText, Qt, QStyle, QToolButton, QInputDialog, QMenu
|
||||
)
|
||||
|
||||
from calibre.ebooks.metadata.tag_mapper import map_tags
|
||||
from calibre.gui2 import error_dialog, elided_text, Application, question_dialog
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
from calibre.utils.config import JSONConfig
|
||||
@ -272,11 +273,43 @@ class Rules(QWidget):
|
||||
if 'action' in rule and 'match_type' in rule and 'query' in rule:
|
||||
RuleItem(rule, self.rule_list)
|
||||
|
||||
class Tester(Dialog):
|
||||
|
||||
def __init__(self, rules, parent=None):
|
||||
self.rules = rules
|
||||
Dialog.__init__(self, _('Test tag mapper rules'), 'test-tag-mapper-rules', parent=parent)
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QVBoxLayout(self)
|
||||
self.bb.setStandardButtons(self.bb.Close)
|
||||
self.la = la = QLabel(_(
|
||||
'Enter a comma separated list of &tags to test:'))
|
||||
l.addWidget(la)
|
||||
self.tags = t = QLineEdit(self)
|
||||
la.setBuddy(t)
|
||||
t.setPlaceholderText(_('Enter tags and click the Test button'))
|
||||
self.h = h = QHBoxLayout()
|
||||
l.addLayout(h)
|
||||
h.addWidget(t)
|
||||
self.test_button = b = QPushButton(_('&Test'), self)
|
||||
b.clicked.connect(self.do_test)
|
||||
h.addWidget(b)
|
||||
self.result = la = QLabel(self)
|
||||
la.setWordWrap(True)
|
||||
l.addWidget(la)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def do_test(self):
|
||||
tags = [x.strip() for x in self.tags.text().split(',')]
|
||||
tags = map_tags(tags, self.rules)
|
||||
self.result.setText(_('<b>Resulting tags:</b> %s') % ', '.join(tags))
|
||||
|
||||
|
||||
class RulesDialog(Dialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
self.loaded_ruleset = None
|
||||
Dialog.__init__(self, _('Edit tag mapper rules'), 'edit-tag-mapper-rules', parent=None)
|
||||
Dialog.__init__(self, _('Edit tag mapper rules'), 'edit-tag-mapper-rules', parent=parent)
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QVBoxLayout(self)
|
||||
@ -291,6 +324,8 @@ class RulesDialog(Dialog):
|
||||
self.load_menu = QMenu(self)
|
||||
b.setMenu(self.load_menu)
|
||||
self.build_load_menu()
|
||||
self.test_button = b = self.bb.addButton(_('&Test rules'), self.bb.ActionRole)
|
||||
b.clicked.connect(self.test_rules)
|
||||
|
||||
@property
|
||||
def rules(self):
|
||||
@ -336,6 +371,9 @@ class RulesDialog(Dialog):
|
||||
del tag_maps[name]
|
||||
self.build_load_menu()
|
||||
|
||||
def test_rules(self):
|
||||
Tester(self.rules, self).exec_()
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = Application([])
|
||||
d = RulesDialog()
|
||||
|
Loading…
x
Reference in New Issue
Block a user