Generate a namespace object for typing settngs
This commit is contained in:
parent
a912c7392b
commit
783e10a9a1
.pre-commit-config.yaml
build-tools
comicapi
comictaggerlib
autotagmatchwindow.pyautotagstartwindow.pycbltransformer.pycli.py
setup.cfgctsettings
fileselectionlist.pygui.pyissueidentifier.pyissueselectionwindow.pymain.pymatchselectionwindow.pyrenamewindow.pyseriesselectionwindow.pysettingswindow.pytaggerwindow.pyui
versionchecker.pytests
@ -41,6 +41,6 @@ repos:
|
||||
rev: v1.2.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
additional_dependencies: [types-setuptools, types-requests]
|
||||
additional_dependencies: [types-setuptools, types-requests, settngs>=0.7.1]
|
||||
ci:
|
||||
skip: [mypy]
|
||||
|
19
build-tools/generate_settngs.py
Normal file
19
build-tools/generate_settngs.py
Normal file
@ -0,0 +1,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
|
||||
import settngs
|
||||
|
||||
import comictaggerlib.main
|
||||
|
||||
|
||||
def generate() -> str:
|
||||
app = comictaggerlib.main.App()
|
||||
app.register_settings()
|
||||
return settngs.generate_ns(app.manager.definitions)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
src = generate()
|
||||
pathlib.Path("./comictaggerlib/ctsettings/settngs_namespace.py").write_text(src)
|
||||
print(src, end="")
|
@ -261,7 +261,7 @@ def get_publisher(publisher: str) -> tuple[str, str]:
|
||||
if ok:
|
||||
break
|
||||
|
||||
return (imprint, publisher)
|
||||
return imprint, publisher
|
||||
|
||||
|
||||
def update_publishers(new_publishers: Mapping[str, Mapping[str, str]]) -> None:
|
||||
@ -290,11 +290,11 @@ class ImprintDict(dict): # type: ignore
|
||||
def __getitem__(self, k: str) -> tuple[str, str, bool]:
|
||||
item = super().__getitem__(k.casefold())
|
||||
if k.casefold() == self.publisher.casefold():
|
||||
return ("", self.publisher, True)
|
||||
return "", self.publisher, True
|
||||
if item is None:
|
||||
return ("", k, False)
|
||||
return "", k, False
|
||||
else:
|
||||
return (item, self.publisher, True)
|
||||
return item, self.publisher, True
|
||||
|
||||
def copy(self) -> ImprintDict:
|
||||
return ImprintDict(self.publisher, super().copy())
|
||||
|
@ -19,12 +19,12 @@ import logging
|
||||
import os
|
||||
from typing import Callable
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||
|
||||
from comicapi.comicarchive import MetaDataStyle
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.resulttypes import IssueResult, MultipleMatch
|
||||
from comictaggerlib.ui import ui_path
|
||||
from comictaggerlib.ui.qtutils import reduce_widget_font_size
|
||||
@ -40,7 +40,7 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
|
||||
match_set_list: list[MultipleMatch],
|
||||
style: int,
|
||||
fetch_func: Callable[[IssueResult], GenericMetadata],
|
||||
config: settngs.Namespace,
|
||||
config: ct_ns,
|
||||
talker: ComicTalker,
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
|
@ -17,16 +17,16 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtWidgets, uic
|
||||
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ui import ui_path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AutoTagStartWindow(QtWidgets.QDialog):
|
||||
def __init__(self, parent: QtWidgets.QWidget, config: settngs.Namespace, msg: str) -> None:
|
||||
def __init__(self, parent: QtWidgets.QWidget, config: ct_ns, msg: str) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
uic.loadUi(ui_path / "autotagstartwindow.ui", self)
|
||||
|
@ -17,15 +17,14 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import settngs
|
||||
|
||||
from comicapi.genericmetadata import CreditMetadata, GenericMetadata
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CBLTransformer:
|
||||
def __init__(self, metadata: GenericMetadata, config: settngs.Namespace) -> None:
|
||||
def __init__(self, metadata: GenericMetadata, config: ct_ns) -> None:
|
||||
self.metadata = metadata
|
||||
self.config = config
|
||||
|
||||
|
@ -23,13 +23,12 @@ import sys
|
||||
from datetime import datetime
|
||||
from pprint import pprint
|
||||
|
||||
import settngs
|
||||
|
||||
from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive, MetaDataStyle
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictaggerlib import ctversion
|
||||
from comictaggerlib.cbltransformer import CBLTransformer
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.filerenamer import FileRenamer, get_rename_dir
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictaggerlib.issueidentifier import IssueIdentifier
|
||||
@ -40,7 +39,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CLI:
|
||||
def __init__(self, config: settngs.Namespace, talkers: dict[str, ComicTalker]) -> None:
|
||||
def __init__(self, config: ct_ns, talkers: dict[str, ComicTalker]) -> None:
|
||||
self.config = config
|
||||
self.talkers = talkers
|
||||
self.batch_mode = False
|
||||
@ -171,14 +170,14 @@ class CLI:
|
||||
self.display_match_set_for_choice(label, match_set)
|
||||
|
||||
def run(self) -> None:
|
||||
if len(self.config.runtime_file_list) < 1:
|
||||
if len(self.config.runtime_files) < 1:
|
||||
logger.error("You must specify at least one filename. Use the -h option for more info")
|
||||
return
|
||||
|
||||
match_results = OnlineMatchResults()
|
||||
self.batch_mode = len(self.config.runtime_file_list) > 1
|
||||
self.batch_mode = len(self.config.runtime_files) > 1
|
||||
|
||||
for f in self.config.runtime_file_list:
|
||||
for f in self.config.runtime_files:
|
||||
self.process_file_cli(f, match_results)
|
||||
sys.stdout.flush()
|
||||
|
||||
@ -318,7 +317,7 @@ class CLI:
|
||||
md = GenericMetadata()
|
||||
logger.error("Failed to load metadata for %s: %s", ca.path, e)
|
||||
|
||||
if self.config.apply_transform_on_bulk_operation_ndetadata_style == MetaDataStyle.CBI:
|
||||
if self.config.cbl_apply_transform_on_bulk_operation == MetaDataStyle.CBI:
|
||||
md = CBLTransformer(md, self.config).apply()
|
||||
|
||||
if not ca.write_metadata(md, metadata_style):
|
||||
@ -342,7 +341,7 @@ class CLI:
|
||||
|
||||
md = self.create_local_metadata(ca)
|
||||
if md.issue is None or md.issue == "":
|
||||
if self.config.runtime_assume_issue_one:
|
||||
if self.config.autotag_assume_1_if_no_issue_num:
|
||||
md.issue = "1"
|
||||
|
||||
# now, search online
|
||||
@ -488,6 +487,7 @@ class CLI:
|
||||
return
|
||||
except Exception:
|
||||
logger.exception("Formatter failure: %s metadata: %s", self.config.rename_template, renamer.metadata)
|
||||
return
|
||||
|
||||
folder = get_rename_dir(ca, self.config.rename_dir if self.config.rename_move_to_dir else None)
|
||||
|
||||
|
@ -7,6 +7,7 @@ from comictaggerlib.ctsettings.commandline import (
|
||||
)
|
||||
from comictaggerlib.ctsettings.file import register_file_settings, validate_file_settings
|
||||
from comictaggerlib.ctsettings.plugin import register_plugin_settings, validate_plugin_settings
|
||||
from comictaggerlib.ctsettings.settngs_namespace import settngs_namespace as ct_ns
|
||||
from comictaggerlib.ctsettings.types import ComicTaggerPaths
|
||||
from comictalker import ComicTalker
|
||||
|
||||
@ -21,4 +22,5 @@ __all__ = [
|
||||
"validate_file_settings",
|
||||
"validate_plugin_settings",
|
||||
"ComicTaggerPaths",
|
||||
"ct_ns",
|
||||
]
|
||||
|
@ -25,14 +25,20 @@ import settngs
|
||||
from comicapi import utils
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictaggerlib import ctversion
|
||||
from comictaggerlib.ctsettings.types import ComicTaggerPaths, metadata_type, parse_metadata_from_string
|
||||
from comictaggerlib.ctsettings.settngs_namespace import settngs_namespace as ct_ns
|
||||
from comictaggerlib.ctsettings.types import (
|
||||
ComicTaggerPaths,
|
||||
metadata_type,
|
||||
metadata_type_single,
|
||||
parse_metadata_from_string,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def initial_commandline_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
# Ensure this stays up to date with register_settings
|
||||
# Ensure this stays up to date with register_runtime
|
||||
parser.add_argument(
|
||||
"--config",
|
||||
help="Config directory defaults to ~/.ComicTagger\non Linux/Mac and %%APPDATA%% on Windows\n",
|
||||
@ -43,7 +49,7 @@ def initial_commandline_parser() -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def register_settings(parser: settngs.Manager) -> None:
|
||||
def register_runtime(parser: settngs.Manager) -> None:
|
||||
parser.add_setting(
|
||||
"--config",
|
||||
help="Config directory defaults to ~/.Config/ComicTagger\non Linux, ~/Library/Application Support/ComicTagger on Mac and %%APPDATA%%\\ComicTagger on Windows\n",
|
||||
@ -83,7 +89,7 @@ def register_settings(parser: settngs.Manager) -> None:
|
||||
parser.add_setting(
|
||||
"--id",
|
||||
dest="issue_id",
|
||||
type=int,
|
||||
type=str,
|
||||
help="""Use the issue ID when searching online.\nOverrides all other metadata.\n\n""",
|
||||
file=False,
|
||||
)
|
||||
@ -177,6 +183,7 @@ def register_settings(parser: settngs.Manager) -> None:
|
||||
help="""Apply metadata to already tagged archives (relevant for -s or -c).""",
|
||||
file=False,
|
||||
)
|
||||
parser.add_setting("--no-gui", action="store_true", help="Do not open the GUI, force the commandline", file=False)
|
||||
parser.add_setting("files", nargs="*", file=False)
|
||||
|
||||
|
||||
@ -200,7 +207,7 @@ def register_commands(parser: settngs.Manager) -> None:
|
||||
parser.add_setting(
|
||||
"-c",
|
||||
"--copy",
|
||||
type=metadata_type,
|
||||
type=metadata_type_single,
|
||||
metavar="{CR,CBL,COMET}",
|
||||
help="Copy the specified source tag block to\ndestination style specified via -t\n(potentially lossy operation).\n\n",
|
||||
file=False,
|
||||
@ -236,12 +243,10 @@ def register_commands(parser: settngs.Manager) -> None:
|
||||
|
||||
def register_commandline_settings(parser: settngs.Manager) -> None:
|
||||
parser.add_group("commands", register_commands, True)
|
||||
parser.add_persistent_group("runtime", register_settings)
|
||||
parser.add_persistent_group("runtime", register_runtime)
|
||||
|
||||
|
||||
def validate_commandline_settings(
|
||||
config: settngs.Config[settngs.Namespace], parser: settngs.Manager
|
||||
) -> settngs.Config[settngs.Namespace]:
|
||||
def validate_commandline_settings(config: settngs.Config[ct_ns], parser: settngs.Manager) -> settngs.Config[ct_ns]:
|
||||
if config[0].commands_version:
|
||||
parser.exit(
|
||||
status=1,
|
||||
@ -258,6 +263,7 @@ def validate_commandline_settings(
|
||||
config[0].commands_rename,
|
||||
config[0].commands_export_to_zip,
|
||||
config[0].commands_only_set_cv_key,
|
||||
config[0].runtime_no_gui,
|
||||
]
|
||||
)
|
||||
|
||||
@ -282,14 +288,9 @@ def validate_commandline_settings(
|
||||
if config[0].commands_copy:
|
||||
if not config[0].runtime_type:
|
||||
parser.exit(message="Please specify the type to copy to with -t\n", status=1)
|
||||
if len(config[0].commands_copy) > 1:
|
||||
parser.exit(message="Please specify only one type to copy to with -c\n", status=1)
|
||||
config[0].commands_copy = config[0].commands_copy[0]
|
||||
|
||||
if config[0].runtime_recursive:
|
||||
config[0].runtime_file_list = utils.get_recursive_filelist(config[0].runtime_files)
|
||||
else:
|
||||
config[0].runtime_file_list = config[0].runtime_files
|
||||
config[0].runtime_files = utils.get_recursive_filelist(config[0].runtime_files)
|
||||
|
||||
# take a crack at finding rar exe if it's not in the path
|
||||
if not utils.which("rar"):
|
||||
|
@ -5,7 +5,7 @@ import uuid
|
||||
|
||||
import settngs
|
||||
|
||||
from comictaggerlib.ctsettings.types import AppendAction
|
||||
from comictaggerlib.ctsettings.settngs_namespace import settngs_namespace as ct_ns
|
||||
from comictaggerlib.defaults import DEFAULT_REPLACEMENTS, Replacement, Replacements
|
||||
|
||||
|
||||
@ -43,8 +43,9 @@ def identifier(parser: settngs.Manager) -> None:
|
||||
parser.add_setting(
|
||||
"--publisher-filter",
|
||||
default=["Panini Comics", "Abril", "Planeta DeAgostini", "Editorial Televisa", "Dino Comics"],
|
||||
action=AppendAction,
|
||||
help="When enabled filters the listed publishers from all search results",
|
||||
action="extend",
|
||||
nargs="+",
|
||||
help="When enabled, filters the listed publishers from all search results. Ending a publisher with a '-' removes a publisher from this list",
|
||||
)
|
||||
parser.add_setting("--series-match-search-thresh", default=90, type=int)
|
||||
parser.add_setting(
|
||||
@ -216,8 +217,22 @@ def autotag(parser: settngs.Manager) -> None:
|
||||
)
|
||||
|
||||
|
||||
def validate_file_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
config[0].identifier_publisher_filter = [x.strip() for x in config[0].identifier_publisher_filter if x.strip()]
|
||||
def validate_file_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
new_filter = []
|
||||
remove = []
|
||||
for x in config[0].identifier_publisher_filter:
|
||||
x = x.strip()
|
||||
if x: # ignore empty arguments
|
||||
if x[-1] == "-": # this publisher needs to be removed. We remove after all publishers have been enumerated
|
||||
remove.append(x.strip("-"))
|
||||
else:
|
||||
if x not in new_filter:
|
||||
new_filter.append(x)
|
||||
for x in remove: # remove publishers
|
||||
if x in new_filter:
|
||||
new_filter.remove(x)
|
||||
config[0].identifier_publisher_filter = new_filter
|
||||
|
||||
config[0].rename_replacements = Replacements(
|
||||
[Replacement(x[0], x[1], x[2]) for x in config[0].rename_replacements[0]],
|
||||
[Replacement(x[0], x[1], x[2]) for x in config[0].rename_replacements[1]],
|
||||
|
@ -2,11 +2,13 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import cast
|
||||
|
||||
import settngs
|
||||
|
||||
import comicapi.comicarchive
|
||||
import comictaggerlib.ctsettings
|
||||
from comictaggerlib.ctsettings.settngs_namespace import settngs_namespace as ct_ns
|
||||
|
||||
logger = logging.getLogger("comictagger")
|
||||
|
||||
@ -47,10 +49,10 @@ def register_talker_settings(manager: settngs.Manager) -> None:
|
||||
logger.exception("Failed to register settings for %s", talker_id)
|
||||
|
||||
|
||||
def validate_archive_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
def validate_archive_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
if "archiver" not in config[1]:
|
||||
return config
|
||||
cfg = settngs.normalize_config(config, file=True, cmdline=True, defaults=False)
|
||||
cfg = settngs.normalize_config(config, file=True, cmdline=True, default=False)
|
||||
for archiver in comicapi.comicarchive.archivers:
|
||||
exe_name = settngs.sanitize_name(archiver.exe)
|
||||
if exe_name in cfg[0]["archiver"] and cfg[0]["archiver"][exe_name]:
|
||||
@ -62,7 +64,7 @@ def validate_archive_settings(config: settngs.Config[settngs.Namespace]) -> sett
|
||||
return config
|
||||
|
||||
|
||||
def validate_talker_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
def validate_talker_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
# Apply talker settings from config file
|
||||
cfg = settngs.normalize_config(config, True, True)
|
||||
for talker_id, talker in list(comictaggerlib.ctsettings.talkers.items()):
|
||||
@ -73,10 +75,10 @@ def validate_talker_settings(config: settngs.Config[settngs.Namespace]) -> settn
|
||||
del comictaggerlib.ctsettings.talkers[talker_id]
|
||||
logger.exception("Failed to initialize talker settings: %s", e)
|
||||
|
||||
return settngs.get_namespace(cfg)
|
||||
return cast(settngs.Config[ct_ns], settngs.get_namespace(cfg, file=True, cmdline=True))
|
||||
|
||||
|
||||
def validate_plugin_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
def validate_plugin_settings(config: settngs.Config[ct_ns]) -> settngs.Config[ct_ns]:
|
||||
config = validate_archive_settings(config)
|
||||
config = validate_talker_settings(config)
|
||||
return config
|
||||
|
105
comictaggerlib/ctsettings/settngs_namespace.py
Normal file
105
comictaggerlib/ctsettings/settngs_namespace.py
Normal file
@ -0,0 +1,105 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import settngs
|
||||
|
||||
import comicapi.genericmetadata
|
||||
import comictaggerlib.ctsettings.types
|
||||
import comictaggerlib.defaults
|
||||
|
||||
|
||||
class settngs_namespace(settngs.TypedNS):
|
||||
commands_version: bool
|
||||
commands_print: bool
|
||||
commands_delete: bool
|
||||
commands_copy: int
|
||||
commands_save: bool
|
||||
commands_rename: bool
|
||||
commands_export_to_zip: bool
|
||||
commands_only_set_cv_key: bool
|
||||
|
||||
runtime_config: comictaggerlib.ctsettings.types.ComicTaggerPaths
|
||||
runtime_verbose: int
|
||||
runtime_abort_on_conflict: bool
|
||||
runtime_delete_after_zip_export: bool
|
||||
runtime_parse_filename: bool
|
||||
runtime_issue_id: str
|
||||
runtime_online: bool
|
||||
runtime_metadata: comicapi.genericmetadata.GenericMetadata
|
||||
runtime_interactive: bool
|
||||
runtime_abort_on_low_confidence: bool
|
||||
runtime_summary: bool
|
||||
runtime_raw: bool
|
||||
runtime_recursive: bool
|
||||
runtime_script: str
|
||||
runtime_split_words: bool
|
||||
runtime_dryrun: bool
|
||||
runtime_darkmode: bool
|
||||
runtime_glob: bool
|
||||
runtime_quiet: bool
|
||||
runtime_type: list[int]
|
||||
runtime_overwrite: bool
|
||||
runtime_no_gui: bool
|
||||
runtime_files: list[str]
|
||||
|
||||
general_check_for_new_version: bool
|
||||
|
||||
internal_install_id: str
|
||||
internal_save_data_style: int
|
||||
internal_load_data_style: int
|
||||
internal_last_opened_folder: str
|
||||
internal_window_width: int
|
||||
internal_window_height: int
|
||||
internal_window_x: int
|
||||
internal_window_y: int
|
||||
internal_form_width: int
|
||||
internal_list_width: int
|
||||
internal_sort_column: int
|
||||
internal_sort_direction: int
|
||||
|
||||
identifier_series_match_identify_thresh: int
|
||||
identifier_border_crop_percent: int
|
||||
identifier_publisher_filter: list[str]
|
||||
identifier_series_match_search_thresh: int
|
||||
identifier_clear_metadata_on_import: bool
|
||||
identifier_auto_imprint: bool
|
||||
identifier_sort_series_by_year: bool
|
||||
identifier_exact_series_matches_first: bool
|
||||
identifier_always_use_publisher_filter: bool
|
||||
identifier_clear_form_before_populating: bool
|
||||
|
||||
dialog_show_disclaimer: bool
|
||||
dialog_dont_notify_about_this_version: str
|
||||
dialog_ask_about_usage_stats: bool
|
||||
|
||||
filename_complicated_parser: bool
|
||||
filename_remove_c2c: bool
|
||||
filename_remove_fcbd: bool
|
||||
filename_remove_publisher: bool
|
||||
|
||||
talker_source: str
|
||||
|
||||
cbl_assume_lone_credit_is_primary: bool
|
||||
cbl_copy_characters_to_tags: bool
|
||||
cbl_copy_teams_to_tags: bool
|
||||
cbl_copy_locations_to_tags: bool
|
||||
cbl_copy_storyarcs_to_tags: bool
|
||||
cbl_copy_notes_to_comments: bool
|
||||
cbl_copy_weblink_to_comments: bool
|
||||
cbl_apply_transform_on_import: bool
|
||||
cbl_apply_transform_on_bulk_operation: bool
|
||||
|
||||
rename_template: str
|
||||
rename_issue_number_padding: int
|
||||
rename_use_smart_string_cleanup: bool
|
||||
rename_set_extension_based_on_archive: bool
|
||||
rename_dir: str
|
||||
rename_move_to_dir: bool
|
||||
rename_strict: bool
|
||||
rename_replacements: comictaggerlib.defaults.Replacements
|
||||
|
||||
autotag_save_on_low_confidence: bool
|
||||
autotag_dont_use_year_when_identifying: bool
|
||||
autotag_assume_1_if_no_issue_num: bool
|
||||
autotag_ignore_leading_numbers_in_filename: bool
|
||||
autotag_remove_archive_after_successful_match: bool
|
||||
autotag_wait_and_retry_on_rate_limit: bool
|
@ -2,8 +2,6 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
from collections.abc import Sequence
|
||||
from typing import Any, Callable
|
||||
|
||||
from appdirs import AppDirs
|
||||
|
||||
@ -59,6 +57,13 @@ class ComicTaggerPaths(AppDirs):
|
||||
return pathlib.Path(super().site_config_dir)
|
||||
|
||||
|
||||
def metadata_type_single(types: str) -> int:
|
||||
result = metadata_type(types)
|
||||
if len(result) > 1:
|
||||
raise argparse.ArgumentTypeError(f"invalid choice: {result} (only one metadata style allowed)")
|
||||
return result[0]
|
||||
|
||||
|
||||
def metadata_type(types: str) -> list[int]:
|
||||
result = []
|
||||
types = types.casefold()
|
||||
@ -71,71 +76,6 @@ def metadata_type(types: str) -> list[int]:
|
||||
return result
|
||||
|
||||
|
||||
def _copy_items(items: Sequence[Any] | None) -> Sequence[Any]:
|
||||
if items is None:
|
||||
return []
|
||||
# The copy module is used only in the 'append' and 'append_const'
|
||||
# actions, and it is needed only when the default value isn't a list.
|
||||
# Delay its import for speeding up the common case.
|
||||
if type(items) is list:
|
||||
return items[:]
|
||||
import copy
|
||||
|
||||
return copy.copy(items)
|
||||
|
||||
|
||||
class AppendAction(argparse.Action):
|
||||
def __init__(
|
||||
self,
|
||||
option_strings: list[str],
|
||||
dest: str,
|
||||
nargs: str | None = None,
|
||||
const: Any = None,
|
||||
default: Any = None,
|
||||
type: Callable[[str], Any] | None = None, # noqa: A002
|
||||
choices: list[Any] | None = None,
|
||||
required: bool = False,
|
||||
help: str | None = None, # noqa: A002
|
||||
metavar: str | None = None,
|
||||
):
|
||||
self.called = False
|
||||
if nargs == 0:
|
||||
raise ValueError(
|
||||
"nargs for append actions must be != 0; if arg "
|
||||
"strings are not supplying the value to append, "
|
||||
"the append const action may be more appropriate"
|
||||
)
|
||||
if const is not None and nargs != argparse.OPTIONAL:
|
||||
raise ValueError("nargs must be %r to supply const" % argparse.OPTIONAL)
|
||||
super().__init__(
|
||||
option_strings=option_strings,
|
||||
dest=dest,
|
||||
nargs=nargs,
|
||||
const=const,
|
||||
default=default,
|
||||
type=type,
|
||||
choices=choices,
|
||||
required=required,
|
||||
help=help,
|
||||
metavar=metavar,
|
||||
)
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
parser: argparse.ArgumentParser,
|
||||
namespace: argparse.Namespace,
|
||||
values: str | Sequence[Any] | None,
|
||||
option_string: str | None = None,
|
||||
) -> None:
|
||||
if values:
|
||||
if not self.called:
|
||||
setattr(namespace, self.dest, [])
|
||||
items = getattr(namespace, self.dest, None)
|
||||
items = _copy_items(items)
|
||||
items.append(values) # type: ignore
|
||||
setattr(namespace, self.dest, items)
|
||||
|
||||
|
||||
def parse_metadata_from_string(mdstr: str) -> GenericMetadata:
|
||||
"""The metadata string is a comma separated list of name-value pairs
|
||||
The names match the attributes of the internal metadata struct (for now)
|
||||
|
@ -20,11 +20,11 @@ import os
|
||||
import platform
|
||||
from typing import Callable, cast
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtWidgets, uic
|
||||
|
||||
from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictaggerlib.optionalmsgdialog import OptionalMessageDialog
|
||||
from comictaggerlib.settingswindow import linuxRarHelp, macRarHelp, windowsRarHelp
|
||||
@ -57,7 +57,7 @@ class FileSelectionList(QtWidgets.QWidget):
|
||||
dataColNum = fileColNum
|
||||
|
||||
def __init__(
|
||||
self, parent: QtWidgets.QWidget, config: settngs.Namespace, dirty_flag_verification: Callable[[str, str], bool]
|
||||
self, parent: QtWidgets.QWidget, config: ct_ns, dirty_flag_verification: Callable[[str, str], bool]
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
|
@ -9,6 +9,7 @@ import types
|
||||
|
||||
import settngs
|
||||
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
@ -83,7 +84,7 @@ except ImportError:
|
||||
|
||||
|
||||
def open_tagger_window(
|
||||
talkers: dict[str, ComicTalker], config: settngs.Config[settngs.Namespace], error: tuple[str, bool] | None
|
||||
talkers: dict[str, ComicTalker], config: settngs.Config[ct_ns], error: tuple[str, bool] | None
|
||||
) -> None:
|
||||
os.environ["QtWidgets.QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
|
||||
args = []
|
||||
|
@ -20,13 +20,13 @@ import logging
|
||||
import sys
|
||||
from typing import Any, Callable
|
||||
|
||||
import settngs
|
||||
from typing_extensions import NotRequired, TypedDict
|
||||
|
||||
from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comicapi.issuestring import IssueString
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.imagefetcher import ImageFetcher, ImageFetcherException
|
||||
from comictaggerlib.imagehasher import ImageHasher
|
||||
from comictaggerlib.resulttypes import IssueResult
|
||||
@ -72,7 +72,7 @@ class IssueIdentifier:
|
||||
result_one_good_match = 4
|
||||
result_multiple_good_matches = 5
|
||||
|
||||
def __init__(self, comic_archive: ComicArchive, config: settngs.Namespace, talker: ComicTalker) -> None:
|
||||
def __init__(self, comic_archive: ComicArchive, config: ct_ns, talker: ComicTalker) -> None:
|
||||
self.config = config
|
||||
self.talker = talker
|
||||
self.comic_archive: ComicArchive = comic_archive
|
||||
|
@ -17,11 +17,11 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||
|
||||
from comicapi.issuestring import IssueString
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ui import ui_path
|
||||
from comictaggerlib.ui.qtutils import reduce_widget_font_size
|
||||
from comictalker.comictalker import ComicTalker, TalkerError
|
||||
@ -42,7 +42,7 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
def __init__(
|
||||
self,
|
||||
parent: QtWidgets.QWidget,
|
||||
config: settngs.Namespace,
|
||||
config: ct_ns,
|
||||
talker: ComicTalker,
|
||||
series_id: str,
|
||||
issue_number: str,
|
||||
|
@ -24,12 +24,15 @@ import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import cast
|
||||
|
||||
import settngs
|
||||
|
||||
import comicapi
|
||||
import comicapi.comicarchive
|
||||
import comicapi.utils
|
||||
import comictalker
|
||||
from comictaggerlib import cli, ctsettings
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ctversion import version
|
||||
from comictaggerlib.log import setup_logging
|
||||
|
||||
@ -95,7 +98,7 @@ def configure_locale() -> None:
|
||||
sys.stdin.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def update_publishers(config: settngs.Config[settngs.Namespace]) -> None:
|
||||
def update_publishers(config: settngs.Config[ct_ns]) -> None:
|
||||
json_file = config[0].runtime_config.user_config_dir / "publishers.json"
|
||||
if json_file.exists():
|
||||
try:
|
||||
@ -108,7 +111,7 @@ class App:
|
||||
"""docstring for App"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.config: settngs.Config[settngs.Namespace]
|
||||
self.config: settngs.Config[ct_ns]
|
||||
self.initial_arg_parser = ctsettings.initial_commandline_parser()
|
||||
self.config_load_success = False
|
||||
|
||||
@ -141,9 +144,11 @@ class App:
|
||||
ctsettings.register_file_settings(self.manager)
|
||||
ctsettings.register_plugin_settings(self.manager)
|
||||
|
||||
def parse_settings(self, config_paths: ctsettings.ComicTaggerPaths) -> settngs.Config[settngs.Namespace]:
|
||||
cfg, self.config_load_success = self.manager.parse_config(config_paths.user_config_dir / "settings.json")
|
||||
config = self.manager.get_namespace(cfg)
|
||||
def parse_settings(self, config_paths: ctsettings.ComicTaggerPaths, *args: str) -> settngs.Config[ct_ns]:
|
||||
cfg, self.config_load_success = self.manager.parse_config(
|
||||
config_paths.user_config_dir / "settings.json", list(args) or None
|
||||
)
|
||||
config = cast(settngs.Config[ct_ns], self.manager.get_namespace(cfg, file=True, cmdline=True))
|
||||
|
||||
config = ctsettings.validate_commandline_settings(config, self.manager)
|
||||
config = ctsettings.validate_file_settings(config)
|
||||
@ -192,8 +197,8 @@ class App:
|
||||
# manage the CV API key
|
||||
# None comparison is used so that the empty string can unset the value
|
||||
if not error and (
|
||||
self.config[0].talker_comicvine_comicvine_key is not None
|
||||
or self.config[0].talker_comicvine_comicvine_url is not None
|
||||
self.config[0].talker_comicvine_comicvine_key is not None # type: ignore[attr-defined]
|
||||
or self.config[0].talker_comicvine_comicvine_url is not None # type: ignore[attr-defined]
|
||||
):
|
||||
settings_path = self.config[0].runtime_config.user_config_dir / "settings.json"
|
||||
if self.config_load_success:
|
||||
|
@ -18,11 +18,11 @@ from __future__ import annotations
|
||||
import logging
|
||||
import os
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtWidgets, uic
|
||||
|
||||
from comicapi.comicarchive import ComicArchive
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.resulttypes import IssueResult
|
||||
from comictaggerlib.ui import ui_path
|
||||
from comictaggerlib.ui.qtutils import reduce_widget_font_size
|
||||
@ -37,7 +37,7 @@ class MatchSelectionWindow(QtWidgets.QDialog):
|
||||
parent: QtWidgets.QWidget,
|
||||
matches: list[IssueResult],
|
||||
comic_archive: ComicArchive,
|
||||
config: settngs.Namespace,
|
||||
config: ct_ns,
|
||||
talker: ComicTalker,
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
|
@ -23,6 +23,7 @@ from PyQt5 import QtCore, QtWidgets, uic
|
||||
from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive, MetaDataStyle
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.filerenamer import FileRenamer, get_rename_dir
|
||||
from comictaggerlib.settingswindow import SettingsWindow
|
||||
from comictaggerlib.ui import ui_path
|
||||
@ -38,7 +39,7 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
parent: QtWidgets.QWidget,
|
||||
comic_archive_list: list[ComicArchive],
|
||||
data_style: int,
|
||||
config: settngs.Config[settngs.Namespace],
|
||||
config: settngs.Config[ct_ns],
|
||||
talkers: dict[str, ComicTalker],
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
@ -124,6 +125,7 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
"<a href='https://github.com/comictagger/comictagger'>"
|
||||
"https://github.com/comictagger/comictagger</a>",
|
||||
)
|
||||
return
|
||||
|
||||
row = self.twList.rowCount()
|
||||
self.twList.insertRow(row)
|
||||
|
@ -19,7 +19,6 @@ import itertools
|
||||
import logging
|
||||
from collections import deque
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
|
||||
@ -27,6 +26,7 @@ from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.issueidentifier import IssueIdentifier
|
||||
from comictaggerlib.issueselectionwindow import IssueSelectionWindow
|
||||
from comictaggerlib.matchselectionwindow import MatchSelectionWindow
|
||||
@ -106,7 +106,7 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
issue_count: int | None,
|
||||
cover_index_list: list[int],
|
||||
comic_archive: ComicArchive | None,
|
||||
config: settngs.Namespace,
|
||||
config: ct_ns,
|
||||
talker: ComicTalker,
|
||||
autoselect: bool = False,
|
||||
literal: bool = False,
|
||||
|
@ -20,7 +20,7 @@ import logging
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||
@ -29,6 +29,7 @@ import comictaggerlib.ui.talkeruigenerator
|
||||
from comicapi import utils
|
||||
from comicapi.genericmetadata import md_test
|
||||
from comictaggerlib import ctsettings
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ctversion import version
|
||||
from comictaggerlib.filerenamer import FileRenamer, Replacement, Replacements
|
||||
from comictaggerlib.imagefetcher import ImageFetcher
|
||||
@ -133,7 +134,7 @@ Spider-Geddon #1 - New Players; Check In
|
||||
|
||||
class SettingsWindow(QtWidgets.QDialog):
|
||||
def __init__(
|
||||
self, parent: QtWidgets.QWidget, config: settngs.Config[settngs.Namespace], talkers: dict[str, ComicTalker]
|
||||
self, parent: QtWidgets.QWidget, config: settngs.Config[ct_ns], talkers: dict[str, ComicTalker]
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
@ -413,7 +414,7 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
setattr(self.config[0], self.config[1]["archiver"].v["rar"].internal_name, str(self.leRarExePath.text()))
|
||||
|
||||
# make sure rar program is now in the path for the rar class
|
||||
if self.config[0].archiver_rar:
|
||||
if self.config[0].archiver_rar: # type: ignore[attr-defined]
|
||||
utils.add_to_path(os.path.dirname(str(self.leRarExePath.text())))
|
||||
|
||||
if not str(self.leIssueNumPadding.text()).isdigit():
|
||||
@ -480,7 +481,7 @@ class SettingsWindow(QtWidgets.QDialog):
|
||||
QtWidgets.QMessageBox.information(self, self.name, "Cache has been cleared.")
|
||||
|
||||
def reset_settings(self) -> None:
|
||||
self.config = settngs.get_namespace(settngs.defaults(self.config[1]))
|
||||
self.config = cast(settngs.Config[ct_ns], settngs.get_namespace(settngs.defaults(self.config[1])))
|
||||
self.settings_to_form()
|
||||
QtWidgets.QMessageBox.information(self, self.name, self.name + " have been returned to default values.")
|
||||
|
||||
|
@ -48,6 +48,7 @@ from comictaggerlib.autotagstartwindow import AutoTagStartWindow
|
||||
from comictaggerlib.cbltransformer import CBLTransformer
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.crediteditorwindow import CreditEditorWindow
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.exportwindow import ExportConflictOpts, ExportWindow
|
||||
from comictaggerlib.fileselectionlist import FileInfo, FileSelectionList
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
@ -79,7 +80,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
def __init__(
|
||||
self,
|
||||
file_list: list[str],
|
||||
config: settngs.Config[settngs.Namespace],
|
||||
config: settngs.Config[ct_ns],
|
||||
talkers: dict[str, ComicTalker],
|
||||
parent: QtWidgets.QWidget | None = None,
|
||||
) -> None:
|
||||
|
@ -8,6 +8,7 @@ from typing import Any, NamedTuple
|
||||
import settngs
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
@ -26,7 +27,7 @@ class PasswordEdit(QtWidgets.QLineEdit):
|
||||
Based on this example https://kushaldas.in/posts/creating-password-input-widget-in-pyqt.html by Kushal Das.
|
||||
"""
|
||||
|
||||
def __init__(self, show_visibility=True, *args, **kwargs):
|
||||
def __init__(self, show_visibility: bool = True, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.visibleIcon = QtGui.QIcon(str(graphics_path / "eye.svg"))
|
||||
@ -42,7 +43,7 @@ class PasswordEdit(QtWidgets.QLineEdit):
|
||||
|
||||
self.password_shown = False
|
||||
|
||||
def on_toggle_password_Action(self):
|
||||
def on_toggle_password_Action(self) -> None:
|
||||
if not self.password_shown:
|
||||
self.setEchoMode(QtWidgets.QLineEdit.Normal)
|
||||
self.password_shown = True
|
||||
@ -58,7 +59,7 @@ class PasswordEdit(QtWidgets.QLineEdit):
|
||||
def generate_api_widgets(
|
||||
talker_id: str,
|
||||
sources: dict[str, QtWidgets.QWidget],
|
||||
config: settngs.Config[settngs.Namespace],
|
||||
config: settngs.Config[ct_ns],
|
||||
layout: QtWidgets.QGridLayout,
|
||||
talkers: dict[str, ComicTalker],
|
||||
) -> None:
|
||||
@ -168,7 +169,7 @@ def generate_password_textbox(option: settngs.Setting, layout: QtWidgets.QGridLa
|
||||
return widget
|
||||
|
||||
|
||||
def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[settngs.Namespace]) -> None:
|
||||
def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[ct_ns]) -> None:
|
||||
# Set the active talker via id in sources combo box
|
||||
sources["cbx_select_talker"].setCurrentIndex(sources["cbx_select_talker"].findData(config[0].talker_source))
|
||||
|
||||
@ -187,7 +188,7 @@ def settings_to_talker_form(sources: dict[str, QtWidgets.QWidget], config: settn
|
||||
logger.debug("Failed to set value of %s", name)
|
||||
|
||||
|
||||
def form_settings_to_config(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[settngs.Namespace]) -> None:
|
||||
def form_settings_to_config(sources: dict[str, QtWidgets.QWidget], config: settngs.Config[ct_ns]) -> None:
|
||||
# Source combo box value
|
||||
config[0].talker_source = sources["cbx_select_talker"].currentData()
|
||||
|
||||
@ -206,7 +207,7 @@ def form_settings_to_config(sources: dict[str, QtWidgets.QWidget], config: settn
|
||||
|
||||
def generate_source_option_tabs(
|
||||
comic_talker_tab: QtWidgets.QWidget,
|
||||
config: settngs.Config[settngs.Namespace],
|
||||
config: settngs.Config[ct_ns],
|
||||
talkers: dict[str, ComicTalker],
|
||||
) -> dict[str, QtWidgets.QWidget]:
|
||||
"""
|
||||
|
@ -40,9 +40,9 @@ class VersionChecker:
|
||||
headers={"user-agent": "comictagger/" + ctversion.version},
|
||||
).json()
|
||||
except Exception:
|
||||
return ("", "")
|
||||
return "", ""
|
||||
|
||||
new_version = release["tag_name"]
|
||||
if new_version is None or new_version == "":
|
||||
return ("", "")
|
||||
return (new_version.strip(), release["name"])
|
||||
return "", ""
|
||||
return new_version.strip(), release["name"]
|
||||
|
@ -42,7 +42,7 @@ install_requires =
|
||||
pycountry
|
||||
rapidfuzz>=2.12.0
|
||||
requests==2.*
|
||||
settngs==0.6.3
|
||||
settngs==0.7.1
|
||||
text2digits
|
||||
typing-extensions>=4.3.0
|
||||
wordninja
|
||||
@ -280,3 +280,4 @@ extend-ignore = E203, E501, A003
|
||||
extend-exclude = venv, scripts, build, dist, comictaggerlib/ctversion.py
|
||||
per-file-ignores =
|
||||
comictaggerlib/cli.py: T20
|
||||
build-tools/generate_settngs.py: T20
|
||||
|
@ -9,7 +9,7 @@ from testing.comicdata import search_results
|
||||
def test_create_cache(config, mock_version):
|
||||
config, definitions = config
|
||||
comictalker.comiccacher.ComicCacher(config.runtime_config.user_cache_dir, mock_version[0])
|
||||
assert (config.runtime_config.user_cache_dir).exists()
|
||||
assert config.runtime_config.user_cache_dir.exists()
|
||||
|
||||
|
||||
def test_search_results(comic_cache):
|
||||
|
@ -9,7 +9,6 @@ from typing import Any
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
import settngs
|
||||
from PIL import Image
|
||||
|
||||
import comicapi.comicarchive
|
||||
@ -128,7 +127,7 @@ def mock_version(monkeypatch):
|
||||
monkeypatch.setattr(comictaggerlib.ctversion, "__version__", version)
|
||||
monkeypatch.setattr(comictaggerlib.ctversion, "version_tuple", version_tuple)
|
||||
monkeypatch.setattr(comictaggerlib.ctversion, "__version_tuple__", version_tuple)
|
||||
yield (version, version_tuple)
|
||||
yield version, version_tuple
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -154,11 +153,13 @@ def seed_all_publishers(monkeypatch):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config(settings_manager, tmp_path):
|
||||
comictaggerlib.ctsettings.register_commandline_settings(settings_manager)
|
||||
comictaggerlib.ctsettings.register_file_settings(settings_manager)
|
||||
defaults = settings_manager.get_namespace(settings_manager.defaults())
|
||||
defaults[0].runtime_config = comictaggerlib.ctsettings.ComicTaggerPaths(tmp_path / "config")
|
||||
def config(tmp_path):
|
||||
from comictaggerlib.main import App
|
||||
|
||||
app = App()
|
||||
app.register_settings()
|
||||
|
||||
defaults = app.parse_settings(comictaggerlib.ctsettings.ComicTaggerPaths(tmp_path / "config"), "")
|
||||
defaults[0].runtime_config.user_data_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].runtime_config.user_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
defaults[0].runtime_config.user_cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
@ -167,12 +168,6 @@ def config(settings_manager, tmp_path):
|
||||
yield defaults
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def settings_manager():
|
||||
manager = settngs.Manager()
|
||||
yield manager
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def comic_cache(config, mock_version) -> Generator[comictalker.comiccacher.ComicCacher, Any, None]:
|
||||
yield comictalker.comiccacher.ComicCacher(config[0].runtime_config.user_cache_dir, mock_version[0])
|
||||
|
Loading…
x
Reference in New Issue
Block a user