From 873e6ab0e22f55db4bb4c179a3f0b5481fe3ed5c Mon Sep 17 00:00:00 2001 From: Ivan Schaller Date: Sun, 2 Jul 2023 16:40:09 +0200 Subject: [PATCH] update pyright and some type annotations. also increase line length to 100 chars Signed-off-by: Ivan Schaller --- justfile | 12 +- mangadlp/api/mangadex.py | 20 +--- mangadlp/app.py | 24 +--- mangadlp/cache.py | 18 +-- mangadlp/downloader.py | 1 - mangadlp/logger.py | 20 ++-- mangadlp/metadata.py | 22 ++-- mangadlp/types.py | 11 +- pyproject.toml | 16 ++- tests/test_01_app.py | 4 +- tests/test_03_downloader.py | 5 +- tests/test_04_input.py | 10 +- tests/test_05_hooks.py | 15 +-- tests/test_07_metadata.py | 17 +-- tests/test_11_api_mangadex.py | 203 +++++++++++++++++++++++++++++----- tests/test_21_full.py | 93 +++++++--------- tests/test_22_all_flags.py | 7 +- 17 files changed, 316 insertions(+), 182 deletions(-) diff --git a/justfile b/justfile index c8e5ee7..a8758fb 100755 --- a/justfile +++ b/justfile @@ -75,6 +75,10 @@ install_deps_dev: @echo "installing dependencies" @pip3 install -r contrib/requirements_dev.txt +create_reqs: + @echo "creating requirements" + @pipreqs --savepath requirements.txt --mode gt --force mangadlp/ + test_shfmt: @find . -type f \( -name "**.sh" -and -not -path "./.**" -and -not -path "./venv**" \) -exec shfmt -d -i 4 -bn -ci -sr "{}" \+; @@ -107,10 +111,10 @@ test_docker_build: # install dependecies and set everything up prepare_workspace: - just show_system_info - just check_asdf - just setup_asdf - just create_venv + just show_system_info + just check_asdf + just setup_asdf + just create_venv lint: just show_system_info diff --git a/mangadlp/api/mangadex.py b/mangadlp/api/mangadex.py index 1d7b046..c32634f 100644 --- a/mangadlp/api/mangadex.py +++ b/mangadlp/api/mangadex.py @@ -57,9 +57,7 @@ class Mangadex: # get the uuid for the manga def get_manga_uuid(self) -> str: # isolate id from url - uuid_regex = re.compile( - "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}" - ) + uuid_regex = re.compile("[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}") # try to get uuid in string try: uuid = uuid_regex.search(self.url_uuid)[0] # type: ignore @@ -75,9 +73,7 @@ class Mangadex: counter = 1 while counter <= 3: try: - response = requests.get( - f"{self.api_base_url}/manga/{self.manga_uuid}", timeout=10 - ) + response = requests.get(f"{self.api_base_url}/manga/{self.manga_uuid}", timeout=10) except Exception as exc: if counter >= 3: log.error("Maybe the MangaDex API is down?") @@ -118,9 +114,7 @@ class Mangadex: break title = alt_title[self.language] # pyright:ignore except (KeyError, UnboundLocalError): - log.warning( - "Manga title also not found in alt titles. Falling back to english title" - ) + log.warning("Manga title also not found in alt titles. Falling back to english title") else: log.debug(f"Language={self.language}, Alt-title='{title}'") return utils.fix_name(title) @@ -139,9 +133,7 @@ class Mangadex: try: total_chapters: int = r.json()["total"] except Exception as exc: - log.error( - "Error retrieving the chapters list. Did you specify a valid language code?" - ) + log.error("Error retrieving the chapters list. Did you specify a valid language code?") raise exc if total_chapters == 0: log.error("No chapters available to download in specified language") @@ -190,9 +182,7 @@ class Mangadex: continue # export chapter data as a dict - chapter_index = ( - chapter_num if not self.forcevol else f"{chapter_vol}:{chapter_num}" - ) + chapter_index = chapter_num if not self.forcevol else f"{chapter_vol}:{chapter_num}" chapter_data[chapter_index] = { "uuid": chapter_uuid, "volume": chapter_vol, diff --git a/mangadlp/app.py b/mangadlp/app.py index 6ee44c0..5a0b8d6 100644 --- a/mangadlp/app.py +++ b/mangadlp/app.py @@ -139,9 +139,7 @@ class MangaDLP: # prechecks userinput/options # no url and no readin list given if not self.url_uuid: - log.error( - 'You need to specify a manga url/uuid with "-u" or a list with "--read"' - ) + log.error('You need to specify a manga url/uuid with "-u" or a list with "--read"') raise ValueError # checks if --list is not used if not self.list_chapters: @@ -179,9 +177,7 @@ class MangaDLP: if self.chapters.lower() == "all": chapters_to_download = self.manga_chapter_list else: - chapters_to_download = utils.get_chapter_list( - self.chapters, self.manga_chapter_list - ) + chapters_to_download = utils.get_chapter_list(self.chapters, self.manga_chapter_list) # show chapters to download log.info(f"Chapters selected: {', '.join(chapters_to_download)}") @@ -192,9 +188,7 @@ class MangaDLP: # prepare cache if specified if self.cache_path: - cache = CacheDB( - self.cache_path, self.manga_uuid, self.language, self.manga_title - ) + cache = CacheDB(self.cache_path, self.manga_uuid, self.language, self.manga_title) cached_chapters = cache.db_uuid_chapters log.info(f"Cached chapters: {cached_chapters}") @@ -257,9 +251,7 @@ class MangaDLP: {"Format": self.file_format[1:], **metadata}, ) except Exception as exc: - log.warning( - f"Can't write metadata for chapter '{chapter}'. Reason={exc}" - ) + log.warning(f"Can't write metadata for chapter '{chapter}'. Reason={exc}") # pack downloaded folder if self.file_format: @@ -316,9 +308,7 @@ class MangaDLP: # get image urls for chapter try: - chapter_image_urls = self.api.get_chapter_images( - chapter, self.download_wait - ) + chapter_image_urls = self.api.get_chapter_images(chapter, self.download_wait) except KeyboardInterrupt as exc: log.critical("Keyboard interrupt. Stopping") raise exc @@ -407,9 +397,7 @@ class MangaDLP: # download images try: - downloader.download_chapter( - chapter_image_urls, chapter_path, self.download_wait - ) + downloader.download_chapter(chapter_image_urls, chapter_path, self.download_wait) except KeyboardInterrupt as exc: log.critical("Keyboard interrupt. Stopping") raise exc diff --git a/mangadlp/cache.py b/mangadlp/cache.py index 1781dba..ac8ed33 100644 --- a/mangadlp/cache.py +++ b/mangadlp/cache.py @@ -1,9 +1,11 @@ import json from pathlib import Path -from typing import Dict, List, Union +from typing import List, Union from loguru import logger as log +from mangadlp.types import CacheData, CacheKeyData + class CacheDB: def __init__( @@ -26,14 +28,12 @@ class CacheDB: if not self.db_data.get(self.db_key): self.db_data[self.db_key] = {} - self.db_uuid_data = self.db_data[self.db_key] - if not self.db_uuid_data.get("name"): - self.db_uuid_data.update({"name": self.name}) + self.db_uuid_data: CacheKeyData = self.db_data[self.db_key] + if not self.db_uuid_data.get("name"): # pyright:ignore + self.db_uuid_data.update({"name": self.name}) # pyright:ignore self._write_db() - self.db_uuid_chapters: List[str] = ( - self.db_uuid_data.get("chapters") or [] # type:ignore - ) + self.db_uuid_chapters: List[str] = self.db_uuid_data.get("chapters") or [] # type:ignore def _prepare_db(self) -> None: if self.db_path.exists(): @@ -46,11 +46,11 @@ class CacheDB: log.error("Can't create db-file") raise exc - def _read_db(self) -> Dict[str, Dict[str, Union[str, List[str]]]]: + def _read_db(self) -> CacheData: log.info(f"Reading cache-db: {self.db_path}") try: db_txt = self.db_path.read_text(encoding="utf8") - db_dict: Dict[str, Dict[str, Union[str, List[str]]]] = json.loads(db_txt) + db_dict: CacheData = json.loads(db_txt) except Exception as exc: log.error("Can't load cache-db") raise exc diff --git a/mangadlp/downloader.py b/mangadlp/downloader.py index 4630dd6..70bdcc8 100644 --- a/mangadlp/downloader.py +++ b/mangadlp/downloader.py @@ -54,5 +54,4 @@ def download_chapter( log.error("Can't write file") raise exc - image_num += 1 sleep(download_wait) diff --git a/mangadlp/logger.py b/mangadlp/logger.py index f0b0897..6f5b0c7 100644 --- a/mangadlp/logger.py +++ b/mangadlp/logger.py @@ -1,6 +1,6 @@ import logging import sys -from typing import Any, Dict +from typing import Any from loguru import logger @@ -24,22 +24,16 @@ class InterceptHandler(logging.Handler): frame = frame.f_back # type: ignore depth += 1 - logger.opt(depth=depth, exception=record.exc_info).log( - level, record.getMessage() - ) + logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage()) # init logger with format and log level def prepare_logger(loglevel: int = 20) -> None: - config: Dict[str, Any] = { - "handlers": [ - { - "sink": sys.stdout, - "level": loglevel, - "format": LOGURU_FMT, - } - ], + stdout_handler: dict[str, Any] = { + "sink": sys.stdout, + "level": loglevel, + "format": LOGURU_FMT, } logging.basicConfig(handlers=[InterceptHandler()], level=loglevel) - logger.configure(**config) + logger.configure(handlers=[stdout_handler]) diff --git a/mangadlp/metadata.py b/mangadlp/metadata.py index 2bd9701..f5dc356 100644 --- a/mangadlp/metadata.py +++ b/mangadlp/metadata.py @@ -10,9 +10,7 @@ METADATA_FILENAME = "ComicInfo.xml" METADATA_TEMPLATE = Path("mangadlp/metadata/ComicInfo_v2.0.xml") # define metadata types, defaults and valid values. an empty list means no value check # {key: (type, default value, valid values)} -METADATA_TYPES: Dict[ - str, Tuple[Any, Union[str, int, None], List[Union[str, int, None]]] -] = { +METADATA_TYPES: Dict[str, Tuple[Any, Union[str, int, None], List[Union[str, int, None]]]] = { "Title": (str, None, []), "Series": (str, None, []), "Number": (str, None, []), @@ -72,14 +70,12 @@ def validate_metadata(metadata_in: ComicInfo) -> Dict[str, ComicInfo]: # add default value if present if metadata_default: - log.debug( - f"Setting default value for Key:{key} -> value={metadata_default}" - ) + log.debug(f"Setting default value for Key:{key} -> value={metadata_default}") metadata_valid["ComicInfo"][key] = metadata_default # check if metadata key is available try: - md_to_check: Union[str, int, None] = metadata_in[key] + md_to_check: Union[str, int, None] = metadata_in[key] # pyright:ignore except KeyError: continue # check if provided metadata item is empty @@ -87,19 +83,17 @@ def validate_metadata(metadata_in: ComicInfo) -> Dict[str, ComicInfo]: continue # check if metadata type is correct - log.debug(f"Key:{key} -> value={type(md_to_check)} -> check={metadata_type}") + log.debug( + f"Key:{key} -> value={type(md_to_check)} -> check={metadata_type}" # pyright:ignore + ) if not isinstance(md_to_check, metadata_type): - log.warning( - f"Metadata has wrong type: {key}:{metadata_type} -> {md_to_check}" - ) + log.warning(f"Metadata has wrong type: {key}:{metadata_type} -> {md_to_check}") continue # check if metadata is valid log.debug(f"Key:{key} -> value={md_to_check} -> valid={metadata_validation}") if (len(metadata_validation) > 0) and (md_to_check not in metadata_validation): - log.warning( - f"Metadata is invalid: {key}:{metadata_validation} -> {md_to_check}" - ) + log.warning(f"Metadata is invalid: {key}:{metadata_validation} -> {md_to_check}") continue log.debug(f"Updating metadata: '{key}' = '{md_to_check}'") diff --git a/mangadlp/types.py b/mangadlp/types.py index b924bf4..de254f9 100644 --- a/mangadlp/types.py +++ b/mangadlp/types.py @@ -1,4 +1,4 @@ -from typing import Optional, TypedDict +from typing import List, Optional, TypedDict class ComicInfo(TypedDict, total=False): @@ -48,3 +48,12 @@ class ChapterData(TypedDict): chapter: str name: str pages: int + + +class CacheKeyData(TypedDict): + chapters: List[str] + name: str + + +class CacheData(TypedDict): + __root__: CacheKeyData diff --git a/pyproject.toml b/pyproject.toml index 2e99004..c070399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,12 @@ dependencies = [ "ruff>=0.0.247", ] +# black + +[tool.black] +line-length = 100 +target-version = ["py39"] + # pyright [tool.pyright] @@ -97,13 +103,14 @@ select = [ "F", # pyflakes "RUF", # ruff specific ] -line-length = 88 +line-length = 100 fix = true show-fixes = true format = "grouped" ignore-init-module-imports = true respect-gitignore = true -ignore = ["E501", "D103", "D100", "D102", "PLR2004"] +ignore = ["E501", "D103", "D100", "D102", "PLR2004", "D403"] +#unfixable = ["F401"] exclude = [ ".direnv", ".git", @@ -119,7 +126,8 @@ exclude = [ ] [tool.ruff.per-file-ignores] -"__init__.py" = ["D104"] +"__init__.py" = ["D104"] +"__about__.py" = ["D104", "F841"] [tool.ruff.pylint] max-args = 10 @@ -131,7 +139,7 @@ max-complexity = 10 convention = "google" [tool.ruff.pycodestyle] -max-doc-length = 88 +max-doc-length = 100 # pytest diff --git a/tests/test_01_app.py b/tests/test_01_app.py index bad76bc..44b396f 100644 --- a/tests/test_01_app.py +++ b/tests/test_01_app.py @@ -5,7 +5,9 @@ from mangadlp.app import MangaDLP def test_check_api_mangadex(): - url = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) test = MangaDLP(url_uuid=url, list_chapters=True, download_wait=2) assert test.api_used == Mangadex diff --git a/tests/test_03_downloader.py b/tests/test_03_downloader.py index 8bb0c57..e502111 100644 --- a/tests/test_03_downloader.py +++ b/tests/test_03_downloader.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest import requests +from pytest import MonkeyPatch from mangadlp import downloader @@ -17,7 +18,7 @@ def test_downloader(): ] chapter_path = Path("tests/test_folder1") chapter_path.mkdir(parents=True, exist_ok=True) - images = [] + images: list[str] = [] downloader.download_chapter(urls, str(chapter_path), 2) for file in chapter_path.iterdir(): images.append(file.name) @@ -28,7 +29,7 @@ def test_downloader(): shutil.rmtree(chapter_path, ignore_errors=True) -def test_downloader_fail(monkeypatch): +def test_downloader_fail(monkeypatch: MonkeyPatch): images = [ "https://uploads.mangadex.org/data/f1117c5e7aff315bc3429a8791c89d63/A1-c111d78b798f1dda1879334a3478f7ae4503578e8adf1af0fcc4e14d2a396ad4.png", "https://uploads.mangadex.org/data/f1117c5e7aff315bc3429a8791c89d63/A2-717ec3c83e8e05ed7b505941431a417ebfed6a005f78b89650efd3b088b951ec.png", diff --git a/tests/test_04_input.py b/tests/test_04_input.py index a4e4636..bd5251c 100644 --- a/tests/test_04_input.py +++ b/tests/test_04_input.py @@ -20,7 +20,9 @@ def test_no_read_and_url(): chapters = "1" file_format = "cbz" download_path = "tests" - command_args = f"-l {language} -c {chapters} --path {download_path} --format {file_format} --debug" + command_args = ( + f"-l {language} -c {chapters} --path {download_path} --format {file_format} --debug" + ) script_path = "manga-dlp.py" assert os.system(f"python3 {script_path} {command_args}") != 0 @@ -30,7 +32,9 @@ def test_no_chaps(): language = "en" file_format = "cbz" download_path = "tests" - command_args = f"-u {url_uuid} -l {language} --path {download_path} --format {file_format} --debug" + command_args = ( + f"-u {url_uuid} -l {language} --path {download_path} --format {file_format} --debug" + ) script_path = "manga-dlp.py" assert os.system(f"python3 {script_path} {command_args}") != 0 @@ -48,7 +52,7 @@ def test_no_volume(): def test_readin_list(): list_file = "tests/test_list.txt" - test_list = mdlpinput.readin_list(None, None, list_file) + test_list = mdlpinput.readin_list(None, None, list_file) # pyright:ignore assert test_list == [ "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu", diff --git a/tests/test_05_hooks.py b/tests/test_05_hooks.py index 31ee074..f685d4a 100644 --- a/tests/test_05_hooks.py +++ b/tests/test_05_hooks.py @@ -4,21 +4,22 @@ import time from pathlib import Path import pytest +from pytest import MonkeyPatch @pytest.fixture -def wait_10s(): +def wait_10s(_: MonkeyPatch): print("sleeping 10 seconds because of api timeouts") time.sleep(10) @pytest.fixture -def wait_20s(): +def wait_20s(_: MonkeyPatch): print("sleeping 20 seconds because of api timeouts") time.sleep(20) -def test_manga_pre_hook(wait_10s): +def test_manga_pre_hook(wait_10s: MonkeyPatch): url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie" manga_path = Path("tests/Shikimori's Not Just a Cutie") language = "en" @@ -50,7 +51,7 @@ def test_manga_pre_hook(wait_10s): hook_file.unlink() -def test_manga_post_hook(wait_10s): +def test_manga_post_hook(wait_10s: MonkeyPatch): url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie" manga_path = Path("tests/Shikimori's Not Just a Cutie") language = "en" @@ -82,7 +83,7 @@ def test_manga_post_hook(wait_10s): hook_file.unlink() -def test_chapter_pre_hook(wait_10s): +def test_chapter_pre_hook(wait_10s: MonkeyPatch): url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie" manga_path = Path("tests/Shikimori's Not Just a Cutie") language = "en" @@ -114,7 +115,7 @@ def test_chapter_pre_hook(wait_10s): hook_file.unlink() -def test_chapter_post_hook(wait_10s): +def test_chapter_post_hook(wait_10s: MonkeyPatch): url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie" manga_path = Path("tests/Shikimori's Not Just a Cutie") language = "en" @@ -146,7 +147,7 @@ def test_chapter_post_hook(wait_10s): hook_file.unlink() -def test_all_hooks(wait_10s): +def test_all_hooks(wait_10s: MonkeyPatch): url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie" manga_path = Path("tests/Shikimori's Not Just a Cutie") language = "en" diff --git a/tests/test_07_metadata.py b/tests/test_07_metadata.py index c67b1fe..653fc23 100644 --- a/tests/test_07_metadata.py +++ b/tests/test_07_metadata.py @@ -5,12 +5,13 @@ from pathlib import Path import pytest import xmlschema +from pytest import MonkeyPatch from mangadlp.metadata import validate_metadata, write_metadata @pytest.fixture -def wait_20s(): +def wait_20s(_: MonkeyPatch): print("sleeping 20 seconds because of api timeouts") time.sleep(20) @@ -33,7 +34,7 @@ def test_metadata_creation(): "Format": "cbz", } - write_metadata(metadata_path, metadata) + write_metadata(metadata_path, metadata) # pyright:ignore assert metadata_file.exists() read_in_metadata = metadata_file.read_text(encoding="utf8") @@ -59,7 +60,7 @@ def test_metadata_validation(): "Format": "cbz", } - valid_metadata = validate_metadata(metadata) + valid_metadata = validate_metadata(metadata) # pyright:ignore assert valid_metadata["ComicInfo"] == { "Title": "title1", @@ -82,7 +83,7 @@ def test_metadata_validation_values(): "CommunityRating": 4, } - valid_metadata = validate_metadata(metadata) + valid_metadata = validate_metadata(metadata) # pyright:ignore assert valid_metadata["ComicInfo"] == { "Notes": "Downloaded with https://github.com/olofvndrhr/manga-dlp", @@ -101,7 +102,7 @@ def test_metadata_validation_values2(): "CommunityRating": 10, # invalid } - valid_metadata = validate_metadata(metadata) + valid_metadata = validate_metadata(metadata) # pyright:ignore assert valid_metadata["ComicInfo"] == { "Notes": "Downloaded with https://github.com/olofvndrhr/manga-dlp", @@ -110,8 +111,10 @@ def test_metadata_validation_values2(): } -def test_metadata_chapter_validity(wait_20s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_metadata_chapter_validity(wait_20s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) manga_path = Path("tests/Tomo-chan wa Onna no ko") metadata_path = manga_path / "Ch. 1 - Once In A Life Time Misfire/ComicInfo.xml" language = "en" diff --git a/tests/test_11_api_mangadex.py b/tests/test_11_api_mangadex.py index 41b34cf..6bffb7e 100644 --- a/tests/test_11_api_mangadex.py +++ b/tests/test_11_api_mangadex.py @@ -1,11 +1,14 @@ import pytest import requests +from pytest import MonkeyPatch from mangadlp.api.mangadex import Mangadex def test_uuid_link(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -33,7 +36,9 @@ def test_uuid_link_false(): def test_title(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -51,7 +56,9 @@ def test_alt_title(): def test_alt_title_fallback(): - url_uuid = "https://mangadex.org/title/d7037b2a-874a-4360-8a7b-07f2899152fd/mairimashita-iruma-kun" + url_uuid = ( + "https://mangadex.org/title/d7037b2a-874a-4360-8a7b-07f2899152fd/mairimashita-iruma-kun" + ) language = "fr" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -60,7 +67,9 @@ def test_alt_title_fallback(): def test_chapter_infos(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -79,7 +88,9 @@ def test_chapter_infos(): def test_non_existing_manga(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-999999999999/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-999999999999/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False @@ -88,12 +99,12 @@ def test_non_existing_manga(): assert e.type == KeyError -def test_api_failure(monkeypatch): - fail_url = ( - "https://api.mangadex.nonexistant/manga/a96676e5-8ae2-425e-b549-7f15dd34a6d8" - ) +def test_api_failure(monkeypatch: MonkeyPatch): + fail_url = "https://api.mangadex.nonexistant/manga/a96676e5-8ae2-425e-b549-7f15dd34a6d8" monkeypatch.setattr(requests, "get", fail_url) - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False @@ -103,7 +114,9 @@ def test_api_failure(monkeypatch): def test_chapter_lang_en(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -112,7 +125,9 @@ def test_chapter_lang_en(): def test_empty_chapter_lang(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "ch" forcevol = False @@ -122,7 +137,9 @@ def test_empty_chapter_lang(): def test_not_existing_lang(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "zz" forcevol = False @@ -132,9 +149,7 @@ def test_not_existing_lang(): def test_create_chapter_list(): - url_uuid = ( - "https://mangadex.org/title/6fef1f74-a0ad-4f0d-99db-d32a7cd24098/fire-punch" - ) + url_uuid = "https://mangadex.org/title/6fef1f74-a0ad-4f0d-99db-d32a7cd24098/fire-punch" language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -160,15 +175,76 @@ def test_create_chapter_list(): "19", "20", "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "34.5", + "35", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "60", + "61", + "62", + "63", + "64", + "65", + "66", + "67", + "68", + "69", + "70", + "71", + "72", + "73", + "74", + "75", + "76", + "77", + "78", + "79", + "80", + "81", + "82", + "83", ] assert test.create_chapter_list() == test_list def test_create_chapter_list_forcevol(): - url_uuid = ( - "https://mangadex.org/title/6fef1f74-a0ad-4f0d-99db-d32a7cd24098/fire-punch" - ) + url_uuid = "https://mangadex.org/title/6fef1f74-a0ad-4f0d-99db-d32a7cd24098/fire-punch" language = "en" forcevol = True test = Mangadex(url_uuid, language, forcevol) @@ -194,13 +270,78 @@ def test_create_chapter_list_forcevol(): "3:19", "3:20", "3:21", + "3:22", + "3:23", + "3:24", + "3:25", + "3:26", + "3:27", + "3:28", + "4:29", + "4:30", + "4:31", + "4:32", + "4:33", + "4:34", + "4:34.5", + "4:35", + "4:36", + "4:37", + "4:38", + "4:39", + "5:40", + "5:41", + "5:42", + "5:43", + "5:44", + "5:45", + "5:46", + "5:47", + "5:48", + "5:49", + "6:50", + "6:51", + "6:52", + "6:53", + "6:54", + "6:55", + "6:56", + "6:57", + "6:58", + "6:59", + "6:60", + "7:61", + "7:62", + "7:63", + "7:64", + "7:65", + "7:66", + "7:67", + "7:68", + "7:69", + "7:70", + "8:71", + "8:72", + "8:73", + "8:74", + "8:75", + "8:76", + "8:77", + "8:78", + "8:79", + "8:80", + "8:81", + "8:82", + "8:83", ] assert test.create_chapter_list() == test_list def test_get_chapter_images(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -226,11 +367,11 @@ def test_get_chapter_images(): assert test.get_chapter_images(chapter_num, 2) == test_list -def test_get_chapter_images_error(monkeypatch): - fail_url = ( - "https://api.mangadex.org/at-home/server/e86ec2c4-c5e4-4710-bfaa-999999999999" +def test_get_chapter_images_error(monkeypatch: MonkeyPatch): + fail_url = "https://api.mangadex.org/at-home/server/e86ec2c4-c5e4-4710-bfaa-999999999999" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" ) - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) @@ -241,16 +382,18 @@ def test_get_chapter_images_error(monkeypatch): def test_chapter_metadata(): - url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + url_uuid = ( + "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu" + ) language = "en" forcevol = False test = Mangadex(url_uuid, language, forcevol) chapter_metadata = test.create_metadata("1") - manga_name = chapter_metadata["Series"] - chapter_name = chapter_metadata["Title"] - chapter_num = chapter_metadata["Number"] - chapter_volume = chapter_metadata["Volume"] - chapter_url = chapter_metadata["Web"] + manga_name = chapter_metadata["Series"] # pyright:ignore + chapter_name = chapter_metadata["Title"] # pyright:ignore + chapter_num = chapter_metadata["Number"] # pyright:ignore + chapter_volume = chapter_metadata["Volume"] # pyright:ignore + chapter_url = chapter_metadata["Web"] # pyright:ignore assert (manga_name, chapter_name, chapter_volume, chapter_num, chapter_url) == ( "Komi-san wa Komyushou Desu", diff --git a/tests/test_21_full.py b/tests/test_21_full.py index 0f4e5fd..2ebc1e0 100644 --- a/tests/test_21_full.py +++ b/tests/test_21_full.py @@ -5,27 +5,26 @@ import time from pathlib import Path import pytest +from pytest import MonkeyPatch from mangadlp import app @pytest.fixture -def wait_10s(): +def wait_10s(_: MonkeyPatch): print("sleeping 10 seconds because of api timeouts") time.sleep(10) @pytest.fixture -def wait_20s(): +def wait_20s(_: MonkeyPatch): print("sleeping 20 seconds because of api timeouts") time.sleep(20) -def test_full_api_mangadex(wait_20s): +def test_full_api_mangadex(wait_20s: MonkeyPatch): manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") mdlp = app.MangaDLP( url_uuid="https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko", language="en", @@ -44,16 +43,16 @@ def test_full_api_mangadex(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_input_cbz(wait_20s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_full_with_input_cbz(wait_20s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "cbz" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" script_path = "manga-dlp.py" os.system(f"python3 {script_path} {command_args}") @@ -64,16 +63,16 @@ def test_full_with_input_cbz(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_input_cbz_info(wait_20s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_full_with_input_cbz_info(wait_20s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "cbz" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --wait 2" script_path = "manga-dlp.py" os.system(f"python3 {script_path} {command_args}") @@ -84,19 +83,17 @@ def test_full_with_input_cbz_info(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -@pytest.mark.skipif( - platform.machine() != "x86_64", reason="pdf only supported on amd64" -) -def test_full_with_input_pdf(wait_20s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +@pytest.mark.skipif(platform.machine() != "x86_64", reason="pdf only supported on amd64") +def test_full_with_input_pdf(wait_20s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "pdf" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.pdf" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.pdf") command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" script_path = "manga-dlp.py" os.system(f"python3 {script_path} {command_args}") @@ -107,16 +104,16 @@ def test_full_with_input_pdf(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_input_folder(wait_20s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_full_with_input_folder(wait_20s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire") metadata_path = Path( "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire/ComicInfo.xml" ) @@ -131,16 +128,16 @@ def test_full_with_input_folder(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_input_skip_cbz(wait_10s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_full_with_input_skip_cbz(wait_10s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "cbz" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" script_path = "manga-dlp.py" manga_path.mkdir(parents=True, exist_ok=True) @@ -153,22 +150,22 @@ def test_full_with_input_skip_cbz(wait_10s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_input_skip_folder(wait_10s): - url_uuid = "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" +def test_full_with_input_skip_folder(wait_10s: MonkeyPatch): + url_uuid = ( + "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" + ) language = "en" chapters = "1" file_format = "" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire" - ) + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire") command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format '{file_format}' --debug --wait 2" script_path = "manga-dlp.py" chapter_path.mkdir(parents=True, exist_ok=True) os.system(f"python3 {script_path} {command_args}") - found_files = [] + found_files: list[str] = [] for file in chapter_path.iterdir(): found_files.append(file.name) @@ -184,17 +181,15 @@ def test_full_with_input_skip_folder(wait_10s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_read_cbz(wait_20s): +def test_full_with_read_cbz(wait_20s: MonkeyPatch): url_list = Path("tests/test_list2.txt") language = "en" chapters = "1" file_format = "cbz" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) - command_args = f"--read {str(url_list)} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") + command_args = f"--read {url_list!s} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" script_path = "manga-dlp.py" url_list.write_text( "https://mangadex.org/title/76ee7069-23b4-493c-bc44-34ccbf3051a8/tomo-chan-wa-onna-no-ko" @@ -208,17 +203,15 @@ def test_full_with_read_cbz(wait_20s): shutil.rmtree(manga_path, ignore_errors=True) -def test_full_with_read_skip_cbz(wait_10s): +def test_full_with_read_skip_cbz(wait_10s: MonkeyPatch): url_list = Path("tests/test_list2.txt") language = "en" chapters = "1" file_format = "cbz" download_path = "tests" manga_path = Path("tests/Tomo-chan wa Onna no ko") - chapter_path = Path( - "tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz" - ) - command_args = f"--read {str(url_list)} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" + chapter_path = Path("tests/Tomo-chan wa Onna no ko/Ch. 1 - Once In A Life Time Misfire.cbz") + command_args = f"--read {url_list!s} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --wait 2" script_path = "manga-dlp.py" manga_path.mkdir(parents=True, exist_ok=True) chapter_path.touch() diff --git a/tests/test_22_all_flags.py b/tests/test_22_all_flags.py index 84d890e..3c35567 100644 --- a/tests/test_22_all_flags.py +++ b/tests/test_22_all_flags.py @@ -4,21 +4,22 @@ import time from pathlib import Path import pytest +from pytest import MonkeyPatch @pytest.fixture -def wait_10s(): +def wait_10s(_: MonkeyPatch): print("sleeping 10 seconds because of api timeouts") time.sleep(10) @pytest.fixture -def wait_20s(): +def wait_20s(_: MonkeyPatch): print("sleeping 20 seconds because of api timeouts") time.sleep(20) -def test_full_with_all_flags(wait_20s): +def test_full_with_all_flags(wait_20s: MonkeyPatch): manga_path = Path("tests/Tomo-chan wa Onna no ko") chapter_path = manga_path / "Ch. 1 - Once In A Life Time Misfire.cbz" cache_path = Path("tests/test_cache.json")