mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-23 06:45:22 -07:00
Updated file format slightly. Updated all current food seed files for all locales to use the new format
This commit is contained in:
parent
6e485060e0
commit
645d276c5d
6 changed files with 18653 additions and 18412 deletions
70
dev/scripts/convert_seed_files_to_new_format.py
Normal file
70
dev/scripts/convert_seed_files_to_new_format.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
|
def get_seed_locale_names() -> set[str]:
|
||||||
|
"""Find all locales in the seed/resources/ folder
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A set of every file name where there's both a seed label and seed food file
|
||||||
|
"""
|
||||||
|
|
||||||
|
LABELS_PATH = "/workspaces/mealie/mealie/repos/seed/resources/labels/locales/"
|
||||||
|
FOODS_PATH = "/workspaces/mealie/mealie/repos/seed/resources/foods/locales/"
|
||||||
|
label_locales = glob.glob("*.json", root_dir=LABELS_PATH)
|
||||||
|
foods_locales = glob.glob("*.json", root_dir=FOODS_PATH)
|
||||||
|
|
||||||
|
# ensure that a locale has both a label and a food seed file
|
||||||
|
return set(label_locales).intersection(foods_locales)
|
||||||
|
|
||||||
|
|
||||||
|
def get_labels_from_file(locale: str) -> list[str]:
|
||||||
|
"""Query a locale to get all of the labels so that they can be added to the new foods seed format
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
All of the labels found within the seed file for a given locale
|
||||||
|
"""
|
||||||
|
|
||||||
|
locale_path = pathlib.Path("/workspaces/mealie/mealie/repos/seed/resources/labels/locales/" + locale)
|
||||||
|
label_names = [label["name"] for label in json.loads(locale_path.read_text(encoding="utf-8"))]
|
||||||
|
return label_names
|
||||||
|
|
||||||
|
|
||||||
|
def transform_foods(locale: str):
|
||||||
|
"""
|
||||||
|
Convert the current food seed file for a locale into a new format which maps each food to a label
|
||||||
|
|
||||||
|
Existing format of foods seed file is a dictionary where each key is a food name and the values are a dictionary
|
||||||
|
of attributes such as name and plural_name
|
||||||
|
|
||||||
|
New format maps each food to a label. The top-level dictionary has each key as a label e.g. "Fruits".
|
||||||
|
Each label key as a value that is a dictionary with an element called "foods"
|
||||||
|
"Foods" is a dictionary of each food for that label, with a key of the english food name e.g. "baking-soda"
|
||||||
|
and a value of attributes, including the translated name of the item e.g. "bicarbonate of soda" for en-GB.
|
||||||
|
"""
|
||||||
|
|
||||||
|
locale_path = pathlib.Path("/workspaces/mealie/mealie/repos/seed/resources/foods/locales/" + locale)
|
||||||
|
|
||||||
|
with open(locale_path, encoding="utf-8") as infile:
|
||||||
|
data = json.load(infile)
|
||||||
|
|
||||||
|
transformed_data = {"": {"foods": dict(data.items())}}
|
||||||
|
|
||||||
|
# Seeding for labels now pulls from the foods file and parses the labels from there (as top-level keys),
|
||||||
|
# thus we need to add all of the existing labels to the new food seed file and give them an empty foods dictionary
|
||||||
|
label_names = get_labels_from_file(locale)
|
||||||
|
for label in label_names:
|
||||||
|
transformed_data[label] = {"foods": {}}
|
||||||
|
|
||||||
|
with open(locale_path, "w", encoding="utf-8") as outfile:
|
||||||
|
json.dump(transformed_data, outfile, indent=4, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
for locale in get_seed_locale_names():
|
||||||
|
transform_foods(locale)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"": {
|
||||||
|
"foods": {
|
||||||
"acorn-squash": {
|
"acorn-squash": {
|
||||||
"name": "acorn squash"
|
"name": "acorn squash"
|
||||||
},
|
},
|
||||||
|
@ -689,4 +691,69 @@
|
||||||
"name": "zucchini",
|
"name": "zucchini",
|
||||||
"plural_name": "zucchinis"
|
"plural_name": "zucchinis"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Produce": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Grains": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Fruits": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Vegetables": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Meat": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Seafood": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Beverages": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Baked Goods": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Canned Goods": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Condiments": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Confectionary": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Dairy Products": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Frozen Foods": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Health Foods": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Household": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Meat Products": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Snacks": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Spices": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Sweets": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Alcohol": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Other": {
|
||||||
|
"foods": {}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"": {
|
||||||
|
"foods": {
|
||||||
"acorn-squash": {
|
"acorn-squash": {
|
||||||
"name": "acorn squash"
|
"name": "acorn squash"
|
||||||
},
|
},
|
||||||
|
@ -689,4 +691,66 @@
|
||||||
"name": "zucchini",
|
"name": "zucchini",
|
||||||
"plural_name": "zucchinis"
|
"plural_name": "zucchinis"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Домаћи производи": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Житарице": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Воће": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Поврће": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Месо": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Морски плодови": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Пића": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Пецива": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Конзервирана храна": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Зачини": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Кондиторски производи": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Млечни производи": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Смрзнута храна": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Здрава храна": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Домаћинство": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Месни производи": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Грицкалице": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Слаткиши": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Алкохол": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Остало": {
|
||||||
|
"foods": {}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"": {
|
||||||
|
"foods": {
|
||||||
"acorn-squash": {
|
"acorn-squash": {
|
||||||
"name": "acorn squash"
|
"name": "acorn squash"
|
||||||
},
|
},
|
||||||
|
@ -689,4 +691,66 @@
|
||||||
"name": "zucchini",
|
"name": "zucchini",
|
||||||
"plural_name": "zucchinis"
|
"plural_name": "zucchinis"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Rau củ": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Các loại hạt": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Trái cây": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Thịt": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Hải sản": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ uống": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Bánh": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ hộp": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ gia vị": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Kẹo": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Sản phẩm từ sữa": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ đông lạnh": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ tốt cho sức khỏe": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Gia đình": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Sản phẩm thịt": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ ăn vặt": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Gia vị": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Đồ ngọt": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Cồn": {
|
||||||
|
"foods": {}
|
||||||
|
},
|
||||||
|
"Khác": {
|
||||||
|
"foods": {}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -33,7 +33,8 @@ class MultiPurposeLabelSeeder(AbstractSeeder):
|
||||||
file = self.get_file(locale)
|
file = self.get_file(locale)
|
||||||
|
|
||||||
current_label_names = {label.name for label in self.get_all_labels()}
|
current_label_names = {label.name for label in self.get_all_labels()}
|
||||||
seed_label_names = set(json.loads(file.read_text(encoding="utf-8")).keys())
|
# load from the foods locale file and remove any empty strings
|
||||||
|
seed_label_names = set(filter(None, json.loads(file.read_text(encoding="utf-8")).keys())) # type: set[str]
|
||||||
# only seed new labels
|
# only seed new labels
|
||||||
to_seed_labels = seed_label_names - current_label_names
|
to_seed_labels = seed_label_names - current_label_names
|
||||||
for label in to_seed_labels:
|
for label in to_seed_labels:
|
||||||
|
@ -101,21 +102,20 @@ class IngredientFoodsSeeder(AbstractSeeder):
|
||||||
file = self.get_file(locale)
|
file = self.get_file(locale)
|
||||||
|
|
||||||
# get all current unique foods
|
# get all current unique foods
|
||||||
seed_foods_names = {food.name for food in self.get_all_foods()}
|
seen_foods_names = {food.name for food in self.get_all_foods()}
|
||||||
for label, value in json.loads(file.read_text(encoding="utf-8")).items():
|
for label, values in json.loads(file.read_text(encoding="utf-8")).items():
|
||||||
label_out = self.get_label(label)
|
label_out = self.get_label(label)
|
||||||
|
|
||||||
for food in value["foods"]:
|
for food_name, attributes in values["foods"].items():
|
||||||
# don't seed foods that already exist, matched on food name
|
if food_name in seen_foods_names:
|
||||||
if food["name"] in seed_foods_names:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
seed_foods_names.add(food["name"])
|
seen_foods_names.add(food_name)
|
||||||
yield SaveIngredientFood(
|
yield SaveIngredientFood(
|
||||||
group_id=self.repos.group_id,
|
group_id=self.repos.group_id,
|
||||||
name=food["name"],
|
name=attributes["name"],
|
||||||
plural_name=food["pluralName"],
|
plural_name=attributes.get("plural_name"),
|
||||||
description="",
|
description="", # description expected to be empty string by UnitFoodBase class
|
||||||
label_id=label_out.id if label_out and label_out.id else None,
|
label_id=label_out.id if label_out and label_out.id else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue