Added pipenv files to offer a consistent python environment, including quality. #20

Merged
caribaud merged 6 commits from issues/14 into release/1.0.0 2023-06-25 11:32:31 +02:00
1 changed files with 60 additions and 33 deletions
Showing only changes of commit ce00b327bb - Show all commits

View File

@ -3,10 +3,10 @@
# CC-BY-NC-SA https://git.aribaud.net/caribaud/melpomene/ # CC-BY-NC-SA https://git.aribaud.net/caribaud/melpomene/
import sys import sys
import re from argparse import ArgumentParser
import xml.etree.ElementTree as ET from xml.etree import ElementTree
import argparse from xml.etree.ElementTree import Element
from typing import Any
from pathlib import Path from pathlib import Path
@ -14,13 +14,19 @@ HTML_TEMPLATE = Path(__file__).parent / "melpomene.html"
HTML_TO_REPLACE = "<!-- your img tags here, see documentation -->" HTML_TO_REPLACE = "<!-- your img tags here, see documentation -->"
def extract_zooms(src_folder): def get_val_has_str(elem: Element, attrib: str, filepath: str | Path) -> str:
value = elem.get(attrib)
if value is None:
sys.exit(f"Attribute '{attrib}' is not valid in file {filepath}")
return str(value)
def extract_zooms(src_folder) -> dict[int, Any]:
folder = Path(src_folder) folder = Path(src_folder)
zooms = {} pages_zooms: dict[int, Any] = {}
max_width = 0
max_height = 0
idx = 0 idx = 0
@ -29,44 +35,52 @@ def extract_zooms(src_folder):
print(f"page {idx} : {svg_path.name}") print(f"page {idx} : {svg_path.name}")
zooms[idx] = { # Setting up default values
pages_zooms[idx] = {
"name": svg_path.stem, "name": svg_path.stem,
"width": 0, "width": 0,
"height": 0, "height": 0,
"zooms": [], "zooms": [],
} }
tree = ET.parse(svg_path) tree = ElementTree.parse(svg_path)
root = tree.getroot() root = tree.getroot()
if "." in root.get("width"): width = get_val_has_str(root, "width", svg_path)
height = get_val_has_str(root, "height", svg_path)
if "." in width:
print( print(
f"WARNING: file {svg_path} has a floating width, it will be rounded", f"WARNING: file {svg_path} has a floating width, it will be rounded",
file=sys.stderr, file=sys.stderr,
) )
zooms[idx]["width"] = round(float(root.get("width"))) pages_zooms[idx]["width"] = round(float(width))
if "." in root.get("height"):
if "." in height:
print( print(
f"WARNING: file {svg_path} has a floating height, it will be rounded", f"WARNING: file {svg_path} has a floating height, it will be rounded",
file=sys.stderr, file=sys.stderr,
) )
zooms[idx]["height"] = round(float(root.get("height"))) pages_zooms[idx]["height"] = round(float(height))
zooms = []
for area in root.findall(".//{*}rect"): for area in root.findall(".//{*}rect"):
zooms[idx]["zooms"].append( zooms.append(
[ [
float(area.get("width")), float(get_val_has_str(area, "width", svg_path)),
float(area.get("height")), float(get_val_has_str(area, "height", svg_path)),
float(area.get("x")), float(get_val_has_str(area, "x", svg_path)),
float(area.get("y")), float(get_val_has_str(area, "y", svg_path)),
] ]
) )
return zooms, max_width, max_height pages_zooms[idx]["zooms"] = zooms
return pages_zooms
def write_json_or_js(zooms, dest_file, is_js): def write_json_or_js(zooms, dest_file, is_js) -> None:
with open(dest_file, "w") as data_file: with open(dest_file, "w", encoding="UTF-8") as data_file:
if is_js: if is_js:
data_file.write("PAGES_ZOOMS = ") data_file.write("PAGES_ZOOMS = ")
data_file.write("[\n") data_file.write("[\n")
@ -75,7 +89,8 @@ def write_json_or_js(zooms, dest_file, is_js):
for zoom in zooms[page_idx]["zooms"]: for zoom in zooms[page_idx]["zooms"]:
if zoom[2] < 0 or zoom[3] < 0: if zoom[2] < 0 or zoom[3] < 0:
print( print(
f"WARNING: negative pos x / pos y in page {page_idx} for zoom {zoom} (is the rectangle flipped?)" f"WARNING: negative pos x / pos y in page {page_idx} for "
f"zoom {zoom} (is the rectangle flipped?)"
) )
if first_coma_skiped: if first_coma_skiped:
@ -86,7 +101,7 @@ def write_json_or_js(zooms, dest_file, is_js):
data_file.write("\n]\n") data_file.write("\n]\n")
def write_html(zooms, dest_file, pages_width, pages_height, prefix, extention): def write_html(zooms, dest_file, prefix, extention) -> None:
img_tags = "" img_tags = ""
for page_idx in sorted(zooms.keys()): for page_idx in sorted(zooms.keys()):
img_url = f"{prefix}{zooms[page_idx]['name']}.{extention}" img_url = f"{prefix}{zooms[page_idx]['name']}.{extention}"
@ -97,22 +112,30 @@ def write_html(zooms, dest_file, pages_width, pages_height, prefix, extention):
zoom_html_str = ";".join(zoom_html_data) zoom_html_str = ";".join(zoom_html_data)
img_tags = ( img_tags = (
img_tags img_tags
+ f' <img loading="lazy" height="{zooms[page_idx]["height"]}" width="{zooms[page_idx]["width"]}" src="{img_url}" data-zooms="{zoom_html_str}"/>\n' + " "
+ f'<img loading="lazy" height="{zooms[page_idx]["height"]}" '
+ f'width="{zooms[page_idx]["width"]}" src="{img_url}" '
+ f'data-zooms="{zoom_html_str}"/>\n'
) )
img_tags = img_tags.strip() img_tags = img_tags.strip()
with open(HTML_TEMPLATE) as template_file, open(dest_file, "w") as data_file: with open(HTML_TEMPLATE, "r", encoding="UTF-8") as template_file, open(
dest_file, "w", encoding="UTF-8"
) as data_file:
data = template_file.read().replace(HTML_TO_REPLACE, img_tags) data = template_file.read().replace(HTML_TO_REPLACE, img_tags)
data_file.write(data) data_file.write(data)
def generate_argparse(): def generate_argparse() -> ArgumentParser:
"""Generate Melpomene's generator input parser""" """Generate Melpomene's generator input parser"""
parser = argparse.ArgumentParser( parser = ArgumentParser(
description="Helper that can generate JSON / JS / HTML files for Melpomene webcomic reader" description=(
"Helper that can generate JSON / JS / "
"HTML files for Melpomene webcomic reader"
)
) )
parser.add_argument( parser.add_argument(
@ -140,7 +163,7 @@ def generate_argparse():
return parser return parser
if __name__ == "__main__": def run():
args = generate_argparse().parse_args() args = generate_argparse().parse_args()
# Get the final outout name # Get the final outout name
@ -160,13 +183,17 @@ if __name__ == "__main__":
elif args.output_format == "js" and not output.endswith(".js"): elif args.output_format == "js" and not output.endswith(".js"):
output += ".js" output += ".js"
zooms, max_width, max_height = extract_zooms(args.svg_folders) zooms = extract_zooms(args.svg_folders)
if args.output_format == "html": if args.output_format == "html":
write_html(zooms, output, max_width, max_height, args.p, args.e) write_html(zooms, output, args.p, args.e)
elif args.output_format == "json": elif args.output_format == "json":
write_json_or_js(zooms, output, False) write_json_or_js(zooms, output, False)
elif args.output_format == "js": elif args.output_format == "js":
write_json_or_js(zooms, output, True) write_json_or_js(zooms, output, True)
if __name__ == "__main__":
run()