diff --git a/.drone.yml b/.drone.yml index 72a3ff7..4a675d9 100644 --- a/.drone.yml +++ b/.drone.yml @@ -36,3 +36,120 @@ steps: sources: . exclusions: contrib/** + + +--- +################ +# docker build # +################ +kind: pipeline +type: docker +name: docker-build-arm64 + +platform: + os: linux + arch: arm64 + +trigger: + event: + - tag + +# anchors +cr_secrets: &cr_secrets + username: + from_secret: cr-dhub-username + password: + from_secret: cr-dhub-key + +docker_build: &docker_build + image: plugins/docker + pull: if-not-exists + group: build + +# build steps arm64 +steps: +- name: 'build and publish docker image' + <<: *docker_build + settings: + repo: olofvndrhr/manga-dlp + registry: hub.docker.com + context: docker + dockerfile: docker/Dockerfile.arm64 + auto_tag: true + auto_tag_suffix: linux-arm64 + <<: *cr_secrets + + +--- +kind: pipeline +type: docker +name: docker-build-amd64 + +platform: + os: linux + arch: amd64 + +trigger: + event: + - tag + +# anchors +cr_secrets: &cr_secrets + username: + from_secret: cr-dhub-username + password: + from_secret: cr-dhub-key + +docker_build: &docker_build + image: plugins/docker + pull: if-not-exists + group: build + +# build steps amd64 +steps: +- name: 'build and publish docker image' + <<: *docker_build + settings: + repo: olofvndrhr/manga-dlp + registry: hub.docker.com + context: docker + dockerfile: docker/Dockerfile.amd64 + auto_tag: true + auto_tag_suffix: linux-amd64 + <<: *cr_secrets + + +--- +kind: pipeline +type: docker +name: docker-publish-manifest + +platform: + os: linux + arch: amd64 + +trigger: + event: + - tag + +# anchors +cr_secrets: &cr_secrets + username: + from_secret: cr-dhub-username + password: + from_secret: cr-dhub-key + +# build steps +steps: +- name: 'publish manifest' + image: plugins/manifest + settings: + spec: docker/manifest.tmpl + auto_tag: true + ignore_missing: true + <<: *cr_secrets + +depends_on: + - docker-build-amd64 + - docker-build-arm64 + diff --git a/docker/Dockerfile.amd64 b/docker/Dockerfile.amd64 new file mode 100644 index 0000000..744be80 --- /dev/null +++ b/docker/Dockerfile.amd64 @@ -0,0 +1,45 @@ +FROM cr.44net.ch/baseimages/debian-s6-slim:1.3.1 + +# set version label +ARG BUILD_DATE +ARG VERSION +LABEL build_version="Version:- ${VERSION} Build-date:- ${BUILD_DATE}" +LABEL maintainer="Ivan Schaller" + +# manga-dlp version +ARG MDLP_VERSION=1.0.0 + +# 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/* + + +# install app +RUN git -C /app/ clone --depth 1 --branch ${MDLP_VERSION} \ + https://github.com/olofvndrhr/manga-dlp.git /app && \ + pip install -r /app/requirements.txt && \ + rm -rf \ + /app/docker \ + /app/contrib \ + /app/tests + + +# copy files to container +COPY rootfs / + +WORKDIR /app + diff --git a/docker/Dockerfile.arm64 b/docker/Dockerfile.arm64 new file mode 100644 index 0000000..744be80 --- /dev/null +++ b/docker/Dockerfile.arm64 @@ -0,0 +1,45 @@ +FROM cr.44net.ch/baseimages/debian-s6-slim:1.3.1 + +# set version label +ARG BUILD_DATE +ARG VERSION +LABEL build_version="Version:- ${VERSION} Build-date:- ${BUILD_DATE}" +LABEL maintainer="Ivan Schaller" + +# manga-dlp version +ARG MDLP_VERSION=1.0.0 + +# 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/* + + +# install app +RUN git -C /app/ clone --depth 1 --branch ${MDLP_VERSION} \ + https://github.com/olofvndrhr/manga-dlp.git /app && \ + pip install -r /app/requirements.txt && \ + rm -rf \ + /app/docker \ + /app/contrib \ + /app/tests + + +# copy files to container +COPY rootfs / + +WORKDIR /app + diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..e14aeed --- /dev/null +++ b/docker/README.md @@ -0,0 +1,74 @@ +# Docker container of manga-dlp + +## Quick start + +```sh +# with docker-compose +curl -O docker-compose.yml https://raw.githubusercontent.com/olofvndrhr/manga-dlp/master/docker/docker-compose.yml +# adjust settings to your needs +docker-compose up -d + +# with docker run +docker run -v ./downloads:/app/downloads -v ./mangas.txt:/app/mangas.txt olofvndrhr/manga-dlp +``` +### Change UID/GID +You can change the UID and GID of the container user simply with: +```yml +# docker-compose.yml + environment: + - PUID= + - PGID= +``` +```sh +docker run -e PUID= -e PGID= +``` + +## Run commands in container +You can simply use the `docker exec` command to run the scripts like normal. + +```sh +docker exec python3 manga-dlp.py +``` + +## Run your own schedule + +The default config runs manga-dlp.py once a day at 03:00 and fetches every chapter of the mangas listed in the file mangas.txt in the root directory of this repo. + +To use your own schedule you need to mount (override) the default crontab or add new ones to the cron directory. + +```yml +# docker-compose.yml + volumes: + - ./crontab:/etc/cron.d/01-manga-dlp # overwrites the default one + - ./crontab2:/etc/cron.d/02-something # adds a new one +``` +```sh +docker run -v ./crontab:/etc/cron.d/01-manga-dlp # overwrites the default one +docker run -v ./crontab2:/etc/cron.d/02-something # adds a new one +``` +## Add mangas to mangas.txt +If you use the default crontab you still need to add some mangas to mangas.txt. This is done almost identical to adding your own cron schedule. +If you use a custom cron schedule you need to mount the file you specified with `--read`. + +```yml +# docker-compose.yml + volumes: + - ./mangas.txt:/app/mangas.txt +``` +```sh +docker run -v ./mangas.txt:/app/mangas.txt +``` + +## Change download directory +Per default as in the script, it downloads everything to "downloads" in the scripts root directory. This data does not persist with container recreation, so you need to mount it. This is already done in the quick start section. +If you want to change the path of the host, simply change `./media/mangas/` to a path of your choice. + +```yml +# docker-compose.yml + volumes: + - ./media/mangas/:/app/downloads +``` +```sh +docker run -v ./media/mangas/:/app/downloads +``` + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..d9f0ea9 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,23 @@ +version: "3" +services: + + manga-dlp: + image: olofvndrhr/manga-dlp:latest + container_name: manga-dlp + restart: unless-stopped + security_opt: + - no-new-privileges:true + networks: + - mangadlp + volumes: + - ./downloads/:/app/downloads/ # default manga download directory + - ./mangas.txt:/app/mangas.txt # default file for manga links to download + environment: + - TZ=Europe/Zurich + # - PUID= # custom userid - defaults to 4444 + # - PGID= # custom groupid - defaults to 4444 + + +networks: + mangadlp: + diff --git a/docker/manifest.tmpl b/docker/manifest.tmpl new file mode 100644 index 0000000..e00295a --- /dev/null +++ b/docker/manifest.tmpl @@ -0,0 +1,20 @@ +image: hub.docker.com/olofvndrhr/manga-dlp:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}} +{{#if build.tags}} +tags: +{{#each build.tags}} + - {{this}} +{{/each}} + - "latest" +{{/if}} +manifests: + - + image: hub.docker.com/olofvndrhr/manga-dlp:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: hub.docker.com/olofvndrhr/manga-dlp:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64 + platform: + architecture: arm64 + os: linux + variant: v8 diff --git a/docker/rootfs/etc/cont-init.d/20-setenv b/docker/rootfs/etc/cont-init.d/20-setenv new file mode 100644 index 0000000..3526d56 --- /dev/null +++ b/docker/rootfs/etc/cont-init.d/20-setenv @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +# set all env variables for further use. If variable is unset, it will have the defaults on the right side after ":=" + + +# custom env vars +#: "${var1:=/path1}" + diff --git a/docker/rootfs/etc/cont-init.d/80-fix-perms b/docker/rootfs/etc/cont-init.d/80-fix-perms new file mode 100644 index 0000000..d5e72a5 --- /dev/null +++ b/docker/rootfs/etc/cont-init.d/80-fix-perms @@ -0,0 +1,13 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +# source env variables +source /etc/cont-init.d/20-setenv + +# fix permissions +find '/app' -type 'd' \( -not -perm 775 -and -not -path '/app/downloads*' \) -exec chmod 775 '{}' \+ +find '/app' -type 'f' \( -not -perm 664 -and -not -path '/app/downloads*' \) -exec chmod 664 '{}' \+ + +find '/app' \( -not -user abc -and -not -path '/app/downloads*' \) -exec chown abc '{}' \+ +find '/app' \( -not -group abc -and -not -path '/app/downloads*' \) -exec chown :abc '{}' \+ + diff --git a/docker/rootfs/etc/cron.d/01-manga-dlp b/docker/rootfs/etc/cron.d/01-manga-dlp new file mode 100644 index 0000000..80789cc --- /dev/null +++ b/docker/rootfs/etc/cron.d/01-manga-dlp @@ -0,0 +1,6 @@ +# default crontab to run manga-dlp once a day +# and get all (new) chapters of the mangas in +# the file mangas.txt + +0 3 * * * abc python3 /app/manga-dlp.py --read /app/mangas.txt -c all + diff --git a/mangadlp/main.py b/mangadlp/main.py index cdbfbee..451e53d 100644 --- a/mangadlp/main.py +++ b/mangadlp/main.py @@ -53,6 +53,8 @@ def main(manga_url='', # loop trough every chapter in readin file for url in readin_list(manga_readlist): ApiUsed = check_api(url) + if not ApiUsed: + continue if log_verbose: print(f'Api used: {ApiUsed}') # get manga @@ -60,6 +62,8 @@ def main(manga_url='', else: # single manga ApiUsed = check_api(manga_url) + if not ApiUsed: + exit(1) if log_verbose: print(f'Api used: {ApiUsed}') # get manga @@ -88,6 +92,10 @@ def check_api(manga_url): # this is only for testing multiple apis elif api_test.search(manga_url): pass + # no supported api found + else: + print(f'No supported api in link found\n{manga_url}') + return False # main function to get the chapters diff --git a/mangas.txt b/mangas.txt new file mode 100644 index 0000000..de3c05b --- /dev/null +++ b/mangas.txt @@ -0,0 +1 @@ +# template file for a list of manga links