Remove all the cool settings changes.

This commit is contained in:
Mizaki 2022-11-18 23:18:41 +00:00
parent 38c3014222
commit 093d20a52b
13 changed files with 492 additions and 622 deletions

View File

@ -50,7 +50,7 @@ def actual_issue_data_fetch(
logger.exception(f"Error retrieving issue details. Save aborted.\n{e}")
return GenericMetadata()
if settings.apply_cbl_transform_on_ct_import:
if settings.apply_cbl_transform_on_cv_import:
ct_md = CBLTransformer(ct_md, settings).apply()
return ct_md
@ -399,7 +399,7 @@ def process_file_cli(
match_results.no_matches.append(str(ca.path.absolute()))
return
if settings.apply_cbl_transform_on_ct_import:
if settings.apply_cbl_transform_on_cv_import:
ct_md = CBLTransformer(ct_md, settings).apply()
else:
if md is None or md.is_empty:

View File

@ -415,151 +415,103 @@ class IssueIdentifier:
# now sort the list by name length
series_second_round_list.sort(key=lambda x: len(x["name"]), reverse=False)
# If the sources lacks issue level data, don't look for it.
if not self.talker_api.static_options.has_issues:
# build a list of volume IDs
volume_id_list = []
for series in series_second_round_list:
volume_id_list.append(series["id"])
issue_list = None
try:
if len(volume_id_list) > 0:
issue_list = self.talker_api.fetch_issues_by_volume_issue_num_and_year(
volume_id_list, keys["issue_number"], keys["year"]
)
except TalkerError as e:
self.log_msg(f"Issue with while searching for series details. Aborting...\n{e}")
return []
if issue_list is None:
return []
shortlist = []
# now re-associate the issues and volumes
for issue in issue_list:
for series in series_second_round_list:
hash_list = [cover_hash]
if narrow_cover_hash is not None:
hash_list.append(narrow_cover_hash)
if series["id"] == issue["volume"]["id"]:
shortlist.append((series, issue))
break
try:
image_url = series["image_url"]
thumb_url = series["image_url"]
score_item = self.get_issue_cover_match_score(
series["id"],
image_url,
thumb_url,
[], # Only required for alt covers
hash_list,
use_remote_alternates=False,
)
except Exception:
self.match_list = []
return self.match_list
match: IssueResult = {
"series": f"{series['name']} ({series['start_year']})",
"distance": score_item["score"],
"issue_number": "",
"cv_issue_count": series["count_of_issues"],
"url_image_hash": score_item["hash"],
"issue_title": series["name"],
"issue_id": 0,
"volume_id": series["id"],
"month": 0,
"year": series["start_year"],
"publisher": series["publisher"],
"image_url": image_url,
"thumb_url": thumb_url,
"alt_image_urls": [],
"description": series["description"],
}
self.match_list.append(match)
self.log_msg(f" --> {match['distance']}", newline=False)
self.log_msg("")
if keys["year"] is None:
self.log_msg(f"Found {len(shortlist)} series that have an issue #{keys['issue_number']}")
else:
# build a list of volume IDs
volume_id_list = []
for series in series_second_round_list:
volume_id_list.append(series["id"])
self.log_msg(
f"Found {len(shortlist)} series that have an issue #{keys['issue_number']} from {keys['year']}"
)
# now we have a shortlist of volumes with the desired issue number
# Do first round of cover matching
counter = len(shortlist)
for series, issue in shortlist:
if self.callback is not None:
self.callback(counter, len(shortlist) * 3)
counter += 1
self.log_msg(
f"Examining covers for ID: {series['id']} {series['name']} ({series['start_year']}) ...",
newline=False,
)
# parse out the cover date
_, month, year = parse_date_str(issue["cover_date"])
# Now check the cover match against the primary image
hash_list = [cover_hash]
if narrow_cover_hash is not None:
hash_list.append(narrow_cover_hash)
issue_list = None
try:
if len(volume_id_list) > 0:
issue_list = self.talker_api.fetch_issues_by_volume_issue_num_and_year(
volume_id_list, keys["issue_number"], keys["year"]
)
except TalkerError as e:
self.log_msg(f"Issue with while searching for series details. Aborting...\n{e}")
return []
image_url = issue["image_url"]
thumb_url = issue["image_thumb_url"]
alt_urls = issue["alt_image_urls"]
if issue_list is None:
return []
shortlist = []
# now re-associate the issues and volumes
for issue in issue_list:
for series in series_second_round_list:
if series["id"] == issue["volume"]["id"]:
shortlist.append((series, issue))
break
if keys["year"] is None:
self.log_msg(f"Found {len(shortlist)} series that have an issue #{keys['issue_number']}")
else:
self.log_msg(
f"Found {len(shortlist)} series that have an issue #{keys['issue_number']} from {keys['year']}"
score_item = self.get_issue_cover_match_score(
issue["id"],
image_url,
thumb_url,
alt_urls,
hash_list,
use_remote_alternates=False,
)
except Exception:
self.match_list = []
return self.match_list
# now we have a shortlist of volumes with the desired issue number
# Do first round of cover matching
counter = len(shortlist)
for series, issue in shortlist:
if self.callback is not None:
self.callback(counter, len(shortlist) * 3)
counter += 1
match: IssueResult = {
"series": f"{series['name']} ({series['start_year']})",
"distance": score_item["score"],
"issue_number": keys["issue_number"],
"cv_issue_count": series["count_of_issues"],
"url_image_hash": score_item["hash"],
"issue_title": issue["name"],
"issue_id": issue["id"],
"volume_id": series["id"],
"month": month,
"year": year,
"publisher": None,
"image_url": image_url,
"thumb_url": thumb_url,
# "page_url": page_url,
"alt_image_urls": alt_urls,
"description": issue["description"],
}
if series["publisher"] is not None:
match["publisher"] = series["publisher"]
self.log_msg(
f"Examining covers for ID: {series['id']} {series['name']} ({series['start_year']}) ...",
newline=False,
)
self.match_list.append(match)
# parse out the cover date
_, month, year = parse_date_str(issue["cover_date"])
self.log_msg(f" --> {match['distance']}", newline=False)
# Now check the cover match against the primary image
hash_list = [cover_hash]
if narrow_cover_hash is not None:
hash_list.append(narrow_cover_hash)
try:
image_url = issue["image_url"]
thumb_url = issue["image_thumb_url"]
page_url = issue["site_detail_url"]
alt_urls = issue["alt_image_urls"]
score_item = self.get_issue_cover_match_score(
issue["id"],
image_url,
thumb_url,
alt_urls,
hash_list,
use_remote_alternates=False,
)
except Exception:
self.match_list = []
return self.match_list
match: IssueResult = {
"series": f"{series['name']} ({series['start_year']})",
"distance": score_item["score"],
"issue_number": keys["issue_number"],
"cv_issue_count": series["count_of_issues"],
"url_image_hash": score_item["hash"],
"issue_title": issue["name"],
"issue_id": issue["id"],
"volume_id": series["id"],
"month": month,
"year": year,
"publisher": None,
"image_url": image_url,
"thumb_url": thumb_url,
"page_url": page_url,
"alt_image_urls": alt_urls,
"description": issue["description"],
}
if series["publisher"] is not None:
match["publisher"] = series["publisher"]
self.match_list.append(match)
self.log_msg(f" --> {match['distance']}", newline=False)
self.log_msg("")
self.log_msg("")
if len(self.match_list) == 0:
self.log_msg(":-( no matches!")

View File

@ -164,12 +164,25 @@ def ctmain() -> None:
talker_failed = False
try:
talker_api = ct_api.get_comic_talker(settings.comic_info_source)()
talker_api = ct_api.get_comic_talker("comicvine")(
settings.cv_url,
settings.cv_api_key,
settings.id_series_match_search_thresh,
settings.remove_html_tables,
settings.use_series_start_as_volume,
settings.wait_and_retry_on_rate_limit,
)
except TalkerError as te:
talker_failed = True
logger.warning(f"Unable to load talker {te.source}. Error: {te.desc}. Defaulting to Comic Vine.")
settings.comic_info_source = "comicvine"
talker_api = ct_api.get_comic_talker("comicvine")()
talker_api = ct_api.get_comic_talker("comicvine")(
settings.cv_url,
settings.cv_api_key,
settings.id_series_match_search_thresh,
settings.remove_html_tables,
settings.use_series_start_as_volume,
settings.wait_and_retry_on_rate_limit,
)
utils.load_publishers()
update_publishers()

View File

@ -41,30 +41,6 @@ class ComicTaggerSettings:
ComicTaggerSettings.folder = pathlib.Path(os.path.expanduser("~")) / ".ComicTagger"
return pathlib.Path(ComicTaggerSettings.folder)
@staticmethod
def get_source_settings(source_name: str, source_settings: dict):
def get_type(section: str, setting: dict):
if setting["type"] is str:
return config.get(section, setting["name"])
elif setting["type"] is int:
return config.getint(section, setting["name"])
elif setting["type"] is float:
return config.getfloat(section, setting["name"])
elif setting["type"] is bool:
return config.getboolean(section, setting["name"])
settings_dir = ComicTaggerSettings.get_settings_folder()
settings_file = os.path.join(settings_dir, "settings")
config = configparser.RawConfigParser()
try:
with open(settings_file, encoding="utf-8") as f:
config.read_file(f)
for setting in source_settings.values():
setting["value"] = get_type(source_name, setting)
return True
except Exception:
return False
def __init__(self, folder: str | pathlib.Path | None) -> None:
# General Settings
self.rar_exe_path = ""
@ -90,7 +66,6 @@ class ComicTaggerSettings:
self.id_series_match_search_thresh = 90
self.id_series_match_identify_thresh = 91
self.id_publisher_filter = "Panini Comics, Abril, Planeta DeAgostini, Editorial Televisa, Dino Comics"
self.comic_info_source = "comicvine" # Default to CV as should always be present
# Show/ask dialog flags
self.ask_about_cbi_in_rar = True
@ -104,8 +79,12 @@ class ComicTaggerSettings:
self.remove_fcbd = False
self.remove_publisher = False
# Comic source general settings
self.clear_form_before_populating = False
# Comic Vine settings
self.use_series_start_as_volume = False
self.clear_form_before_populating_from_cv = False
self.remove_html_tables = False
self.cv_api_key = ""
self.cv_url = ""
self.auto_imprint = False
self.sort_series_by_year = True
@ -121,7 +100,7 @@ class ComicTaggerSettings:
self.copy_storyarcs_to_tags = False
self.copy_notes_to_comments = False
self.copy_weblink_to_comments = False
self.apply_cbl_transform_on_ct_import = False
self.apply_cbl_transform_on_cv_import = False
self.apply_cbl_transform_on_bulk_operation = False
# Rename settings
@ -230,8 +209,6 @@ class ComicTaggerSettings:
self.id_series_match_identify_thresh = self.config.getint("identifier", "id_series_match_identify_thresh")
if self.config.has_option("identifier", "id_publisher_filter"):
self.id_publisher_filter = self.config.get("identifier", "id_publisher_filter")
if self.config.has_option("identifier", "always_use_publisher_filter"):
self.always_use_publisher_filter = self.config.getboolean("identifier", "always_use_publisher_filter")
if self.config.has_option("filenameparser", "complicated_parser"):
self.complicated_parser = self.config.getboolean("filenameparser", "complicated_parser")
@ -251,18 +228,27 @@ class ComicTaggerSettings:
if self.config.has_option("dialogflags", "ask_about_usage_stats"):
self.ask_about_usage_stats = self.config.getboolean("dialogflags", "ask_about_usage_stats")
if self.config.has_option("comic_source_general", "clear_form_before_populating"):
self.clear_form_before_populating = self.config.getboolean(
"comic_source_general", "clear_form_before_populating"
if self.config.has_option("comicvine", "use_series_start_as_volume"):
self.use_series_start_as_volume = self.config.getboolean("comicvine", "use_series_start_as_volume")
if self.config.has_option("comicvine", "clear_form_before_populating_from_cv"):
self.clear_form_before_populating_from_cv = self.config.getboolean(
"comicvine", "clear_form_before_populating_from_cv"
)
if self.config.has_option("comic_source_general", "sort_series_by_year"):
self.sort_series_by_year = self.config.getboolean("comic_source_general", "sort_series_by_year")
if self.config.has_option("comic_source_general", "exact_series_matches_first"):
self.exact_series_matches_first = self.config.getboolean(
"comic_source_general", "exact_series_matches_first"
)
if self.config.has_option("comic_source_general", "comic_info_source"):
self.comic_info_source = self.config.get("identifier", "comic_info_source")
if self.config.has_option("comicvine", "remove_html_tables"):
self.remove_html_tables = self.config.getboolean("comicvine", "remove_html_tables")
if self.config.has_option("comicvine", "sort_series_by_year"):
self.sort_series_by_year = self.config.getboolean("comicvine", "sort_series_by_year")
if self.config.has_option("comicvine", "exact_series_matches_first"):
self.exact_series_matches_first = self.config.getboolean("comicvine", "exact_series_matches_first")
if self.config.has_option("comicvine", "always_use_publisher_filter"):
self.always_use_publisher_filter = self.config.getboolean("comicvine", "always_use_publisher_filter")
if self.config.has_option("comicvine", "cv_api_key"):
self.cv_api_key = self.config.get("comicvine", "cv_api_key")
if self.config.has_option("comicvine", "cv_url"):
self.cv_url = self.config.get("comicvine", "cv_url")
if self.config.has_option("cbl_transform", "assume_lone_credit_is_primary"):
self.assume_lone_credit_is_primary = self.config.getboolean(
@ -280,9 +266,9 @@ class ComicTaggerSettings:
self.copy_storyarcs_to_tags = self.config.getboolean("cbl_transform", "copy_storyarcs_to_tags")
if self.config.has_option("cbl_transform", "copy_weblink_to_comments"):
self.copy_weblink_to_comments = self.config.getboolean("cbl_transform", "copy_weblink_to_comments")
if self.config.has_option("cbl_transform", "apply_cbl_transform_on_ct_import"):
self.apply_cbl_transform_on_ct_import = self.config.getboolean(
"cbl_transform", "apply_cbl_transform_on_ct_import"
if self.config.has_option("cbl_transform", "apply_cbl_transform_on_cv_import"):
self.apply_cbl_transform_on_cv_import = self.config.getboolean(
"cbl_transform", "apply_cbl_transform_on_cv_import"
)
if self.config.has_option("cbl_transform", "apply_cbl_transform_on_bulk_operation"):
self.apply_cbl_transform_on_bulk_operation = self.config.getboolean(
@ -357,9 +343,6 @@ class ComicTaggerSettings:
self.config.set("identifier", "id_series_match_search_thresh", self.id_series_match_search_thresh)
self.config.set("identifier", "id_series_match_identify_thresh", self.id_series_match_identify_thresh)
self.config.set("identifier", "id_publisher_filter", self.id_publisher_filter)
self.config.set("identifier", "always_use_publisher_filter", self.always_use_publisher_filter)
self.config.set("identifier", "comic_info_source", self.comic_info_source)
if not self.config.has_section("dialogflags"):
self.config.add_section("dialogflags")
@ -377,12 +360,19 @@ class ComicTaggerSettings:
self.config.set("filenameparser", "remove_fcbd", self.remove_fcbd)
self.config.set("filenameparser", "remove_publisher", self.remove_publisher)
if not self.config.has_section("comic_source_general"):
self.config.add_section("comic_source_general")
if not self.config.has_section("comicvine"):
self.config.add_section("comicvine")
self.config.set("comic_source_general", "clear_form_before_populating", self.clear_form_before_populating)
self.config.set("comic_source_general", "sort_series_by_year", self.sort_series_by_year)
self.config.set("comic_source_general", "exact_series_matches_first", self.exact_series_matches_first)
self.config.set("comicvine", "use_series_start_as_volume", self.use_series_start_as_volume)
self.config.set("comicvine", "clear_form_before_populating_from_cv", self.clear_form_before_populating_from_cv)
self.config.set("comicvine", "remove_html_tables", self.remove_html_tables)
self.config.set("comicvine", "sort_series_by_year", self.sort_series_by_year)
self.config.set("comicvine", "exact_series_matches_first", self.exact_series_matches_first)
self.config.set("comicvine", "always_use_publisher_filter", self.always_use_publisher_filter)
self.config.set("comicvine", "cv_api_key", self.cv_api_key)
self.config.set("comicvine", "cv_url", self.cv_url)
if not self.config.has_section("cbl_transform"):
self.config.add_section("cbl_transform")
@ -394,7 +384,7 @@ class ComicTaggerSettings:
self.config.set("cbl_transform", "copy_storyarcs_to_tags", self.copy_storyarcs_to_tags)
self.config.set("cbl_transform", "copy_notes_to_comments", self.copy_notes_to_comments)
self.config.set("cbl_transform", "copy_weblink_to_comments", self.copy_weblink_to_comments)
self.config.set("cbl_transform", "apply_cbl_transform_on_ct_import", self.apply_cbl_transform_on_ct_import)
self.config.set("cbl_transform", "apply_cbl_transform_on_cv_import", self.apply_cbl_transform_on_cv_import)
self.config.set(
"cbl_transform",
"apply_cbl_transform_on_bulk_operation",
@ -422,7 +412,5 @@ class ComicTaggerSettings:
self.config.set("autotag", "wait_and_retry_on_rate_limit", self.wait_and_retry_on_rate_limit)
self.config.set("autotag", "auto_imprint", self.auto_imprint)
# NOTE: Source settings are added in settingswindow module
with open(self.settings_file, "w", encoding="utf-8") as configfile:
self.config.write(configfile)

View File

@ -20,12 +20,9 @@ import logging
import os
import pathlib
import platform
import webbrowser
from urllib.parse import urlparse
from PyQt5 import QtCore, QtGui, QtWidgets, uic
import comictalker.comictalkerapi as ct_api
from comicapi import utils
from comicapi.genericmetadata import md_test
from comictaggerlib.filerenamer import FileRenamer
@ -141,8 +138,6 @@ class SettingsWindow(QtWidgets.QDialog):
)
self.settings = settings
# TODO Quick hack to allow menus to work
self.available_talkers = ct_api.get_talkers()
self.talker_api = talker_api
self.name = "Settings"
@ -192,6 +187,7 @@ class SettingsWindow(QtWidgets.QDialog):
self.btnBrowseRar.clicked.connect(self.select_rar)
self.btnClearCache.clicked.connect(self.clear_cache)
self.btnResetSettings.clicked.connect(self.reset_settings)
self.btnTestKey.clicked.connect(self.test_api_key)
self.btnTemplateHelp.clicked.connect(self.show_template_help)
self.leRenameTemplate.textEdited.connect(self._rename_test)
self.cbxMoveFiles.clicked.connect(self.rename_test)
@ -200,136 +196,6 @@ class SettingsWindow(QtWidgets.QDialog):
self.leDirectory.textEdited.connect(self.dir_test)
self.cbxComplicatedParser.clicked.connect(self.switch_parser)
self.sources: dict = {}
self.generate_source_option_tabs()
def generate_source_option_tabs(self) -> None:
# TODO Move to utils?
def open_web_link(link) -> None:
if link is not None:
web_link = link.strip()
try:
result = urlparse(web_link)
all([result.scheme in ["http", "https"], result.netloc])
webbrowser.open_new_tab(web_link)
except ValueError:
QtWidgets.QMessageBox.warning(self, "Web Link", "Web Link is invalid.")
# Add source sub tabs to Comic Sources tab
for source_cls in self.available_talkers.values():
# TODO Remove hack
source = source_cls()
# Add source to general tab dropdown list
self.cobxInfoSource.addItem(source.source_details.name, source.source_details.id)
# Use a dict to make a var name from var
source_info = {}
tab_name = source.source_details.id
source_info[tab_name] = {"tab": QtWidgets.QWidget(), "widgets": {}}
layout_grid = QtWidgets.QGridLayout()
row = 0
# Add logo and web link if available
if source.static_options.website:
source_label_logo = QtGui.QPixmap(source.source_details.logo)
source_website_icon_link = QtWidgets.QPushButton()
source_website_icon_link.clicked.connect(
lambda state, w=source.static_options.website: open_web_link(w)
)
source_website_icon_link.setToolTip(f"Click to visit website: {source.static_options.website}")
source_website_icon_link.setMaximumSize(250, 100)
if source_label_logo.isNull():
source_website_icon_link.setFont(QtGui.QFont("Arial", 14, 3))
source_website_icon_link.setText(source.source_details.name)
else:
if source_label_logo.height() > 100 or source_label_logo.width() > 250:
source_label_logo = source_label_logo.scaled(
250, 100, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation
)
source_website_icon_link.setIconSize(QtCore.QSize(source_label_logo.rect().size()))
source_website_icon_link.setFixedSize(QtCore.QSize(source_label_logo.rect().size()))
source_website_icon_link.setIcon(QtGui.QIcon(source_label_logo))
source_website_icon_link.setFlat(True)
layout_grid.addWidget(source_website_icon_link, row, 0, 1, -1)
row += 1
for option in source.settings_options.values():
if not option["hidden"]:
current_widget = None
if option["type"] is bool:
# bool equals a checkbox (QCheckBox)
current_widget = QtWidgets.QCheckBox(option["text"])
# Set widget status
# This works because when a talker class is initialised it loads its settings from disk
if option["value"]:
current_widget.setChecked(option["value"])
# Add widget and span all columns
layout_grid.addWidget(current_widget, row, 0, 1, -1)
if option["type"] is int:
# int equals a spinbox (QSpinBox)
lbl = QtWidgets.QLabel(option["text"])
# Create a label
layout_grid.addWidget(lbl, row, 0)
current_widget = QtWidgets.QSpinBox()
current_widget.setRange(0, 9999)
if option["value"]:
current_widget.setValue(option["value"])
layout_grid.addWidget(current_widget, row, 1, alignment=QtCore.Qt.AlignLeft)
if option["type"] is float:
# float equals a spinbox (QDoubleSpinBox)
lbl = QtWidgets.QLabel(option["text"])
# Create a label
layout_grid.addWidget(lbl, row, 0)
current_widget = QtWidgets.QDoubleSpinBox()
current_widget.setRange(0, 9999.99)
if option["value"]:
current_widget.setValue(option["value"])
layout_grid.addWidget(current_widget, row, 1, alignment=QtCore.Qt.AlignLeft)
if option["type"] is str:
# str equals a text field (QLineEdit)
lbl = QtWidgets.QLabel(option["text"])
# Create a label
layout_grid.addWidget(lbl, row, 0)
current_widget = QtWidgets.QLineEdit()
# Set widget status
if option["value"]:
current_widget.setText(option["value"])
layout_grid.addWidget(current_widget, row, 1)
# Special case for api_key, make a test button
if option["name"] == "api_key":
btn = QtWidgets.QPushButton("Test Key")
layout_grid.addWidget(btn, row, 2)
btn.clicked.connect(lambda state, key=source.source_details.id: self.test_api_key(key))
row += 1
if current_widget:
# Add tooltip text
current_widget.setToolTip(option["help_text"])
source_info[tab_name]["widgets"][option["name"]] = current_widget
else:
# An empty current_widget implies an unsupported type
logger.info(f"Unsupported talker option found. Name: {option['name']} Type: {option['type']}")
# Add vertical spacer
vspacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
layout_grid.addItem(vspacer, row, 0)
# Display the new widgets
source_info[tab_name]["tab"].setLayout(layout_grid)
# Add new sub tab to Comic Source tab
self.tComicSourcesOptions.addTab(source_info[tab_name]["tab"], source.source_details.name)
self.sources.update(source_info)
# Select active source in dropdown
self.cobxInfoSource.setCurrentIndex(self.cobxInfoSource.findData(self.settings.comic_info_source))
# Set General as start tab
self.tabWidget.setCurrentIndex(0)
def rename_test(self) -> None:
self._rename_test(self.leRenameTemplate.text())
@ -373,12 +239,17 @@ class SettingsWindow(QtWidgets.QDialog):
self.cbxRemovePublisher.setChecked(self.settings.remove_publisher)
self.switch_parser()
self.cbxClearFormBeforePopulating.setChecked(self.settings.clear_form_before_populating)
self.cbxUseSeriesStartAsVolume.setChecked(self.settings.use_series_start_as_volume)
self.cbxClearFormBeforePopulating.setChecked(self.settings.clear_form_before_populating_from_cv)
self.cbxRemoveHtmlTables.setChecked(self.settings.remove_html_tables)
self.cbxUseFilter.setChecked(self.settings.always_use_publisher_filter)
self.cbxSortByYear.setChecked(self.settings.sort_series_by_year)
self.cbxExactMatches.setChecked(self.settings.exact_series_matches_first)
self.leKey.setText(self.settings.cv_api_key)
self.leURL.setText(self.settings.cv_url)
self.cbxAssumeLoneCreditIsPrimary.setChecked(self.settings.assume_lone_credit_is_primary)
self.cbxCopyCharactersToTags.setChecked(self.settings.copy_characters_to_tags)
self.cbxCopyTeamsToTags.setChecked(self.settings.copy_teams_to_tags)
@ -386,7 +257,7 @@ class SettingsWindow(QtWidgets.QDialog):
self.cbxCopyStoryArcsToTags.setChecked(self.settings.copy_storyarcs_to_tags)
self.cbxCopyNotesToComments.setChecked(self.settings.copy_notes_to_comments)
self.cbxCopyWebLinkToComments.setChecked(self.settings.copy_weblink_to_comments)
self.cbxApplyCBLTransformOnCVIMport.setChecked(self.settings.apply_cbl_transform_on_ct_import)
self.cbxApplyCBLTransformOnCVIMport.setChecked(self.settings.apply_cbl_transform_on_cv_import)
self.cbxApplyCBLTransformOnBatchOperation.setChecked(self.settings.apply_cbl_transform_on_bulk_operation)
self.leRenameTemplate.setText(self.settings.rename_template)
@ -442,21 +313,27 @@ class SettingsWindow(QtWidgets.QDialog):
self.settings.id_series_match_identify_thresh = self.sbNameMatchIdentifyThresh.value()
self.settings.id_series_match_search_thresh = self.sbNameMatchSearchThresh.value()
self.settings.id_publisher_filter = str(self.tePublisherFilter.toPlainText())
self.settings.comic_info_source = str(self.cobxInfoSource.itemData(self.cobxInfoSource.currentIndex()))
# Also change current talker_api object
if self.settings.comic_info_source != self.talker_api.source_details.id:
self.talker_api = ct_api.get_comic_talker(self.settings.comic_info_source)()
self.settings.complicated_parser = self.cbxComplicatedParser.isChecked()
self.settings.remove_c2c = self.cbxRemoveC2C.isChecked()
self.settings.remove_fcbd = self.cbxRemoveFCBD.isChecked()
self.settings.remove_publisher = self.cbxRemovePublisher.isChecked()
self.settings.clear_form_before_populating = self.cbxClearFormBeforePopulating.isChecked()
self.settings.use_series_start_as_volume = self.cbxUseSeriesStartAsVolume.isChecked()
self.settings.clear_form_before_populating_from_cv = self.cbxClearFormBeforePopulating.isChecked()
self.settings.remove_html_tables = self.cbxRemoveHtmlTables.isChecked()
self.settings.always_use_publisher_filter = self.cbxUseFilter.isChecked()
self.settings.sort_series_by_year = self.cbxSortByYear.isChecked()
self.settings.exact_series_matches_first = self.cbxExactMatches.isChecked()
# Ignore empty field
if self.leKey.text().strip():
self.settings.cv_api_key = self.leKey.text().strip()
self.talker_api.api_key = self.settings.cv_api_key
if self.leURL.text().strip():
self.settings.cv_url = self.leURL.text().strip()
self.talker_api.api_base_url = self.settings.cv_url
self.settings.assume_lone_credit_is_primary = self.cbxAssumeLoneCreditIsPrimary.isChecked()
self.settings.copy_characters_to_tags = self.cbxCopyCharactersToTags.isChecked()
self.settings.copy_teams_to_tags = self.cbxCopyTeamsToTags.isChecked()
@ -464,7 +341,7 @@ class SettingsWindow(QtWidgets.QDialog):
self.settings.copy_storyarcs_to_tags = self.cbxCopyStoryArcsToTags.isChecked()
self.settings.copy_notes_to_comments = self.cbxCopyNotesToComments.isChecked()
self.settings.copy_weblink_to_comments = self.cbxCopyWebLinkToComments.isChecked()
self.settings.apply_cbl_transform_on_ct_import = self.cbxApplyCBLTransformOnCVIMport.isChecked()
self.settings.apply_cbl_transform_on_cv_import = self.cbxApplyCBLTransformOnCVIMport.isChecked()
self.settings.apply_cbl_transform_on_bulk_operation = self.cbxApplyCBLTransformOnBatchOperation.isChecked()
self.settings.rename_template = str(self.leRenameTemplate.text())
@ -476,57 +353,6 @@ class SettingsWindow(QtWidgets.QDialog):
self.settings.rename_strict = self.cbxRenameStrict.isChecked()
# Read settings from sources tabs and generate self.settings.config data
for source_cls in self.available_talkers.values():
# TODO Remove hack
source = source_cls()
source_info = self.sources[source.source_details.id]
if not self.settings.config.has_section(source.source_details.id):
self.settings.config.add_section(source.source_details.id)
# Iterate over sources options and get the tab setting
for option in source.settings_options.values():
# Only save visible here
if option["name"] in source_info["widgets"]:
# Set the tab setting for the talker class var
if option["type"] is bool:
current_widget: QtWidgets.QCheckBox = source_info["widgets"][option["name"]]
option["value"] = current_widget.isChecked()
if option["type"] is int:
current_widget: QtWidgets.QSpinBox = source_info["widgets"][option["name"]]
option["value"] = current_widget.value()
if option["type"] is float:
current_widget: QtWidgets.QDoubleSpinBox = source_info["widgets"][option["name"]]
option["value"] = current_widget.value()
if option["type"] is str:
current_widget: QtWidgets.QLineEdit = source_info["widgets"][option["name"]]
option["value"] = current_widget.text().strip()
else:
# Handle hidden, assume changed programmatically
if option["name"] == "enabled":
# Set to disabled if is not the selected talker
if source.source_details.id != self.settings.comic_info_source:
source.settings_options["enabled"]["value"] = False
else:
source.settings_options["enabled"]["value"] = True
else:
# Ensure correct type
if option["type"] is bool:
option["value"] = bool(option["value"])
if option["type"] is int:
option["value"] = int(option["value"])
if option["type"] is float:
option["value"] = float(option["value"])
if option["type"] is str:
option["value"] = str(option["value"]).strip()
# Save out option
self.settings.config.set(source.source_details.id, option["name"], option["value"])
# Update talker options in object
if source.source_details.id == self.talker_api.source_details.id:
self.talker_api.settings_options[option["name"]]["value"] = option["value"]
self.settings.save()
QtWidgets.QDialog.accept(self)
@ -538,18 +364,11 @@ class SettingsWindow(QtWidgets.QDialog):
ComicCacher().clear_cache()
QtWidgets.QMessageBox.information(self, self.name, "Cache has been cleared.")
def test_api_key(self, source_id) -> None:
# TODO Only allow testing of active talker?
if source_id == self.settings.comic_info_source:
key = self.sources[source_id]["widgets"]["api_key"].text().strip()
url = self.sources[source_id]["widgets"]["url_root"].text().strip()
if self.talker_api.check_api_key(key, url):
QtWidgets.QMessageBox.information(self, "API Key Test", "Key is valid!")
else:
QtWidgets.QMessageBox.warning(self, "API Key Test", "Key is NOT valid!")
def test_api_key(self) -> None:
if self.talker_api.check_api_key(self.leKey.text().strip(), self.leURL.text().strip()):
QtWidgets.QMessageBox.information(self, "API Key Test", "Key is valid!")
else:
QtWidgets.QMessageBox.warning(self, "API Key Test", "Can only test active comic source.")
QtWidgets.QMessageBox.warning(self, "API Key Test", "Key is NOT valid.")
def reset_settings(self) -> None:
self.settings.reset()

View File

@ -1032,7 +1032,7 @@ Have fun!
issue_number = str(self.leIssueNum.text()).strip()
# Only need this check is the source has issue level data.
if autoselect and issue_number == "" and self.talker_api.static_options.has_issues:
if autoselect and issue_number == "":
QtWidgets.QMessageBox.information(
self, "Automatic Identify Search", "Can't auto-identify without an issue number (yet!)"
)
@ -1096,10 +1096,10 @@ Have fun!
else:
QtWidgets.QApplication.restoreOverrideCursor()
if new_metadata is not None:
if self.settings.apply_cbl_transform_on_ct_import:
if self.settings.apply_cbl_transform_on_cv_import:
new_metadata = CBLTransformer(new_metadata, self.settings).apply()
if self.settings.clear_form_before_populating:
if self.settings.clear_form_before_populating_from_cv:
self.clear_form()
notes = (
@ -1698,7 +1698,7 @@ Have fun!
logger.exception(f"Save aborted.\n{e}")
if not ct_md.is_empty:
if self.settings.apply_cbl_transform_on_ct_import:
if self.settings.apply_cbl_transform_on_cv_import:
ct_md = CBLTransformer(ct_md, self.settings).apply()
QtWidgets.QApplication.restoreOverrideCursor()

View File

@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>519</width>
<height>452</height>
<height>440</height>
</rect>
</property>
<property name="sizePolicy">
@ -44,7 +44,30 @@
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<item row="6" column="0">
<widget class="QCheckBox" name="cbxAutoImprint">
<property name="toolTip">
<string>Checks the publisher against a list of imprints.</string>
</property>
<property name="text">
<string>Auto Imprint</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="cbxSpecifySearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Specify series search string for all selected archives:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="cbxIgnoreLeadingDigitsInFilename">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -57,74 +80,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="cbxDontUseYear">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Don't use publication year in identification process</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLineEdit" name="leSearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="cbxSplitWords">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Split words in filenames (e.g. 'judgedredd' to 'judge dredd') (Experimental)</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QSpinBox" name="sbNameMatchSearchThresh">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Adjust Name Match Ratio Threshold: Auto-Identify</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="cbxSaveOnLowConfidence">
<property name="sizePolicy">
@ -138,13 +93,52 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="cbxRemoveMetadata">
<property name="toolTip">
<string>Removes existing metadata before applying retrieved metadata</string>
<item row="10" column="0">
<widget class="QLineEdit" name="leSearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Overwrite metadata</string>
<string>Adjust Name Match Ratio Threshold: Auto-Identify</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="cbxSplitWords">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Split words in filenames (e.g. 'judgedredd' to 'judge dredd') (Experimental)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="cbxDontUseYear">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Don't use publication year in identification process</string>
</property>
</widget>
</item>
@ -161,7 +155,17 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="7" column="0">
<widget class="QCheckBox" name="cbxRemoveMetadata">
<property name="toolTip">
<string>Removes existing metadata before applying retrieved metadata</string>
</property>
<property name="text">
<string>Overwrite metadata</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="cbxRemoveAfterSuccess">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -174,26 +178,29 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="cbxAutoImprint">
<property name="toolTip">
<string>Checks the publisher against a list of imprints.</string>
</property>
<item row="3" column="0">
<widget class="QCheckBox" name="cbxWaitForRateLimit">
<property name="text">
<string>Auto Imprint</string>
<string>Wait and retry when Comic Vine rate limit is exceeded (experimental)</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="cbxSpecifySearchString">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="12" column="0">
<widget class="QSpinBox" name="sbNameMatchSearchThresh">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Specify series search string for all selected archives:</string>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>

View File

@ -28,7 +28,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>4</number>
<number>0</number>
</property>
<widget class="QWidget" name="tGeneral">
<attribute name="title">
@ -308,56 +308,53 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tComicSources">
<widget class="QWidget" name="tComicVine">
<attribute name="title">
<string>Comic Sources</string>
<string>Comic Vine</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTabWidget" name="tComicSourcesOptions">
<property name="currentIndex">
<number>0</number>
<widget class="QGroupBox" name="grpBoxCVTop">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QWidget" name="tComicSourceGeneral">
<attribute name="title">
<string>General</string>
</attribute>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>641</width>
<height>341</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="leInfoSource">
<widget class="QCheckBox" name="cbxUseSeriesStartAsVolume">
<property name="text">
<string>Select Information Source:</string>
<string>Use Series Start Date as Volume</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cobxInfoSource"/>
</item>
<item>
<widget class="QCheckBox" name="cbxClearFormBeforePopulating">
<property name="text">
<string>Clear Form Before Importing Comic Data</string>
<string>Clear Form Before Importing Comic Vine data</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbxRemoveHtmlTables">
<property name="text">
<string>Remove HTML tables from CV summary field</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
@ -375,24 +372,132 @@
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="grpBoxKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="lblKeyHelp">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;A personal API key from &lt;a href=&quot;http://www.comicvine.com/api/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Comic Vine&lt;/span&gt;&lt;/a&gt; is recommended in order to search for tag data. Login (or create a new account) there to get your key, and enter it below.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="btnTestKey">
<property name="text">
<string>Test Key</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leKey">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblKey">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Comic Vine API Key</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblURL">
<property name="text">
<string>Comic Vine URL</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="leURL"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tCBL">
@ -403,7 +508,7 @@
<item row="0" column="0">
<widget class="QCheckBox" name="cbxApplyCBLTransformOnCVIMport">
<property name="text">
<string>Apply CBL Transforms on Comic Import</string>
<string>Apply CBL Transforms on ComicVine Import</string>
</property>
</widget>
</item>
@ -431,7 +536,7 @@
<x>11</x>
<y>21</y>
<width>251</width>
<height>206</height>
<height>199</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_7">
@ -757,8 +862,8 @@ By default only removes restricted characters and filenames for the current Oper
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>477</y>
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -773,8 +878,8 @@ By default only removes restricted characters and filenames for the current Oper
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>326</x>
<y>477</y>
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>

View File

@ -177,14 +177,8 @@ class VolumeSelectionWindow(QtWidgets.QDialog):
self.btnRequery.setEnabled(enabled)
if self.talker_api.static_options.has_issues:
self.btnIssues.setEnabled(enabled)
self.btnAutoSelect.setEnabled(enabled)
else:
self.btnIssues.setEnabled(False)
self.btnIssues.setToolTip("Unsupported by " + self.talker_api.source_details.name)
self.btnAutoSelect.setEnabled(False)
self.btnAutoSelect.setToolTip("Unsupported by " + self.talker_api.source_details.name)
self.btnIssues.setEnabled(enabled)
self.btnAutoSelect.setEnabled(enabled)
self.buttonBox.button(QtWidgets.QDialogButtonBox.StandardButton.Ok).setEnabled(enabled)
@ -198,43 +192,40 @@ class VolumeSelectionWindow(QtWidgets.QDialog):
def auto_select(self) -> None:
if self.talker_api.static_options.has_issues:
if self.comic_archive is None:
QtWidgets.QMessageBox.information(self, "Auto-Select", "You need to load a comic first!")
return
if self.comic_archive is None:
QtWidgets.QMessageBox.information(self, "Auto-Select", "You need to load a comic first!")
return
if self.issue_number is None or self.issue_number == "":
QtWidgets.QMessageBox.information(
self, "Auto-Select", "Can't auto-select without an issue number (yet!)"
)
return
if self.issue_number is None or self.issue_number == "":
QtWidgets.QMessageBox.information(self, "Auto-Select", "Can't auto-select without an issue number (yet!)")
return
self.iddialog = IDProgressWindow(self)
self.iddialog.setModal(True)
self.iddialog.rejected.connect(self.identify_cancel)
self.iddialog.show()
self.iddialog = IDProgressWindow(self)
self.iddialog.setModal(True)
self.iddialog.rejected.connect(self.identify_cancel)
self.iddialog.show()
self.ii = IssueIdentifier(self.comic_archive, self.settings, self.talker_api)
self.ii = IssueIdentifier(self.comic_archive, self.settings, self.talker_api)
md = GenericMetadata()
md.series = self.series_name
md.issue = self.issue_number
md.year = self.year
md.issue_count = self.issue_count
md = GenericMetadata()
md.series = self.series_name
md.issue = self.issue_number
md.year = self.year
md.issue_count = self.issue_count
self.ii.set_additional_metadata(md)
self.ii.only_use_additional_meta_data = True
self.ii.set_additional_metadata(md)
self.ii.only_use_additional_meta_data = True
self.ii.cover_page_index = int(self.cover_index_list[0])
self.ii.cover_page_index = int(self.cover_index_list[0])
self.id_thread = IdentifyThread(self.ii)
self.id_thread.identifyComplete.connect(self.identify_complete)
self.id_thread.identifyLogMsg.connect(self.log_id_output)
self.id_thread.identifyProgress.connect(self.identify_progress)
self.id_thread = IdentifyThread(self.ii)
self.id_thread.identifyComplete.connect(self.identify_complete)
self.id_thread.identifyLogMsg.connect(self.log_id_output)
self.id_thread.identifyProgress.connect(self.identify_progress)
self.id_thread.start()
self.id_thread.start()
self.iddialog.exec()
self.iddialog.exec()
def log_id_output(self, text: str) -> None:
if self.iddialog is not None:
@ -501,11 +492,7 @@ class VolumeSelectionWindow(QtWidgets.QDialog):
self.auto_select()
def cell_double_clicked(self, r: int, c: int) -> None:
if self.talker_api.static_options.has_issues:
self.show_issues()
else:
# Pass back to have taggerwindow get full series data
self.accept()
self.show_issues()
def current_item_changed(self, curr: QtCore.QModelIndex | None, prev: QtCore.QModelIndex | None) -> None:

View File

@ -29,7 +29,6 @@ from comicapi import utils
from comicapi.genericmetadata import GenericMetadata
from comicapi.issuestring import IssueString
from comictaggerlib import ctversion
from comictaggerlib.settings import ComicTaggerSettings
from comictalker.comiccacher import ComicCacher
from comictalker.resulttypes import ComicIssue, ComicVolume, Credits
from comictalker.talkerbase import (
@ -172,13 +171,16 @@ CV_RATE_LIMIT_STATUS = 107
class ComicVineTalker(ComicTalker):
def __init__(self, series_match_thresh: int = 90) -> None:
def __init__(
self, api_url, api_key, series_match_thresh, remove_html_tables, use_series_start_as_volume, wait_on_ratelimit
):
super().__init__()
self.source_details = SourceDetails(
name="Comic Vine",
ident="comicvine",
logo="comictalker/talkers/logos/comicvine.png",
)
# TODO Remove or leave in for future?
self.static_options = SourceStaticOptions(
logo_url="", # Unable to find a viable URL. Current logo is SVG using CSS
website="https://comicvine.gamespot.com/",
@ -188,6 +190,7 @@ class ComicVineTalker(ComicTalker):
has_nsfw=False,
has_censored_covers=False,
)
# TODO Remove or leave in for future?
self.settings_options = {
"enabled": SourceSettingsOptions(
name="enabled", text="Enabled", help_text="", hidden=True, type=bool, value=True
@ -247,20 +250,17 @@ class ComicVineTalker(ComicTalker):
self.source_name = self.source_details.id
self.source_name_friendly = self.source_details.name
# Overwrite any source_details.options that have saved settings
source_settings = ComicTaggerSettings.get_source_settings(self.source_name, self.settings_options)
if not source_settings:
# No saved settings, do something?
...
self.wait_for_rate_limit = self.settings_options["wait_on_ratelimit"]["value"]
self.wait_for_rate_limit_time = self.settings_options["ratelimit_waittime"]["value"]
self.wait_for_rate_limit = wait_on_ratelimit
# NOTE: This was hardcoded before which is why it isn't passed in
self.wait_for_rate_limit_time = 20
self.issue_id: int | None = None
self.api_key = self.settings_options["api_key"]["value"]
self.api_base_url = self.settings_options["url_root"]["value"]
self.api_key = api_key if api_key else "27431e6787042105bd3e47e169a624521f89f3a4"
self.api_base_url = api_url if api_url else "https://comicvine.gamespot.com/api"
self.remove_html_tables = remove_html_tables
self.use_series_start_as_volume = use_series_start_as_volume
tmp_url = urlsplit(self.api_base_url)
@ -698,8 +698,8 @@ class ComicVineTalker(ComicTalker):
return talker_utils.map_comic_issue_to_metadata(
f_record,
self.source_name_friendly,
self.settings_options["remove_html_tables"]["value"],
self.settings_options["use_series_start_as_volume"]["value"],
self.remove_html_tables,
self.use_series_start_as_volume,
)
if f_record is not None:
@ -723,8 +723,8 @@ class ComicVineTalker(ComicTalker):
return talker_utils.map_comic_issue_to_metadata(
formatted_issues_result[0],
self.source_name_friendly,
self.settings_options["remove_html_tables"]["value"],
self.settings_options["use_series_start_as_volume"]["value"],
self.remove_html_tables,
self.use_series_start_as_volume,
)
def fetch_issue_data_by_issue_id(self, issue_id: int) -> GenericMetadata:
@ -736,8 +736,8 @@ class ComicVineTalker(ComicTalker):
return talker_utils.map_comic_issue_to_metadata(
cached_issues_result,
self.source_name_friendly,
self.settings_options["remove_html_tables"]["value"],
self.settings_options["use_series_start_as_volume"]["value"],
self.remove_html_tables,
self.use_series_start_as_volume,
)
issue_url = urljoin(self.api_base_url, f"issue/{CVTypeID.Issue}-{issue_id}")
@ -759,8 +759,8 @@ class ComicVineTalker(ComicTalker):
return talker_utils.map_comic_issue_to_metadata(
formatted_issues_result[0],
self.source_name_friendly,
self.settings_options["remove_html_tables"]["value"],
self.settings_options["use_series_start_as_volume"]["value"],
self.remove_html_tables,
self.use_series_start_as_volume,
)
# TODO Why is this required? Was this to get around ii and empty URL?

View File

@ -8,14 +8,14 @@ import testing.comicvine
def test_search_for_series(comicvine_api, comic_cache):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
results = ct.search_for_series("cory doctorows futuristic tales of the here and now")
cache_issues = comic_cache.get_search_results(ct.source_name, "cory doctorows futuristic tales of the here and now")
assert results == cache_issues
def test_fetch_volume_data(comicvine_api, comic_cache):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
result = ct.fetch_partial_volume_data(23437)
del result["description"]
del result["image_url"]
@ -26,7 +26,7 @@ def test_fetch_volume_data(comicvine_api, comic_cache):
def test_fetch_issues_by_volume(comicvine_api, comic_cache):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
results = ct.fetch_issues_by_volume(23437)
cache_issues = comic_cache.get_volume_issues_info(23437, ct.source_name)
for r in results:
@ -46,14 +46,14 @@ def test_fetch_issues_by_volume(comicvine_api, comic_cache):
def test_fetch_issue_data_by_issue_id(comicvine_api, settings, mock_version):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
result = ct.fetch_comic_data(140529)
result.notes = None
assert result == testing.comicvine.cv_md
def test_fetch_issues_by_volume_issue_num_and_year(comicvine_api):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
results = ct.fetch_issues_by_volume_issue_num_and_year([23437], "1", None)
cv_expected = testing.comicvine.comic_issue_result.copy()
testing.comicvine.filter_field_list(
@ -83,7 +83,7 @@ cv_issue = [
@pytest.mark.parametrize("volume_id, issue_number, expected", cv_issue)
def test_fetch_issue_data(comicvine_api, settings, mock_version, volume_id, issue_number, expected):
ct = comictalker.talkers.comicvine.ComicVineTalker()
ct = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
results = ct.fetch_issue_data(volume_id, issue_number)
results.notes = None
assert results == expected

View File

@ -112,7 +112,7 @@ def comicvine_api(monkeypatch, cbz, comic_cache) -> comictalker.talkers.comicvin
# apply the monkeypatch for requests.get to mock_get
monkeypatch.setattr(requests, "get", m_get)
cv = comictalker.talkers.comicvine.ComicVineTalker()
cv = comictalker.talkers.comicvine.ComicVineTalker("", "", 90, False, False, False)
return cv

View File

@ -66,7 +66,6 @@ def test_search(cbz, settings, comicvine_api):
"publisher": testing.comicvine.cv_volume_result["results"]["publisher"]["name"],
"image_url": testing.comicvine.cv_issue_result["results"]["image"]["super_url"],
"thumb_url": testing.comicvine.cv_issue_result["results"]["image"]["thumb_url"],
"page_url": testing.comicvine.cv_issue_result["results"]["site_detail_url"],
"description": testing.comicvine.cv_issue_result["results"]["description"],
}
for r, e in zip(results, [cv_expected]):