127 lines
3.5 KiB
Python
127 lines
3.5 KiB
Python
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import timedelta
|
|
import re
|
|
from pathvalidate import validate_filename
|
|
import os
|
|
from tqdm import tqdm
|
|
|
|
from config import *
|
|
|
|
|
|
include_title = False
|
|
|
|
|
|
def valid_description(description):
|
|
if not description:
|
|
return False
|
|
return True
|
|
|
|
|
|
def normalize_amount(a):
|
|
if a == round(a):
|
|
return round(a)
|
|
else:
|
|
return a
|
|
|
|
|
|
def md_for_step_ingredients(step):
|
|
md = []
|
|
for ingredient in step["ingredients"]:
|
|
i_amount = ingredient["amount"]
|
|
i_amount = normalize_amount(i_amount)
|
|
|
|
if not ingredient.get("unit"):
|
|
i_unit = ""
|
|
else:
|
|
i_unit = ingredient["unit"]["name"]
|
|
# TODO → 1_clean_json.py
|
|
if i_unit == "g / Gramm":
|
|
i_unit = "g"
|
|
elif i_unit == "kg / Kilogramm":
|
|
i_unit = "kg"
|
|
|
|
if not ingredient.get("food"):
|
|
# TODO → 1_clean_json.py
|
|
continue
|
|
i_name = ingredient["food"]["name"]
|
|
|
|
if i_amount:
|
|
md.append(f"- {i_amount} {i_unit} {i_name}")
|
|
else:
|
|
md.append(f"- {i_name}")
|
|
return md
|
|
|
|
|
|
def format_recipe_to_markdown(recipe):
|
|
md = []
|
|
|
|
# Title (may be implicit by filename)
|
|
if include_title:
|
|
md.append(f"# {recipe.get('name', 'Untitled Recipe')}")
|
|
|
|
# Description
|
|
if valid_description(recipe.get("description")):
|
|
md.append(f"\n{recipe['description']}\n")
|
|
|
|
# Details
|
|
details_parts = []
|
|
prep_time = recipe.get("working_time") or 0
|
|
total_time = (recipe.get("working_time") or 0) + (recipe.get("waiting_time") or 0)
|
|
if prep_time:
|
|
details_parts.append(f"Prep time: {prep_time}")
|
|
if total_time:
|
|
details_parts.append(f"Total time: {total_time}")
|
|
if "servings" in recipe:
|
|
details_parts.append(f"Portionen: {recipe['servings']}")
|
|
# TODO servings_text
|
|
if details_parts:
|
|
for p in details_parts:
|
|
md.append(f"* {p}\n")
|
|
|
|
# Ingredients
|
|
if recipe["show_ingredient_overview"]:
|
|
md.append("\n## Zutaten (gesamt)")
|
|
for step in recipe["steps"]:
|
|
md += md_for_step_ingredients(step)
|
|
|
|
# Instructions
|
|
if "steps" in recipe:
|
|
md.append("\n## Zubereitung")
|
|
steps = recipe["steps"]
|
|
for i, step in enumerate(steps, 1):
|
|
step_name = step["name"] or "<span></span>"
|
|
md.append(f"{i}. {step_name}")
|
|
md += md_for_step_ingredients(step)
|
|
md.append(f"{step["instructions_markdown"]}")
|
|
|
|
# Nutrition TODO
|
|
# if 'nutrition' in recipe and recipe['nutrition']:
|
|
# md.append("\n## Nutrition")
|
|
# for key, value in recipe['nutrition'].items():
|
|
# if key != "@type":
|
|
# md.append(f"- **{key.replace('_', ' ').capitalize()}**: {value}")
|
|
|
|
return "\n".join(md) + "\n"
|
|
|
|
|
|
def main():
|
|
|
|
recipes = []
|
|
for json_file in os.listdir(OUTDIR_JSON):
|
|
with open(os.path.join(OUTDIR_JSON, json_file), "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
recipes.append(data)
|
|
|
|
for recipe in tqdm(recipes):
|
|
markdown_fn = f"{recipe.get('name', 'Untitled Recipe')}.md"
|
|
validate_filename(markdown_fn) # XXX does this check directory traversal?
|
|
markdown = format_recipe_to_markdown(recipe)
|
|
os.makedirs(OUTDIR_MARKDOWN, exist_ok=True)
|
|
with open(os.path.join(OUTDIR_MARKDOWN, markdown_fn), "w") as f:
|
|
f.write(markdown)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|