[2.1.10] - 2022-07-14
## [2.1.10] - 2022-07-14 ### Fixed - Removed some unused files ### Added - `logger.py` for all log related settings and functions ### Changed - Logging of output. The script now uses the `logging` library
This commit is contained in:
commit
8972556415
22 changed files with 268 additions and 203 deletions
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 2.1.9
|
||||
current_version = 2.1.10
|
||||
commit = True
|
||||
tag = False
|
||||
serialize = {major}.{minor}.{patch}
|
||||
|
|
|
@ -30,7 +30,7 @@ pipeline:
|
|||
dockerfile: docker/Dockerfile.amd64
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-amd64-test
|
||||
build_args: BUILD_VERSION=2.1.9
|
||||
build_args: BUILD_VERSION=2.1.10
|
||||
|
||||
# build docker image for arm64
|
||||
test-build-arm64:
|
||||
|
@ -46,4 +46,4 @@ pipeline:
|
|||
dockerfile: docker/Dockerfile.arm64
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm64-test
|
||||
build_args: BUILD_VERSION=2.1.9
|
||||
build_args: BUILD_VERSION=2.1.10
|
||||
|
|
|
@ -34,5 +34,5 @@ pipeline:
|
|||
image: cr.44net.ch/baseimages/debian-base
|
||||
pull: true
|
||||
commands:
|
||||
- bash get_release_notes.sh 2.1.9
|
||||
- bash get_release_notes.sh 2.1.10
|
||||
- cat RELEASENOTES.md
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -9,6 +9,20 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
|
||||
- Add support for more sites
|
||||
|
||||
## [2.1.10] - 2022-07-14
|
||||
|
||||
### Fixed
|
||||
|
||||
- Removed some unused files
|
||||
|
||||
### Added
|
||||
|
||||
- `logger.py` for all log related settings and functions
|
||||
|
||||
### Changed
|
||||
|
||||
- Logging of output. The script now uses the `logging` library
|
||||
|
||||
## [2.1.9] - 2022-06-26
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -103,7 +103,9 @@ options:
|
|||
--format FORMAT Archive format to create. An empty string means dont archive the folder. Defaults to 'cbz'
|
||||
--forcevol Force naming of volumes. For mangas where chapters reset each volume
|
||||
--wait WAIT Time to wait for each picture to download in seconds(float). Defaults 0.5
|
||||
--verbose Verbose logging. Defaults to false
|
||||
--lean Lean logging. Minimal log output. Defaults to false
|
||||
--verbose Verbose logging. More log output. Defaults to false
|
||||
--debug Debug logging. Most log output. Defaults to false
|
||||
```
|
||||
|
||||
### Downloads file-structure
|
||||
|
|
|
@ -7,12 +7,11 @@ class YourAPI:
|
|||
img_base_url = "https://uploads.mangadex.org"
|
||||
|
||||
# get infos to initiate class
|
||||
def __init__(self, url_uuid, language, forcevol, verbose):
|
||||
def __init__(self, url_uuid, language, forcevol):
|
||||
# static info
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.forcevol = forcevol
|
||||
self.verbose = verbose
|
||||
|
||||
# attributes needed by app.py
|
||||
self.manga_uuid = "abc"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM cr.44net.ch/baseimages/debian-s6:1.3.5-linux-amd64
|
||||
FROM cr.44net.ch/baseimages/debian-s6:1.3.6-linux-amd64
|
||||
|
||||
# set version label
|
||||
ARG BUILD_VERSION
|
||||
|
@ -10,29 +10,35 @@ LABEL description="A CLI manga downloader"
|
|||
|
||||
# install packages
|
||||
RUN \
|
||||
echo "**** install base packages ****" && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& \
|
||||
echo "**** creating folders ****" && \
|
||||
mkdir -p /app && \
|
||||
echo "**** cleanup ****" && \
|
||||
apt-get purge --auto-remove -y && \
|
||||
apt-get clean && \
|
||||
rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
echo "**** install base packages ****" \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip
|
||||
|
||||
# prepare app
|
||||
RUN \
|
||||
echo "**** creating folders ****" \
|
||||
&& mkdir -p /app
|
||||
|
||||
# cleanup installation
|
||||
RUN \
|
||||
echo "**** cleanup ****" \
|
||||
&& apt-get purge --auto-remove -y \
|
||||
&& apt-get clean \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
|
||||
|
||||
# copy files to container
|
||||
COPY docker/rootfs /
|
||||
COPY mangadlp/ /app/mangadlp/
|
||||
COPY manga-dlp.py \
|
||||
requirements.txt \
|
||||
LICENSE \
|
||||
COPY \
|
||||
manga-dlp.py \
|
||||
requirements.txt \
|
||||
LICENSE \
|
||||
/app/
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM cr.44net.ch/baseimages/debian-s6:1.3.5-linux-arm64
|
||||
FROM cr.44net.ch/baseimages/debian-s6:1.3.6-linux-arm64
|
||||
|
||||
# set version label
|
||||
ARG BUILD_VERSION
|
||||
|
@ -10,29 +10,35 @@ LABEL description="A CLI manga downloader"
|
|||
|
||||
# install packages
|
||||
RUN \
|
||||
echo "**** install base packages ****" && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip \
|
||||
&& \
|
||||
echo "**** creating folders ****" && \
|
||||
mkdir -p /app && \
|
||||
echo "**** cleanup ****" && \
|
||||
apt-get purge --auto-remove -y && \
|
||||
apt-get clean && \
|
||||
rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
echo "**** install base packages ****" \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
python3 \
|
||||
python3-pip
|
||||
|
||||
# prepare app
|
||||
RUN \
|
||||
echo "**** creating folders ****" \
|
||||
&& mkdir -p /app
|
||||
|
||||
# cleanup installation
|
||||
RUN \
|
||||
echo "**** cleanup ****" \
|
||||
&& apt-get purge --auto-remove -y \
|
||||
&& apt-get clean \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
|
||||
|
||||
# copy files to container
|
||||
COPY docker/rootfs /
|
||||
COPY mangadlp/ /app/mangadlp/
|
||||
COPY manga-dlp.py \
|
||||
requirements.txt \
|
||||
LICENSE \
|
||||
COPY \
|
||||
manga-dlp.py \
|
||||
requirements.txt \
|
||||
LICENSE \
|
||||
/app/
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from mangadlp.input import main
|
||||
|
||||
MDLP_VERSION = "2.1.9"
|
||||
MDLP_VERSION = "2.1.10"
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import logging
|
||||
|
||||
from mangadlp.logger import logger_lean, logger_verbose
|
||||
|
||||
# prepare logger with default level INFO==20
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s | %(levelname)s: %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
level=20,
|
||||
handlers=[logging.StreamHandler()],
|
||||
)
|
||||
|
||||
# create custom log levels
|
||||
logging.addLevelName(15, "VERBOSE")
|
||||
logging.VERBOSE = 15 # type: ignore
|
||||
logging.verbose = logger_verbose # type: ignore
|
||||
logging.Logger.verbose = logger_verbose # type: ignore
|
||||
|
||||
logging.addLevelName(25, "LEAN")
|
||||
logging.VERBOSE = 25 # type: ignore
|
||||
logging.lean = logger_lean # type: ignore
|
||||
logging.Logger.lean = logger_lean # type: ignore
|
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
import re
|
||||
import sys
|
||||
from time import sleep
|
||||
|
@ -15,12 +16,11 @@ class Mangadex:
|
|||
img_base_url = "https://uploads.mangadex.org"
|
||||
|
||||
# get infos to initiate class
|
||||
def __init__(self, url_uuid: str, language: str, forcevol: bool, verbosity: int):
|
||||
def __init__(self, url_uuid: str, language: str, forcevol: bool):
|
||||
# static info
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.forcevol = forcevol
|
||||
self.verbosity = verbosity
|
||||
|
||||
# api stuff
|
||||
self.api_content_ratings = "contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic"
|
||||
|
@ -36,8 +36,7 @@ class Mangadex:
|
|||
|
||||
# make initial request
|
||||
def get_manga_data(self) -> requests.Response:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting manga data for: {self.manga_uuid}")
|
||||
logging.verbose(f"Getting manga data for: {self.manga_uuid}") # type: ignore
|
||||
counter = 1
|
||||
while counter <= 3:
|
||||
try:
|
||||
|
@ -46,17 +45,17 @@ class Mangadex:
|
|||
)
|
||||
except:
|
||||
if counter >= 3:
|
||||
print("ERR: Maybe the MangaDex API is down?")
|
||||
logging.error("Maybe the MangaDex API is down?")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("ERR: Mangadex API not reachable. Retrying")
|
||||
logging.error("Mangadex API not reachable. Retrying")
|
||||
sleep(2)
|
||||
counter += 1
|
||||
else:
|
||||
break
|
||||
# check if manga exists
|
||||
if manga_data.json()["result"] != "ok":
|
||||
print("ERR: Manga not found")
|
||||
logging.error("Manga not found")
|
||||
sys.exit(1)
|
||||
|
||||
return manga_data
|
||||
|
@ -69,15 +68,14 @@ class Mangadex:
|
|||
)
|
||||
# check for new mangadex id
|
||||
if not uuid_regex.search(self.url_uuid):
|
||||
print("ERR: No valid UUID found")
|
||||
logging.error("No valid UUID found")
|
||||
sys.exit(1)
|
||||
manga_uuid = uuid_regex.search(self.url_uuid)[0]
|
||||
return manga_uuid
|
||||
|
||||
# get the title of the manga (and fix the filename)
|
||||
def get_manga_title(self) -> str:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting manga title for: {self.manga_uuid}")
|
||||
logging.verbose(f"Getting manga title for: {self.manga_uuid}") # type: ignore
|
||||
manga_data = self.manga_data.json()
|
||||
try:
|
||||
title = manga_data["data"]["attributes"]["title"][self.language]
|
||||
|
@ -89,37 +87,35 @@ class Mangadex:
|
|||
alt_titles.update(title)
|
||||
title = alt_titles[self.language]
|
||||
except: # no title on requested language found
|
||||
print("ERR: Chapter in requested language not found.")
|
||||
logging.error("Chapter in requested language not found.")
|
||||
sys.exit(1)
|
||||
return utils.fix_name(title)
|
||||
|
||||
# check if chapters are available in requested language
|
||||
def check_chapter_lang(self) -> int:
|
||||
if self.verbosity >= 2:
|
||||
print(
|
||||
f"INFO: Checking for chapters in specified language for: {self.manga_uuid}"
|
||||
)
|
||||
logging.verbose( # type: ignore
|
||||
f"Checking for chapters in specified language for: {self.manga_uuid}"
|
||||
)
|
||||
r = requests.get(
|
||||
f"{self.api_base_url}/manga/{self.manga_uuid}/feed?limit=0&{self.api_additions}"
|
||||
)
|
||||
try:
|
||||
total_chapters = r.json()["total"]
|
||||
except:
|
||||
print(
|
||||
"ERR: Error retrieving the chapters list. Did you specify a valid language code?"
|
||||
logging.error(
|
||||
"Error retrieving the chapters list. Did you specify a valid language code?"
|
||||
)
|
||||
return 0
|
||||
else:
|
||||
if total_chapters == 0:
|
||||
print("ERR: No chapters available to download!")
|
||||
logging.error("No chapters available to download!")
|
||||
return 0
|
||||
|
||||
return total_chapters
|
||||
|
||||
# get chapter data like name, uuid etc
|
||||
def get_chapter_data(self) -> dict:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting chapter data for: {self.manga_uuid}")
|
||||
logging.verbose(f"Getting chapter data for: {self.manga_uuid}") # type: ignore
|
||||
api_sorting = "order[chapter]=asc&order[volume]=asc"
|
||||
# check for chapters in specified lang
|
||||
total_chapters = self.check_chapter_lang()
|
||||
|
@ -177,8 +173,7 @@ class Mangadex:
|
|||
|
||||
# get images for the chapter (mangadex@home)
|
||||
def get_chapter_images(self, chapter: str, wait_time: float) -> list:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting chapter images for: {self.manga_uuid}")
|
||||
logging.verbose(f"Getting chapter images for: {self.manga_uuid}") # type: ignore
|
||||
athome_url = f"{self.api_base_url}/at-home/server"
|
||||
chapter_uuid = self.manga_chapter_data[chapter][0]
|
||||
|
||||
|
@ -190,11 +185,11 @@ class Mangadex:
|
|||
r = requests.get(f"{athome_url}/{chapter_uuid}")
|
||||
api_data = r.json()
|
||||
if api_data["result"] != "ok":
|
||||
print(f"ERR: No chapter with the id {chapter_uuid} found")
|
||||
logging.error(f"No chapter with the id {chapter_uuid} found")
|
||||
api_error = True
|
||||
raise IndexError
|
||||
elif api_data["chapter"]["data"] is None:
|
||||
print(f"ERR: No chapter data found for chapter {chapter_uuid}")
|
||||
logging.error(f"No chapter data found for chapter {chapter_uuid}")
|
||||
api_error = True
|
||||
raise IndexError
|
||||
else:
|
||||
|
@ -203,7 +198,7 @@ class Mangadex:
|
|||
except:
|
||||
if counter >= 3:
|
||||
api_error = True
|
||||
print(f"ERR: Retrying in a few seconds")
|
||||
logging.error(f"Retrying in a few seconds")
|
||||
counter += 1
|
||||
sleep(wait_time + 2)
|
||||
# check if result is ok
|
||||
|
@ -224,8 +219,7 @@ class Mangadex:
|
|||
|
||||
# create list of chapters
|
||||
def create_chapter_list(self) -> list:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Creating chapter list for: {self.manga_uuid}")
|
||||
logging.verbose(f"Creating chapter list for: {self.manga_uuid}") # type: ignore
|
||||
chapter_list = []
|
||||
for chapter in self.manga_chapter_data.items():
|
||||
chapter_info = self.get_chapter_infos(chapter[0])
|
||||
|
@ -240,10 +234,9 @@ class Mangadex:
|
|||
|
||||
# create easy to access chapter infos
|
||||
def get_chapter_infos(self, chapter: str) -> dict:
|
||||
if self.verbosity >= 3:
|
||||
print(
|
||||
f"INFO: Getting chapter infos for: {self.manga_chapter_data[chapter][0]}"
|
||||
)
|
||||
logging.debug(
|
||||
f"Getting chapter infos for: {self.manga_chapter_data[chapter][0]}"
|
||||
)
|
||||
chapter_uuid = self.manga_chapter_data[chapter][0]
|
||||
chapter_vol = self.manga_chapter_data[chapter][1]
|
||||
chapter_num = self.manga_chapter_data[chapter][2]
|
||||
|
|
104
mangadlp/app.py
104
mangadlp/app.py
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
@ -23,7 +24,7 @@ class MangaDLP:
|
|||
:param forcevol: Force naming of volumes. Useful for mangas where chapters reset each volume
|
||||
:param download_path: Download path. Defaults to '<script_dir>/downloads'
|
||||
:param download_wait: Time to wait for each picture to download in seconds
|
||||
:param verbosity: Verbosity of the output
|
||||
:param verbosity: Verbosity of the output. Uses the logging library values
|
||||
|
||||
:return: Nothing. Just the files
|
||||
"""
|
||||
|
@ -38,7 +39,7 @@ class MangaDLP:
|
|||
forcevol: bool = False,
|
||||
download_path: str = "downloads",
|
||||
download_wait: float = 0.5,
|
||||
verbosity: int = 0,
|
||||
verbosity: int = 20,
|
||||
) -> None:
|
||||
# init parameters
|
||||
self.url_uuid = url_uuid
|
||||
|
@ -54,7 +55,6 @@ class MangaDLP:
|
|||
self._prepare()
|
||||
|
||||
def _prepare(self) -> None:
|
||||
# additional stuff
|
||||
# set manga format suffix
|
||||
if self.file_format and "." not in self.file_format:
|
||||
self.file_format = f".{self.file_format}"
|
||||
|
@ -62,9 +62,7 @@ class MangaDLP:
|
|||
self.pre_checks()
|
||||
# init api
|
||||
self.api_used = self.check_api(self.url_uuid)
|
||||
self.api = self.api_used(
|
||||
self.url_uuid, self.language, self.forcevol, self.verbosity
|
||||
)
|
||||
self.api = self.api_used(self.url_uuid, self.language, self.forcevol)
|
||||
# get manga title and uuid
|
||||
self.manga_uuid = self.api.manga_uuid
|
||||
self.manga_title = self.api.manga_title
|
||||
|
@ -76,25 +74,25 @@ class MangaDLP:
|
|||
# prechecks userinput/options
|
||||
# no url and no readin list given
|
||||
if not self.url_uuid:
|
||||
print(
|
||||
f'ERR: You need to specify a manga url/uuid with "-u" or a list with "--read"'
|
||||
logging.error(
|
||||
'You need to specify a manga url/uuid with "-u" or a list with "--read"'
|
||||
)
|
||||
sys.exit(1)
|
||||
# checks if --list is not used
|
||||
if not self.list_chapters:
|
||||
if self.chapters is None:
|
||||
# no chapters to download were given
|
||||
print(
|
||||
f'ERR: You need to specify one or more chapters to download. To see all chapters use "--list"'
|
||||
logging.error(
|
||||
'You need to specify one or more chapters to download. To see all chapters use "--list"'
|
||||
)
|
||||
sys.exit(1)
|
||||
# if forcevol is used, but didn't specify a volume in the chapters selected
|
||||
if self.forcevol and ":" not in self.chapters:
|
||||
print(f"ERR: You need to specify the volume if you use --forcevol")
|
||||
logging.error("You need to specify the volume if you use --forcevol")
|
||||
sys.exit(1)
|
||||
# if forcevol is not used, but a volume is specified
|
||||
if not self.forcevol and ":" in self.chapters:
|
||||
print(f"ERR: Don't specify the volume without --forcevol")
|
||||
logging.error("Don't specify the volume without --forcevol")
|
||||
sys.exit(1)
|
||||
|
||||
# check the api which needs to be used
|
||||
|
@ -112,11 +110,11 @@ class MangaDLP:
|
|||
|
||||
# this is only for testing multiple apis
|
||||
if api_test.search(url_uuid):
|
||||
print("Not supported yet")
|
||||
logging.critical("Not supported yet")
|
||||
sys.exit(1)
|
||||
|
||||
# no supported api found
|
||||
print(f"ERR: No supported api in link/uuid found: {url_uuid}")
|
||||
logging.error(f"No supported api in link/uuid found: {url_uuid}")
|
||||
raise ValueError
|
||||
|
||||
# once called per manga
|
||||
|
@ -127,18 +125,15 @@ class MangaDLP:
|
|||
|
||||
print_divider = "========================================="
|
||||
# show infos
|
||||
if self.verbosity == 1:
|
||||
print(f"INFO: Manga Name: {self.manga_title}")
|
||||
else:
|
||||
print(f"{print_divider}")
|
||||
print(f"INFO: Manga Name: {self.manga_title}")
|
||||
print(f"INFO: Manga UUID: {self.manga_uuid}")
|
||||
print(f"INFO: Total chapters: {len(self.manga_chapter_list)}")
|
||||
logging.info(f"{print_divider}")
|
||||
logging.lean(f"Manga Name: {self.manga_title}") # type: ignore
|
||||
logging.info(f"Manga UUID: {self.manga_uuid}")
|
||||
logging.info(f"Total chapters: {len(self.manga_chapter_list)}")
|
||||
|
||||
# list chapters if list_chapters is true
|
||||
if self.list_chapters:
|
||||
print(f"INFO: Available Chapters:\n{', '.join(self.manga_chapter_list)}")
|
||||
print(f"{print_divider}\n")
|
||||
logging.info(f"Available Chapters: {', '.join(self.manga_chapter_list)}")
|
||||
logging.info(f"{print_divider}\n")
|
||||
return None
|
||||
|
||||
# check chapters to download if not all
|
||||
|
@ -150,11 +145,8 @@ class MangaDLP:
|
|||
)
|
||||
|
||||
# show chapters to download
|
||||
if self.verbosity == 1:
|
||||
print(f"INFO: Chapters selected: {', '.join(chapters_to_download)}")
|
||||
else:
|
||||
print(f"INFO: Chapters selected:\n{', '.join(chapters_to_download)}")
|
||||
print(f"{print_divider}")
|
||||
logging.lean(f"Chapters selected: {', '.join(chapters_to_download)}") # type: ignore
|
||||
logging.info(f"{print_divider}")
|
||||
|
||||
# create manga folder
|
||||
self.manga_path.mkdir(parents=True, exist_ok=True)
|
||||
|
@ -174,28 +166,21 @@ class MangaDLP:
|
|||
# chapter was not skipped
|
||||
except KeyError:
|
||||
# done with chapter
|
||||
print("INFO: Done with chapter\n")
|
||||
logging.info("Done with chapter\n")
|
||||
|
||||
# done with manga
|
||||
if self.verbosity != 1:
|
||||
print(f"{print_divider}")
|
||||
print(f"INFO: Done with manga: {self.manga_title}")
|
||||
logging.info(f"{print_divider}")
|
||||
logging.lean(f"Done with manga: {self.manga_title}") # type: ignore
|
||||
# filter skipped list
|
||||
skipped_chapters = list(filter(None, skipped_chapters))
|
||||
if len(skipped_chapters) >= 1:
|
||||
if self.verbosity == 1:
|
||||
print(f"INFO: Skipped chapters: {', '.join(skipped_chapters)}")
|
||||
else:
|
||||
print(f"INFO: Skipped chapters:\n{', '.join(skipped_chapters)}")
|
||||
logging.lean(f"Skipped chapters: {', '.join(skipped_chapters)}") # type: ignore
|
||||
# filter error list
|
||||
error_chapters = list(filter(None, error_chapters))
|
||||
if len(error_chapters) >= 1:
|
||||
if self.verbosity == 1:
|
||||
print(f"INFO: Chapters with errors: {', '.join(error_chapters)}")
|
||||
else:
|
||||
print(f"INFO: Chapters with errors:\n{', '.join(error_chapters)}")
|
||||
if self.verbosity != 1:
|
||||
print(f"{print_divider}\n")
|
||||
logging.lean(f"Chapters with errors: {', '.join(error_chapters)}") # type: ignore
|
||||
|
||||
logging.info(f"{print_divider}\n")
|
||||
|
||||
# once called per chapter
|
||||
def get_chapter(self, chapter: str) -> dict:
|
||||
|
@ -208,13 +193,13 @@ class MangaDLP:
|
|||
chapter, self.download_wait
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print("ERR: Stopping")
|
||||
logging.critical("Stopping")
|
||||
sys.exit(1)
|
||||
|
||||
# check if the image urls are empty. if yes skip this chapter (for mass downloads)
|
||||
if not chapter_image_urls:
|
||||
print(
|
||||
f"ERR: No images: Skipping Vol. {chapter_infos['volume']} Ch.{chapter_infos['chapter']}"
|
||||
logging.error(
|
||||
f"No images: Skipping Vol. {chapter_infos['volume']} Ch.{chapter_infos['chapter']}"
|
||||
)
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
|
@ -239,8 +224,8 @@ class MangaDLP:
|
|||
# check if chapter already exists
|
||||
# check for folder, if file format is an empty string
|
||||
if chapter_archive_path.exists():
|
||||
if self.verbosity != 1:
|
||||
print(f"INFO: '{chapter_archive_path}' already exists. Skipping")
|
||||
if self.verbosity != "lean":
|
||||
logging.warning(f"'{chapter_archive_path}' already exists. Skipping")
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -255,25 +240,24 @@ class MangaDLP:
|
|||
chapter_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# verbose log
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Chapter UUID: {chapter_infos['uuid']}")
|
||||
print(f"INFO: Filename: '{chapter_archive_path.name}'\n")
|
||||
print(f"INFO: File path: '{chapter_archive_path}'\n")
|
||||
print(f"INFO: Image URLS:\n{chapter_image_urls}\n")
|
||||
logging.verbose(f"Chapter UUID: {chapter_infos['uuid']}") # type: ignore
|
||||
logging.verbose(f"Filename: '{chapter_archive_path.name}'") # type: ignore
|
||||
logging.verbose(f"File path: '{chapter_archive_path}'") # type: ignore
|
||||
logging.verbose(f"Image URLS:\n{chapter_image_urls}") # type: ignore
|
||||
|
||||
# log
|
||||
print(f"INFO: Downloading: '{chapter_filename}'")
|
||||
logging.lean(f"Downloading: '{chapter_filename}'") # type: ignore
|
||||
|
||||
# download images
|
||||
try:
|
||||
downloader.download_chapter(
|
||||
chapter_image_urls, chapter_path, self.download_wait, self.verbosity
|
||||
chapter_image_urls, chapter_path, self.download_wait
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print("ERR: Stopping")
|
||||
logging.critical("Stopping")
|
||||
sys.exit(1)
|
||||
except:
|
||||
print(f"ERR: Cant download: '{chapter_filename}'. Skipping")
|
||||
logging.error(f"Cant download: '{chapter_filename}'. Skipping")
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -286,23 +270,23 @@ class MangaDLP:
|
|||
|
||||
else:
|
||||
# Done with chapter
|
||||
print(f"INFO: Successfully downloaded: '{chapter_filename}'")
|
||||
logging.lean(f"INFO: Successfully downloaded: '{chapter_filename}'") # type: ignore
|
||||
return {"chapter_path": chapter_path}
|
||||
|
||||
# create an archive of the chapter if needed
|
||||
def archive_chapter(self, chapter_path: Path) -> dict:
|
||||
print(f"INFO: Creating '{self.file_format}' archive")
|
||||
logging.lean(f"INFO: Creating '{self.file_format}' archive") # type: ignore
|
||||
try:
|
||||
# check if image folder is existing
|
||||
if not chapter_path.exists():
|
||||
print(f"ERR: Image folder: {chapter_path} does not exist")
|
||||
logging.error(f"Image folder: {chapter_path} does not exist")
|
||||
raise IOError
|
||||
if self.file_format == ".pdf":
|
||||
utils.make_pdf(chapter_path)
|
||||
else:
|
||||
utils.make_archive(chapter_path, self.file_format)
|
||||
except:
|
||||
print(f"ERR: Archive error. Skipping chapter")
|
||||
logging.error(f"Archive error. Skipping chapter")
|
||||
# add to skipped chapters list
|
||||
return {
|
||||
"error": chapter_path,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
@ -14,7 +15,6 @@ def download_chapter(
|
|||
image_urls: list,
|
||||
chapter_path: Union[str, Path],
|
||||
download_wait: float,
|
||||
verbosity: int,
|
||||
) -> None:
|
||||
total_img = len(image_urls)
|
||||
for image_num, image in enumerate(image_urls, 1):
|
||||
|
@ -22,25 +22,24 @@ def download_chapter(
|
|||
image_suffix = str(Path(image).suffix) or ".png"
|
||||
# set image path
|
||||
image_path = Path(f"{chapter_path}/{image_num:03d}{image_suffix}")
|
||||
# show progress bar or progress by image for verbose
|
||||
if verbosity == 0:
|
||||
# show progress bar for default log level
|
||||
if logging.root.level == logging.INFO:
|
||||
utils.progress_bar(image_num, total_img)
|
||||
elif verbosity >= 2:
|
||||
print(f"INFO: Downloading image {image_num}/{total_img}")
|
||||
logging.verbose(f"Downloading image {image_num}/{total_img}") # type: ignore
|
||||
|
||||
counter = 1
|
||||
while counter <= 3:
|
||||
try:
|
||||
r = requests.get(image, stream=True)
|
||||
if r.status_code != 200:
|
||||
print(f"ERR: Request for image {image} failed, retrying")
|
||||
logging.error(f"Request for image {image} failed, retrying")
|
||||
raise ConnectionError
|
||||
except KeyboardInterrupt:
|
||||
print("ERR: Stopping")
|
||||
logging.critical("Stopping")
|
||||
sys.exit(1)
|
||||
except:
|
||||
if counter >= 3:
|
||||
print("ERR: Maybe the MangaDex Servers are down?")
|
||||
logging.error("Maybe the MangaDex Servers are down?")
|
||||
raise ConnectionError
|
||||
sleep(download_wait)
|
||||
counter += 1
|
||||
|
@ -53,7 +52,7 @@ def download_chapter(
|
|||
r.raw.decode_content = True
|
||||
shutil.copyfileobj(r.raw, file)
|
||||
except:
|
||||
print("ERR: Can't write file")
|
||||
logging.error("Can't write file")
|
||||
raise IOError
|
||||
|
||||
image_num += 1
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import mangadlp.app as app
|
||||
import mangadlp.logger as logger
|
||||
|
||||
MDLP_VERSION = "2.1.9"
|
||||
MDLP_VERSION = "2.1.10"
|
||||
|
||||
|
||||
def check_args(args):
|
||||
|
@ -38,6 +38,8 @@ def readin_list(readlist: str) -> list:
|
|||
|
||||
|
||||
def call_app(args):
|
||||
# set logger formatting
|
||||
logger.format_logger(args.verbosity)
|
||||
# call main function with all input arguments
|
||||
mdlp = app.MangaDLP(
|
||||
args.url_uuid,
|
||||
|
@ -182,28 +184,28 @@ def get_args():
|
|||
"--lean",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Lean logging. Defaults to false",
|
||||
help="Lean logging. Minimal log output. Defaults to false",
|
||||
action="store_const",
|
||||
const=1,
|
||||
default=0,
|
||||
const=25,
|
||||
default=20,
|
||||
)
|
||||
verbosity.add_argument(
|
||||
"--verbose",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Verbose logging. Defaults to false",
|
||||
help="Verbose logging. More log output. Defaults to false",
|
||||
action="store_const",
|
||||
const=2,
|
||||
default=0,
|
||||
const=15,
|
||||
default=20,
|
||||
)
|
||||
verbosity.add_argument(
|
||||
"--debug",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Lean logging. Defaults to false",
|
||||
help="Debug logging. Most log output. Defaults to false",
|
||||
action="store_const",
|
||||
const=3,
|
||||
default=0,
|
||||
const=10,
|
||||
default=20,
|
||||
)
|
||||
|
||||
# parser.print_help()
|
||||
|
|
32
mangadlp/logger.py
Normal file
32
mangadlp/logger.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import logging
|
||||
|
||||
|
||||
# set log message format
|
||||
def format_logger(verbosity: int):
|
||||
logging.getLogger().setLevel(verbosity)
|
||||
|
||||
# dont show log level name on default/lean logging
|
||||
if verbosity >= 20:
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s | %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
force=True,
|
||||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s | %(levelname)s: %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
||||
# create verbose logger with level 15
|
||||
def logger_verbose(msg, *args, **kwargs):
|
||||
if logging.getLogger().isEnabledFor(15):
|
||||
logging.log(15, msg)
|
||||
|
||||
|
||||
# create lean logger with level 25
|
||||
def logger_lean(msg, *args, **kwargs):
|
||||
if logging.getLogger().isEnabledFor(25):
|
||||
logging.log(25, msg)
|
|
@ -1,4 +1,6 @@
|
|||
import logging
|
||||
import re
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from zipfile import ZipFile
|
||||
|
@ -22,7 +24,7 @@ def make_pdf(chapter_path: Path) -> None:
|
|||
try:
|
||||
import img2pdf
|
||||
except:
|
||||
print("Cant import img2pdf. Please install it first")
|
||||
logging.error("Cant import img2pdf. Please install it first")
|
||||
raise ImportError
|
||||
|
||||
pdf_path = Path(f"{chapter_path}.pdf")
|
||||
|
@ -32,7 +34,7 @@ def make_pdf(chapter_path: Path) -> None:
|
|||
try:
|
||||
pdf_path.write_bytes(img2pdf.convert(images))
|
||||
except:
|
||||
print("ERR: Can't create '.pdf' archive")
|
||||
logging.error("Can't create '.pdf' archive")
|
||||
raise IOError
|
||||
|
||||
|
||||
|
@ -115,6 +117,7 @@ def get_filename(
|
|||
|
||||
|
||||
def progress_bar(progress: float, total: float) -> None:
|
||||
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
percent = int(progress / (int(total) / 100))
|
||||
bar_length = 50
|
||||
bar_progress = int(progress / (int(total) / bar_length))
|
||||
|
@ -122,6 +125,6 @@ def progress_bar(progress: float, total: float) -> None:
|
|||
whitespace_texture = " " * (bar_length - bar_progress)
|
||||
if progress == total:
|
||||
full_bar = "■" * bar_length
|
||||
print(f"\r❙{full_bar}❙ 100%", end="\n")
|
||||
print(f"\r{time} | ❙{full_bar}❙ 100%", end="\n")
|
||||
else:
|
||||
print(f"\r❙{bar_texture}{whitespace_texture}❙ {percent}%", end="\r")
|
||||
print(f"\r{time} | ❙{bar_texture}{whitespace_texture}❙ {percent}%", end="\r")
|
||||
|
|
|
@ -3,7 +3,7 @@ requires = ["hatchling"]
|
|||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
version = "2.1.9"
|
||||
version = "2.1.10"
|
||||
name = "manga-dlp"
|
||||
description = "A cli manga downloader"
|
||||
readme = "README.md"
|
||||
|
@ -107,3 +107,10 @@ exclude_lines = [
|
|||
"@(abc.)?abstractmethod",
|
||||
]
|
||||
ignore_errors = true
|
||||
|
||||
[tool.pylint.main]
|
||||
py-version = "3.9"
|
||||
|
||||
[tool.pylint.logging]
|
||||
logging-modules = ["logging"]
|
||||
logging-format-style = "fstr"
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
mangadlp/
|
||||
manga-dlp.py
|
||||
pyproject.toml
|
||||
requirements.txt
|
||||
MANIFEST.in
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
LICENSE
|
|
@ -57,7 +57,7 @@ def test_chapter_list_full():
|
|||
forcevol=True,
|
||||
download_path="tests",
|
||||
download_wait=2,
|
||||
verbosity=3,
|
||||
verbosity=10,
|
||||
)
|
||||
chap_list = utils.get_chapter_list("1:1,1:2,1:4-1:7,2:", mdlp.manga_chapter_list)
|
||||
assert chap_list == [
|
||||
|
|
|
@ -18,7 +18,7 @@ def test_downloader():
|
|||
chapter_path = Path("tests/test_folder1")
|
||||
chapter_path.mkdir(parents=True, exist_ok=True)
|
||||
images = []
|
||||
downloader.download_chapter(urls, str(chapter_path), 2, True)
|
||||
downloader.download_chapter(urls, str(chapter_path), 2)
|
||||
for file in chapter_path.iterdir():
|
||||
images.append(file.name)
|
||||
|
||||
|
@ -43,7 +43,7 @@ def test_downloader_fail(monkeypatch):
|
|||
chapter_path.mkdir(parents=True, exist_ok=True)
|
||||
monkeypatch.setattr(requests, "get", fail_url)
|
||||
with pytest.raises(ConnectionError) as e:
|
||||
downloader.download_chapter(images, str(chapter_path), 2, True)
|
||||
downloader.download_chapter(images, str(chapter_path), 2)
|
||||
|
||||
assert e.type == ConnectionError
|
||||
# cleanup
|
||||
|
|
|
@ -8,8 +8,7 @@ def test_uuid_link():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
|
||||
assert test.manga_uuid == "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
|
||||
|
@ -18,8 +17,7 @@ def test_uuid_pure():
|
|||
url_uuid = "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
|
||||
assert test.manga_uuid == "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
|
||||
|
@ -28,10 +26,9 @@ def test_uuid_link_false():
|
|||
url_uuid = "https://mangadex.org/title/a966-76e-5-8a-e2-42-5e-b-549-7f15dd-34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -40,8 +37,7 @@ def test_title():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
|
||||
assert test.manga_title == "Komi-san wa Komyushou Desu"
|
||||
|
||||
|
@ -50,8 +46,7 @@ def test_chapter_infos():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
chapter_infos = test.get_chapter_infos("1")
|
||||
chapter_uuid = chapter_infos["uuid"]
|
||||
chapter_name = chapter_infos["name"]
|
||||
|
@ -70,10 +65,9 @@ def test_non_existing_manga():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-999999999999/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -86,10 +80,9 @@ def test_api_failure(monkeypatch):
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -98,8 +91,7 @@ def test_chapter_lang_en():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = True
|
||||
test = Mangadex(url_uuid, language, forcevol, 3)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
|
||||
assert test.check_chapter_lang() > 0
|
||||
|
||||
|
@ -108,11 +100,10 @@ def test_empty_chapter_lang():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "ch"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity).check_chapter_lang()
|
||||
Mangadex(url_uuid, language, forcevol)
|
||||
Mangadex(url_uuid, language, forcevol).check_chapter_lang()
|
||||
assert e.type == KeyError or e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -121,10 +112,9 @@ def test_not_existing_lang():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "zz"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -135,8 +125,7 @@ def test_create_chapter_list():
|
|||
)
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
test_list = [
|
||||
"1",
|
||||
"2",
|
||||
|
@ -170,8 +159,7 @@ def test_create_chapter_list_forcevol():
|
|||
)
|
||||
language = "en"
|
||||
forcevol = True
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
test_list = [
|
||||
"1:1",
|
||||
"1:2",
|
||||
|
@ -203,8 +191,7 @@ def test_get_chapter_images():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
img_base_url = "https://uploads.mangadex.org"
|
||||
chapter_hash = "0752bc5db298beff6b932b9151dd8437"
|
||||
chapter_uuid = "e86ec2c4-c5e4-4710-bfaa-7604f00939c7"
|
||||
|
@ -235,8 +222,7 @@ def test_get_chapter_images_error(monkeypatch):
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test = Mangadex(url_uuid, language, forcevol)
|
||||
chapter_num = "1"
|
||||
monkeypatch.setattr(requests, "get", fail_url)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ def test_full_api_mangadex(wait_20s):
|
|||
forcevol=False,
|
||||
download_path="tests",
|
||||
download_wait=2,
|
||||
verbosity=3,
|
||||
verbosity=10,
|
||||
)
|
||||
mdlp.get_manga()
|
||||
|
||||
|
@ -61,6 +61,24 @@ 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/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
file_format = "cbz"
|
||||
download_path = "tests"
|
||||
manga_path = Path("tests/Shikimori's Not Just a Cutie")
|
||||
chapter_path = Path("tests/Shikimori's Not Just a Cutie/Ch. 1.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}")
|
||||
|
||||
assert manga_path.exists() and manga_path.is_dir()
|
||||
assert chapter_path.exists() and chapter_path.is_file()
|
||||
# cleanup
|
||||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_pdf(wait_20s):
|
||||
# check if its arm64, if yes skip this step
|
||||
if platform.machine() != "x86_64":
|
||||
|
|
Loading…
Reference in a new issue