Add publisher and imprint handling

Imprint handling has been added to utils and uses a subclassed dict to
return a tuple for imprint matching, this may not be the best idea but
it works for now.

Add settings option auto_imprint
Add cli flag -a, --auto-import
This commit is contained in:
lordwelch 2021-08-07 21:50:45 -07:00 committed by Timmy Welch
parent 444e67100c
commit aefe778b36
9 changed files with 242 additions and 3 deletions

View File

@ -319,3 +319,21 @@ class GenericMetadata:
outstr += fmt_str.format(i[0] + ":", i[1])
return outstr
def fixPublisher(self):
if self.publisher is None:
return
if self.imprint is None:
self.imprint = ""
imprint, publisher = utils.getPublisher(self.publisher)
self.publisher = publisher
if self.imprint.lower() in publisher.lower():
self.imprint = None
if self.imprint is None or self.imprint == "":
self.imprint = imprint
elif self.imprint.lower() in imprint.lower():
self.imprint = imprint

View File

@ -615,3 +615,170 @@ def getLanguageFromISO(iso):
return None
else:
return lang_dict[iso]
def getPublisher(publisher):
if publisher is None:
return ("", "")
imprint = ""
for pub in publishers:
imprint, publisher, ok = pub[publisher]
if ok:
break
return (imprint, publisher)
class ImprintDict(dict):
'''
ImprintDict takes a publisher and a dict or mapping of lowercased
imprint names to the proper imprint name. Retreiving a value from an
ImprintDict returns a tuple of (imprint, publisher, keyExists).
if the key does not exist the key is returned as the publisher unchanged
'''
def __init__(self, publisher, mapping=(), **kwargs):
super().__init__(mapping, **kwargs)
self.publisher = publisher
def __missing__(self, key):
return None
def __getitem__(self, k):
item = super().__getitem__(k.lower())
if item is None:
return ("", k, False)
else:
return (item, self.publisher, True)
Marvel = ImprintDict("Marvel", {
"marvel comics": "",
"marvel": "",
"aircel comics": "Aircel Comics",
"aircel": "Aircel Comics",
"atlas comics": "Atlas Comics",
"atlas": "Atlas Comics",
"crossgen comics": "CrossGen comics",
"crossgen": "CrossGen comics",
"curtis magazines": "Curtis Magazines",
"disney books group": "Disney Books Group",
"disney books": "Disney Books Group",
"disney kingdoms": "Disney Kingdoms",
"epic comics": "Epic Comics",
"epic": "Epic Comics",
"epic comics group": "Epic Comics",
"eternity comics": "Eternity Comics",
"humorama": "Humorama",
"icon comics": "Icon Comics",
"infinite comics": "Infinite Comics",
"malibu comics": "Malibu Comics",
"malibu": "Malibu Comics",
"marvel 2099": "Marvel 2099",
"marvel absurd": "Marvel Absurd",
"marvel adventures": "Marvel Adventures",
"marvel age": "Marvel Age",
"marvel books": "Marvel Books",
"marvel comics 2": "Marvel Comics 2",
"marvel edge": "Marvel Edge",
"marvel frontier": "Marvel Frontier",
"marvel illustrated": "Marvel Illustrated",
"marvel knights": "Marvel Knights",
"marvel digital comics unlimited": "Marvel Unlimited",
"marvel magazine group": "Marvel Magazine Group",
"marvel mangaverse": "Marvel Mangaverse",
"marvel monsters group": "Marvel Monsters Group",
"marvel music": "Marvel Music",
"marvel next": "Marvel Next",
"marvel noir": "Marvel Noir",
"marvel press": "Marvel Press",
"marvel uk": "Marvel UK",
"marvel unlimited": "Marvel Unlimited",
"max": "MAX",
"mc2": "Marvel Comics 2",
"new universe": "New Universe",
"non-pareil publishing corp.": "Non-Pareil Publishing Corp.",
"paramount comics": "Paramount Comics",
"power comics": "Power Comics",
"razorline": "Razorline",
"star comics": "Star Comics",
"timely comics": "Timely Comics",
"timely": "Timely Comics",
"tsunami": "Tsunami",
"ultimate comics": "Ultimate Comics",
"ultimate marvel": "Ultimate Marvel",
"vital publications, inc.": "Vital Publications, Inc."
})
DC_Comics = ImprintDict("DC Comics", {
"dc comics": "",
"dc_comics": "",
"dc": "",
"tangent comics": "Tangent Comics",
"dccomics": "",
"all star dc": "All-Star",
"all star": "All-Star",
"all-star dc": "All-Star",
"all-star": "All-Star",
"america's best comics": "America's Best Comics",
"black label": "DC Black Label",
"cliffhanger": "Cliffhanger",
"cmx manga": "CMX Manga",
"dc black label": "DC Black Label",
"dc focus": "DC Focus",
"dc ink": "DC Ink",
"dc zoom": "DC Zoom",
"earth m": "Earth M",
"earth one": "Earth One",
"earth-m": "Earth M",
"elseworlds": "Elseworlds",
"eo": "Earth One",
"first wave": "First Wave",
"focus": "DC Focus",
"helix": "Helix",
"homage comics": "Homage Comics",
"impact comics": "Impact Comics",
"impact! comics": "Impact Comics",
"!mpact comics": "Impact Comics",
"johnny dc": "Johnny DC",
"mad": "Mad",
"minx": "Minx",
"paradox press": "Paradox Press",
"piranha press": "Piranha Press",
"sandman universe": "Sandman Universe",
"tsr": "TSR",
"vertigo": "Vertigo",
"wildstorm productions": "WildStorm Productions",
"wildstorm signature": "WildStorm Productions",
"wildstorm": "WildStorm Productions",
"wonder comics": "Wonder Comics",
"young animal": "Young Animal",
"zuda comics": "Zuda Comics",
"zuda": "Zuda Comics",
})
Dark_Horse_Comics = ImprintDict("Dark Horse Comics", {
"legend": "Legend",
"comics' greatest world": "Dark Horse Heroes",
"dark horse heroes": "Dark Horse Heroes",
"dark horse manga": "Dark Horse Manga",
"maverick": "Maverick",
"dh press": "DH Press",
"m press": "M Press",
"dark horse digital": "Dark Horse Digital",
"dh deluxe": "DH Deluxe",
"kitchen sink books": "Kitchen Sink Books",
"berger books": "Berger Books",
})
Archie_Comics = ImprintDict("Archie Comics", {
"Archie Action": "Archie Action",
"Archie Horror": "Archie Horror",
"Dark Circle Comics": "Dark Circle Comics",
"Dark Circle": "Dark Circle Comics",
"Red Circle Comics": "Dark Circle Comics",
"Red Circle": "Dark Circle Comics",
"Archie Adventure Series": "Archie Adventure Series",
"Radio Comics": "Mighty Comics Group",
"Mighty Comics Group": "Mighty Comics Group",
})
publishers = [Marvel, DC_Comics, Dark_Horse_Comics, Archie_Comics]

View File

@ -45,6 +45,7 @@ class AutoTagStartWindow(QtWidgets.QDialog):
QtCore.Qt.Unchecked)
self.cbxRemoveAfterSuccess.setCheckState(QtCore.Qt.Unchecked)
self.cbxSpecifySearchString.setCheckState(QtCore.Qt.Unchecked)
self.cbxAutoImprint.setCheckState(QtCore.Qt.Unchecked)
self.leNameLengthMatchTolerance.setText(
str(self.settings.id_length_delta_thresh))
self.leSearchString.setEnabled(False)
@ -62,6 +63,9 @@ class AutoTagStartWindow(QtWidgets.QDialog):
self.cbxRemoveAfterSuccess.setCheckState(QtCore.Qt.Checked)
if self.settings.wait_and_retry_on_rate_limit:
self.cbxWaitForRateLimit.setCheckState(QtCore.Qt.Checked)
if self.settings.auto_imprint:
self.cbxAutoImprint.setCheckState(QtCore.Qt.Checked)
nlmtTip = (
""" <html>The <b>Name Length Match Tolerance</b> is for eliminating automatic

View File

@ -132,6 +132,10 @@ def display_match_set_for_choice(label, match_set, opts, settings):
cv_md = actual_issue_data_fetch(
match_set.matches[int(i)], settings, opts)
md.overlay(cv_md)
if settings.auto_imprint:
md.fixPublisher()
actual_metadata_save(ca, opts, md)
@ -219,6 +223,8 @@ def process_file_cli(filename, opts, settings, match_results):
batch_mode = len(opts.file_list) > 1
settings.auto_imprint = opts.auto_imprint
ca = ComicArchive(
filename,
settings.rar_exe_path,
@ -473,6 +479,9 @@ def process_file_cli(filename, opts, settings, match_results):
md.overlay(cv_md)
if settings.auto_imprint:
md.fixPublisher()
# ok, done building our metadata. time to save
if not actual_metadata_save(ca, opts, md):
match_results.writeFailures.append(filename)

View File

@ -113,6 +113,7 @@ For more help visit the wiki at: https://github.com/comictagger/comictagger/wiki
self.filename = None
self.verbose = False
self.terse = False
self.auto_imprint = False
self.metadata = None
self.print_tags = False
self.copy_tags = False
@ -291,6 +292,8 @@ For more help visit the wiki at: https://github.com/comictagger/comictagger/wiki
self.delete_tags = True
if o in ("-i", "--interactive"):
self.interactive = True
if o in ("-a", "--auto-imprint"):
self.auto_imprint = True
if o in ("-c", "--copy"):
self.copy_tags = True
if a.lower() == "cr":

View File

@ -94,6 +94,7 @@ class ComicTaggerSettings:
self.clear_form_before_populating_from_cv = False
self.remove_html_tables = False
self.cv_api_key = ""
self.auto_imprint = False
# CBL Tranform settings
@ -323,6 +324,8 @@ class ComicTaggerSettings:
if self.config.has_option('autotag', 'wait_and_retry_on_rate_limit'):
self.wait_and_retry_on_rate_limit = self.config.getboolean(
'autotag', 'wait_and_retry_on_rate_limit')
if self.config.has_option('autotag', 'auto_imprint'):
self.auto_imprint = self.config.getboolean('autotag', 'auto_imprint')
def save(self):
@ -483,6 +486,7 @@ class ComicTaggerSettings:
'autotag',
'wait_and_retry_on_rate_limit',
self.wait_and_retry_on_rate_limit)
self.config.set('autotag', 'auto_imprint', self.auto_imprint)
with codecs.open(self.settings_file, 'wb', 'utf8') as configfile:
self.config.write(configfile)

View File

@ -248,6 +248,8 @@ class TaggerWindow(QtWidgets.QMainWindow):
self.fileSelectionList.addAppAction(self.actionRemoveAuto)
self.fileSelectionList.addAppAction(self.actionRepackage)
self.btnAutoImprint.clicked.connect(self.autoImprint)
if len(file_list) != 0:
self.fileSelectionList.addPathList(file_list)
@ -384,6 +386,8 @@ class TaggerWindow(QtWidgets.QMainWindow):
self.actionSearchOnline.setStatusTip('Search online for tags')
self.actionSearchOnline.triggered.connect(self.queryOnline)
self.actionAutoImprint.triggered.connect(self.autoImprint)
self.actionAutoIdentify.setShortcut('Ctrl+I')
self.actionAutoIdentify.triggered.connect(self.autoIdentifySearch)
@ -425,6 +429,8 @@ class TaggerWindow(QtWidgets.QMainWindow):
QtGui.QIcon(ComicTaggerSettings.getGraphic('auto.png')))
self.actionAutoTag.setIcon(
QtGui.QIcon(ComicTaggerSettings.getGraphic('autotag.png')))
self.actionAutoImprint.setIcon(
QtGui.QIcon(ComicTaggerSettings.getGraphic('autotag.png')))
self.actionClearEntryForm.setIcon(
QtGui.QIcon(ComicTaggerSettings.getGraphic('clear.png')))
self.actionPageBrowser.setIcon(
@ -438,6 +444,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
self.toolBar.addAction(self.actionAutoTag)
self.toolBar.addAction(self.actionClearEntryForm)
self.toolBar.addAction(self.actionPageBrowser)
self.toolBar.addAction(self.actionAutoImprint)
def repackageArchive(self):
ca_list = self.fileSelectionList.getSelectedArchiveList()
@ -1816,6 +1823,9 @@ class TaggerWindow(QtWidgets.QMainWindow):
if cv_md is not None:
md.overlay(cv_md)
if self.settings.auto_imprint:
md.fixPublisher()
if not ca.writeMetadata(md, self.save_data_style):
match_results.writeFailures.append(ca.path)
self.autoTagLog("Save failed ;-(\n")
@ -2167,3 +2177,8 @@ class TaggerWindow(QtWidgets.QMainWindow):
# self.show()
self.setWindowFlags(flags)
self.show()
def autoImprint(self):
self.formToMetadata()
self.metadata.fixPublisher()
self.metadataToForm()

View File

@ -44,7 +44,7 @@
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="6" column="0">
<item row="7" column="0">
<widget class="QCheckBox" name="cbxSpecifySearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -129,6 +129,16 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="cbxAutoImprint">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Checks the publisher against a list of imprints.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Auto Imprint</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLineEdit" name="leNameLengthMatchTolerance">
<property name="sizePolicy">
@ -145,7 +155,7 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLineEdit" name="leSearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -155,7 +165,7 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">

View File

@ -1176,6 +1176,7 @@
<addaction name="actionParse_Filename"/>
<addaction name="actionSearchOnline"/>
<addaction name="actionAutoIdentify"/>
<addaction name="actionAutoImprint"/>
<addaction name="separator"/>
<addaction name="actionApplyCBLTransform"/>
</widget>
@ -1373,6 +1374,14 @@
<string>Search online for tags,auto-identify best match, and save to archive</string>
</property>
</action>
<action name="actionAutoImprint">
<property name="text">
<string>Auto Imprint</string>
</property>
<property name="toolTip">
<string>Normalize the publisher and map imprints to their parent publisher (e.g. Vertigo is an imprint of DC Comics)</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>