add a markdown source field to recipe

This commit is contained in:
Emi Vasilek 2023-11-21 03:12:41 +01:00
parent cb541423c7
commit 247fd37560
4 changed files with 41 additions and 1 deletions

View file

@ -6,6 +6,37 @@ import comfyrecipes.settings as settings
import comfyrecipes.issues as issues import comfyrecipes.issues as issues
import jsonschema import jsonschema
import lxml.html.clean
import mistune
class SafeHTML:
def __init__(self, clean_html: str) -> None:
self.html = clean_html
@classmethod
def from_html(cls, dirty_html: str) -> Self:
cleaner = lxml.html.clean.Cleaner(
allow_tags=["a", "b", "em", "i", "strong"],
safe_attrs_only=True,
safe_attrs=["href"],
)
html = cleaner.clean_html(dirty_html).strip()
assert isinstance(html, str)
assert html.startswith("<div>")
assert html.endswith("</div>")
html = html[5:-6]
return cls(html)
@classmethod
def from_markdown(cls, markdowntxt: str) -> Self:
dirty_html = mistune.html(markdowntxt)
assert isinstance(dirty_html, str)
return cls.from_html(dirty_html)
class Context: class Context:
def __init__(self) -> None: def __init__(self) -> None:
@ -219,6 +250,7 @@ class Recipe(Element):
self, self,
ctx: Context, ctx: Context,
title: str, title: str,
source: Optional[SafeHTML],
ingredients: List[IngredientInstance], ingredients: List[IngredientInstance],
subrecipes: List["Recipe"], subrecipes: List["Recipe"],
price: Optional["PriceDB"], price: Optional["PriceDB"],
@ -232,6 +264,7 @@ class Recipe(Element):
self.subrecipes = subrecipes self.subrecipes = subrecipes
self.price = price self.price = price
self.stepsections = stepsections self.stepsections = stepsections
self.source = source
@classmethod @classmethod
def from_dict(cls, ctx: Context, dct: Dict[str, Any]) -> Self: def from_dict(cls, ctx: Context, dct: Dict[str, Any]) -> Self:
@ -287,9 +320,14 @@ class Recipe(Element):
section = StepSection.from_dict(ctx, step) section = StepSection.from_dict(ctx, step)
stepsections.append(section) stepsections.append(section)
source = None
if "source" in dct:
source = SafeHTML.from_markdown(dct["source"])
return cls( return cls(
ctx=ctx, ctx=ctx,
title=dct["title"], title=dct["title"],
source=source,
ingredients=ingredients, ingredients=ingredients,
subrecipes=subrecipes, subrecipes=subrecipes,
price=price, price=price,

View file

@ -8,6 +8,7 @@
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"title": { "type": "string" }, "title": { "type": "string" },
"source": { "type": "string" },
"ingredients": { "ingredients": {
"type": "array", "type": "array",
"items": { "items": {

View file

@ -17,6 +17,7 @@
{{getrecipe(subrecipe)}} {{getrecipe(subrecipe)}}
{% endfor %} {% endfor %}
<h1>{{rec.title}}</h1> <h1>{{rec.title}}</h1>
{% if rec.source != None %}source: {{rec.source.html|safe}}{%endif%}
{% if rec.ingredients|length != 0 %} {% if rec.ingredients|length != 0 %}
<h3>Ingredients</h3> <h3>Ingredients</h3>
{% for ing in rec.ingredients %} {% for ing in rec.ingredients %}

View file

@ -9,7 +9,7 @@ description = "Smart recipe static site generator"
authors = [{ name = "Emi Vasilek", email = "emi.vasilek@gmail.com" }] authors = [{ name = "Emi Vasilek", email = "emi.vasilek@gmail.com" }]
keywords = ["recipes", "recipe", "static site generator"] keywords = ["recipes", "recipe", "static site generator"]
requires-python = ">= 3.8" requires-python = ">= 3.8"
dependencies = ["jsonschema", "jinja2", "PyYAML"] dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml"]
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
"Programming Language :: Python", "Programming Language :: Python",