[2.1.9] - 2022-06-26
## [2.1.9] - 2022-06-26 ### Fixed - Timeouts in tests, due to api limitations. Now added a wait time between tests - Pytest path ### Added - `--lean` flag for less output - [justfile](https://github.com/casey/just) for setting up a dev environment and testing the code - [asdf](https://github.com/asdf-vm/asdf) for version management - Dev requirements in [contrib/requirements_dev.txt](contrib/requirements_dev.txt) - `README` in [contrib](contrib) ### Changed - Handling of verbosity and logging. Now there are 4 types of verbosity: `normal`, `lean`, `verbose` and `debug` - CI/CD pipeline for testing and releases - Coverage testing now also done with `tox` - Default verbosity of docker container is now `--lean` - Reorganised [pyproject.toml](pyproject.toml)
This commit is contained in:
commit
b4d636a845
32 changed files with 512 additions and 251 deletions
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 2.1.8
|
||||
current_version = 2.1.9
|
||||
commit = True
|
||||
tag = False
|
||||
serialize = {major}.{minor}.{patch}
|
||||
|
|
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
|||
use asdf
|
5
.tool-versions
Normal file
5
.tool-versions
Normal file
|
@ -0,0 +1,5 @@
|
|||
python 3.9.13 3.10.5 3.8.13 3.7.13 3.6.15
|
||||
shfmt 3.5.1
|
||||
shellcheck 0.8.0
|
||||
just 1.2.0
|
||||
direnv 2.32.1
|
|
@ -1,42 +0,0 @@
|
|||
#############
|
||||
# build app #
|
||||
#############
|
||||
# branch: master
|
||||
# event: tag
|
||||
|
||||
depends_on:
|
||||
- tests
|
||||
|
||||
clone:
|
||||
git:
|
||||
when:
|
||||
#branch: master
|
||||
event: tag
|
||||
image: woodpeckerci/plugin-git
|
||||
|
||||
pipeline:
|
||||
|
||||
# build wheel and dist
|
||||
build-pypi:
|
||||
when:
|
||||
#branch: master
|
||||
event: tag
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
commands:
|
||||
- hatch build
|
||||
|
||||
# release pypi
|
||||
release-pypi:
|
||||
when:
|
||||
#branch: master
|
||||
event: tag
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
secrets:
|
||||
- source: pypi_username
|
||||
target: HATCH_PYPI_USER
|
||||
- source: pypi_token
|
||||
target: HATCH_PYPI_AUTH
|
||||
commands:
|
||||
- hatch publish
|
|
@ -16,15 +16,15 @@ clone:
|
|||
|
||||
pipeline:
|
||||
|
||||
# create release tar
|
||||
create-release-tar:
|
||||
# build wheel and dist
|
||||
build-pypi:
|
||||
when:
|
||||
#branch: master
|
||||
event: tag
|
||||
image: cr.44net.ch/baseimages/debian-base
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
commands:
|
||||
- tar -czf manga-dlp-${CI_COMMIT_TAG}.tar.gz --files-from=release-files.txt
|
||||
- hatch build
|
||||
|
||||
# create release-notes
|
||||
create-release-notes:
|
||||
|
@ -47,7 +47,7 @@ pipeline:
|
|||
api_key:
|
||||
from_secret: gitea-olofvndrhr-token
|
||||
base_url: https://git.44net.ch
|
||||
files: manga-dlp-${CI_COMMIT_TAG}.tar.gz
|
||||
files: dist/*
|
||||
title: ${CI_COMMIT_TAG}
|
||||
note: RELEASENOTES.md
|
||||
|
||||
|
@ -61,6 +61,21 @@ pipeline:
|
|||
settings:
|
||||
api_key:
|
||||
from_secret: github-olofvndrhr-token
|
||||
files: manga-dlp-${CI_COMMIT_TAG}.tar.gz
|
||||
files: dist/*
|
||||
title: ${CI_COMMIT_TAG}
|
||||
note: RELEASENOTES.md
|
||||
|
||||
# release pypi
|
||||
release-pypi:
|
||||
when:
|
||||
#branch: master
|
||||
event: tag
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
secrets:
|
||||
- source: pypi_username
|
||||
target: HATCH_PYPI_USER
|
||||
- source: pypi_token
|
||||
target: HATCH_PYPI_AUTH
|
||||
commands:
|
||||
- hatch publish
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
##################
|
||||
# test build app #
|
||||
##################
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
|
||||
depends_on:
|
||||
- tests
|
||||
|
||||
clone:
|
||||
git:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: woodpeckerci/plugin-git
|
||||
|
||||
pipeline:
|
||||
|
||||
# build wheel and dist
|
||||
test-build-pypi:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
commands:
|
||||
- hatch build
|
||||
|
||||
# # test code with different python versions - amd64
|
||||
# test-tox-amd64:
|
||||
# when:
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
# image: cr.44net.ch/ci-plugins/tests:1-linux-amd64
|
||||
# pull: true
|
||||
# commands:
|
||||
# - tox
|
||||
#
|
||||
# # test code with different python versions - arm64
|
||||
# test-tox-arm64:
|
||||
# when:
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
# image: cr.44net.ch/ci-plugins/tests:1-linux-arm64
|
||||
# pull: true
|
||||
# commands:
|
||||
# - tox
|
|
@ -30,7 +30,7 @@ pipeline:
|
|||
dockerfile: docker/Dockerfile.amd64
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-amd64-test
|
||||
build_args: BUILD_VERSION=2.1.8
|
||||
build_args: BUILD_VERSION=2.1.9
|
||||
|
||||
# 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.8
|
||||
build_args: BUILD_VERSION=2.1.9
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
########################
|
||||
# test publish release #
|
||||
########################
|
||||
################
|
||||
# test release #
|
||||
################
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
|
||||
|
@ -16,18 +16,17 @@ clone:
|
|||
|
||||
pipeline:
|
||||
|
||||
# create release tar
|
||||
test-create-release-tar:
|
||||
# build wheel and dist
|
||||
test-build-pypi:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: cr.44net.ch/baseimages/debian-base
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
pull: true
|
||||
commands:
|
||||
- tar -czf manga-dlp-2.1.8.tar.gz --files-from=release-files.txt
|
||||
- tar -tzf manga-dlp-2.1.8.tar.gz
|
||||
- hatch build
|
||||
|
||||
# create release-notes
|
||||
# create release-notes
|
||||
test-create-release-notes:
|
||||
when:
|
||||
branch: master
|
||||
|
@ -35,5 +34,5 @@ pipeline:
|
|||
image: cr.44net.ch/baseimages/debian-base
|
||||
pull: true
|
||||
commands:
|
||||
- bash get_release_notes.sh 2.1.8
|
||||
- bash get_release_notes.sh 2.1.9
|
||||
- cat RELEASENOTES.md
|
||||
|
|
27
.woodpecker/test_tox_amd64.yml
Normal file
27
.woodpecker/test_tox_amd64.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
##################
|
||||
# test tox amd64 #
|
||||
##################
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
|
||||
depends_on:
|
||||
- tests
|
||||
|
||||
clone:
|
||||
git:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: woodpeckerci/plugin-git
|
||||
|
||||
pipeline:
|
||||
|
||||
# test code with different python versions - amd64
|
||||
test-tox-amd64:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: cr.44net.ch/ci-plugins/multipy:1-linux-amd64
|
||||
pull: true
|
||||
commands:
|
||||
- tox
|
30
.woodpecker/test_tox_arm64.yml
Normal file
30
.woodpecker/test_tox_arm64.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
##################
|
||||
# test tox arm64 #
|
||||
##################
|
||||
# branch: master
|
||||
# event: pull_request
|
||||
|
||||
depends_on:
|
||||
- tests
|
||||
|
||||
clone:
|
||||
git:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: woodpeckerci/plugin-git
|
||||
|
||||
pipeline:
|
||||
|
||||
# test code with different python versions - arm64
|
||||
test-tox-arm64:
|
||||
when:
|
||||
branch: master
|
||||
event: pull_request
|
||||
image: cr.44net.ch/ci-plugins/multipy:1-linux-arm64
|
||||
pull: true
|
||||
commands:
|
||||
- grep -v img2pdf contrib/requirements_dev.txt > contrib/requirements_dev_arm64.txt
|
||||
- rm -f contrib/requirements_dev.txt
|
||||
- mv contrib/requirements_dev_arm64.txt contrib/requirements_dev.txt
|
||||
- tox
|
|
@ -38,20 +38,30 @@ pipeline:
|
|||
commands:
|
||||
- mypy --install-types --non-interactive mangadlp/
|
||||
|
||||
# test code and generate coverage report
|
||||
test-coverage-pytest:
|
||||
image: cr.44net.ch/ci-plugins/tests
|
||||
# test code with different python versions
|
||||
test-tox-pytest:
|
||||
when:
|
||||
event: [ push ]
|
||||
image: cr.44net.ch/ci-plugins/multipy:1-linux-amd64
|
||||
pull: true
|
||||
commands:
|
||||
- pip install -r requirements.txt
|
||||
- coverage erase
|
||||
- coverage run
|
||||
- coverage xml -i
|
||||
- tox -e basic
|
||||
|
||||
# generate coverage report
|
||||
test-tox-coverage:
|
||||
when:
|
||||
branch: master
|
||||
event: [ pull_request ]
|
||||
image: cr.44net.ch/ci-plugins/multipy:1-linux-amd64
|
||||
pull: true
|
||||
commands:
|
||||
- tox -e coverage
|
||||
|
||||
# analyse code with sonarqube and upload it
|
||||
sonarqube-analysis:
|
||||
when:
|
||||
branch: master
|
||||
event: [ pull_request ]
|
||||
image: cr.44net.ch/ci-plugins/sonar-scanner
|
||||
pull: true
|
||||
settings:
|
||||
|
|
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -9,6 +9,29 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
|
||||
- Add support for more sites
|
||||
|
||||
## [2.1.9] - 2022-06-26
|
||||
|
||||
### Fixed
|
||||
|
||||
- Timeouts in tests, due to api limitations. Now added a wait time between tests
|
||||
- Pytest path
|
||||
|
||||
### Added
|
||||
|
||||
- `--lean` flag for less output
|
||||
- [justfile](https://github.com/casey/just) for setting up a dev environment and testing the code
|
||||
- [asdf](https://github.com/asdf-vm/asdf) for version management
|
||||
- Dev requirements in [contrib/requirements_dev.txt](contrib/requirements_dev.txt)
|
||||
- `README` in [contrib](contrib)
|
||||
|
||||
### Changed
|
||||
|
||||
- Handling of verbosity and logging. Now there are 4 types of verbosity: `normal`, `lean`, `verbose` and `debug`
|
||||
- CI/CD pipeline for testing and releases
|
||||
- Coverage testing now also done with `tox`
|
||||
- Default verbosity of docker container is now `--lean`
|
||||
- Reorganised [pyproject.toml](pyproject.toml)
|
||||
|
||||
## [2.1.8] - 2022-06-22
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -224,10 +224,12 @@ This will download the chapter and save it as a zip archive.
|
|||
For suggestions for improvement, just open a pull request.
|
||||
|
||||
If you want to add support for a new site, there is an api [template file](./contrib/api_template.py) which you can use.
|
||||
And more infos and tools in the contrib [README.md](contrib/README.md)
|
||||
|
||||
Otherwise you can open a issue with the name of the site which you want support for. (not guaranteed to be implemented)
|
||||
Otherwise, you can open am issue with the name of the site which you want support for. (not guaranteed to be
|
||||
implemented)
|
||||
|
||||
If you encounter any bugs, also just open a issue with a description of the problem.
|
||||
If you encounter any bugs, also just open an issue with a description of the problem.
|
||||
|
||||
## TODO's
|
||||
|
||||
|
|
16
contrib/README.md
Normal file
16
contrib/README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# contribute
|
||||
|
||||
### install dev requirements
|
||||
|
||||
```sh
|
||||
python3 -m pip install -r contrib/requirements_dev.txt
|
||||
```
|
||||
|
||||
### setup asdf with all needed tools and versions
|
||||
|
||||
> you may need to install just first: [link](https://github.com/casey/just)
|
||||
|
||||
```sh
|
||||
just prepare_workspace
|
||||
```
|
||||
|
13
contrib/requirements_dev.txt
Normal file
13
contrib/requirements_dev.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
# application requirements
|
||||
requests>=2.24.0
|
||||
img2pdf>=0.4.4
|
||||
|
||||
# dev and testing requirements
|
||||
pytest>=7.0.0
|
||||
coverage>=6.3.1
|
||||
black>=22.1.0
|
||||
isort>=5.10.0
|
||||
pylint>=2.13.0
|
||||
mypy>=0.940
|
||||
tox>=3.24.5
|
||||
hatch>=1.0.0
|
|
@ -55,7 +55,8 @@ python3 /app/manga-dlp.py \
|
|||
--path /app/downloads \
|
||||
--read /app/mangas.txt \
|
||||
--chapters all \
|
||||
--wait 2
|
||||
--wait 2 \
|
||||
--lean
|
||||
```
|
||||
|
||||
To use your own schedule you need to mount (override) the default schedule or add new ones to the crontab.
|
||||
|
|
|
@ -4,4 +4,5 @@ python3 /app/manga-dlp.py \
|
|||
--path /app/downloads \
|
||||
--read /app/mangas.txt \
|
||||
--chapters all \
|
||||
--wait 2
|
||||
--wait 2 \
|
||||
--lean
|
||||
|
|
137
justfile
Executable file
137
justfile
Executable file
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env just --justfile
|
||||
|
||||
default: show_receipts
|
||||
|
||||
set shell := ["bash", "-uc"]
|
||||
set dotenv-load := true
|
||||
#set export
|
||||
|
||||
# aliases
|
||||
alias s := show_receipts
|
||||
alias i := show_system_info
|
||||
alias p := prepare_workspace
|
||||
alias l := lint
|
||||
alias t := tests
|
||||
alias f := tests_full
|
||||
|
||||
# variables
|
||||
export asdf_version := "v0.10.2"
|
||||
|
||||
# default recipe to display help information
|
||||
show_receipts:
|
||||
@just --list
|
||||
|
||||
show_system_info:
|
||||
@echo "=================================="
|
||||
@echo "os : {{os()}}"
|
||||
@echo "arch: {{arch()}}"
|
||||
@echo "home: ${HOME}"
|
||||
@echo "project dir: {{justfile_directory()}}"
|
||||
@echo "=================================="
|
||||
|
||||
check_asdf:
|
||||
@if ! asdf --version; then \
|
||||
just install_asdf \
|
||||
;else \
|
||||
echo "asdf already installed" \
|
||||
;fi
|
||||
just install_asdf_bins
|
||||
|
||||
install_asdf:
|
||||
@echo "installing asdf"
|
||||
@echo "asdf version: ${asdf_version}"
|
||||
@git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch "${asdf_version}"
|
||||
@echo "adding asdf to .bashrc"
|
||||
@if ! grep -q ".asdf/asdf.sh" "${HOME}/.bashrc"; then \
|
||||
echo -e '\n# source asdf' >> "${HOME}/.bashrc" \
|
||||
;echo 'source "${HOME}/.asdf/asdf.sh"' >> "${HOME}/.bashrc" \
|
||||
;echo -e 'source "${HOME}/.asdf/completions/asdf.bash"\n' >> "${HOME}/.bashrc" \
|
||||
;fi
|
||||
@echo "to load asdf either restart your shell or do: 'source \${HOME}/.bashrc'"
|
||||
|
||||
setup_asdf:
|
||||
@echo "installing asdf bins"
|
||||
# add plugins
|
||||
@if ! asdf plugin add python; then :; fi
|
||||
@if ! asdf plugin add shfmt; then :; fi
|
||||
@if ! asdf plugin add shellcheck; then :; fi
|
||||
@if ! asdf plugin add just https://github.com/franklad/asdf-just; then :; fi
|
||||
@if ! asdf plugin add direnv; then :; fi
|
||||
# install bins
|
||||
@if ! asdf install; then :; fi
|
||||
# setup direnv
|
||||
@if ! asdf direnv setup --shell bash --version latest; then :; fi
|
||||
|
||||
create_venv:
|
||||
@echo "creating venv"
|
||||
@python3 -m pip install --upgrade pip setuptools wheel
|
||||
@python3 -m venv venv
|
||||
|
||||
test_shfmt:
|
||||
@find . -type f \( -name "**.sh" -and -not -path "./venv/*" -and -not -path "./.tox/*" \) -exec shfmt -d -i 4 -bn -ci -sr "{}" \+;
|
||||
|
||||
test_black:
|
||||
@python3 -m black --check --diff .
|
||||
|
||||
test_isort:
|
||||
@python3 -m isort --check-only --diff .
|
||||
|
||||
test_mypy:
|
||||
@python3 -m mypy --install-types --non-interactive mangadlp/
|
||||
|
||||
test_pytest:
|
||||
@python3 -m tox -e basic
|
||||
|
||||
test_tox:
|
||||
@python3 -m tox
|
||||
|
||||
test_tox_coverage:
|
||||
@python3 -m tox -e coverage
|
||||
|
||||
test_build:
|
||||
@python3 -m hatch build
|
||||
|
||||
test_ci_conf:
|
||||
@woodpecker-cli lint .woodpecker/
|
||||
|
||||
test_docker_build:
|
||||
@docker build . -f docker/Dockerfile.amd64 -t manga-dlp:test
|
||||
|
||||
# install dependecies and set everything up
|
||||
prepare_workspace:
|
||||
just show_system_info
|
||||
just check_asdf
|
||||
just setup_asdf
|
||||
just create_venv
|
||||
|
||||
lint:
|
||||
just show_system_info
|
||||
-just test_ci_conf
|
||||
just test_shfmt
|
||||
just test_black
|
||||
just test_isort
|
||||
just test_mypy
|
||||
@echo -e "\n\033[0;32m=== ALL DONE ===\033[0m\n"
|
||||
|
||||
tests:
|
||||
just show_system_info
|
||||
-just test_ci_conf
|
||||
just test_shfmt
|
||||
just test_black
|
||||
just test_isort
|
||||
just test_mypy
|
||||
just test_pytest
|
||||
@echo -e "\n\033[0;32m=== ALL DONE ===\033[0m\n"
|
||||
|
||||
tests_full:
|
||||
just show_system_info
|
||||
-just test_ci_conf
|
||||
just test_shfmt
|
||||
just test_black
|
||||
just test_isort
|
||||
just test_mypy
|
||||
just test_build
|
||||
just test_tox
|
||||
just test_tox_coverage
|
||||
just test_docker_build
|
||||
@echo -e "\n\033[0;32m=== ALL DONE ===\033[0m\n"
|
|
@ -1,6 +1,6 @@
|
|||
from mangadlp.input import main
|
||||
|
||||
MDLP_VERSION = "2.1.8"
|
||||
MDLP_VERSION = "2.1.9"
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -15,12 +15,12 @@ class Mangadex:
|
|||
img_base_url = "https://uploads.mangadex.org"
|
||||
|
||||
# get infos to initiate class
|
||||
def __init__(self, url_uuid: str, language: str, forcevol: bool, verbose: bool):
|
||||
def __init__(self, url_uuid: str, language: str, forcevol: bool, verbosity: int):
|
||||
# static info
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.forcevol = forcevol
|
||||
self.verbose = verbose
|
||||
self.verbosity = verbosity
|
||||
|
||||
# api stuff
|
||||
self.api_content_ratings = "contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic"
|
||||
|
@ -36,7 +36,7 @@ class Mangadex:
|
|||
|
||||
# make initial request
|
||||
def get_manga_data(self) -> requests.Response:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting manga data for: {self.manga_uuid}")
|
||||
counter = 1
|
||||
while counter <= 3:
|
||||
|
@ -76,7 +76,7 @@ class Mangadex:
|
|||
|
||||
# get the title of the manga (and fix the filename)
|
||||
def get_manga_title(self) -> str:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting manga title for: {self.manga_uuid}")
|
||||
manga_data = self.manga_data.json()
|
||||
try:
|
||||
|
@ -95,7 +95,7 @@ class Mangadex:
|
|||
|
||||
# check if chapters are available in requested language
|
||||
def check_chapter_lang(self) -> int:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(
|
||||
f"INFO: Checking for chapters in specified language for: {self.manga_uuid}"
|
||||
)
|
||||
|
@ -118,7 +118,7 @@ class Mangadex:
|
|||
|
||||
# get chapter data like name, uuid etc
|
||||
def get_chapter_data(self) -> dict:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting chapter data for: {self.manga_uuid}")
|
||||
api_sorting = "order[chapter]=asc&order[volume]=asc"
|
||||
# check for chapters in specified lang
|
||||
|
@ -177,7 +177,7 @@ class Mangadex:
|
|||
|
||||
# get images for the chapter (mangadex@home)
|
||||
def get_chapter_images(self, chapter: str, wait_time: float) -> list:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Getting chapter images for: {self.manga_uuid}")
|
||||
athome_url = f"{self.api_base_url}/at-home/server"
|
||||
chapter_uuid = self.manga_chapter_data[chapter][0]
|
||||
|
@ -224,7 +224,7 @@ class Mangadex:
|
|||
|
||||
# create list of chapters
|
||||
def create_chapter_list(self) -> list:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 2:
|
||||
print(f"INFO: Creating chapter list for: {self.manga_uuid}")
|
||||
chapter_list = []
|
||||
for chapter in self.manga_chapter_data.items():
|
||||
|
@ -240,7 +240,7 @@ class Mangadex:
|
|||
|
||||
# create easy to access chapter infos
|
||||
def get_chapter_infos(self, chapter: str) -> dict:
|
||||
if self.verbose:
|
||||
if self.verbosity >= 3:
|
||||
print(
|
||||
f"INFO: Getting chapter infos for: {self.manga_chapter_data[chapter][0]}"
|
||||
)
|
||||
|
|
|
@ -23,7 +23,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 verbose: If verbose logging is enabled
|
||||
:param verbosity: Verbosity of the output
|
||||
|
||||
:return: Nothing. Just the files
|
||||
"""
|
||||
|
@ -38,7 +38,7 @@ class MangaDLP:
|
|||
forcevol: bool = False,
|
||||
download_path: str = "downloads",
|
||||
download_wait: float = 0.5,
|
||||
verbose: bool = False,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
# init parameters
|
||||
self.url_uuid = url_uuid
|
||||
|
@ -49,7 +49,7 @@ class MangaDLP:
|
|||
self.forcevol = forcevol
|
||||
self.download_path = download_path
|
||||
self.download_wait = download_wait
|
||||
self.verbose = verbose
|
||||
self.verbosity = verbosity
|
||||
# prepare everything
|
||||
self._prepare()
|
||||
|
||||
|
@ -63,7 +63,7 @@ class MangaDLP:
|
|||
# init api
|
||||
self.api_used = self.check_api(self.url_uuid)
|
||||
self.api = self.api_used(
|
||||
self.url_uuid, self.language, self.forcevol, self.verbose
|
||||
self.url_uuid, self.language, self.forcevol, self.verbosity
|
||||
)
|
||||
# get manga title and uuid
|
||||
self.manga_uuid = self.api.manga_uuid
|
||||
|
@ -125,12 +125,15 @@ class MangaDLP:
|
|||
skipped_chapters: list[Any] = []
|
||||
error_chapters: list[Any] = []
|
||||
|
||||
# show infos
|
||||
print_divider = "========================================="
|
||||
print(f"\n{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)}")
|
||||
# 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)}")
|
||||
|
||||
# list chapters if list_chapters is true
|
||||
if self.list_chapters:
|
||||
|
@ -147,8 +150,11 @@ class MangaDLP:
|
|||
)
|
||||
|
||||
# show chapters to download
|
||||
print(f"INFO: Chapters selected:\n{', '.join(chapters_to_download)}")
|
||||
print(f"{print_divider}\n")
|
||||
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}")
|
||||
|
||||
# create manga folder
|
||||
self.manga_path.mkdir(parents=True, exist_ok=True)
|
||||
|
@ -171,17 +177,25 @@ class MangaDLP:
|
|||
print("INFO: Done with chapter\n")
|
||||
|
||||
# done with manga
|
||||
print(f"{print_divider}")
|
||||
if self.verbosity != 1:
|
||||
print(f"{print_divider}")
|
||||
print(f"INFO: Done with manga: {self.manga_title}")
|
||||
# filter skipped list
|
||||
skipped_chapters = list(filter(None, skipped_chapters))
|
||||
if len(skipped_chapters) >= 1:
|
||||
print(f"INFO: Skipped chapters:\n{', '.join(skipped_chapters)}")
|
||||
if self.verbosity == 1:
|
||||
print(f"INFO: Skipped chapters: {', '.join(skipped_chapters)}")
|
||||
else:
|
||||
print(f"INFO: Skipped chapters:\n{', '.join(skipped_chapters)}")
|
||||
# filter error list
|
||||
error_chapters = list(filter(None, error_chapters))
|
||||
if len(error_chapters) >= 1:
|
||||
print(f"INFO: Chapters with errors:\n{', '.join(error_chapters)}")
|
||||
print(f"{print_divider}\n")
|
||||
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")
|
||||
|
||||
# once called per chapter
|
||||
def get_chapter(self, chapter: str) -> dict:
|
||||
|
@ -225,7 +239,8 @@ class MangaDLP:
|
|||
# check if chapter already exists
|
||||
# check for folder, if file format is an empty string
|
||||
if chapter_archive_path.exists():
|
||||
print(f"INFO: '{chapter_archive_path}' already exists. Skipping")
|
||||
if self.verbosity != 1:
|
||||
print(f"INFO: '{chapter_archive_path}' already exists. Skipping")
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -240,7 +255,7 @@ class MangaDLP:
|
|||
chapter_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# verbose log
|
||||
if self.verbose:
|
||||
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")
|
||||
|
@ -252,7 +267,7 @@ class MangaDLP:
|
|||
# download images
|
||||
try:
|
||||
downloader.download_chapter(
|
||||
chapter_image_urls, chapter_path, self.download_wait, self.verbose
|
||||
chapter_image_urls, chapter_path, self.download_wait, self.verbosity
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print("ERR: Stopping")
|
||||
|
|
|
@ -14,7 +14,7 @@ def download_chapter(
|
|||
image_urls: list,
|
||||
chapter_path: Union[str, Path],
|
||||
download_wait: float,
|
||||
verbose: bool,
|
||||
verbosity: int,
|
||||
) -> None:
|
||||
total_img = len(image_urls)
|
||||
for image_num, image in enumerate(image_urls, 1):
|
||||
|
@ -22,11 +22,11 @@ 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 if verbose logging is not active
|
||||
if verbose:
|
||||
print(f"INFO: Downloading image {image_num}/{total_img}")
|
||||
else:
|
||||
# show progress bar or progress by image for verbose
|
||||
if verbosity == 0:
|
||||
utils.progress_bar(image_num, total_img)
|
||||
elif verbosity >= 2:
|
||||
print(f"INFO: Downloading image {image_num}/{total_img}")
|
||||
|
||||
counter = 1
|
||||
while counter <= 3:
|
||||
|
|
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||
|
||||
import mangadlp.app as app
|
||||
|
||||
MDLP_VERSION = "2.1.8"
|
||||
MDLP_VERSION = "2.1.9"
|
||||
|
||||
|
||||
def check_args(args):
|
||||
|
@ -48,7 +48,7 @@ def call_app(args):
|
|||
args.forcevol,
|
||||
args.path,
|
||||
args.wait,
|
||||
args.verbose,
|
||||
args.verbosity,
|
||||
)
|
||||
mdlp.get_manga()
|
||||
|
||||
|
@ -95,8 +95,10 @@ def get_args():
|
|||
parser = argparse.ArgumentParser(
|
||||
description="Script to download mangas from various sites"
|
||||
)
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument(
|
||||
action = parser.add_mutually_exclusive_group(required=True)
|
||||
verbosity = parser.add_mutually_exclusive_group(required=False)
|
||||
|
||||
action.add_argument(
|
||||
"-u",
|
||||
"--url",
|
||||
"--uuid",
|
||||
|
@ -105,14 +107,14 @@ def get_args():
|
|||
help="URL or UUID of the manga",
|
||||
action="store",
|
||||
)
|
||||
group.add_argument(
|
||||
action.add_argument(
|
||||
"--read",
|
||||
dest="read",
|
||||
required=False,
|
||||
help="Path of file with manga links to download. One per line",
|
||||
action="store",
|
||||
)
|
||||
group.add_argument(
|
||||
action.add_argument(
|
||||
"-v",
|
||||
"--version",
|
||||
dest="version",
|
||||
|
@ -176,12 +178,32 @@ def get_args():
|
|||
default=0.5,
|
||||
help="Time to wait for each picture to download in seconds(float). Defaults 0.5",
|
||||
)
|
||||
parser.add_argument(
|
||||
verbosity.add_argument(
|
||||
"--lean",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Lean logging. Defaults to false",
|
||||
action="store_const",
|
||||
const=1,
|
||||
default=0,
|
||||
)
|
||||
verbosity.add_argument(
|
||||
"--verbose",
|
||||
dest="verbose",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Verbose logging. Defaults to false",
|
||||
action="store_true",
|
||||
action="store_const",
|
||||
const=2,
|
||||
default=0,
|
||||
)
|
||||
verbosity.add_argument(
|
||||
"--debug",
|
||||
dest="verbosity",
|
||||
required=False,
|
||||
help="Lean logging. Defaults to false",
|
||||
action="store_const",
|
||||
const=3,
|
||||
default=0,
|
||||
)
|
||||
|
||||
# parser.print_help()
|
||||
|
|
|
@ -3,7 +3,7 @@ requires = ["hatchling"]
|
|||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
version = "2.1.8"
|
||||
version = "2.1.9"
|
||||
name = "manga-dlp"
|
||||
description = "A cli manga downloader"
|
||||
readme = "README.md"
|
||||
|
@ -39,7 +39,25 @@ Source = "https://github.com/olofvndrhr/manga-dlp"
|
|||
mangadlp = "mangadlp.input:main"
|
||||
manga-dlp = "mangadlp.input:main"
|
||||
|
||||
# isort config
|
||||
[tool.hatch.build]
|
||||
ignore-vcs = true
|
||||
|
||||
[tool.hatch.build.targets.sdist]
|
||||
include = ["mangadlp"]
|
||||
exclude = [
|
||||
"docker",
|
||||
".tox",
|
||||
".mypy_cache"
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
include = ["mangadlp"]
|
||||
exclude = [
|
||||
"docker",
|
||||
".tox",
|
||||
".mypy_cache"
|
||||
]
|
||||
|
||||
[tool.isort]
|
||||
py_version = 39
|
||||
skip_gitignore = true
|
||||
|
@ -49,7 +67,6 @@ multi_line_output = 3
|
|||
include_trailing_comma = true
|
||||
use_parentheses = true
|
||||
|
||||
# mypy config
|
||||
[tool.mypy]
|
||||
python_version = "3.9"
|
||||
disallow_untyped_defs = false
|
||||
|
@ -62,11 +79,15 @@ show_column_numbers = true
|
|||
show_error_codes = true
|
||||
pretty = true
|
||||
|
||||
# coverage.py config
|
||||
[tool.pytest.ini_options]
|
||||
pythonpath = [
|
||||
"."
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
source = ["mangadlp"]
|
||||
branch = true
|
||||
command_line = "-m pytest --verbose --exitfirst"
|
||||
command_line = "-m pytest --exitfirst"
|
||||
|
||||
[tool.coverage.report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
|
@ -86,22 +107,3 @@ exclude_lines = [
|
|||
"@(abc.)?abstractmethod",
|
||||
]
|
||||
ignore_errors = true
|
||||
|
||||
[tool.hatch.build]
|
||||
ignore-vcs = true
|
||||
|
||||
[tool.hatch.build.targets.sdist]
|
||||
include = ["mangadlp"]
|
||||
exclude = [
|
||||
"docker",
|
||||
".tox",
|
||||
".mypy_cache"
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
include = ["mangadlp"]
|
||||
exclude = [
|
||||
"docker",
|
||||
".tox",
|
||||
".mypy_cache"
|
||||
]
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
requests>=2.24.0
|
||||
|
||||
img2pdf>=0.4.4
|
||||
img2pdf>=0.4.4
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import mangadlp.app as app
|
||||
|
@ -8,7 +6,7 @@ from mangadlp.api.mangadex import Mangadex
|
|||
|
||||
def test_check_api_mangadex():
|
||||
url = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
test = app.MangaDLP(url_uuid=url, list_chapters=True)
|
||||
test = app.MangaDLP(url_uuid=url, list_chapters=True, download_wait=2)
|
||||
|
||||
assert test.api_used == Mangadex
|
||||
|
||||
|
@ -16,5 +14,5 @@ def test_check_api_mangadex():
|
|||
def test_check_api_none():
|
||||
url = "https://abc.defghjk/title/abc/def"
|
||||
with pytest.raises(ValueError) as e:
|
||||
app.MangaDLP(url_uuid=url, list_chapters=True)
|
||||
app.MangaDLP(url_uuid=url, list_chapters=True, download_wait=2)
|
||||
assert e.type == ValueError
|
||||
|
|
|
@ -56,8 +56,8 @@ def test_chapter_list_full():
|
|||
file_format="cbz",
|
||||
forcevol=True,
|
||||
download_path="tests",
|
||||
download_wait=0.5,
|
||||
verbose=True,
|
||||
download_wait=2,
|
||||
verbosity=3,
|
||||
)
|
||||
chap_list = utils.get_chapter_list("1:1,1:2,1:4-1:7,2:", mdlp.manga_chapter_list)
|
||||
assert chap_list == [
|
||||
|
|
|
@ -18,11 +18,11 @@ 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), 0.5, True)
|
||||
downloader.download_chapter(urls, str(chapter_path), 2, True)
|
||||
for file in chapter_path.iterdir():
|
||||
images.append(file.name)
|
||||
|
||||
print(images)
|
||||
images.sort()
|
||||
assert images == ["001.png", "002.png", "003.png", "004.png", "005.png"]
|
||||
# cleanup
|
||||
shutil.rmtree(chapter_path, ignore_errors=True)
|
||||
|
@ -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), 0.5, True)
|
||||
downloader.download_chapter(images, str(chapter_path), 2, True)
|
||||
|
||||
assert e.type == ConnectionError
|
||||
# cleanup
|
||||
|
|
|
@ -13,7 +13,7 @@ def test_read_and_url():
|
|||
chapters = "1"
|
||||
file_format = "cbz"
|
||||
download_path = "tests"
|
||||
command_args = f"-u {url_uuid} --read {link_file} -l {language} -c {chapters} --path {download_path} --format {file_format} --verbose"
|
||||
command_args = f"-u {url_uuid} --read {link_file} -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
|
||||
|
||||
|
@ -25,7 +25,7 @@ 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} --verbose"
|
||||
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
|
||||
|
||||
|
@ -36,7 +36,7 @@ def test_no_chaps():
|
|||
chapters = ""
|
||||
file_format = "cbz"
|
||||
download_path = "tests"
|
||||
command_args = f"-u {url_uuid} -l {language} --path {download_path} --format {file_format} --verbose"
|
||||
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
|
||||
|
||||
|
@ -47,7 +47,7 @@ def test_no_volume():
|
|||
chapters = "1"
|
||||
file_format = "cbz"
|
||||
download_path = "tests"
|
||||
command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --verbose --forcevol"
|
||||
command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --debug --forcevol"
|
||||
script_path = "manga-dlp.py"
|
||||
assert os.system(f"python3 {script_path} {command_args}") != 0
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ def test_uuid_link():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
|
||||
assert test.manga_uuid == "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
|
||||
|
@ -18,8 +18,8 @@ def test_uuid_pure():
|
|||
url_uuid = "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
|
||||
assert test.manga_uuid == "a96676e5-8ae2-425e-b549-7f15dd34a6d8"
|
||||
|
||||
|
@ -28,10 +28,10 @@ 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
|
||||
verbose = True
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbose)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -40,8 +40,8 @@ def test_title():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
|
||||
assert test.manga_title == "Komi-san wa Komyushou Desu"
|
||||
|
||||
|
@ -50,8 +50,8 @@ def test_chapter_infos():
|
|||
url_uuid = "https://mangadex.org/title/a96676e5-8ae2-425e-b549-7f15dd34a6d8/komi-san-wa-komyushou-desu"
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
chapter_infos = test.get_chapter_infos("1")
|
||||
chapter_uuid = chapter_infos["uuid"]
|
||||
chapter_name = chapter_infos["name"]
|
||||
|
@ -70,10 +70,10 @@ 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
|
||||
verbose = True
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbose)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -86,10 +86,10 @@ 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
|
||||
verbose = True
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbose)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -98,8 +98,8 @@ 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
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = True
|
||||
test = Mangadex(url_uuid, language, forcevol, 3)
|
||||
|
||||
assert test.check_chapter_lang() > 0
|
||||
|
||||
|
@ -108,11 +108,11 @@ 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
|
||||
verbose = True
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbose)
|
||||
Mangadex(url_uuid, language, forcevol, verbose).check_chapter_lang()
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity).check_chapter_lang()
|
||||
assert e.type == KeyError or e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -121,10 +121,10 @@ 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
|
||||
verbose = True
|
||||
verbosity = 3
|
||||
|
||||
with pytest.raises(SystemExit) as e:
|
||||
Mangadex(url_uuid, language, forcevol, verbose)
|
||||
Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
assert e.type == SystemExit
|
||||
assert e.value.code == 1
|
||||
|
||||
|
@ -135,8 +135,8 @@ def test_create_chapter_list():
|
|||
)
|
||||
language = "en"
|
||||
forcevol = False
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test_list = [
|
||||
"1",
|
||||
"2",
|
||||
|
@ -170,8 +170,8 @@ def test_create_chapter_list_forcevol():
|
|||
)
|
||||
language = "en"
|
||||
forcevol = True
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
test_list = [
|
||||
"1:1",
|
||||
"1:2",
|
||||
|
@ -203,8 +203,8 @@ 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
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
img_base_url = "https://uploads.mangadex.org"
|
||||
chapter_hash = "0752bc5db298beff6b932b9151dd8437"
|
||||
chapter_uuid = "e86ec2c4-c5e4-4710-bfaa-7604f00939c7"
|
||||
|
@ -225,7 +225,7 @@ def test_get_chapter_images():
|
|||
f"{img_base_url}/data/{chapter_hash}/x13-54d9718036b9d79e930e448b592c4a3df9045ed5b8c22ab411b09dadb864756f.jpg",
|
||||
f"{img_base_url}/data/{chapter_hash}/x14-f6ed71bbb9af2bceab51028b460813c57935c923e1872fb277beb21d54425434.jpg",
|
||||
]
|
||||
assert test.get_chapter_images(chapter_num, 0.5) == test_list
|
||||
assert test.get_chapter_images(chapter_num, 2) == test_list
|
||||
|
||||
|
||||
def test_get_chapter_images_error(monkeypatch):
|
||||
|
@ -235,9 +235,9 @@ 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
|
||||
verbose = True
|
||||
test = Mangadex(url_uuid, language, forcevol, verbose)
|
||||
verbosity = 3
|
||||
test = Mangadex(url_uuid, language, forcevol, verbosity)
|
||||
chapter_num = "1"
|
||||
monkeypatch.setattr(requests, "get", fail_url)
|
||||
|
||||
assert not test.get_chapter_images(chapter_num, 0.5)
|
||||
assert not test.get_chapter_images(chapter_num, 2)
|
||||
|
|
|
@ -1,11 +1,27 @@
|
|||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import mangadlp.app as app
|
||||
|
||||
|
||||
def test_full_api_mangadex():
|
||||
@pytest.fixture
|
||||
def wait_10s():
|
||||
print("sleeping 10 seconds because of api timeouts")
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def wait_20s():
|
||||
print("sleeping 20 seconds because of api timeouts")
|
||||
time.sleep(20)
|
||||
|
||||
|
||||
def test_full_api_mangadex(wait_20s):
|
||||
manga_path = Path("tests/Shikimori's Not Just a Cutie")
|
||||
chapter_path = Path("tests/Shikimori's Not Just a Cutie/Ch. 1.cbz")
|
||||
mdlp = app.MangaDLP(
|
||||
|
@ -16,8 +32,8 @@ def test_full_api_mangadex():
|
|||
file_format="cbz",
|
||||
forcevol=False,
|
||||
download_path="tests",
|
||||
download_wait=0.5,
|
||||
verbose=True,
|
||||
download_wait=2,
|
||||
verbosity=3,
|
||||
)
|
||||
mdlp.get_manga()
|
||||
|
||||
|
@ -27,7 +43,7 @@ def test_full_api_mangadex():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_cbz():
|
||||
def test_full_with_input_cbz(wait_20s):
|
||||
url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -35,7 +51,7 @@ def test_full_with_input_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} --verbose"
|
||||
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}")
|
||||
|
||||
|
@ -45,7 +61,11 @@ def test_full_with_input_cbz():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_pdf():
|
||||
def test_full_with_input_pdf(wait_20s):
|
||||
# check if its arm64, if yes skip this step
|
||||
if platform.machine() != "x86_64":
|
||||
return True
|
||||
|
||||
url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -53,7 +73,7 @@ def test_full_with_input_pdf():
|
|||
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.pdf")
|
||||
command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format {file_format} --verbose"
|
||||
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}")
|
||||
|
||||
|
@ -63,7 +83,7 @@ def test_full_with_input_pdf():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_folder():
|
||||
def test_full_with_input_folder(wait_20s):
|
||||
url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -71,7 +91,7 @@ def test_full_with_input_folder():
|
|||
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")
|
||||
command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format '{file_format}' --verbose"
|
||||
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}")
|
||||
|
||||
|
@ -81,7 +101,7 @@ def test_full_with_input_folder():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_skip_cbz():
|
||||
def test_full_with_input_skip_cbz(wait_10s):
|
||||
url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -89,7 +109,7 @@ def test_full_with_input_skip_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} --verbose"
|
||||
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)
|
||||
chapter_path.touch()
|
||||
|
@ -101,7 +121,7 @@ def test_full_with_input_skip_cbz():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_input_skip_folder():
|
||||
def test_full_with_input_skip_folder(wait_10s):
|
||||
url_uuid = "https://mangadex.org/title/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -109,7 +129,7 @@ def test_full_with_input_skip_folder():
|
|||
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")
|
||||
command_args = f"-u {url_uuid} -l {language} -c {chapters} --path {download_path} --format '{file_format}' --verbose"
|
||||
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)
|
||||
|
||||
|
@ -126,7 +146,7 @@ def test_full_with_input_skip_folder():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_read_cbz():
|
||||
def test_full_with_read_cbz(wait_20s):
|
||||
url_list = Path("tests/test_list2.txt")
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -134,7 +154,7 @@ def test_full_with_read_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"--read {str(url_list)} -l {language} -c {chapters} --path {download_path} --format {file_format} --verbose"
|
||||
command_args = f"--read {str(url_list)} -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/0aea9f43-d4a9-4bf7-bebc-550a512f9b95/shikimori-s-not-just-a-cutie"
|
||||
|
@ -148,7 +168,7 @@ def test_full_with_read_cbz():
|
|||
shutil.rmtree(manga_path, ignore_errors=True)
|
||||
|
||||
|
||||
def test_full_with_read_skip_cbz():
|
||||
def test_full_with_read_skip_cbz(wait_10s):
|
||||
url_list = Path("tests/test_list2.txt")
|
||||
language = "en"
|
||||
chapters = "1"
|
||||
|
@ -156,7 +176,7 @@ def test_full_with_read_skip_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"--read {str(url_list)} -l {language} -c {chapters} --path {download_path} --format {file_format} --verbose"
|
||||
command_args = f"--read {str(url_list)} -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()
|
||||
|
|
21
tox.ini
21
tox.ini
|
@ -4,10 +4,23 @@ isolated_build = True
|
|||
|
||||
[testenv]
|
||||
deps =
|
||||
pytest
|
||||
coverage
|
||||
-rrequirements.txt
|
||||
-rcontrib/requirements_dev.txt
|
||||
|
||||
commands =
|
||||
pytest -x --basetemp="{envtmpdir}" {posargs}
|
||||
pytest --exitfirst --basetemp="{envtmpdir}" {posargs}
|
||||
|
||||
[testenv:basic]
|
||||
deps =
|
||||
-rcontrib/requirements_dev.txt
|
||||
|
||||
commands =
|
||||
pytest --exitfirst --basetemp="{envtmpdir}" {posargs}
|
||||
|
||||
[testenv:coverage]
|
||||
deps =
|
||||
-rcontrib/requirements_dev.txt
|
||||
|
||||
commands =
|
||||
coverage erase
|
||||
coverage run
|
||||
coverage xml -i
|
||||
|
|
Loading…
Reference in a new issue