Skip to content

Commit 2718f73

Browse files
committed
adding the rest ofthe nutrition properties from schema.org
1 parent 1bd3d38 commit 2718f73

File tree

9 files changed

+114
-22
lines changed

9 files changed

+114
-22
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""'add the rest of the schema.org nutrition properties'
2+
3+
Revision ID: 602927e1013e
4+
Revises: 1fe4bd37ccc8
5+
Create Date: 2024-10-01 14:17:00.611398
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
11+
from alembic import op
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "602927e1013e"
15+
down_revision: str | None = "1fe4bd37ccc8"
16+
branch_labels: str | tuple[str, ...] | None = None
17+
depends_on: str | tuple[str, ...] | None = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
with op.batch_alter_table("recipe_nutrition", schema=None) as batch_op:
23+
batch_op.add_column(sa.Column("cholesterol_content", sa.String(), nullable=True))
24+
batch_op.add_column(sa.Column("saturated_fat_content", sa.String(), nullable=True))
25+
batch_op.add_column(sa.Column("trans_fat_content", sa.String(), nullable=True))
26+
batch_op.add_column(sa.Column("unsaturated_fat_content", sa.String(), nullable=True))
27+
28+
# ### end Alembic commands ###
29+
30+
31+
def downgrade():
32+
# ### commands auto generated by Alembic - please adjust! ###
33+
with op.batch_alter_table("recipe_nutrition", schema=None) as batch_op:
34+
batch_op.drop_column("unsaturated_fat_content")
35+
batch_op.drop_column("trans_fat_content")
36+
batch_op.drop_column("saturated_fat_content")
37+
batch_op.drop_column("cholesterol_content")
38+
39+
# ### end Alembic commands ###

frontend/composables/recipes/use-recipe-nutrition.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ export function useNutritionLabels() {
1717
label: i18n.tc("recipe.calories"),
1818
suffix: i18n.tc("recipe.calories-suffix"),
1919
},
20+
carbohydrateContent: {
21+
label: i18n.tc("recipe.carbohydrate-content"),
22+
suffix: i18n.tc("recipe.grams"),
23+
},
24+
cholesterolContent: {
25+
label: i18n.tc("recipe.cholesterol-content"),
26+
suffix: i18n.tc("recipe.milligrams"),
27+
},
2028
fatContent: {
2129
label: i18n.tc("recipe.fat-content"),
2230
suffix: i18n.tc("recipe.grams"),
@@ -29,6 +37,10 @@ export function useNutritionLabels() {
2937
label: i18n.tc("recipe.protein-content"),
3038
suffix: i18n.tc("recipe.grams"),
3139
},
40+
saturatedFatContent: {
41+
label: i18n.tc("recipe.saturated-fat-content"),
42+
suffix: i18n.tc("recipe.grams"),
43+
},
3244
sodiumContent: {
3345
label: i18n.tc("recipe.sodium-content"),
3446
suffix: i18n.tc("recipe.milligrams"),
@@ -37,8 +49,12 @@ export function useNutritionLabels() {
3749
label: i18n.tc("recipe.sugar-content"),
3850
suffix: i18n.tc("recipe.grams"),
3951
},
40-
carbohydrateContent: {
41-
label: i18n.tc("recipe.carbohydrate-content"),
52+
transFatContent: {
53+
label: i18n.tc("recipe.trans-fat-content"),
54+
suffix: i18n.tc("recipe.grams"),
55+
},
56+
unsaturatedFatContent: {
57+
label: i18n.tc("recipe.unsaturated-fat-content"),
4258
suffix: i18n.tc("recipe.grams"),
4359
},
4460
};

frontend/lang/messages/en-US.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@
461461
"calories-suffix": "calories",
462462
"carbohydrate-content": "Carbohydrate",
463463
"categories": "Categories",
464+
"cholesterol-content": "Cholesterol",
464465
"comment-action": "Comment",
465466
"comment": "Comment",
466467
"comments": "Comments",
@@ -507,8 +508,10 @@
507508
"recipe-updated": "Recipe updated",
508509
"remove-from-favorites": "Remove from Favorites",
509510
"remove-section": "Remove Section",
511+
"saturated-fat-content": "Saturated fat",
510512
"save-recipe-before-use": "Save recipe before use",
511513
"section-title": "Section Title",
514+
"serving-size": "Serving size",
512515
"servings": "Servings",
513516
"share-recipe-message": "I wanted to share my {0} recipe with you.",
514517
"show-nutrition-values": "Show Nutrition Values",
@@ -517,7 +520,9 @@
517520
"sugar-content": "Sugar",
518521
"title": "Title",
519522
"total-time": "Total Time",
523+
"trans-fat-content": "Trans-fat",
520524
"unable-to-delete-recipe": "Unable to Delete Recipe",
525+
"unsaturated-fat-content": "Unsaturated fat",
521526
"no-recipe": "No Recipe",
522527
"locked-by-owner": "Locked by Owner",
523528
"join-the-conversation": "Join the Conversation",

frontend/lib/api/types/recipe.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,16 @@ export interface MergeUnit {
194194
}
195195
export interface Nutrition {
196196
calories?: string | null;
197-
fatContent?: string | null;
198-
proteinContent?: string | null;
199197
carbohydrateContent?: string | null;
198+
cholesterolContent?: string | null;
199+
fatContent?: string | null;
200200
fiberContent?: string | null;
201+
proteinContent?: string | null;
202+
saturatedFatContent?: string | null;
201203
sodiumContent?: string | null;
202204
sugarContent?: string | null;
205+
transFatContent?: string | null;
206+
unsaturatedFatContent?: string | null;
203207
}
204208
export interface ParsedIngredient {
205209
input?: string | null;
@@ -486,7 +490,7 @@ export interface ScrapeRecipeTest {
486490
url: string;
487491
useOpenAI?: boolean;
488492
}
489-
export interface SlugResponse {}
493+
export interface SlugResponse { }
490494
export interface TagIn {
491495
name: string;
492496
}

mealie/db/models/recipe/nutrition.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,52 @@ class Nutrition(SqlAlchemyBase):
99
__tablename__ = "recipe_nutrition"
1010
id: Mapped[int] = mapped_column(sa.Integer, primary_key=True)
1111
recipe_id: Mapped[GUID | None] = mapped_column(GUID, sa.ForeignKey("recipes.id"), index=True)
12+
1213
calories: Mapped[str | None] = mapped_column(sa.String)
14+
carbohydrate_content: Mapped[str | None] = mapped_column(sa.String)
15+
cholesterol_content: Mapped[str | None] = mapped_column(sa.String)
1316
fat_content: Mapped[str | None] = mapped_column(sa.String)
1417
fiber_content: Mapped[str | None] = mapped_column(sa.String)
1518
protein_content: Mapped[str | None] = mapped_column(sa.String)
16-
carbohydrate_content: Mapped[str | None] = mapped_column(sa.String)
19+
saturated_fat_content: Mapped[str | None] = mapped_column(sa.String)
20+
21+
# `serving_size` is not a scaling factor, but a per-serving volume or mass
22+
# according to schema.org. E.g., "2 L", "500 g", "5 cups", etc.
23+
#
24+
# Ignoring for now because it's too difficult to work around variable units
25+
# in translation for the frontend. Also, it causes cognitive dissonance wrt
26+
# "servings" (i.e., "serves 2" etc.), which is an unrelated concept that
27+
# might cause confusion.
28+
#
29+
# serving_size: Mapped[str | None] = mapped_column(sa.String)
30+
1731
sodium_content: Mapped[str | None] = mapped_column(sa.String)
1832
sugar_content: Mapped[str | None] = mapped_column(sa.String)
33+
trans_fat_content: Mapped[str | None] = mapped_column(sa.String)
34+
unsaturated_fat_content: Mapped[str | None] = mapped_column(sa.String)
1935

2036
def __init__(
2137
self,
2238
calories=None,
39+
carbohydrate_content=None,
40+
cholesterol_content=None,
2341
fat_content=None,
2442
fiber_content=None,
2543
protein_content=None,
44+
saturated_fat_content=None,
2645
sodium_content=None,
2746
sugar_content=None,
28-
carbohydrate_content=None,
47+
trans_fat_content=None,
48+
unsaturated_fat_content=None,
2949
) -> None:
3050
self.calories = calories
51+
self.carbohydrate_content = carbohydrate_content
52+
self.cholesterol_content = cholesterol_content
3153
self.fat_content = fat_content
3254
self.fiber_content = fiber_content
3355
self.protein_content = protein_content
56+
self.saturated_fat_content = saturated_fat_content
3457
self.sodium_content = sodium_content
3558
self.sugar_content = sugar_content
36-
self.carbohydrate_content = carbohydrate_content
59+
self.trans_fat_content = trans_fat_content
60+
self.unsaturated_fat_content = unsaturated_fat_content

mealie/db/models/recipe/recipe.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def __init__(
187187
settings: dict | None = None,
188188
**_,
189189
) -> None:
190-
self.nutrition = Nutrition(**nutrition) if nutrition else Nutrition()
190+
self.nutrition = Nutrition(**(nutrition or {}))
191191

192192
if recipe_instructions is not None:
193193
self.recipe_instructions = [RecipeInstruction(**step, session=session) for step in recipe_instructions]
@@ -198,7 +198,7 @@ def __init__(
198198
if assets:
199199
self.assets = [RecipeAsset(**a) for a in assets]
200200

201-
self.settings = RecipeSettings(**settings) if settings else RecipeSettings()
201+
self.settings = RecipeSettings(**(settings or {}))
202202

203203
if notes:
204204
self.notes = [Note(**n) for n in notes]

mealie/routes/spa/__init__.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,7 @@ def content_with_meta(group_slug: str, recipe: Recipe) -> str:
104104

105105
ingredients.append(s)
106106

107-
nutrition: dict[str, str | None] = {}
108-
if recipe.nutrition:
109-
nutrition["calories"] = recipe.nutrition.calories
110-
nutrition["fatContent"] = recipe.nutrition.fat_content
111-
nutrition["fiberContent"] = recipe.nutrition.fiber_content
112-
nutrition["proteinContent"] = recipe.nutrition.protein_content
113-
nutrition["carbohydrateContent"] = recipe.nutrition.carbohydrate_content
114-
nutrition["sodiumContent"] = recipe.nutrition.sodium_content
115-
nutrition["sugarContent"] = recipe.nutrition.sugar_content
107+
nutrition: dict[str, str | None] = recipe.nutrition.model_dump(by_alias=True) if recipe.nutrition else {}
116108

117109
as_schema_org = {
118110
"@context": "https://schema.org",
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
from pydantic import ConfigDict
2+
from pydantic.alias_generators import to_camel
23

34
from mealie.schema._mealie import MealieModel
45

56

67
class Nutrition(MealieModel):
78
calories: str | None = None
8-
fat_content: str | None = None
9-
protein_content: str | None = None
109
carbohydrate_content: str | None = None
10+
cholesterol_content: str | None = None
11+
fat_content: str | None = None
1112
fiber_content: str | None = None
13+
protein_content: str | None = None
14+
saturated_fat_content: str | None = None
1215
sodium_content: str | None = None
1316
sugar_content: str | None = None
14-
model_config = ConfigDict(from_attributes=True, coerce_numbers_to_str=True)
17+
trans_fat_content: str | None = None
18+
unsaturated_fat_content: str | None = None
19+
20+
model_config = ConfigDict(
21+
from_attributes=True,
22+
coerce_numbers_to_str=True,
23+
alias_generator=to_camel,
24+
)

mealie/services/migrations/plantoeat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def _parse_recipe_nutrition_from_row(self, row: dict) -> dict:
7474
nut_dict["sodiumContent"] = get_value_as_string_or_none(row, "Sodium")
7575
nut_dict["sugarContent"] = get_value_as_string_or_none(row, "Sugar")
7676

77+
# FIXME: do we have the other schema.org values here to migrate?
78+
7779
return cleaner.clean_nutrition(nut_dict)
7880

7981
def _get_categories_from_row(self, row: dict) -> list[str]:

0 commit comments

Comments
 (0)