diff --git a/comictaggerlib/cli.py b/comictaggerlib/cli.py index f146a68..3a13e2c 100644 --- a/comictaggerlib/cli.py +++ b/comictaggerlib/cli.py @@ -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: diff --git a/comictaggerlib/issueidentifier.py b/comictaggerlib/issueidentifier.py index 136309f..bd6736d 100644 --- a/comictaggerlib/issueidentifier.py +++ b/comictaggerlib/issueidentifier.py @@ -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!") diff --git a/comictaggerlib/main.py b/comictaggerlib/main.py index 8c0f230..f82a3dd 100755 --- a/comictaggerlib/main.py +++ b/comictaggerlib/main.py @@ -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() diff --git a/comictaggerlib/settings.py b/comictaggerlib/settings.py index 9cdc949..2bb0e36 100644 --- a/comictaggerlib/settings.py +++ b/comictaggerlib/settings.py @@ -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) diff --git a/comictaggerlib/settingswindow.py b/comictaggerlib/settingswindow.py index ba19065..7cdfa09 100644 --- a/comictaggerlib/settingswindow.py +++ b/comictaggerlib/settingswindow.py @@ -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() diff --git a/comictaggerlib/taggerwindow.py b/comictaggerlib/taggerwindow.py index 9bc0fd1..fd60e9b 100644 --- a/comictaggerlib/taggerwindow.py +++ b/comictaggerlib/taggerwindow.py @@ -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() diff --git a/comictaggerlib/ui/autotagstartwindow.ui b/comictaggerlib/ui/autotagstartwindow.ui index 3a30a76..dcf341d 100644 --- a/comictaggerlib/ui/autotagstartwindow.ui +++ b/comictaggerlib/ui/autotagstartwindow.ui @@ -10,7 +10,7 @@ 0 0 519 - 452 + 440 @@ -44,7 +44,30 @@ - + + + + Checks the publisher against a list of imprints. + + + Auto Imprint + + + + + + + + 0 + 0 + + + + Specify series search string for all selected archives: + + + + @@ -57,74 +80,6 @@ - - - - - 0 - 0 - - - - Don't use publication year in identification process - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Split words in filenames (e.g. 'judgedredd' to 'judge dredd') (Experimental) - - - - - - - - 60 - 16777215 - - - - % - - - 1 - - - 100 - - - - - - - - 0 - 0 - - - - Adjust Name Match Ratio Threshold: Auto-Identify - - - @@ -138,13 +93,52 @@ - - - - Removes existing metadata before applying retrieved metadata + + + + + 0 + 0 + + + + + + + + + 0 + 0 + - Overwrite metadata + Adjust Name Match Ratio Threshold: Auto-Identify + + + + + + + + 0 + 0 + + + + Split words in filenames (e.g. 'judgedredd' to 'judge dredd') (Experimental) + + + + + + + + 0 + 0 + + + + Don't use publication year in identification process @@ -161,7 +155,17 @@ - + + + + Removes existing metadata before applying retrieved metadata + + + Overwrite metadata + + + + @@ -174,26 +178,29 @@ - - - - Checks the publisher against a list of imprints. - + + - Auto Imprint + Wait and retry when Comic Vine rate limit is exceeded (experimental) - - - - - 0 - 0 - + + + + + 60 + 16777215 + - - Specify series search string for all selected archives: + + % + + + 1 + + + 100 diff --git a/comictaggerlib/ui/settingswindow.ui b/comictaggerlib/ui/settingswindow.ui index 2753b6f..418bf4c 100644 --- a/comictaggerlib/ui/settingswindow.ui +++ b/comictaggerlib/ui/settingswindow.ui @@ -28,7 +28,7 @@ - 4 + 0 @@ -308,56 +308,53 @@ - + - Comic Sources + Comic Vine - - - 0 + + + + 0 + 0 + - - - General - - - - - 0 - 0 - 641 - 341 - - + + - - 6 - - - 6 - - - 6 - - - 6 - - + - Select Information Source: + Use Series Start Date as Volume - - - - Clear Form Before Importing Comic Data + Clear Form Before Importing Comic Vine data + + + + + + + Remove HTML tables from CV summary field + + + + + + + + 0 + 0 + + + + Qt::Horizontal @@ -375,24 +372,132 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>A personal API key from <a href="http://www.comicvine.com/api/"><span style=" text-decoration: underline; color:#0000ff;">Comic Vine</span></a> is recommended in order to search for tag data. Login (or create a new account) there to get your key, and enter it below.</p></body></html> + + + Qt::RichText + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse + + + + + + + Test Key + + + + + + + + 0 + 0 + + + + false + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 200 + 16777215 + + + + Comic Vine API Key + + + + + + + Comic Vine URL + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -403,7 +508,7 @@ - Apply CBL Transforms on Comic Import + Apply CBL Transforms on ComicVine Import @@ -431,7 +536,7 @@ 11 21 251 - 206 + 199 @@ -757,8 +862,8 @@ By default only removes restricted characters and filenames for the current Oper accept() - 258 - 477 + 248 + 254 157 @@ -773,8 +878,8 @@ By default only removes restricted characters and filenames for the current Oper reject() - 326 - 477 + 316 + 260 286 diff --git a/comictaggerlib/volumeselectionwindow.py b/comictaggerlib/volumeselectionwindow.py index ffc8a27..f4bcd9a 100644 --- a/comictaggerlib/volumeselectionwindow.py +++ b/comictaggerlib/volumeselectionwindow.py @@ -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: diff --git a/comictalker/talkers/comicvine.py b/comictalker/talkers/comicvine.py index 05ba0c6..bffbd04 100644 --- a/comictalker/talkers/comicvine.py +++ b/comictalker/talkers/comicvine.py @@ -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? diff --git a/tests/comicvinetalker_test.py b/tests/comicvinetalker_test.py index a6bb400..ae8372f 100644 --- a/tests/comicvinetalker_test.py +++ b/tests/comicvinetalker_test.py @@ -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 diff --git a/tests/conftest.py b/tests/conftest.py index f4008e7..7cccda8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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 diff --git a/tests/issueidentifier_test.py b/tests/issueidentifier_test.py index 7f03c9b..a4e3498 100644 --- a/tests/issueidentifier_test.py +++ b/tests/issueidentifier_test.py @@ -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]):