gpn23-recipes/2_to_markdown.py

123 lines
3.4 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
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()