Create simple dict of talkers with objects. Moved thresh setting back to talkers (general) as it is called outside of talker.

This commit is contained in:
Mizaki 2023-01-26 00:52:02 +00:00
parent 0d69ba3c49
commit 0f10e6e848
10 changed files with 59 additions and 83 deletions

View File

@ -75,7 +75,7 @@ class AutoTagStartWindow(QtWidgets.QDialog):
self.remove_after_success = False
self.wait_and_retry_on_rate_limit = False
self.search_string = ""
self.name_length_match_tolerance = self.options.comicvine_series_match_search_thresh
self.name_length_match_tolerance = self.options.talkers_series_match_search_thresh
self.split_words = self.cbxSplitWords.isChecked()
def search_string_toggle(self) -> None:

View File

@ -96,7 +96,11 @@ def filename(parser: settngs.Manager) -> None:
def talkers(parser: settngs.Manager) -> None:
# General settings for all information talkers
parser.add_setting("--source", default="comicvine", help="Use a specified source by source ID")
parser.add_setting("--use-series-start-as-volume", default=False, action=argparse.BooleanOptionalAction)
parser.add_setting(
"--series-match-search-thresh",
default=90,
type=int,
)
parser.add_setting(
"--clear-metadata",
default=True,

View File

@ -4,14 +4,14 @@ import logging
import settngs
from comictalker.comictalkerapi import TalkerPlugin
from comictalker.talkerbase import ComicTalker
logger = logging.getLogger(__name__)
def register_talker_settings(parser: settngs.Manager, plugins: dict[str, TalkerPlugin]) -> None:
def register_talker_settings(parser: settngs.Manager, plugins: dict[str, ComicTalker]) -> None:
for talker_name, talker in plugins.items():
try:
parser.add_group(talker_name, talker["cls"].comic_settings, False)
parser.add_group(talker_name, talker.comic_settings, False)
except Exception:
logger.exception("Failed to register settings for %s", talker_name)

View File

@ -21,6 +21,7 @@ import logging.handlers
import platform
import signal
import sys
from typing import Any
import settngs
@ -29,7 +30,6 @@ from comicapi import utils
from comictaggerlib import cli, ctoptions
from comictaggerlib.ctversion import version
from comictaggerlib.log import setup_logging
from comictalker.talkerbase import TalkerError
if sys.version_info < (3, 10):
import importlib_metadata
@ -66,14 +66,14 @@ class App:
self.options = settngs.Config({}, {})
self.initial_arg_parser = ctoptions.initial_cmd_line_parser()
self.config_load_success = False
# First get a list of classes
self.talker_plugins = ct_api.get_talkers()
self.talker_plugins: dict[str, Any] = {}
def run(self) -> None:
opts = self.initialize()
self.initialize_dirs(opts.config)
self.talker_plugins = ct_api.get_talkers(version, opts.config.user_cache_dir)
self.register_options()
self.parse_options(opts.config)
self.initialize_dirs()
self.initialize_talkers()
self.main()
@ -103,28 +103,27 @@ class App:
self.options = ctoptions.validate_settings(self.options, self.manager)
self.options = self.options
def initialize_dirs(self) -> None:
self.options[0].runtime_config.user_data_dir.mkdir(parents=True, exist_ok=True)
self.options[0].runtime_config.user_config_dir.mkdir(parents=True, exist_ok=True)
self.options[0].runtime_config.user_cache_dir.mkdir(parents=True, exist_ok=True)
self.options[0].runtime_config.user_state_dir.mkdir(parents=True, exist_ok=True)
self.options[0].runtime_config.user_log_dir.mkdir(parents=True, exist_ok=True)
logger.debug("user_data_dir: %s", self.options[0].runtime_config.user_data_dir)
logger.debug("user_config_dir: %s", self.options[0].runtime_config.user_config_dir)
logger.debug("user_cache_dir: %s", self.options[0].runtime_config.user_cache_dir)
logger.debug("user_state_dir: %s", self.options[0].runtime_config.user_state_dir)
logger.debug("user_log_dir: %s", self.options[0].runtime_config.user_log_dir)
def initialize_dirs(self, paths: ctoptions.ComicTaggerPaths) -> None:
paths.user_data_dir.mkdir(parents=True, exist_ok=True)
paths.user_config_dir.mkdir(parents=True, exist_ok=True)
paths.user_cache_dir.mkdir(parents=True, exist_ok=True)
paths.user_state_dir.mkdir(parents=True, exist_ok=True)
paths.user_log_dir.mkdir(parents=True, exist_ok=True)
logger.debug("user_data_dir: %s", paths.user_data_dir)
logger.debug("user_config_dir: %s", paths.user_config_dir)
logger.debug("user_cache_dir: %s", paths.user_cache_dir)
logger.debug("user_state_dir: %s", paths.user_state_dir)
logger.debug("user_log_dir: %s", paths.user_log_dir)
def initialize_talkers(self) -> None:
# Apply talker settings from config file
try:
self.talker_plugins = ct_api.get_talker_objects(
version=version,
cache_folder=self.options[0].runtime_config.user_cache_dir,
settings=self.options[0],
plugins=self.talker_plugins,
)
except Exception:
logger.exception("Failed to initialize talkers. See log for full details.")
for talker_name, talker in self.talker_plugins.items():
ct_api.set_talker_settings(talker, self.options[0])
except Exception as e:
# Remove talker as we failed to apply the settings
del self.talker_plugins[e.source] # type: ignore[attr-defined]
logger.exception("Failed to initialize talker settings. Error %s", str(e))
def main(self) -> None:
assert self.options is not None
@ -154,10 +153,12 @@ class App:
# TODO Have option to save passed in config options and quit?
try:
talker_api = self.talker_plugins[self.options[0].talkers_source]["obj"]
except TalkerError as e:
talker_api = self.talker_plugins[self.options[0].talkers_source]
except Exception as e:
logger.exception(f"Unable to load talker {self.options[0].talkers_source}. Error: {str(e)}")
error = (str(e), True)
talker_api = None
# TODO error True can be changed to False after the talker settings menu generation is in
error = (f"Unable to load talker {self.options[0].talkers_source}. Error: {str(e)}", True)
if not self.config_load_success:
error = (

View File

@ -328,7 +328,7 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
def perform_query(self, refresh: bool = False) -> None:
self.search_thread = SearchThread(
self.talker_api, self.series_name, refresh, self.literal, self.options.comicvine_series_match_search_thresh
self.talker_api, self.series_name, refresh, self.literal, self.options.talkers_series_match_search_thresh
)
self.search_thread.searchComplete.connect(self.search_complete)
self.search_thread.progressUpdate.connect(self.search_progress_update)

View File

@ -271,7 +271,7 @@ class SettingsWindow(QtWidgets.QDialog):
# Copy values from settings to form
self.leRarExePath.setText(self.options[0].general_rar_exe_path)
self.sbNameMatchIdentifyThresh.setValue(self.options[0].identifier_series_match_identify_thresh)
self.sbNameMatchSearchThresh.setValue(self.options[0].comicvine_series_match_search_thresh)
self.sbNameMatchSearchThresh.setValue(self.options[0].talkers_series_match_search_thresh)
self.tePublisherFilter.setPlainText("\n".join(self.options[0].identifier_publisher_filter))
self.cbxCheckForNewVersion.setChecked(self.options[0].general_check_for_new_version)
@ -386,7 +386,7 @@ class SettingsWindow(QtWidgets.QDialog):
self.options[0].general_check_for_new_version = self.cbxCheckForNewVersion.isChecked()
self.options[0].identifier_series_match_identify_thresh = self.sbNameMatchIdentifyThresh.value()
self.options[0].comicvine_series_match_search_thresh = self.sbNameMatchSearchThresh.value()
self.options[0].talkers_series_match_search_thresh = self.sbNameMatchSearchThresh.value()
self.options[0].identifier_publisher_filter = [
x.strip() for x in str(self.tePublisherFilter.toPlainText()).splitlines() if x.strip()
]

View File

@ -15,9 +15,10 @@
# limitations under the License.
from __future__ import annotations
import argparse
import logging
import pathlib
from typing import Any, TypedDict
from typing import Any
import comictalker.talkers.comicvine
from comictalker.talkerbase import ComicTalker, TalkerError
@ -25,37 +26,25 @@ from comictalker.talkerbase import ComicTalker, TalkerError
logger = logging.getLogger(__name__)
class TalkerPlugin(TypedDict, total=False):
cls: type[ComicTalker]
obj: ComicTalker
def set_talker_settings(talker, settings) -> None:
def set_talker_settings(talker: ComicTalker, settings: argparse.Namespace) -> None:
try:
talker.set_settings(settings)
except Exception as e:
logger.exception(
f"Failed to set talker settings for {talker.talker_id}, will use defaults. Error: {str(e)}",
f"Failed to set talker settings for {talker.source_details.name}, will use defaults. Error: {str(e)}",
)
raise TalkerError(source=talker.talker_id, code=4, desc="Could not apply talker settings, will use defaults")
raise TalkerError(source=talker.source_details.name, code=4, desc="Could not apply talker settings")
def get_talker_objects(
version: str, cache_folder: pathlib.Path, settings: dict[str, Any], plugins: dict[str, TalkerPlugin]
) -> dict[str, TalkerPlugin]:
for talker_name, talker in plugins.items():
def get_talkers(version: str, cache: pathlib.Path) -> dict[str, Any]:
"""Returns all comic talker instances"""
# TODO separate PR will bring talkers in via entry points. TalkerError etc. source will then be a var
talkers = {}
for talker in [comictalker.talkers.comicvine.ComicVineTalker]:
try:
obj = talker["cls"](version, cache_folder)
plugins[talker_name]["obj"] = obj
obj = talker(version, cache)
talkers[obj.source_details.id] = obj
except Exception:
logger.exception("Failed to create talker object")
raise TalkerError(source=talker_name, code=4, desc="Failed to initialise talker object")
# Run outside of try block so as to keep except separate
set_talker_settings(plugins[talker_name]["obj"], settings)
return plugins
def get_talkers() -> dict[str, TalkerPlugin]:
"""Returns all comic talker modules NOT objects"""
return {"comicvine": TalkerPlugin(cls=comictalker.talkers.comicvine.ComicVineTalker)}
logger.exception("Failed to load talker: %s", "comicvine")
raise TalkerError(source="comicvine", code=4, desc="Failed to initialise talker")
return talkers

View File

@ -139,8 +139,6 @@ class TalkerDataError(TalkerError):
class ComicTalker:
"""The base class for all comic source talkers"""
talker_id = ""
def __init__(self, version: str, cache_folder: pathlib.Path) -> None:
# Identity name for the information source etc.
self.source_details = SourceDetails()
@ -150,8 +148,7 @@ class ComicTalker:
self.api_key: str = ""
self.api_url: str = ""
@classmethod
def comic_settings(cls, parser: settngs.Manager) -> None:
def comic_settings(self, parser: settngs.Manager) -> None:
"""Talker settings."""
def set_settings(self, settings: argparse.Namespace) -> None:

View File

@ -154,15 +154,13 @@ CV_RATE_LIMIT_STATUS = 107
class ComicVineTalker(ComicTalker):
talker_id = "comicvine"
def __init__(
self,
version: str,
cache_folder: pathlib.Path,
):
super().__init__(version, cache_folder)
self.source_details = SourceDetails(name="Comic Vine", ident=ComicVineTalker.talker_id)
self.source_details = SourceDetails(name="Comic Vine", ident="comicvine")
self.static_options = SourceStaticOptions(
website="https://comicvine.gamespot.com/",
has_issues=True,
@ -194,17 +192,9 @@ class ComicVineTalker(ComicTalker):
# NOTE: This was hardcoded before which is why it isn't in settings
self.wait_for_rate_limit_time: int = 20
@classmethod
def comic_settings(cls, parser: settngs.Manager) -> None:
# Might be general settings?
parser.add_setting(
"--series-match-search-thresh",
default=90,
type=int,
)
def comic_settings(self, parser: settngs.Manager) -> None:
"""Register settings"""
parser.add_setting("--cv-use-series-start-as-volume", default=False, action=argparse.BooleanOptionalAction)
# Comic Vine settings
parser.add_setting("--cv-wait-on-ratelimit", default=False, action=argparse.BooleanOptionalAction)
parser.add_setting(
"--cv-remove-html-tables",
@ -238,7 +228,7 @@ class ComicVineTalker(ComicTalker):
self.api_url = tmp_url.geturl()
except Exception:
logger.exception("Failed to parse new talker URL for %s, will use default", self.talker_id)
logger.exception("Failed to parse new talker URL for %s, will use default", self.source_name)
def check_api_key(self, key: str, url: str) -> bool:
if not url:

View File

@ -157,16 +157,11 @@ def seed_all_publishers(monkeypatch):
monkeypatch.setattr(utils, "publishers", publisher_seed)
def get_plugins() -> dict:
return comictalker.comictalkerapi.get_talkers()
@pytest.fixture
def options(settings_manager, tmp_path):
comictaggerlib.ctoptions.register_commandline(settings_manager)
comictaggerlib.ctoptions.register_settings(settings_manager)
comictaggerlib.ctoptions.register_talker_settings(settings_manager, get_plugins())
defaults = settings_manager.get_namespace(settings_manager.defaults())
defaults[0].runtime_config = comictaggerlib.ctoptions.ComicTaggerPaths(tmp_path / "config")
defaults[0].runtime_config.user_data_dir.mkdir(parents=True, exist_ok=True)