Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
2e5859342d | |||
ae3ee28ab4 | |||
8a9ae16ad3 | |||
cc9206306a | |||
3e3de7ea59 | |||
e35bc3852b | |||
7b3aa25c95 | |||
88f801cadb | |||
8046f0d237 | |||
08fce0ae16 |
26 changed files with 94 additions and 446 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,4 +4,3 @@ recipes
|
||||||
venv
|
venv
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
.vscode
|
.vscode
|
||||||
docs/book
|
|
||||||
|
|
15
.woodpecker/containers.yaml
Normal file
15
.woodpecker/containers.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
when:
|
||||||
|
- event: push
|
||||||
|
branch: main
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: publish
|
||||||
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
|
settings:
|
||||||
|
platforms: linux/amd64,linux/arm64/v8
|
||||||
|
repo: git.comfy.city/emi/comfy-recipes
|
||||||
|
registry: git.comfy.city
|
||||||
|
tags: latest
|
||||||
|
username: ${CI_REPO_OWNER}
|
||||||
|
password:
|
||||||
|
from_secret: registry_token
|
15
Dockerfile
15
Dockerfile
|
@ -1,12 +1,11 @@
|
||||||
FROM alpine:3.18 AS build
|
FROM python:3.13-alpine AS build
|
||||||
COPY . /build
|
COPY . /build
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
RUN apk add --no-cache python3 py3-build py3-hatchling && \
|
RUN pip install build hatchling && \
|
||||||
python3 -m build .
|
python3 -m build .
|
||||||
|
|
||||||
FROM alpine:3.18
|
FROM python:3.13-alpine
|
||||||
COPY --from=build /build/dist/comfy-recipes-*-py3-none-any.whl /
|
COPY --from=build /build/dist/ /mnt
|
||||||
RUN apk add --no-cache python3 py3-pip && \
|
RUN pip install /mnt/comfy_recipes-*-py3-none-any.whl && \
|
||||||
pip install /comfy-recipes-*-py3-none-any.whl && \
|
rm -r /mnt
|
||||||
apk del py3-pip
|
ENTRYPOINT ["/usr/local/bin/recipes-cli"]
|
||||||
ENTRYPOINT ["/usr/bin/recipes-cli"]
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -4,7 +4,13 @@ Comfy Recipes is a simple application that renders your recipes into HTML.
|
||||||
|
|
||||||
Documentation is available at <https://comfy.city/comfy-recipes/docs>
|
Documentation is available at <https://comfy.city/comfy-recipes/docs>
|
||||||
|
|
||||||
## Building the python package
|
## Running
|
||||||
|
```sh
|
||||||
|
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:latest build /recipes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
### Building the python package
|
||||||
Make sure you have hatchling and build modules installed.
|
Make sure you have hatchling and build modules installed.
|
||||||
```sh
|
```sh
|
||||||
python3 -m build
|
python3 -m build
|
||||||
|
@ -15,17 +21,17 @@ The package can now be installed with
|
||||||
pip install dist/comfy-recipes-*-py3-none-any.whl
|
pip install dist/comfy-recipes-*-py3-none-any.whl
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building the docker container
|
### Building the docker container
|
||||||
```sh
|
```sh
|
||||||
docker build -t codeberg.org/comfy.city/comfy-recipes .
|
docker buildx build -t git.comfy.city/Emi/comfy-recipes:local .
|
||||||
```
|
```
|
||||||
|
|
||||||
The container can now be ran
|
The container can now be ran
|
||||||
```sh
|
```sh
|
||||||
docker run --rm codeberg.org/comfy.city/comfy-recipes
|
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:local build /recipes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building the documentation
|
### Building the documentation
|
||||||
```sh
|
```sh
|
||||||
cd docs
|
cd docs
|
||||||
mdbook build
|
mdbook build
|
||||||
|
|
|
@ -197,19 +197,20 @@ class IngredientInstance(Element):
|
||||||
def from_dict(cls, ctx: Context, dct: str | Dict[str, Any]) -> Self:
|
def from_dict(cls, ctx: Context, dct: str | Dict[str, Any]) -> Self:
|
||||||
if isinstance(dct, str):
|
if isinstance(dct, str):
|
||||||
string = dct.strip()
|
string = dct.strip()
|
||||||
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )?([\w ]+)(?: \((.*)\))?$")
|
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )+([\w ]+)(?: \((.*)\))?$")
|
||||||
match = p.match(string)
|
match = p.match(string)
|
||||||
if match is None:
|
|
||||||
raise RuntimeError(
|
amount = float(1)
|
||||||
"ingredient {string} regex not matched, it should be in the format [amount(num) unit(string, one word)] name(string, any number of words) [(note(string))]"
|
unit = ctx.default_unit
|
||||||
)
|
name = string
|
||||||
|
note = None
|
||||||
|
if match is not None:
|
||||||
amount = float(match.group(1))
|
amount = float(match.group(1))
|
||||||
unitstr = match.group(2)
|
unitstr = match.group(2)
|
||||||
unit = ctx.default_unit
|
|
||||||
if unit is not None:
|
if unit is not None:
|
||||||
unitx = ctx.units.get(unitstr)
|
unitx = ctx.units.get(unitstr)
|
||||||
if unitx is None:
|
if unitx is None:
|
||||||
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, "unknown unit {unitstr}")
|
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, f"unknown unit {unitstr}")
|
||||||
else:
|
else:
|
||||||
unit = unitx
|
unit = unitx
|
||||||
name = match.group(3)
|
name = match.group(3)
|
||||||
|
@ -289,7 +290,7 @@ class Recipe(Element):
|
||||||
source: Optional[SafeHTML],
|
source: Optional[SafeHTML],
|
||||||
ingredients: List[IngredientInstance],
|
ingredients: List[IngredientInstance],
|
||||||
subrecipes: List["Recipe"],
|
subrecipes: List["Recipe"],
|
||||||
price: Optional["PriceDB"],
|
price: Optional["MultiPriceDB"],
|
||||||
stepsections: List[StepSection],
|
stepsections: List[StepSection],
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(ctx)
|
super().__init__(ctx)
|
||||||
|
@ -317,7 +318,7 @@ class Recipe(Element):
|
||||||
rp = Recipe.from_dict(ctx, partdct)
|
rp = Recipe.from_dict(ctx, partdct)
|
||||||
subrecipes.append(rp)
|
subrecipes.append(rp)
|
||||||
|
|
||||||
price: Optional[PriceDB] = None
|
price: Optional[MultiPriceDB] = None
|
||||||
pricex: float = 0
|
pricex: float = 0
|
||||||
ingswithprice = 0
|
ingswithprice = 0
|
||||||
ingswithoutprice = 0
|
ingswithoutprice = 0
|
||||||
|
@ -335,16 +336,22 @@ class Recipe(Element):
|
||||||
# we don't know how to convert currencies yet
|
# we don't know how to convert currencies yet
|
||||||
currency = None
|
currency = None
|
||||||
break
|
break
|
||||||
if currency is None or ingswithoutprice != 0 or len(ingredients) == 0:
|
if currency is None or len(ingredients) == 0:
|
||||||
price = None
|
price = None
|
||||||
else:
|
else:
|
||||||
price = PriceDB(
|
pricedb = PriceDB(
|
||||||
ctx=ctx,
|
ctx=ctx,
|
||||||
price=pricex,
|
price=pricex,
|
||||||
amount=1,
|
amount=1,
|
||||||
unit=ctx.default_unit,
|
unit=ctx.default_unit,
|
||||||
currency=currency,
|
currency=currency,
|
||||||
)
|
)
|
||||||
|
price = MultiPriceDB(
|
||||||
|
ctx=ctx,
|
||||||
|
pricedb=pricedb,
|
||||||
|
item_count=len(ingredients),
|
||||||
|
item_prices_missing=ingswithoutprice,
|
||||||
|
)
|
||||||
|
|
||||||
stepsections: List[StepSection] = []
|
stepsections: List[StepSection] = []
|
||||||
if "steps" in dct:
|
if "steps" in dct:
|
||||||
|
@ -594,3 +601,16 @@ class PriceDB(Element):
|
||||||
if currency is None:
|
if currency is None:
|
||||||
raise RuntimeError("currency not specified and default_currency is also not set")
|
raise RuntimeError("currency not specified and default_currency is also not set")
|
||||||
return cls(ctx=ctx, price=price, amount=amount, unit=unit, currency=currency)
|
return cls(ctx=ctx, price=price, amount=amount, unit=unit, currency=currency)
|
||||||
|
|
||||||
|
class MultiPriceDB(Element):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ctx: Context,
|
||||||
|
pricedb: PriceDB,
|
||||||
|
item_count: int,
|
||||||
|
item_prices_missing: int,
|
||||||
|
) -> None:
|
||||||
|
super().__init__(ctx)
|
||||||
|
self.pricedb = pricedb
|
||||||
|
self.item_count = item_count
|
||||||
|
self.item_prices_missing = item_prices_missing
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
{% macro price(price) -%}
|
{% macro price(price) -%}
|
||||||
{% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
|
{% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
{% macro multiprice(multiprice, shortform) -%}
|
||||||
|
{% if multiprice != None and multiprice.pricedb != None and multiprice.pricedb is defined and multiprice.pricedb.price is defined -%}
|
||||||
|
{{multiprice.pricedb.price|round(1)|numprint}}
|
||||||
|
{%else%}
|
||||||
|
?
|
||||||
|
{%- endif %}
|
||||||
|
{{multiprice.pricedb.currency}}
|
||||||
|
{%if multiprice.item_prices_missing != 0 and not shortform%}
|
||||||
|
({{multiprice.item_prices_missing}}/{{multiprice.item_count}} prices missing)
|
||||||
|
{%endif%}
|
||||||
|
{%- endmacro %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
{%block body %}
|
{%block body %}
|
||||||
<h1>Recipes</h1>
|
<h1>Recipes</h1>
|
||||||
{% for recipe in recipes %}
|
{% for recipe in recipes %}
|
||||||
<li>{% if recipe.price != None %}{{price(recipe.price)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
<li>{% if recipe.price != None %}{{multiprice(recipe.price, true)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%endblock%}
|
{%endblock%}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% macro ingredientpart(ing) -%}
|
{% macro ingredientpart(ing) -%}
|
||||||
{% if recipe.price != None %}{{price(ing.price)}} {%endif%}
|
{% if ing.price != None %}{{price(ing.price)}} {%endif%}
|
||||||
{% if ing.amount != None %} {{ing.amount|amountprint}}
|
{% if ing.amount != None %} {{ing.amount|amountprint}}
|
||||||
{% if ing.unit != None %} {{ing.unit.name}}{% endif %}
|
{% if ing.unit != None %} {{ing.unit.name}}{% endif %}
|
||||||
{%endif%}
|
{%endif%}
|
||||||
|
@ -29,7 +29,10 @@
|
||||||
{% for ing in rec.ingredients %}
|
{% for ing in rec.ingredients %}
|
||||||
<li>{{ingredient(ing)}}</li>
|
<li>{{ingredient(ing)}}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if rec.price != None %}price: {{price(rec.price)}}{%endif%}
|
{% if rec.price != None %}
|
||||||
|
<br>
|
||||||
|
price: {{multiprice(rec.price)}}
|
||||||
|
{%endif%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if rec.stepsections|length != 0 %}
|
{% if rec.stepsections|length != 0 %}
|
||||||
<h3>Steps</h3>
|
<h3>Steps</h3>
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
[book]
|
|
||||||
authors = ["Emi Vasilek"]
|
|
||||||
language = "en"
|
|
||||||
multilingual = false
|
|
||||||
title = "Comfy Recipes Documentation"
|
|
||||||
|
|
||||||
[build]
|
|
||||||
create-missing = true
|
|
||||||
|
|
||||||
[output.html]
|
|
||||||
preferred-dark-theme = "Ayu"
|
|
||||||
git-repository-url = "https://codeberg.org/comfy.city/comfy-recipes"
|
|
||||||
git-repository-icon = "fa-git"
|
|
|
@ -1,15 +0,0 @@
|
||||||
title: Swedish Pancakes
|
|
||||||
ingredients:
|
|
||||||
- 3 piece egg
|
|
||||||
- 1.25 cup milk
|
|
||||||
- 0.75 cup all purpose flour
|
|
||||||
- 1 tablespoon white sugar
|
|
||||||
- 1 tablespoon butter
|
|
||||||
steps:
|
|
||||||
- Beat eggs in a bowl until the mixture is smooth.
|
|
||||||
- Add milk
|
|
||||||
- Mix flour, sugar and salt in a separate bowl
|
|
||||||
- Mix together with the egg mixture, mix until it's smooth
|
|
||||||
- heat a griddle
|
|
||||||
- Drop just enough of the mixture to the griddle to spread to all corners
|
|
||||||
- After about a minute, turn the pancake over
|
|
|
@ -1 +0,0 @@
|
||||||
- title: Pancakes
|
|
|
@ -1,5 +0,0 @@
|
||||||
- title: Pancakes
|
|
||||||
ingredients:
|
|
||||||
- 100 gram flour
|
|
||||||
steps:
|
|
||||||
- make pancakes
|
|
|
@ -1,14 +0,0 @@
|
||||||
# Summary
|
|
||||||
|
|
||||||
- [Introduction](./introduction.md)
|
|
||||||
- [Installation](./installation.md)
|
|
||||||
- [Tutorial](./tutorial/index.md)
|
|
||||||
- [Quick Start](./tutorial/quickstart.md)
|
|
||||||
- [Units](./tutorial/units.md)
|
|
||||||
- [Ingredients](./tutorial/ingredients.md)
|
|
||||||
- [Prices and Conversions](./tutorial/pricesconversions.md)
|
|
||||||
- [Reference](./reference/index.md)
|
|
||||||
- [Recipe (recipes/*.yaml)](./reference/recipe.md)
|
|
||||||
- [Units (units.yaml)](./reference/units.md)
|
|
||||||
- [Ingredients (ingredients.yaml)](./reference/ingredients.md)
|
|
||||||
- [Settings (settings.yaml)](./reference/settings.md)
|
|
|
@ -1,14 +0,0 @@
|
||||||
# Installation
|
|
||||||
## Docker
|
|
||||||
The containers are available on <https://codeberg.org/comfy.city/-/packages/container/comfy-recipes/latest>
|
|
||||||
```sh
|
|
||||||
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes ARGUMENTS
|
|
||||||
```
|
|
||||||
|
|
||||||
for example:
|
|
||||||
```sh
|
|
||||||
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes build /mnt
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
Docker is currently the only supported installation method, if you would like to use another method, please refer to the building instructions which are available in the project [README.md](https://codeberg.org/comfy.city/comfy-recipes/src/branch/main/README.md)
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Introduction
|
|
||||||
|
|
||||||
Comfy Recipes is a program that allows you to create a rich collection of recipes and create a presentable website from them.
|
|
||||||
|
|
||||||
## Get started
|
|
||||||
If you don't have comfyrecipes installed yet, please see [Installation](./installation.md)
|
|
||||||
|
|
||||||
1. write a recipe in a yaml format to `myrecipes/recipes/xxxx.yaml`, for example
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../examples/firstrealrecipe.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. run `comfyrecipes build myrecipes/` (this will build the website to `myrecipes/out/html`)
|
|
||||||
3. run `comfyrecipes serve` myrecipes and navigate to <http://localhost:8000> (this will run a web server and allow you to see your rendered recipe)
|
|
||||||
|
|
||||||
## Links
|
|
||||||
* Repository: <https://codeberg.org/comfy.city/comfy-recipes>
|
|
||||||
* Issues: <https://codeberg.org/comfy.city/comfy-recipes/issues>
|
|
||||||
* Website: <https://comfy.city/comfy-recipes>
|
|
||||||
* Documentation: <https://comfy.city/comfy-recipes/docs>
|
|
|
@ -1,15 +0,0 @@
|
||||||
# Reference
|
|
||||||
|
|
||||||
* What's not marked as **MANDATORY** is optional.
|
|
||||||
|
|
||||||
## Data Types
|
|
||||||
* `string` - text of arbitrary length
|
|
||||||
* `integer` - a whole number
|
|
||||||
* `float` - a decimal number
|
|
||||||
* `number` - `integer` or `float`
|
|
||||||
|
|
||||||
## Table Of Contents
|
|
||||||
* [Recipes](recipe.md) - documenting recipes/*.yaml
|
|
||||||
* [Units](units.md) - documenting units.yaml
|
|
||||||
* [Ingredients](ingredients.md) - documenting ingredients.yaml
|
|
||||||
* [Settings](settings.md) - documenting settings.yaml
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Ingredients (ingredients.yaml)
|
|
||||||
- list of [Ingredient](#ingredient)
|
|
||||||
|
|
||||||
## Ingredient
|
|
||||||
- name, **MANDATORY**, string
|
|
||||||
- aliases, list of strings
|
|
||||||
- wdid, integer
|
|
||||||
- prices, list of [Prices](#price)
|
|
||||||
- conversions, list of [Conversions](#conversion)
|
|
||||||
|
|
||||||
## Price
|
|
||||||
- price, **MANDATORY**, number
|
|
||||||
- amount, **MANDATORY**, number
|
|
||||||
- unit, **MANDATORY**, string, unit has to be listed in units.yaml if units.yaml exists
|
|
||||||
- currency, string
|
|
||||||
|
|
||||||
## Conversion
|
|
||||||
- from, **MANDATORY**, string, from has to be listed in units.yaml if units.yaml exists
|
|
||||||
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
|
||||||
- ratio, **MANDATORY**, number
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Recipe (recipes/*.yaml)
|
|
||||||
- title - **MANDATORY**, string
|
|
||||||
- ingredients - list of [Simplified Ingredients](#simplified-ingredient) and [Ingredients](#ingredient)
|
|
||||||
- steps - list of strings and [Steps Sections](#steps-section)
|
|
||||||
- subrecipes - list of [Recipes](#recipe-recipesyaml)
|
|
||||||
|
|
||||||
## Simplified Ingredient
|
|
||||||
= string in a specific format
|
|
||||||
```
|
|
||||||
[amount unit] ingredient name [(note)]
|
|
||||||
```
|
|
||||||
[] means these sections are optional
|
|
||||||
|
|
||||||
* `amount` - number
|
|
||||||
* `unit` - a single word string
|
|
||||||
* `name` - string with arbitrary content
|
|
||||||
* `note` - string with arbitrary content, but has to be enclosed in parentheses, otherwise it will be considered to be part of `name`
|
|
||||||
|
|
||||||
for example, valid values are:
|
|
||||||
```
|
|
||||||
1 piece carrot (sliced)
|
|
||||||
^ amount
|
|
||||||
^---^ unit
|
|
||||||
^----^ ingredient name
|
|
||||||
^-----^ note
|
|
||||||
```
|
|
||||||
```
|
|
||||||
200 gram green onion
|
|
||||||
^-^ amount
|
|
||||||
^--^ unit
|
|
||||||
^---------^ ingredient name
|
|
||||||
```
|
|
||||||
```
|
|
||||||
apple
|
|
||||||
^---^ ingredient name
|
|
||||||
```
|
|
||||||
```
|
|
||||||
apple (red)
|
|
||||||
^---^ ingredient name
|
|
||||||
^---^ note
|
|
||||||
```
|
|
||||||
|
|
||||||
When amount and unit is not in the string, it is assumed to be `1 piece`.
|
|
||||||
|
|
||||||
## Ingredient
|
|
||||||
- name - **MANDATORY**, string, name has to be listed in ingredients.yaml if ingredients.yaml exists
|
|
||||||
- amount - number
|
|
||||||
- unit - string, unit has to be listed in units.yaml if units.yaml exists
|
|
||||||
- or - list of [Ingredient](#ingredient)
|
|
||||||
- note - string
|
|
||||||
|
|
||||||
## Steps Section
|
|
||||||
- section - **MANDATORY**, string, section name
|
|
||||||
- steps - list of strings
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Settings (settings.yaml)
|
|
||||||
* default_currency, string
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Units (units.yaml)
|
|
||||||
- list of [Units](#unit)
|
|
||||||
|
|
||||||
## Unit
|
|
||||||
- name, **MANDATORY**, string
|
|
||||||
- conversions, list of [Conversions](#conversion)
|
|
||||||
- aliases, list of strings
|
|
||||||
|
|
||||||
## Conversion
|
|
||||||
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
|
||||||
- ratio, **MANDATORY**, number
|
|
||||||
|
|
||||||
(this is similar to [Ingredients Conversion](./ingredients.md#conversion), but the `from` field is automatically set to unit's name)
|
|
|
@ -1,21 +0,0 @@
|
||||||
# Tutorial
|
|
||||||
|
|
||||||
This is the full file structure of comfy recipes input data:
|
|
||||||
|
|
||||||
```
|
|
||||||
- myrecipes/ - can be named according to your preference
|
|
||||||
|
|
||||||
- recipes/ - directory that will hold the recipes
|
|
||||||
- pancakes.yaml - the individual recipe
|
|
||||||
|
|
||||||
- units.yaml - OPTIONAL, file containing all valid units and their properties
|
|
||||||
- ingredients.yaml - OPTIONAL, file containing all valid ingredients and their properties
|
|
||||||
- settings.yaml - OPTIONAL, file for overriding default settings
|
|
||||||
```
|
|
||||||
|
|
||||||
In the following sub-chapters we will first create a simple recipe and then find out what each file does and what functionalities they can offer.
|
|
||||||
|
|
||||||
- [Quick Start](./quickstart.md) - Creating simple recipes
|
|
||||||
- [Units](./units.md) - What units.yaml is for and how to use it
|
|
||||||
- [Ingredients](./ingredients.md) - Why list ingredients in ingredients.yaml and what it can offer
|
|
||||||
- [Prices and Conversions](./pricesconversions.md) - Let's start adding and calculating prices of recipes
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Ingredients
|
|
||||||
|
|
||||||
Similar to `units.yaml`, also `ingredients.yaml` is not a mandatory file, but having it gives us several advantages.
|
|
||||||
* spelling mistakes are not silently ignored, if something is not listed in ingredients.yaml, comfyrecipes will warn you
|
|
||||||
* we can use aliases - different names referring the same ingredient
|
|
||||||
* we will be able to add some more data to ingredients that will allow us to calculate prices (described in [Prices and Conversions](./pricesconversions.md))
|
|
||||||
|
|
||||||
```
|
|
||||||
- myrecipes/
|
|
||||||
- recipes/
|
|
||||||
- pancakes.yaml
|
|
||||||
...
|
|
||||||
- ingredients.yaml (we will be creating this file)
|
|
||||||
```
|
|
||||||
|
|
||||||
We will again use the final recipe from [Quick Start](quickstart.md).
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you don't want to write the file manually, we can generate it using:
|
|
||||||
```sh
|
|
||||||
$ comfyrecipes generate-ingredients
|
|
||||||
```
|
|
||||||
|
|
||||||
This will generate a minimal ingredients.yaml:
|
|
||||||
|
|
||||||
`🗎 myrecipes/ingredients.yaml:`
|
|
||||||
```yaml
|
|
||||||
- name: all purpose flour
|
|
||||||
- name: butter
|
|
||||||
- name: egg
|
|
||||||
- name: milk
|
|
||||||
- name: white sugar
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, let's say we would want to call `all purpose flour` just `flour`, we can add an alias:
|
|
||||||
|
|
||||||
`🗎 myrecipes/ingredients.yaml:`
|
|
||||||
```yaml
|
|
||||||
- name: all purpose flour
|
|
||||||
aliases:
|
|
||||||
- flour
|
|
||||||
- name: butter
|
|
||||||
- name: egg
|
|
||||||
- name: milk
|
|
||||||
- name: white sugar
|
|
||||||
```
|
|
||||||
|
|
||||||
Now whenever we add an ingredient called flour, it will be a reference to `all purpose flour`.
|
|
||||||
|
|
||||||
For a full reference for what an ingredients yaml can contain, please see the [Ingredients Reference](../reference/ingredients.md)
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Prices and Conversions
|
|
||||||
|
|
||||||
ComfyRecipes has the ability to compute recipe prices if we give it enough information.
|
|
||||||
This requires your recipe collection to have an [`ingredients.yaml` file](./ingredients.md).
|
|
||||||
Like with the previous sections, we will use
|
|
||||||
|
|
||||||
# Settings
|
|
||||||
|
|
||||||
Sometimes we need to configure some defaults globally, this is what settings.yaml is for.
|
|
||||||
Currently it's only used for setting the default_currency.
|
|
||||||
|
|
||||||
Let's create settings.yaml and set the default currency to USD.
|
|
||||||
|
|
||||||
```
|
|
||||||
- myrecipes/
|
|
||||||
- recipes/
|
|
||||||
- pancakes.yaml
|
|
||||||
...
|
|
||||||
- settings.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
`🗎 myrecipes/settings.yaml:`
|
|
||||||
```yaml
|
|
||||||
default_currency: USD
|
|
||||||
```
|
|
||||||
|
|
||||||
For a full reference for what a settings yaml can contain, please see the [Settings Reference](../reference/settings.md)
|
|
|
@ -1,65 +0,0 @@
|
||||||
# Quick Start
|
|
||||||
|
|
||||||
Let's start writing recipes. First, create the directory structure that will hold all our input data.
|
|
||||||
|
|
||||||
```
|
|
||||||
- myrecipes/
|
|
||||||
- recipes/
|
|
||||||
- pancakes.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Now when we have the structure created, let's create the most minimal possible `pancakes.yaml`:
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../../examples/minimal.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
And render it by running:
|
|
||||||
```sh
|
|
||||||
$ comfyrecipes build myrecipes
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create a new directory `out/` in `myrecipes/` containing the built data.
|
|
||||||
```
|
|
||||||
- myrecipes/
|
|
||||||
- out/
|
|
||||||
- html/
|
|
||||||
- index.html
|
|
||||||
- pancakes.html
|
|
||||||
- recipes/
|
|
||||||
- pancakes.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
We can see the result if we start a web server pointing to that directory, for example by using:
|
|
||||||
```sh
|
|
||||||
$ comfyrecipes serve myrecipes
|
|
||||||
```
|
|
||||||
and navigate to <http://127.0.0.1:8000/>
|
|
||||||
|
|
||||||
`serve` should NOT be used in production.
|
|
||||||
|
|
||||||
While that was a valid recipe, it's not very useful and we can only see the title. Let's improve that:
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../../examples/minimalusable.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
* each ingredient is a step in the format `amount unit name`
|
|
||||||
* `amount` has to be a number
|
|
||||||
* `unit` has to be a single word
|
|
||||||
* `name` can be a string with arbitrary content
|
|
||||||
* for a full description of this format, please see the [Reference section](../reference/recipe.md#simplified-ingredient)
|
|
||||||
* each step is a string with arbitrary content
|
|
||||||
|
|
||||||
And again, build, make sure the server is running and navigate to <http://127.0.0.1:8000/>. From now on, we will assume you know how to build and serve your output directory.
|
|
||||||
|
|
||||||
Once more, let's improve the recipe once again to something that can actually be made and is not just a demo. This does not introduce any new concepts compared to the last recipe we wrote.
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
For a full reference for what a recipe yaml can contain, please see the [Recipe Reference](../reference/recipe.md)
|
|
|
@ -1,51 +0,0 @@
|
||||||
# Units
|
|
||||||
|
|
||||||
Each recipe ingredient has a string unit assigned to it. This is great, but a centralized list of all alowed units with some additional properties has several advantages:
|
|
||||||
|
|
||||||
* spelling mistakes are not silently ignored, if you make a mistake in the ingredient unit name, comfyrecipes will warn you that it's not on the units list
|
|
||||||
* `gram` and `g` can refer to the same unit (using aliases)
|
|
||||||
* we can tell comfyrecipes unit conversion rates (for example 1000 gram = 1 kilogram) which it can then use for example for calculating prices
|
|
||||||
|
|
||||||
This example will use the final example from [Quick Start](quickstart.md).
|
|
||||||
|
|
||||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
|
||||||
```yaml
|
|
||||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
- myrecipes/
|
|
||||||
- recipes/
|
|
||||||
- pancakes.yaml
|
|
||||||
...
|
|
||||||
- units.yaml (we will be creating this file)
|
|
||||||
```
|
|
||||||
|
|
||||||
If you don't want to write the file manually, we can generate it using:
|
|
||||||
```sh
|
|
||||||
$ comfyrecipes generate-units
|
|
||||||
```
|
|
||||||
|
|
||||||
This will generate a minimal units.yaml:
|
|
||||||
|
|
||||||
`🗎 myrecipes/units.yaml:`
|
|
||||||
```yaml
|
|
||||||
- name: cup
|
|
||||||
- name: piece
|
|
||||||
- name: tablespoon
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, let's say we would want to call `tablespoon` just `tbsp`, we can add an alias:
|
|
||||||
|
|
||||||
`🗎 myrecipes/units.yaml:`
|
|
||||||
```yaml
|
|
||||||
- name: cup
|
|
||||||
- name: piece
|
|
||||||
- name: tablespoon
|
|
||||||
aliases:
|
|
||||||
- tbsp
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we can rename the `tablespoon` unit in the recipe to `tbsp` and it will reference the `tablespoon` unit.
|
|
||||||
|
|
||||||
For a full reference for what a recipe yaml can contain, please see the [Units Reference](../reference/units.md)
|
|
|
@ -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", "mistune", "lxml"]
|
dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml", "lxml_html_clean"]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 3 - Alpha",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
|
@ -17,9 +17,9 @@ classifiers = [
|
||||||
license = { file = "LICENSE" }
|
license = { file = "LICENSE" }
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "https://codeberg.org/comfy.city/comfy-recipes"
|
Homepage = "https://git.comfy.city/Emi/comfy-recipes"
|
||||||
Repository = "https://codeberg.org/comfy.city/comfy-recipes.git"
|
Repository = "https://git.comfy.city/Emi/comfy-recipes.git"
|
||||||
Issues = "https://codeberg.org/comfy.city/comfy-recipes/issues"
|
Issues = "https://git.comfy.city/Emi/comfy-recipes/issues"
|
||||||
Documentation = "https://comfy.city/comfy-recipes/docs"
|
Documentation = "https://comfy.city/comfy-recipes/docs"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue