diff options
Diffstat (limited to 'bake.py')
| -rw-r--r-- | bake.py | 237 |
1 files changed, 237 insertions, 0 deletions
@@ -0,0 +1,237 @@ +import os +import json +import shutil +import string +from glob import glob +from slugify import slugify +from tqdm import tqdm +import statistics + +from config import INPUT_DIRECTORY, OUTPUT_DIRECTORY, DOWNLOAD_FILES, CONTENT_RATINGS +from render import render_chapter_pages, render_series_pages, render_index_pages, render_home, render_style + +BAD_TAGS = [ + "girls-love" +] + +SERIES_LOC = set() + +def chapter_loc(loc, i): + return f"{loc}/{int(i)+1:x}" + +def _loc_with_num(loc, num): + if num == 0: + return loc + return f"{loc}.{num}" + +def series_loc(series): + + loc = slugify(series["sort_name"]) + original_loc = loc + + i = 0 + loc = _loc_with_num(original_loc, i) + while loc in SERIES_LOC: + loc = _loc_with_num(original_loc, i) + i += 1 + + SERIES_LOC.add(loc) + + return loc + + +def parse_metadata(metadata, series_dir): + result = {} + + result["id"] = metadata["id"] + + result["name"] = metadata["title"] + result["rating"] = metadata["rating"] + + assert result["rating"] in CONTENT_RATINGS + + sort_name = metadata["title"].lower() + if sort_name.startswith("the "): + sort_name = sort_name[4:] + result["sort_name"] = sort_name + loc = series_loc(result) + result["location"] = loc + result["description"] = metadata["description"] + result["cover"] = glob(os.path.join(series_dir, "cover.*"))[0] + tags = [slugify(tag) for tag in metadata["tags"]] + + for tag in BAD_TAGS: + if tag in tags: + tags.remove(tag) + + tags.append("all") + + result["tags"] = tags + + result["score"] = get_score(metadata["id"]) + + chapters = [] + for i, chapter_data in enumerate(metadata["chapters"]): + + chapter = chapter_data["name"] + chapter_dir = chapter.replace("Volume.", "Vol.").replace("Chapter.", "Ch.") + + chapter = { + "index": i, + "name": chapter, + "location": chapter_loc(loc, i), + "images": list( + im for im in sorted(glob(os.path.join(series_dir, chapter_dir, "*"))) + if im.endswith((".webp", ".png", ".jpeg", ".jpg")) + ) + } + + if len(chapter["images"]) == 0: + continue + + chapters.append(chapter) + + # Add prev/next links + for i, chapter in enumerate(chapters): + if i > 0: + chapter["prev"] = chapter_loc(loc, i-1) + + if i < len(chapters) - 1: + chapter["next"] = chapter_loc(loc, i+1) + + result["chapters"] = chapters + + + return result + +def create_index(directory): + index = [] + + i = 0 + + for dirname in tqdm(os.listdir(directory)): + series_dir = str(os.path.join(directory, dirname)) + + try: + with open(os.path.join(series_dir, "manga_info.json")) as f: + metadata = json.load(f)[0] + except FileNotFoundError: + continue + except PermissionError: + continue + + if not glob(os.path.join(series_dir, "cover.*")): + continue + + series_data = parse_metadata(metadata, series_dir) + + first_letter = series_data["sort_name"][0].lower() + series_data["index_letter"] = first_letter if first_letter in string.ascii_lowercase else "#" + + index.append(series_data) + + i += 1 + # if i > 100: + # break + + return index + +def load_scores(): + + score_files = [] + + for filename in DOWNLOAD_FILES: + with open(filename) as f: + num_lines = len([_ for _ in f]) + + scores = {} + + with open(filename) as f: + for i, line in enumerate(f): + + manga_id = line.strip().split("/")[-1] + score = num_lines - i + + scores[manga_id] = score + score_files.append(scores) + + return score_files + +def get_score(manga_id): + manga_scores = [] + + for score_file in scores: + if manga_id in score_file: + manga_scores.append(score_file[manga_id]) + + return statistics.mean(manga_scores) + +def _filter_index(original_index, r, keep_empty): + if r is None: + return original_index + + new_index = {} + + for key, s in original_index.items(): + new_list = list(filter(lambda x: x["rating"] == r, s)) + if new_list or keep_empty: + new_index[key] = new_list + + return new_index + + +if __name__ == "__main__": + + scores = load_scores() + + print("create index") + index = create_index(INPUT_DIRECTORY) + + print("Prepare output folder") + shutil.rmtree(OUTPUT_DIRECTORY, ignore_errors=True) + os.makedirs(OUTPUT_DIRECTORY) + + # Letter index + letter_index = {} + for letter in string.ascii_lowercase + "#": + letter_index[letter] = [] + + for series in index: + if series["index_letter"] == letter: + letter_index[letter].append(series) + + # Tag index + all_tags = set() + for series in index: + all_tags.update(series["tags"]) + all_tags = list(sorted(all_tags)) + + tag_index = {} + for tag in all_tags: + tag_index[tag] = [] + + for series in index: + if tag in series["tags"]: + tag_index[tag].append(series) + + render_home(OUTPUT_DIRECTORY) + render_style(OUTPUT_DIRECTORY) + print("series") + render_series_pages(OUTPUT_DIRECTORY, index) + print("chapters") + render_chapter_pages(OUTPUT_DIRECTORY, index) + + + print("letter index") + for i, rating in enumerate([None] + CONTENT_RATINGS): + filtered_tag_index = _filter_index(letter_index, rating, keep_empty=True) + render_index_pages(OUTPUT_DIRECTORY, f"i", filtered_tag_index, rating) + + print("tag index") + for i, rating in enumerate([None] + CONTENT_RATINGS): + filtered_letter_index = _filter_index(tag_index, rating, keep_empty=False) + render_index_pages(OUTPUT_DIRECTORY, f"t", filtered_letter_index, rating) + + for asset in ["lexend.woff2", "home.mp4", "favicon.ico"]: + shutil.copy(os.path.join("assets", asset), OUTPUT_DIRECTORY) + |
