add hooks for custom actions
All checks were successful
ci/woodpecker/push/tests Pipeline was successful
All checks were successful
ci/woodpecker/push/tests Pipeline was successful
This commit is contained in:
parent
30955369c8
commit
c2d9ca9f72
5 changed files with 204 additions and 16 deletions
|
@ -9,6 +9,8 @@ class YourAPI:
|
|||
# get infos to initiate class
|
||||
def __init__(self, url_uuid, language, forcevol):
|
||||
# static info
|
||||
self.api_name = "Your API Name"
|
||||
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.forcevol = forcevol
|
||||
|
|
|
@ -36,6 +36,8 @@ class Mangadex:
|
|||
# get infos to initiate class
|
||||
def __init__(self, url_uuid: str, language: str, forcevol: bool):
|
||||
# static info
|
||||
self.api_name = "Mangadex"
|
||||
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.forcevol = forcevol
|
||||
|
|
|
@ -6,6 +6,7 @@ from typing import Any
|
|||
|
||||
from mangadlp import downloader, utils
|
||||
from mangadlp.api.mangadex import Mangadex
|
||||
from mangadlp.hooks import Hooks
|
||||
from mangadlp.logger import Logger
|
||||
|
||||
# prepare logger
|
||||
|
@ -38,16 +39,28 @@ class MangaDLP:
|
|||
forcevol: bool = False,
|
||||
download_path: str = "downloads",
|
||||
download_wait: float = 0.5,
|
||||
manga_pre_hook_cmd: str = "",
|
||||
manga_post_hook_cmd: str = "",
|
||||
chapter_pre_hook_cmd: str = "",
|
||||
chapter_post_hook_cmd: str = "",
|
||||
) -> None:
|
||||
# init parameters
|
||||
self.url_uuid = url_uuid
|
||||
self.language = language
|
||||
self.chapters = chapters
|
||||
self.list_chapters = list_chapters
|
||||
self.file_format = file_format
|
||||
self.forcevol = forcevol
|
||||
self.download_path = download_path
|
||||
self.download_wait = download_wait
|
||||
self.url_uuid: str = url_uuid
|
||||
self.language: str = language
|
||||
self.chapters: str = chapters
|
||||
self.list_chapters: bool = list_chapters
|
||||
self.file_format: str = file_format
|
||||
self.forcevol: bool = forcevol
|
||||
self.download_path: str = download_path
|
||||
self.download_wait: float = download_wait
|
||||
# hooks
|
||||
self.hook: Hooks = Hooks(
|
||||
manga_pre_hook_cmd,
|
||||
manga_post_hook_cmd,
|
||||
chapter_pre_hook_cmd,
|
||||
chapter_post_hook_cmd,
|
||||
)
|
||||
self.hook_infos: dict = {}
|
||||
# prepare everything
|
||||
self._prepare()
|
||||
|
||||
|
@ -147,15 +160,37 @@ class MangaDLP:
|
|||
# create manga folder
|
||||
self.manga_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# create dict with all variables for the hooks
|
||||
self.hook_infos.update(
|
||||
{
|
||||
"api": self.api.api_name,
|
||||
"manga_url_uuid": self.url_uuid,
|
||||
"manga_uuid": self.manga_uuid,
|
||||
"manga_title": self.manga_title,
|
||||
"language": self.language,
|
||||
"total_chapters": len(self.manga_chapter_list),
|
||||
"chapters_to_download": chapters_to_download,
|
||||
"file_format": self.file_format,
|
||||
"forcevol": self.forcevol,
|
||||
"download_path": self.download_path,
|
||||
"manga_path": self.manga_path,
|
||||
}
|
||||
)
|
||||
|
||||
# start manga pre hook
|
||||
self.hook.run("manga_pre", {"status": "starting"}, self.hook_infos)
|
||||
|
||||
# get chapters
|
||||
for chapter in chapters_to_download:
|
||||
return_infos = self.get_chapter(chapter)
|
||||
error_chapters.append(return_infos.get("error"))
|
||||
skipped_chapters.append(return_infos.get("skipped"))
|
||||
|
||||
if self.file_format and return_infos["chapter_path"]:
|
||||
return_infos = self.archive_chapter(return_infos["chapter_path"])
|
||||
error_chapters.append(return_infos.get("error"))
|
||||
skipped_chapters.append(return_infos.get("skipped"))
|
||||
|
||||
# check if chapter was skipped
|
||||
try:
|
||||
return_infos["skipped"]
|
||||
|
@ -164,18 +199,26 @@ class MangaDLP:
|
|||
# done with chapter
|
||||
log.info(f"Done with chapter '{chapter}'\n")
|
||||
|
||||
# start chapter post hook
|
||||
self.hook.run("chapter_post", {"status": "successful"}, self.hook_infos)
|
||||
|
||||
# done with manga
|
||||
log.info(f"{print_divider}")
|
||||
log.lean(f"Done with manga: {self.manga_title}")
|
||||
|
||||
# filter skipped list
|
||||
skipped_chapters = list(filter(None, skipped_chapters))
|
||||
if len(skipped_chapters) >= 1:
|
||||
log.lean(f"Skipped chapters: {', '.join(skipped_chapters)}")
|
||||
|
||||
# filter error list
|
||||
error_chapters = list(filter(None, error_chapters))
|
||||
if len(error_chapters) >= 1:
|
||||
log.lean(f"Chapters with errors: {', '.join(error_chapters)}")
|
||||
|
||||
# start manga post hook
|
||||
self.hook.run("manga_post", {"status": "successful"}, self.hook_infos)
|
||||
|
||||
log.info(f"{print_divider}\n")
|
||||
|
||||
# once called per chapter
|
||||
|
@ -197,6 +240,11 @@ class MangaDLP:
|
|||
log.error(
|
||||
f"No images: Skipping Vol. {chapter_infos['volume']} Ch.{chapter_infos['chapter']}"
|
||||
)
|
||||
|
||||
self.hook.run(
|
||||
"chapter_pre", {"status": "skipped", "reason": "No images"}, {}
|
||||
)
|
||||
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -221,6 +269,11 @@ class MangaDLP:
|
|||
# check for folder, if file format is an empty string
|
||||
if chapter_archive_path.exists():
|
||||
log.warning(f"'{chapter_archive_path}' already exists. Skipping")
|
||||
|
||||
self.hook.run(
|
||||
"chapter_pre", {"status": "skipped", "reason": "Existing"}, {}
|
||||
)
|
||||
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -240,6 +293,22 @@ class MangaDLP:
|
|||
log.verbose(f"File path: '{chapter_archive_path}'")
|
||||
log.verbose(f"Image URLS:\n{chapter_image_urls}")
|
||||
|
||||
# create dict with all variables for the hooks
|
||||
self.hook_infos.update(
|
||||
{
|
||||
"chapter_filename": chapter_filename,
|
||||
"chapter_path": chapter_path,
|
||||
"chapter_archive_path": chapter_archive_path,
|
||||
"chapter_uuid": chapter_infos["uuid"],
|
||||
"chapter_volume": chapter_infos["volume"],
|
||||
"chapter_number": chapter_infos["chapter"],
|
||||
"chapter_name": chapter_infos["name"],
|
||||
}
|
||||
)
|
||||
|
||||
# start chapter pre hook
|
||||
self.hook.run("chapter_pre", {"status": "starting"}, self.hook_infos)
|
||||
|
||||
# log
|
||||
log.lean(f"Downloading: '{chapter_filename}'")
|
||||
|
||||
|
@ -253,6 +322,11 @@ class MangaDLP:
|
|||
sys.exit(1)
|
||||
except Exception:
|
||||
log.error(f"Cant download: '{chapter_filename}'. Skipping")
|
||||
|
||||
self.hook.run(
|
||||
"chapter_post", {"status": "error", "reason": "Download error"}, {}
|
||||
)
|
||||
|
||||
# add to skipped chapters list
|
||||
return (
|
||||
{
|
||||
|
@ -266,6 +340,7 @@ class MangaDLP:
|
|||
else:
|
||||
# Done with chapter
|
||||
log.lean(f"Successfully downloaded: '{chapter_filename}'")
|
||||
|
||||
return {"chapter_path": chapter_path}
|
||||
|
||||
# create an archive of the chapter if needed
|
||||
|
|
71
mangadlp/hooks.py
Normal file
71
mangadlp/hooks.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
from mangadlp.logger import Logger
|
||||
|
||||
# prepare logger
|
||||
log = Logger(__name__)
|
||||
|
||||
|
||||
class Hooks:
|
||||
"""Pre- and post-hooks for each download.
|
||||
|
||||
Args:
|
||||
cmd_manga_pre (str): Commands to execute before the manga download starts
|
||||
cmd_manga_post (str): Commands to execute after the manga download finished
|
||||
cmd_chapter_pre (str): Commands to execute before the chapter download starts
|
||||
cmd_chapter_post (str): Commands to execute after the chapter download finished
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
cmd_manga_pre: str,
|
||||
cmd_manga_post: str,
|
||||
cmd_chapter_pre: str,
|
||||
cmd_chapter_post: str,
|
||||
) -> None:
|
||||
self.cmd_manga_pre = cmd_manga_pre
|
||||
self.cmd_manga_post = cmd_manga_post
|
||||
self.cmd_chapter_pre = cmd_chapter_pre
|
||||
self.cmd_chapter_post = cmd_chapter_post
|
||||
|
||||
def run(self, hook_type: str, hook_status: dict, hook_info: dict) -> int:
|
||||
if hook_type == "manga_pre":
|
||||
hook_cmd_str = self.cmd_manga_pre
|
||||
elif hook_type == "manga_post":
|
||||
hook_cmd_str = self.cmd_manga_post
|
||||
elif hook_type == "chapter_pre":
|
||||
hook_cmd_str = self.cmd_chapter_pre
|
||||
elif hook_type == "chapter_post":
|
||||
hook_cmd_str = self.cmd_chapter_post
|
||||
else:
|
||||
log.error(f"Hook type '{hook_type}' is not valid. Not running")
|
||||
return 1
|
||||
|
||||
# check if hook commands are empty
|
||||
if not hook_cmd_str or hook_cmd_str == "None":
|
||||
log.verbose(f"Hook '{hook_type}' empty. Not running")
|
||||
return 2
|
||||
|
||||
hook_cmd_list = hook_cmd_str.split(" ")
|
||||
|
||||
# setting env vars
|
||||
hook_info["hook_type"] = hook_type
|
||||
hook_info["status"] = hook_status.get("status")
|
||||
hook_info["reason"] = hook_status.get("reason")
|
||||
|
||||
for key, value in hook_info.items():
|
||||
os.environ[f"MDLP_{key.upper()}"] = str(value)
|
||||
|
||||
# running command
|
||||
log.info(f"Hook '{hook_type}' - running command: '{hook_cmd_str}'")
|
||||
ecode = subprocess.call(hook_cmd_list)
|
||||
|
||||
if ecode == 0:
|
||||
log.verbose("Hook returned status code 0. All good")
|
||||
else:
|
||||
log.warning(f"Hook returned status code {ecode}. Possible error")
|
||||
|
||||
# return exit code of command
|
||||
return ecode
|
|
@ -49,14 +49,18 @@ def readin_list(readlist: str) -> list:
|
|||
def call_app(args):
|
||||
# call main function with all input arguments
|
||||
mdlp = app.MangaDLP(
|
||||
args.url_uuid,
|
||||
args.lang,
|
||||
args.chapters,
|
||||
args.list,
|
||||
args.format,
|
||||
args.forcevol,
|
||||
args.path,
|
||||
args.wait,
|
||||
url_uuid=args.url_uuid,
|
||||
language=args.lang,
|
||||
chapters=args.chapters,
|
||||
list_chapters=args.list,
|
||||
file_format=args.format,
|
||||
forcevol=args.forcevol,
|
||||
download_path=args.path,
|
||||
download_wait=args.wait,
|
||||
manga_pre_hook_cmd=args.hook_manga_pre,
|
||||
manga_post_hook_cmd=args.hook_manga_post,
|
||||
chapter_pre_hook_cmd=args.hook_chapter_pre,
|
||||
chapter_post_hook_cmd=args.hook_chapter_post,
|
||||
)
|
||||
mdlp.get_manga()
|
||||
|
||||
|
@ -105,6 +109,7 @@ def get_args():
|
|||
action = parser.add_mutually_exclusive_group(required=True)
|
||||
verbosity = parser.add_mutually_exclusive_group(required=False)
|
||||
|
||||
# selection options
|
||||
action.add_argument(
|
||||
"-u",
|
||||
"--url",
|
||||
|
@ -129,6 +134,8 @@ def get_args():
|
|||
help="Show version of manga-dlp and exit",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
# base options
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--chapters",
|
||||
|
@ -185,6 +192,8 @@ def get_args():
|
|||
default=0.5,
|
||||
help="Time to wait for each picture to download in seconds(float). Defaults 0.5",
|
||||
)
|
||||
|
||||
# logging options
|
||||
verbosity.add_argument(
|
||||
"--lean",
|
||||
dest="verbosity",
|
||||
|
@ -212,6 +221,35 @@ def get_args():
|
|||
const=10,
|
||||
default=20,
|
||||
)
|
||||
# hook options
|
||||
parser.add_argument(
|
||||
"--hook-manga-pre",
|
||||
dest="hook_manga_pre",
|
||||
required=False,
|
||||
help="Commands to execute before the manga download starts",
|
||||
action="store",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--hook-manga-post",
|
||||
dest="hook_manga_post",
|
||||
required=False,
|
||||
help="Commands to execute after the manga download finished",
|
||||
action="store",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--hook-chapter-pre",
|
||||
dest="hook_chapter_pre",
|
||||
required=False,
|
||||
help="Commands to execute before the chapter download starts",
|
||||
action="store",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--hook-chapter-post",
|
||||
dest="hook_chapter_post",
|
||||
required=False,
|
||||
help="Commands to execute after the chapter download finished",
|
||||
action="store",
|
||||
)
|
||||
|
||||
# parser.print_help()
|
||||
args = parser.parse_args()
|
||||
|
|
Loading…
Reference in a new issue