161 lines
4.3 KiB
Python
161 lines
4.3 KiB
Python
# main.py
|
|
|
|
import argparse
|
|
import configparser
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import questionary
|
|
import requests
|
|
from manga import Manga
|
|
from rich import print
|
|
from sites import parse_provider
|
|
|
|
parser = argparse.ArgumentParser(
|
|
prog="Manga Downloader",
|
|
description="Download all your favourite manga!",
|
|
epilog="Happy Reading!",
|
|
)
|
|
parser.add_argument(
|
|
"--auto",
|
|
default=False,
|
|
action=argparse.BooleanOptionalAction,
|
|
help="Run using auto mode (default: %(default)s)",
|
|
)
|
|
parser.add_argument(
|
|
"--save-dir",
|
|
dest="save_dir",
|
|
type=Path,
|
|
help="Set temporary save dir instead of using config value",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
s = requests.session()
|
|
cache_file = Path(__file__).parent.resolve().joinpath("manga.json")
|
|
config_file = Path(__file__).parent.resolve().joinpath("config.ini")
|
|
|
|
|
|
def get_config() -> configparser.ConfigParser:
|
|
config = configparser.ConfigParser()
|
|
if config_file.exists():
|
|
config.read(config_file)
|
|
|
|
if not config.has_option("DEFAULT", "savedir"):
|
|
path = questionary.path(
|
|
"Enter default save path for downloaded Manga: ", qmark=""
|
|
).ask()
|
|
config["DEFAULT"] = {"savedir": path}
|
|
|
|
with open(config_file, "w") as cf:
|
|
config.write(cf)
|
|
|
|
return config
|
|
|
|
|
|
def read_from_cache() -> dict:
|
|
if cache_file.exists():
|
|
return json.loads(cache_file.read_bytes())
|
|
else:
|
|
return {}
|
|
|
|
|
|
def write_to_cache(manga: Manga) -> None:
|
|
cache = read_from_cache()
|
|
series = manga.info.get("series")
|
|
cached_chapters = cache.get(series, {}).get("cached", []) + manga.cached
|
|
|
|
cache[series] = {"url": manga.site.get_url(), "cached": list(set(cached_chapters))}
|
|
|
|
with open(cache_file, "w") as fp:
|
|
json.dump(cache, fp, indent=4)
|
|
|
|
|
|
def parse_cache(cache: dict) -> list[Manga]:
|
|
if not cache:
|
|
print("[yellow]Cache is empty![/yellow]", flush=True)
|
|
exit()
|
|
|
|
total = len(cache)
|
|
print(f"[bold cyan]Found {total} manga in cache. Fetching metadata...[/bold cyan]", flush=True)
|
|
|
|
manga = []
|
|
for idx, (series_name, entry) in enumerate(cache.items(), start=1):
|
|
print(f"[{idx}/{total}] Fetching info for: [bold]{series_name}[/bold]...", flush=True)
|
|
provider = parse_provider(s, entry.get("url"))
|
|
if provider:
|
|
manga.append(Manga(provider, entry.get("cached", [])))
|
|
else:
|
|
print(f"[red]Failed to parse provider for:[/] {series_name}", flush=True)
|
|
|
|
return manga
|
|
|
|
|
|
def get_cached_manga() -> list[Manga]:
|
|
cache = read_from_cache()
|
|
return parse_cache(cache)
|
|
|
|
|
|
def input_manga() -> list[str]:
|
|
manga = list()
|
|
add_more = True
|
|
while add_more:
|
|
manga.append(questionary.text("Input Manga url:", qmark="").ask())
|
|
add_more = questionary.confirm(
|
|
"Do you want to add more Manga", default=False
|
|
).ask()
|
|
|
|
return manga
|
|
|
|
|
|
def parse_manga(manga: list[str]) -> list[Manga]:
|
|
parsed_manga = list()
|
|
for entry in manga:
|
|
provider = parse_provider(s, entry)
|
|
if not provider:
|
|
print(f"Failed to parse: {entry}")
|
|
else:
|
|
parsed_manga.append(Manga(provider))
|
|
return parsed_manga
|
|
|
|
|
|
def choose_manga() -> list[Manga]:
|
|
use_cached = questionary.confirm(
|
|
"Do you want to choose from cached Manga", default=True
|
|
).ask()
|
|
|
|
if use_cached:
|
|
return get_cached_manga()
|
|
else:
|
|
manga = input_manga()
|
|
return parse_manga(manga)
|
|
|
|
|
|
def main():
|
|
|
|
config = get_config()
|
|
save_dir = args.save_dir if args.save_dir else Path(config["DEFAULT"]["savedir"])
|
|
|
|
if args.auto:
|
|
if not config_file.exists():
|
|
print("No config file exists")
|
|
exit(1)
|
|
else:
|
|
list_of_manga = get_cached_manga()
|
|
else:
|
|
list_of_manga = choose_manga()
|
|
|
|
print(f"[bold green]Starting check/download run for {len(list_of_manga)} manga...[/bold green]", flush=True)
|
|
|
|
for manga in list_of_manga:
|
|
series = manga.info.get("series", "Unknown")
|
|
print(f"\n[bold]Checking:[/] {series}", flush=True)
|
|
|
|
manga.choose_chapters(args.auto)
|
|
manga.download(save_dir)
|
|
write_to_cache(manga)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|