add a markdown source field to recipe
This commit is contained in:
parent
cb541423c7
commit
247fd37560
4 changed files with 41 additions and 1 deletions
|
@ -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,
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue