summaryrefslogtreecommitdiff
path: root/render.py
diff options
context:
space:
mode:
Diffstat (limited to 'render.py')
-rw-r--r--render.py209
1 files changed, 209 insertions, 0 deletions
diff --git a/render.py b/render.py
new file mode 100644
index 0000000..d2ecf2e
--- /dev/null
+++ b/render.py
@@ -0,0 +1,209 @@
+import json
+import os
+import time
+from glob import glob
+from itertools import batched
+
+import jinja2
+from PIL import ImageFile
+
+from config import WILDCARD_LETTER, THUMBNAIL_CHUNK_SIZE, PROCS, GLOBALS
+from imgutils import create_thumbnail_sheet, convert_cover, \
+ convert_chapter
+
+ImageFile.LOAD_TRUNCATED_IMAGES = True
+from minify_html import minify
+from slugify import slugify
+from tqdm import tqdm
+from rcssmin import cssmin
+from multiprocessing.pool import ThreadPool
+
+env = jinja2.Environment(
+ undefined=jinja2.StrictUndefined,
+)
+
+env.filters["slug"] = slugify
+env.filters["minify_css"] = cssmin
+
+
+def render_index_pages(path, prefix, index_items, content_rating):
+
+ with open("assets/index.html.jinja") as f:
+ template = env.from_string(f.read())
+
+ index_parent_dir = f"{prefix}{('-' + content_rating.lower()) if content_rating else ''}"
+
+ def _work(task):
+ item, series = task
+
+ index_loc = item.replace(WILDCARD_LETTER, "_")
+ index_dir = str(os.path.join(path, index_parent_dir, index_loc))
+ os.makedirs(index_dir)
+
+ if prefix == "t":
+ series = sorted(series, key=lambda s: s["score"], reverse=True)
+ else:
+ series = sorted(series, key=lambda s: s["sort_name"])
+
+ thumbnails = [
+ {
+ "cover": glob(os.path.join(path, s["location"], "cover.*"))[0],
+ "name": s["name"],
+ "loc": s["location"]
+ }
+ for s in series
+ ]
+
+ for i, chunk in enumerate(batched(thumbnails, THUMBNAIL_CHUNK_SIZE)):
+ sheet_name = f"{int(time.time()):x}{i:x}"
+ create_thumbnail_sheet(chunk, os.path.join(index_dir, sheet_name + ".webp"))
+
+ sheet_img = os.path.join(index_parent_dir, index_loc, sheet_name + ".webp")
+
+ for j, tn in enumerate(chunk):
+ offset_class = f"o{j:x}"
+
+ tn["offset"] = offset_class
+ tn["img"] = sheet_img
+
+ is_long_list = len(index_items) > 27
+
+ html = minify(template.render(
+ name=item,
+ thumbnails=thumbnails,
+ parent_loc=index_parent_dir,
+ loc=index_loc,
+ prefix=prefix,
+ index_pages=[
+ (
+ item.replace("-", " ") if is_long_list else item.upper(),
+ item,
+ os.path.join(index_parent_dir, item.replace(WILDCARD_LETTER, "_")),
+ len(series) > 0
+ )
+ for item, series in index_items.items()
+ ],
+ tags=is_long_list,
+ rating=content_rating,
+ **GLOBALS
+ ))
+
+ with open(os.path.join(index_dir, "index.html"), "w") as f:
+ f.write(html)
+
+
+ with ThreadPool(processes=PROCS) as pool:
+ tasks = list(index_items.items())
+
+ for _ in tqdm(pool.imap_unordered(_work, tasks), total=len(tasks)):
+ pass
+
+
+def render_series_pages(path, index):
+ with open("assets/series.html.jinja") as f:
+ template = env.from_string(f.read())
+
+ def _work(series):
+
+ series_dir = str(os.path.join(path, series["location"]))
+ os.makedirs(series_dir)
+
+ convert_cover(series["id"] + "_c", series["cover"], series_dir)
+
+ html = minify(template.render(
+ series_name = series["name"],
+ loc = series["location"],
+ chapters = series["chapters"],
+ tags = list(filter(lambda t: t != "all", series["tags"])),
+ rating = series["rating"],
+ **GLOBALS
+ ))
+
+ with open(os.path.join(series_dir, "index.html"), "w") as f:
+ #TODO: Debug
+ # f.write(f"<!-- rm -r data/{slugify(series['name'])} && echo '{series['_url']}' >> history.txt && echo '{series['_url']}' >> bl.txt -->")
+ f.write(html)
+
+ with ThreadPool(processes=PROCS) as pool:
+ for _ in tqdm(pool.imap_unordered(_work, index), total=len(index)):
+ pass
+
+
+def render_chapter_pages(path, index):
+
+ with open("assets/chapter.html.jinja") as f:
+ template = env.from_string(f.read())
+
+
+ def _work(task):
+ series, chapter = task
+
+ chapter_dir = str(os.path.join(path, *chapter["location"].split("/")))
+
+ convert_chapter(
+ cache_key=f"{series['id']}.{chapter['index']:03d}",
+ images=chapter["images"],
+ output_folder=chapter_dir
+ )
+
+ images = [
+ os.path.basename(filename)
+ for filename in
+ sorted(glob(os.path.join(chapter_dir, "*.webp")))
+ ]
+
+ html = minify(template.render(
+ series_name = series["name"],
+ series_loc = series["location"],
+ chapter_name = chapter["name"],
+ loc = chapter["location"],
+ prev_loc = chapter.get("prev"),
+ next_loc = chapter.get("next"),
+ images = images,
+ **GLOBALS
+ ))
+
+ with open(os.path.join(chapter_dir, "index.html"), "w") as f:
+ f.write(html)
+
+ tasks = []
+ for series in index:
+ for chapter in series["chapters"]:
+ tasks.append((series, chapter))
+
+ with ThreadPool(processes=PROCS) as pool:
+ for _ in tqdm(pool.imap_unordered(_work, tasks), total=len(tasks)):
+ pass
+
+
+def render_home(path):
+ with open("assets/home.html.jinja") as f:
+ template = env.from_string(f.read())
+
+ html = minify(template.render(
+ **GLOBALS
+ ))
+
+ with open(os.path.join(path, "index.html"), "w") as f:
+ f.write(html)
+
+ with open("assets/manifest.json.jinja") as f:
+ template = env.from_string(f.read())
+
+ data = json.loads(template.render(
+ **GLOBALS
+ ))
+
+ with open(os.path.join(path, "manifest.json"), "w") as f:
+ json.dump(data, f, sort_keys=True)
+
+def render_style(path):
+ with open("assets/style.css.jinja") as f:
+ template = env.from_string(f.read())
+
+ css = cssmin(template.render(
+ **GLOBALS
+ ))
+
+ with open(os.path.join(path, GLOBALS["style"]), "w") as f:
+ f.write(css)