-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmanga_downloader.py
117 lines (88 loc) · 3.57 KB
/
manga_downloader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import argparse
import logging
import os
import shutil
from typing import List
from manga_provider.mangahost import MangaHost
from util.manga import Manga
from util.pdf import PdfUtils
from util.search_render import SearchRender
from util.utils import FormatText, clear_tmp, dynamic_pad
logger = logging.getLogger("manga_downloader")
handler = logging.StreamHandler()
formatter = logging.Formatter(logging.BASIC_FORMAT)
handler.setFormatter(formatter)
logger.addHandler(handler)
SECTION_RANGE_ERROR_MSG = "Chapter selection has invalid type. Choices must be integer"
def validate_section_range(section_range: List[str]):
for section in section_range:
if not section.isdigit():
raise TypeError(SECTION_RANGE_ERROR_MSG)
def parse_chapter_selection(selection: str) -> list[int]:
chapters = []
for section in selection.split(","):
section_range = section.split("-")
validate_section_range(section_range)
if len(section_range) > 2:
raise IndexError(f"Invalid range: {section}")
elif len(section_range) == 2:
chapters = chapters + list(
range(int(section_range[0]), int(section_range[1]) + 1)
)
elif len(section_range) == 1:
chapters = chapters + [int(section_range[0])]
return chapters
def chose_manga(provider: MangaHost, manga_name: str):
sr = SearchRender(provider.find_mangas(manga_name))
if sr.search_query is None:
print("Couldn't find this manga")
return sr.select()
def select_chapters(provider: MangaHost, manga: Manga):
chapters = provider.find_manga_chapters(manga)
for index, elem in enumerate(chapters, 1):
print(("{} - Chapter #{}").format(dynamic_pad(len(chapters), index), elem))
response = input(FormatText.option("Which indexes to download? "))
selected_chapters = parse_chapter_selection(response)
return selected_chapters, chapters
def download_chapters(provider: MangaHost, manga: Manga, selected_chapters, chapters):
all_folders = []
for chapter in selected_chapters:
folder, _ = provider.download_chapter(manga, chapters[chapter - 1])
all_folders.append(folder)
return all_folders
def move_to_output(path: str, output: str):
os.makedirs(output, exist_ok=True)
shutil.move(path, output)
def manga_downloader(args: dict):
clear_tmp()
provider = MangaHost()
try:
manga = chose_manga(provider, args.manga)
selected_chapters, chapters = select_chapters(provider, manga)
# TODO Run all operations below atomic for each chapter
all_folders = download_chapters(provider, manga, selected_chapters, chapters)
except (TypeError, IndexError) as error:
print(error)
quit(1)
if not args.image:
result_pdfs = PdfUtils.convert_multiple_folders_to_pdf(all_folders)
results = result_pdfs
else:
results = all_folders
for f in results:
move_to_output(f, args.output)
clear_tmp()
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="manga_downloader")
parser.add_argument("-m", "--manga", required=True, help="Manga to be downloaded.")
parser.add_argument("-o", "--output", required=True, help="Output folder.")
parser.add_argument(
"--image", action="store_true", help="Store downloaded chapter as images."
)
parser.add_argument("--debug", action="store_true", help="Enable debug flag")
args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
manga_downloader(args)