Rename talkers_general to talkers. Moved plugin option register to own file. Due to chicken and egg, first get talker classes then create objects.
This commit is contained in:
parent
100e0f2101
commit
0d69ba3c49
@ -49,7 +49,7 @@ class AutoTagStartWindow(QtWidgets.QDialog):
|
||||
self.cbxIgnoreLeadingDigitsInFilename.setChecked(self.options.autotag_ignore_leading_numbers_in_filename)
|
||||
self.cbxRemoveAfterSuccess.setChecked(self.options.autotag_remove_archive_after_successful_match)
|
||||
self.cbxWaitForRateLimit.setChecked(self.options.autotag_wait_and_retry_on_rate_limit)
|
||||
self.cbxAutoImprint.setChecked(self.options.talkers_general_auto_imprint)
|
||||
self.cbxAutoImprint.setChecked(self.options.talkers_auto_imprint)
|
||||
|
||||
nlmt_tip = """<html>The <b>Name Match Ratio Threshold: Auto-Identify</b> is for eliminating automatic
|
||||
search matches that are too long compared to your series name search. The lower
|
||||
|
@ -108,7 +108,7 @@ class CLI:
|
||||
ca = match_set.ca
|
||||
md = self.create_local_metadata(ca)
|
||||
ct_md = self.actual_issue_data_fetch(match_set.matches[int(i) - 1]["issue_id"])
|
||||
if self.options.talkers_general_clear_metadata_on_import:
|
||||
if self.options.talkers_clear_metadata_on_import:
|
||||
md = ct_md
|
||||
else:
|
||||
notes = (
|
||||
@ -117,7 +117,7 @@ class CLI:
|
||||
)
|
||||
md.overlay(ct_md.replace(notes=utils.combine_notes(md.notes, notes, "Tagged with ComicTagger")))
|
||||
|
||||
if self.options.talkers_general_auto_imprint:
|
||||
if self.options.talkers_auto_imprint:
|
||||
md.fix_publisher()
|
||||
|
||||
self.actual_metadata_save(ca, md)
|
||||
@ -428,7 +428,7 @@ class CLI:
|
||||
match_results.fetch_data_failures.append(str(ca.path.absolute()))
|
||||
return
|
||||
|
||||
if self.options.talkers_general_clear_metadata_on_import:
|
||||
if self.options.talkers_clear_metadata_on_import:
|
||||
md = ct_md
|
||||
else:
|
||||
notes = (
|
||||
@ -437,7 +437,7 @@ class CLI:
|
||||
)
|
||||
md.overlay(ct_md.replace(notes=utils.combine_notes(md.notes, notes, "Tagged with ComicTagger")))
|
||||
|
||||
if self.options.talkers_general_auto_imprint:
|
||||
if self.options.talkers_auto_imprint:
|
||||
md.fix_publisher()
|
||||
|
||||
# ok, done building our metadata. time to save
|
||||
|
@ -2,12 +2,14 @@ from __future__ import annotations
|
||||
|
||||
from comictaggerlib.ctoptions.cmdline import initial_cmd_line_parser, register_commandline, validate_commandline_options
|
||||
from comictaggerlib.ctoptions.file import register_settings, validate_settings
|
||||
from comictaggerlib.ctoptions.talker_plugins import register_talker_settings
|
||||
from comictaggerlib.ctoptions.types import ComicTaggerPaths
|
||||
|
||||
__all__ = [
|
||||
"initial_cmd_line_parser",
|
||||
"register_commandline",
|
||||
"register_settings",
|
||||
"register_talker_settings",
|
||||
"validate_commandline_options",
|
||||
"validate_settings",
|
||||
"ComicTaggerPaths",
|
||||
|
@ -93,7 +93,7 @@ def filename(parser: settngs.Manager) -> None:
|
||||
)
|
||||
|
||||
|
||||
def talkers_general(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)
|
||||
@ -239,17 +239,13 @@ def validate_settings(options: settngs.Config[settngs.Values], parser: settngs.M
|
||||
return options
|
||||
|
||||
|
||||
def register_settings(parser: settngs.Manager, talkers: dict[str, Any]) -> None:
|
||||
def register_settings(parser: settngs.Manager) -> None:
|
||||
parser.add_group("general", general, False)
|
||||
parser.add_group("internal", internal, False)
|
||||
parser.add_group("identifier", identifier, False)
|
||||
parser.add_group("dialog", dialog, False)
|
||||
parser.add_group("filename", filename, False)
|
||||
parser.add_group("talkers_general", talkers_general, False)
|
||||
parser.add_group("talkers", talkers, False)
|
||||
parser.add_group("cbl", cbl, False)
|
||||
parser.add_group("rename", rename, False)
|
||||
parser.add_group("autotag", autotag, False)
|
||||
|
||||
# Register talker plugin settings
|
||||
for talker, cls in talkers.items():
|
||||
parser.add_group(talker, cls.comic_settings, False)
|
||||
|
17
comictaggerlib/ctoptions/talker_plugins.py
Normal file
17
comictaggerlib/ctoptions/talker_plugins.py
Normal file
@ -0,0 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import settngs
|
||||
|
||||
from comictalker.comictalkerapi import TalkerPlugin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register_talker_settings(parser: settngs.Manager, plugins: dict[str, TalkerPlugin]) -> None:
|
||||
for talker_name, talker in plugins.items():
|
||||
try:
|
||||
parser.add_group(talker_name, talker["cls"].comic_settings, False)
|
||||
except Exception:
|
||||
logger.exception("Failed to register settings for %s", talker_name)
|
@ -66,6 +66,7 @@ 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()
|
||||
|
||||
def run(self) -> None:
|
||||
@ -73,6 +74,7 @@ class App:
|
||||
self.register_options()
|
||||
self.parse_options(opts.config)
|
||||
self.initialize_dirs()
|
||||
self.initialize_talkers()
|
||||
|
||||
self.main()
|
||||
|
||||
@ -88,7 +90,8 @@ class App:
|
||||
"For more help visit the wiki at: https://github.com/comictagger/comictagger/wiki",
|
||||
)
|
||||
ctoptions.register_commandline(self.manager)
|
||||
ctoptions.register_settings(self.manager, self.talker_plugins)
|
||||
ctoptions.register_settings(self.manager)
|
||||
ctoptions.register_talker_settings(self.manager, self.talker_plugins)
|
||||
|
||||
def parse_options(self, config_paths: ctoptions.ComicTaggerPaths) -> None:
|
||||
self.options, self.config_load_success = self.manager.parse_config(
|
||||
@ -100,18 +103,6 @@ class App:
|
||||
self.options = ctoptions.validate_settings(self.options, self.manager)
|
||||
self.options = self.options
|
||||
|
||||
# parse talker settings
|
||||
for loaded in self.talker_plugins.values():
|
||||
parse_options = getattr(loaded, "parse_settings", None)
|
||||
if parse_options is None:
|
||||
logger.warning(f"Failed to find parse_settings in talker {loaded}")
|
||||
continue
|
||||
|
||||
try:
|
||||
parse_options(self.options)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to parse talker options for {loaded}: {e}")
|
||||
|
||||
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)
|
||||
@ -124,6 +115,17 @@ class App:
|
||||
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_talkers(self) -> None:
|
||||
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.")
|
||||
|
||||
def main(self) -> None:
|
||||
assert self.options is not None
|
||||
# options already loaded
|
||||
@ -152,12 +154,9 @@ class App:
|
||||
# TODO Have option to save passed in config options and quit?
|
||||
|
||||
try:
|
||||
talker_api = ct_api.get_comic_talker(self.options[0].talkers_general_source)( # type: ignore[call-arg]
|
||||
version=version,
|
||||
cache_folder=self.options[0].runtime_config.user_cache_dir,
|
||||
)
|
||||
talker_api = self.talker_plugins[self.options[0].talkers_source]["obj"]
|
||||
except TalkerError as e:
|
||||
logger.exception("Unable to load talker")
|
||||
logger.exception(f"Unable to load talker {self.options[0].talkers_source}. Error: {str(e)}")
|
||||
error = (str(e), True)
|
||||
|
||||
if not self.config_load_success:
|
||||
|
@ -156,7 +156,7 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
self.progdialog: QtWidgets.QProgressDialog | None = None
|
||||
self.search_thread: SearchThread | None = None
|
||||
|
||||
self.use_filter = self.options.talkers_general_always_use_publisher_filter
|
||||
self.use_filter = self.options.talkers_always_use_publisher_filter
|
||||
|
||||
# Load to retrieve settings
|
||||
self.talker_api = talker_api
|
||||
@ -395,7 +395,7 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
# compare as str in case extra chars ie. '1976?'
|
||||
# - missing (none) values being converted to 'None' - consistent with prior behaviour in v1.2.3
|
||||
# sort by start_year if set
|
||||
if self.options.talkers_general_sort_series_by_year:
|
||||
if self.options.talkers_sort_series_by_year:
|
||||
try:
|
||||
self.ct_search_results = sorted(
|
||||
self.ct_search_results,
|
||||
@ -413,7 +413,7 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
logger.exception("bad data error sorting results by count_of_issues")
|
||||
|
||||
# move sanitized matches to the front
|
||||
if self.options.talkers_general_exact_series_matches_first:
|
||||
if self.options.talkers_exact_series_matches_first:
|
||||
try:
|
||||
sanitized = utils.sanitize_title(self.series_name, False).casefold()
|
||||
sanitized_no_articles = utils.sanitize_title(self.series_name, True).casefold()
|
||||
|
@ -283,12 +283,12 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
self.switch_parser()
|
||||
|
||||
self.cbxUseSeriesStartAsVolume.setChecked(self.options[0].comicvine_cv_use_series_start_as_volume)
|
||||
self.cbxClearFormBeforePopulating.setChecked(self.options[0].talkers_general_clear_form_before_populating)
|
||||
self.cbxClearFormBeforePopulating.setChecked(self.options[0].talkers_clear_form_before_populating)
|
||||
self.cbxRemoveHtmlTables.setChecked(self.options[0].comicvine_cv_remove_html_tables)
|
||||
|
||||
self.cbxUseFilter.setChecked(self.options[0].talkers_general_always_use_publisher_filter)
|
||||
self.cbxSortByYear.setChecked(self.options[0].talkers_general_sort_series_by_year)
|
||||
self.cbxExactMatches.setChecked(self.options[0].talkers_general_exact_series_matches_first)
|
||||
self.cbxUseFilter.setChecked(self.options[0].talkers_always_use_publisher_filter)
|
||||
self.cbxSortByYear.setChecked(self.options[0].talkers_sort_series_by_year)
|
||||
self.cbxExactMatches.setChecked(self.options[0].talkers_exact_series_matches_first)
|
||||
|
||||
self.leKey.setText(self.options[0].comicvine_cv_api_key)
|
||||
self.leURL.setText(self.options[0].comicvine_cv_url)
|
||||
@ -397,12 +397,12 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
self.options[0].filename_remove_publisher = self.cbxRemovePublisher.isChecked()
|
||||
|
||||
self.options[0].comicvine_cv_use_series_start_as_volume = self.cbxUseSeriesStartAsVolume.isChecked()
|
||||
self.options[0].talkers_general_clear_form_before_populating = self.cbxClearFormBeforePopulating.isChecked()
|
||||
self.options[0].talkers_clear_form_before_populating = self.cbxClearFormBeforePopulating.isChecked()
|
||||
self.options[0].comicvine_cv_remove_html_tables = self.cbxRemoveHtmlTables.isChecked()
|
||||
|
||||
self.options[0].talkers_general_always_use_publisher_filter = self.cbxUseFilter.isChecked()
|
||||
self.options[0].talkers_general_sort_series_by_year = self.cbxSortByYear.isChecked()
|
||||
self.options[0].talkers_general_exact_series_matches_first = self.cbxExactMatches.isChecked()
|
||||
self.options[0].talkers_always_use_publisher_filter = self.cbxUseFilter.isChecked()
|
||||
self.options[0].talkers_sort_series_by_year = self.cbxSortByYear.isChecked()
|
||||
self.options[0].talkers_exact_series_matches_first = self.cbxExactMatches.isChecked()
|
||||
|
||||
if self.leKey.text().strip():
|
||||
self.options[0].comicvine_cv_api_key = self.leKey.text().strip()
|
||||
|
@ -1084,7 +1084,7 @@ Have fun!
|
||||
if self.options[0].cbl_apply_transform_on_import:
|
||||
new_metadata = CBLTransformer(new_metadata, self.options[0]).apply()
|
||||
|
||||
if self.options[0].talkers_general_clear_form_before_populating:
|
||||
if self.options[0].talkers_clear_form_before_populating:
|
||||
self.clear_form()
|
||||
|
||||
notes = (
|
||||
@ -1802,7 +1802,7 @@ Have fun!
|
||||
)
|
||||
md.overlay(ct_md.replace(notes=utils.combine_notes(md.notes, notes, "Tagged with ComicTagger")))
|
||||
|
||||
if self.options[0].talkers_general_auto_imprint:
|
||||
if self.options[0].talkers_auto_imprint:
|
||||
md.fix_publisher()
|
||||
|
||||
if not ca.write_metadata(md, self.save_data_style):
|
||||
|
@ -16,6 +16,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from typing import Any, TypedDict
|
||||
|
||||
import comictalker.talkers.comicvine
|
||||
from comictalker.talkerbase import ComicTalker, TalkerError
|
||||
@ -23,16 +25,37 @@ from comictalker.talkerbase import ComicTalker, TalkerError
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_comic_talker(source_name: str) -> type[ComicTalker]:
|
||||
"""Retrieve the available sources modules"""
|
||||
sources = get_talkers()
|
||||
if source_name not in sources:
|
||||
raise TalkerError(source=source_name, code=4, desc="The talker does not exist")
|
||||
|
||||
talker = sources[source_name]
|
||||
return talker
|
||||
class TalkerPlugin(TypedDict, total=False):
|
||||
cls: type[ComicTalker]
|
||||
obj: ComicTalker
|
||||
|
||||
|
||||
def get_talkers() -> dict[str, type[ComicTalker]]:
|
||||
def set_talker_settings(talker, settings) -> 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)}",
|
||||
)
|
||||
raise TalkerError(source=talker.talker_id, code=4, desc="Could not apply talker settings, will use defaults")
|
||||
|
||||
|
||||
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():
|
||||
try:
|
||||
obj = talker["cls"](version, cache_folder)
|
||||
plugins[talker_name]["obj"] = 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": comictalker.talkers.comicvine.ComicVineTalker}
|
||||
return {"comicvine": TalkerPlugin(cls=comictalker.talkers.comicvine.ComicVineTalker)}
|
||||
|
@ -139,27 +139,23 @@ class TalkerDataError(TalkerError):
|
||||
class ComicTalker:
|
||||
"""The base class for all comic source talkers"""
|
||||
|
||||
default_api_url: str = ""
|
||||
default_api_key: str = ""
|
||||
talker_id = ""
|
||||
|
||||
def __init__(self, version: str, cache_folder: pathlib.Path, api_url: str = "", api_key: str = "") -> None:
|
||||
def __init__(self, version: str, cache_folder: pathlib.Path) -> None:
|
||||
# Identity name for the information source etc.
|
||||
self.source_details = SourceDetails()
|
||||
self.static_options = SourceStaticOptions()
|
||||
self.api_key = api_key
|
||||
self.cache_folder = cache_folder
|
||||
self.version = version
|
||||
|
||||
self.api_key = ""
|
||||
self.api_url = ""
|
||||
self.api_key: str = ""
|
||||
self.api_url: str = ""
|
||||
|
||||
@classmethod
|
||||
def comic_settings(cls, parser: settngs.Manager) -> None:
|
||||
"""Talker settings."""
|
||||
|
||||
@classmethod
|
||||
def parse_settings(cls, settings: argparse.Namespace) -> None:
|
||||
"""Parse settings."""
|
||||
def set_settings(self, settings: argparse.Namespace) -> None:
|
||||
"""Apply talker settings from config to object."""
|
||||
|
||||
def check_api_key(self, key: str, url: str) -> bool:
|
||||
"""
|
||||
|
@ -154,16 +154,7 @@ CV_RATE_LIMIT_STATUS = 107
|
||||
|
||||
|
||||
class ComicVineTalker(ComicTalker):
|
||||
default_api_key = "27431e6787042105bd3e47e169a624521f89f3a4"
|
||||
default_api_url = "https://comicvine.gamespot.com/api"
|
||||
|
||||
# Settings
|
||||
api_url: str = ""
|
||||
api_key: str = ""
|
||||
series_match_thresh: int = 90
|
||||
remove_html_tables: bool = False
|
||||
use_series_start_as_volume: bool = False
|
||||
wait_on_ratelimit: bool = False
|
||||
talker_id = "comicvine"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -171,7 +162,7 @@ class ComicVineTalker(ComicTalker):
|
||||
cache_folder: pathlib.Path,
|
||||
):
|
||||
super().__init__(version, cache_folder)
|
||||
self.source_details = SourceDetails(name="Comic Vine", ident="comicvine")
|
||||
self.source_details = SourceDetails(name="Comic Vine", ident=ComicVineTalker.talker_id)
|
||||
self.static_options = SourceStaticOptions(
|
||||
website="https://comicvine.gamespot.com/",
|
||||
has_issues=True,
|
||||
@ -180,15 +171,18 @@ class ComicVineTalker(ComicTalker):
|
||||
has_nsfw=False,
|
||||
has_censored_covers=False,
|
||||
)
|
||||
# Default settings
|
||||
self.api_url: str = "https://comicvine.gamespot.com/api"
|
||||
self.api_key: str = "27431e6787042105bd3e47e169a624521f89f3a4"
|
||||
self.series_match_thresh: int = 90
|
||||
self.remove_html_tables: bool = False
|
||||
self.use_series_start_as_volume: bool = False
|
||||
self.wait_for_rate_limit: bool = False
|
||||
|
||||
# Identity name for the information source
|
||||
self.source_name: str = self.source_details.id
|
||||
self.source_name_friendly: str = self.source_details.name
|
||||
|
||||
# If cls api_url or api_key is empty, use default
|
||||
self.api_url = ComicVineTalker.api_url or ComicVineTalker.default_api_url
|
||||
self.api_key = ComicVineTalker.api_key or ComicVineTalker.default_api_key
|
||||
|
||||
tmp_url = urlsplit(self.api_url)
|
||||
|
||||
# joinurl only works properly if there is a trailing slash
|
||||
@ -197,15 +191,9 @@ class ComicVineTalker(ComicTalker):
|
||||
|
||||
self.api_url = tmp_url.geturl()
|
||||
|
||||
self.wait_for_rate_limit: bool = ComicVineTalker.wait_on_ratelimit
|
||||
# NOTE: This was hardcoded before which is why it isn't passed in
|
||||
# NOTE: This was hardcoded before which is why it isn't in settings
|
||||
self.wait_for_rate_limit_time: int = 20
|
||||
|
||||
self.remove_html_tables: bool = ComicVineTalker.remove_html_tables
|
||||
self.use_series_start_as_volume: bool = ComicVineTalker.use_series_start_as_volume
|
||||
|
||||
self.series_match_thresh: int = ComicVineTalker.series_match_thresh
|
||||
|
||||
@classmethod
|
||||
def comic_settings(cls, parser: settngs.Manager) -> None:
|
||||
# Might be general settings?
|
||||
@ -233,17 +221,24 @@ class ComicVineTalker(ComicTalker):
|
||||
help="Use the given Comic Vine URL.",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def parse_settings(cls, settings: settngs.Config) -> None:
|
||||
"""Parse settings."""
|
||||
if settings[0].comicvine_cv_remove_html_tables:
|
||||
cls.remove_html_tables = bool(settings[0].comicvine_cv_remove_html_tables)
|
||||
if settings[0].comicvine_cv_use_series_start_as_volume:
|
||||
cls.use_series_start_as_volume = settings[0].comicvine_cv_use_series_start_as_volume
|
||||
if settings[0].comicvine_cv_api_key:
|
||||
cls.api_key = settings[0].comicvine_cv_api_key
|
||||
if settings[0].comicvine_cv_url:
|
||||
cls.api_url = settings[0].comicvine_cv_url
|
||||
def set_settings(self, settings: argparse.Namespace) -> None:
|
||||
"""Set settings."""
|
||||
if settings.comicvine_cv_remove_html_tables:
|
||||
self.remove_html_tables = bool(settings.comicvine_cv_remove_html_tables)
|
||||
if settings.comicvine_cv_use_series_start_as_volume:
|
||||
self.use_series_start_as_volume = settings.comicvine_cv_use_series_start_as_volume
|
||||
if settings.comicvine_cv_api_key:
|
||||
self.api_key = settings.comicvine_cv_api_key
|
||||
if settings.comicvine_cv_url:
|
||||
try:
|
||||
tmp_url = urlsplit(settings.comicvine_cv_url)
|
||||
# joinurl only works properly if there is a trailing slash
|
||||
if tmp_url.path and tmp_url.path[-1] != "/":
|
||||
tmp_url = tmp_url._replace(path=tmp_url.path + "/")
|
||||
|
||||
self.api_url = tmp_url.geturl()
|
||||
except Exception:
|
||||
logger.exception("Failed to parse new talker URL for %s, will use default", self.talker_id)
|
||||
|
||||
def check_api_key(self, key: str, url: str) -> bool:
|
||||
if not url:
|
||||
|
@ -165,7 +165,8 @@ def get_plugins() -> dict:
|
||||
def options(settings_manager, tmp_path):
|
||||
|
||||
comictaggerlib.ctoptions.register_commandline(settings_manager)
|
||||
comictaggerlib.ctoptions.register_settings(settings_manager, get_plugins())
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user