mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-05 14:18:51 -05:00
Merge branch 'develop' into feature/unit-conversion
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
# when unset: 1 (true) - dont unset this, just for development
|
# when unset: 1 (true) - dont unset this, just for development
|
||||||
DEBUG=0
|
DEBUG=0
|
||||||
SQL_DEBUG=0
|
SQL_DEBUG=0
|
||||||
|
DEBUG_TOOLBAR=0
|
||||||
|
|
||||||
# HTTP port to bind to
|
# HTTP port to bind to
|
||||||
# TANDOOR_PORT=8080
|
# TANDOOR_PORT=8080
|
||||||
|
|||||||
4
.github/workflows/build-docker.yml
vendored
4
.github/workflows/build-docker.yml
vendored
@@ -69,11 +69,13 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
|
if: github.secret_source == 'Actions'
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
|
if: github.secret_source == 'Actions'
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -100,7 +102,7 @@ jobs:
|
|||||||
context: .
|
context: .
|
||||||
file: ${{ matrix.dockerfile }}
|
file: ${{ matrix.dockerfile }}
|
||||||
pull: true
|
pull: true
|
||||||
push: true
|
push: ${{ github.secret_source == 'Actions' }}
|
||||||
platforms: ${{ matrix.platforms }}
|
platforms: ${{ matrix.platforms }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|||||||
@@ -2,24 +2,54 @@ import json
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Ingredient, Recipe, Step
|
from cookbook.models import Ingredient, Recipe, Step, Keyword, Comment, CookLog
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
class OpenEats(Integration):
|
class OpenEats(Integration):
|
||||||
|
|
||||||
def get_recipe_from_file(self, file):
|
def get_recipe_from_file(self, file):
|
||||||
recipe = Recipe.objects.create(name=file['name'].strip(), created_by=self.request.user, internal=True,
|
|
||||||
|
description = file['info']
|
||||||
|
description_max_length = Recipe._meta.get_field('description').max_length
|
||||||
|
if len(description) > description_max_length:
|
||||||
|
description = description[0:description_max_length]
|
||||||
|
|
||||||
|
recipe = Recipe.objects.create(name=file['name'].strip(), description=description, created_by=self.request.user, internal=True,
|
||||||
servings=file['servings'], space=self.request.space, waiting_time=file['cook_time'], working_time=file['prep_time'])
|
servings=file['servings'], space=self.request.space, waiting_time=file['cook_time'], working_time=file['prep_time'])
|
||||||
|
|
||||||
instructions = ''
|
instructions = ''
|
||||||
if file["info"] != '':
|
|
||||||
instructions += file["info"]
|
|
||||||
|
|
||||||
if file["directions"] != '':
|
if file["directions"] != '':
|
||||||
instructions += file["directions"]
|
instructions += file["directions"]
|
||||||
|
|
||||||
if file["source"] != '':
|
if file["source"] != '':
|
||||||
instructions += file["source"]
|
instructions += '\n' + _('Recipe source:') + f'[{file["source"]}]({file["source"]})'
|
||||||
|
|
||||||
|
cuisine_keyword, created = Keyword.objects.get_or_create(name="Cuisine", space=self.request.space)
|
||||||
|
if file["cuisine"] != '':
|
||||||
|
keyword, created = Keyword.objects.get_or_create(name=file["cuisine"].strip(), space=self.request.space)
|
||||||
|
if created:
|
||||||
|
keyword.move(cuisine_keyword, pos="last-child")
|
||||||
|
recipe.keywords.add(keyword)
|
||||||
|
|
||||||
|
course_keyword, created = Keyword.objects.get_or_create(name="Course", space=self.request.space)
|
||||||
|
if file["course"] != '':
|
||||||
|
keyword, created = Keyword.objects.get_or_create(name=file["course"].strip(), space=self.request.space)
|
||||||
|
if created:
|
||||||
|
keyword.move(course_keyword, pos="last-child")
|
||||||
|
recipe.keywords.add(keyword)
|
||||||
|
|
||||||
|
for tag in file["tags"]:
|
||||||
|
keyword, created = Keyword.objects.get_or_create(name=tag.strip(), space=self.request.space)
|
||||||
|
recipe.keywords.add(keyword)
|
||||||
|
|
||||||
|
for comment in file['comments']:
|
||||||
|
Comment.objects.create(recipe=recipe, text=comment['text'], created_by=self.request.user)
|
||||||
|
CookLog.objects.create(recipe=recipe, rating=comment['rating'], created_by=self.request.user, space=self.request.space)
|
||||||
|
|
||||||
|
if file["photo"] != '':
|
||||||
|
recipe.image = f'recipes/openeats-import/{file["photo"]}'
|
||||||
|
recipe.save()
|
||||||
|
|
||||||
step = Step.objects.create(instruction=instructions, space=self.request.space,)
|
step = Step.objects.create(instruction=instructions, space=self.request.space,)
|
||||||
|
|
||||||
@@ -38,6 +68,9 @@ class OpenEats(Integration):
|
|||||||
recipe_json = json.loads(file.read())
|
recipe_json = json.loads(file.read())
|
||||||
recipe_dict = {}
|
recipe_dict = {}
|
||||||
ingredient_group_dict = {}
|
ingredient_group_dict = {}
|
||||||
|
cuisine_group_dict = {}
|
||||||
|
course_group_dict = {}
|
||||||
|
tag_group_dict = {}
|
||||||
|
|
||||||
for o in recipe_json:
|
for o in recipe_json:
|
||||||
if o['model'] == 'recipe.recipe':
|
if o['model'] == 'recipe.recipe':
|
||||||
@@ -50,11 +83,27 @@ class OpenEats(Integration):
|
|||||||
'cook_time': o['fields']['cook_time'],
|
'cook_time': o['fields']['cook_time'],
|
||||||
'servings': o['fields']['servings'],
|
'servings': o['fields']['servings'],
|
||||||
'ingredients': [],
|
'ingredients': [],
|
||||||
|
'photo': o['fields']['photo'],
|
||||||
|
'cuisine': o['fields']['cuisine'],
|
||||||
|
'course': o['fields']['course'],
|
||||||
|
'tags': o['fields']['tags'],
|
||||||
|
'comments': [],
|
||||||
}
|
}
|
||||||
if o['model'] == 'ingredient.ingredientgroup':
|
if o['model'] == 'ingredient.ingredientgroup':
|
||||||
ingredient_group_dict[o['pk']] = o['fields']['recipe']
|
ingredient_group_dict[o['pk']] = o['fields']['recipe']
|
||||||
|
if o['model'] == 'recipe_groups.cuisine':
|
||||||
|
cuisine_group_dict[o['pk']] = o['fields']['title']
|
||||||
|
if o['model'] == 'recipe_groups.course':
|
||||||
|
course_group_dict[o['pk']] = o['fields']['title']
|
||||||
|
if o['model'] == 'recipe_groups.tag':
|
||||||
|
tag_group_dict[o['pk']] = o['fields']['title']
|
||||||
|
|
||||||
for o in recipe_json:
|
for o in recipe_json:
|
||||||
|
if o['model'] == 'rating.rating':
|
||||||
|
recipe_dict[o['fields']['recipe']]["comments"].append({
|
||||||
|
"text": o['fields']['comment'],
|
||||||
|
"rating": o['fields']['rating']
|
||||||
|
})
|
||||||
if o['model'] == 'ingredient.ingredient':
|
if o['model'] == 'ingredient.ingredient':
|
||||||
ingredient = {
|
ingredient = {
|
||||||
'food': o['fields']['title'],
|
'food': o['fields']['title'],
|
||||||
@@ -63,6 +112,15 @@ class OpenEats(Integration):
|
|||||||
}
|
}
|
||||||
recipe_dict[ingredient_group_dict[o['fields']['ingredient_group']]]['ingredients'].append(ingredient)
|
recipe_dict[ingredient_group_dict[o['fields']['ingredient_group']]]['ingredients'].append(ingredient)
|
||||||
|
|
||||||
|
for k, r in recipe_dict.items():
|
||||||
|
if r["cuisine"] in cuisine_group_dict:
|
||||||
|
r["cuisine"] = cuisine_group_dict[r["cuisine"]]
|
||||||
|
if r["course"] in course_group_dict:
|
||||||
|
r["course"] = course_group_dict[r["course"]]
|
||||||
|
for index in range(len(r["tags"])):
|
||||||
|
if r["tags"][index] in tag_group_dict:
|
||||||
|
r["tags"][index] = tag_group_dict[r["tags"][index]]
|
||||||
|
|
||||||
return list(recipe_dict.values())
|
return list(recipe_dict.values())
|
||||||
|
|
||||||
def get_file_from_recipe(self, recipe):
|
def get_file_from_recipe(self, recipe):
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
|
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
|
||||||
"PO-Revision-Date: 2023-01-08 17:55+0000\n"
|
"PO-Revision-Date: 2023-03-25 11:32+0000\n"
|
||||||
"Last-Translator: Joachim Weber <joachim.weber@gmx.de>\n"
|
"Last-Translator: Matěj Kubla <matykubla@gmail.com>\n"
|
||||||
"Language-Team: Czech <http://translate.tandoor.dev/projects/tandoor/"
|
"Language-Team: Czech <http://translate.tandoor.dev/projects/tandoor/"
|
||||||
"recipes-backend/cs/>\n"
|
"recipes-backend/cs/>\n"
|
||||||
"Language: cs\n"
|
"Language: cs\n"
|
||||||
@@ -553,7 +553,7 @@ msgstr "Cesta musí být v následujícím formátu"
|
|||||||
|
|
||||||
#: .\cookbook\templates\batch\monitor.html:27
|
#: .\cookbook\templates\batch\monitor.html:27
|
||||||
msgid "Sync Now!"
|
msgid "Sync Now!"
|
||||||
msgstr "Zahájit synchronizaci"
|
msgstr "Zahájit synchronizaci!"
|
||||||
|
|
||||||
#: .\cookbook\templates\batch\waiting.html:4
|
#: .\cookbook\templates\batch\waiting.html:4
|
||||||
#: .\cookbook\templates\batch\waiting.html:10
|
#: .\cookbook\templates\batch\waiting.html:10
|
||||||
@@ -1036,7 +1036,7 @@ msgstr "Tento text je kurzívou"
|
|||||||
#: .\cookbook\templates\markdown_info.html:61
|
#: .\cookbook\templates\markdown_info.html:61
|
||||||
#: .\cookbook\templates\markdown_info.html:77
|
#: .\cookbook\templates\markdown_info.html:77
|
||||||
msgid "Blockquotes are also possible"
|
msgid "Blockquotes are also possible"
|
||||||
msgstr "Lze použít i kvotace "
|
msgstr "Lze použít i kvotace"
|
||||||
|
|
||||||
#: .\cookbook\templates\markdown_info.html:84
|
#: .\cookbook\templates\markdown_info.html:84
|
||||||
msgid "Lists"
|
msgid "Lists"
|
||||||
@@ -1106,8 +1106,8 @@ msgid ""
|
|||||||
"rel=\"noreferrer noopener\" target=\"_blank\">this one.</a>"
|
"rel=\"noreferrer noopener\" target=\"_blank\">this one.</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ruční vytváření tabulek pomocí značek je složité. Doporučujeme použít "
|
"Ruční vytváření tabulek pomocí značek je složité. Doporučujeme použít "
|
||||||
"například <a href=\"https://www.tablesgenerator.com/markdown_tables\" "
|
"například <a href=\"https://www.tablesgenerator.com/markdown_tables\" rel="
|
||||||
"rel=\"noreferrer noopener\" target=\"_blank\">tento tabulkový editor</a>."
|
"\"noreferrer noopener\" target=\"_blank\">tento tabulkový editor.</a>"
|
||||||
|
|
||||||
#: .\cookbook\templates\markdown_info.html:155
|
#: .\cookbook\templates\markdown_info.html:155
|
||||||
#: .\cookbook\templates\markdown_info.html:157
|
#: .\cookbook\templates\markdown_info.html:157
|
||||||
@@ -1256,22 +1256,36 @@ msgid ""
|
|||||||
" "
|
" "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
" <p>Modul jídelníčku umožňuje plánovat jídlo pomocí receptů i poznámek.</p>\n"
|
" <p>Modul jídelníčku umožňuje plánovat jídlo "
|
||||||
" <p>Jednoduše vyberte recept ze seznamu naposledy navštívených receptů, nebo ho vyhledejte\n"
|
"pomocí receptů i poznámek.</p>\n"
|
||||||
" s přetáhněte na požadovaný den v rozvrhu. Můžete také přidat poznámku s popiskem\n"
|
" <p>Jednoduše vyberte recept ze seznamu naposledy "
|
||||||
" a poté přetáhnout recept pro vytvoření plánu s vlatními popisky. Vytvořením samotné poznámky\n"
|
"navštívených receptů, nebo ho vyhledejte\n"
|
||||||
" je možné přetažením pole poznámky do rozvrhu.</p>\n"
|
" s přetáhněte na požadovaný den v rozvrhu. "
|
||||||
" <p>Kliknutím na recept zobrazíte detailní náhled. Odtud lze také přidat položky\n"
|
"Můžete také přidat poznámku s popiskem\n"
|
||||||
" do nákupního seznamu. Do nákupního seznamu můžete také přidat všechny recepty na daný den\n"
|
" a poté přetáhnout recept pro vytvoření plánu "
|
||||||
" kliknutím na ikonu nákupního košíku na horní straně tabulky.</p>\n"
|
"s vlatními popisky. Vytvořením samotné poznámky\n"
|
||||||
" <p>V běžném případě se jídelníček plánuje hromadně, proto můžete v nastavení definovat\n"
|
" je možné přetažením pole poznámky do "
|
||||||
" se kterými uživateli si přejete jídelníčky sdílet.\n"
|
"rozvrhu.</p>\n"
|
||||||
|
" <p>Kliknutím na recept zobrazíte detailní "
|
||||||
|
"náhled. Odtud lze také přidat položky\n"
|
||||||
|
" do nákupního seznamu. Do nákupního seznamu "
|
||||||
|
"můžete také přidat všechny recepty na daný den\n"
|
||||||
|
" kliknutím na ikonu nákupního košíku na horní "
|
||||||
|
"straně tabulky.</p>\n"
|
||||||
|
" <p>V běžném případě se jídelníček plánuje "
|
||||||
|
"hromadně, proto můžete v nastavení definovat\n"
|
||||||
|
" se kterými uživateli si přejete jídelníčky "
|
||||||
|
"sdílet.\n"
|
||||||
" </p>\n"
|
" </p>\n"
|
||||||
" <p>Můžete také upravovat typy jídel, které si přejete naplánovat. Pokud budete sdílet jídelníček \n"
|
" <p>Můžete také upravovat typy jídel, které si "
|
||||||
|
"přejete naplánovat. Pokud budete sdílet jídelníček \n"
|
||||||
" s někým, kdo\n"
|
" s někým, kdo\n"
|
||||||
" má přidána jiná jídla, jeho typy jídel se objeví i ve vašem seznamu. Pro předcházení\n"
|
" má přidána jiná jídla, jeho typy jídel se "
|
||||||
|
"objeví i ve vašem seznamu. Pro předcházení\n"
|
||||||
" duplicitám (např. Ostatní, Jiná)\n"
|
" duplicitám (např. Ostatní, Jiná)\n"
|
||||||
" pojmenujte váš typ jídla stejně, jako uživatel se kterým své seznamy sdílíte. Tím budou seznamy sloučeny.</p>\n"
|
" pojmenujte váš typ jídla stejně, jako "
|
||||||
|
"uživatel se kterým své seznamy sdílíte. Tím budou seznamy\n"
|
||||||
|
" sloučeny.</p>\n"
|
||||||
" "
|
" "
|
||||||
|
|
||||||
#: .\cookbook\templates\meal_plan_entry.html:6
|
#: .\cookbook\templates\meal_plan_entry.html:6
|
||||||
@@ -1333,12 +1347,12 @@ msgstr "Obrázek receptu"
|
|||||||
#: .\cookbook\templates\recipes_table.html:46
|
#: .\cookbook\templates\recipes_table.html:46
|
||||||
#: .\cookbook\templates\url_import.html:55
|
#: .\cookbook\templates\url_import.html:55
|
||||||
msgid "Preparation time ca."
|
msgid "Preparation time ca."
|
||||||
msgstr "Doba přípravy cca"
|
msgstr "Doba přípravy cca."
|
||||||
|
|
||||||
#: .\cookbook\templates\recipes_table.html:52
|
#: .\cookbook\templates\recipes_table.html:52
|
||||||
#: .\cookbook\templates\url_import.html:60
|
#: .\cookbook\templates\url_import.html:60
|
||||||
msgid "Waiting time ca."
|
msgid "Waiting time ca."
|
||||||
msgstr "Doba čekání cca"
|
msgstr "Doba čekání cca."
|
||||||
|
|
||||||
#: .\cookbook\templates\recipes_table.html:55
|
#: .\cookbook\templates\recipes_table.html:55
|
||||||
msgid "External"
|
msgid "External"
|
||||||
@@ -1386,7 +1400,7 @@ msgid ""
|
|||||||
" in the following examples:"
|
" in the following examples:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Použijte tajný klíč jako autorizační hlavičku definovanou slovním klíčem, "
|
"Použijte tajný klíč jako autorizační hlavičku definovanou slovním klíčem, "
|
||||||
"jak je uvedeno v následujících příkladech."
|
"jak je uvedeno v následujících příkladech:"
|
||||||
|
|
||||||
#: .\cookbook\templates\settings.html:94
|
#: .\cookbook\templates\settings.html:94
|
||||||
msgid "or"
|
msgid "or"
|
||||||
@@ -1808,7 +1822,7 @@ msgstr "Import není pro tohoto poskytovatele implementován!"
|
|||||||
|
|
||||||
#: .\cookbook\views\import_export.py:58
|
#: .\cookbook\views\import_export.py:58
|
||||||
msgid "Exporting is not implemented for this provider"
|
msgid "Exporting is not implemented for this provider"
|
||||||
msgstr "Eport není pro tohoto poskytovatele implementován!"
|
msgstr "Export není pro tohoto poskytovatele implementován!"
|
||||||
|
|
||||||
#: .\cookbook\views\lists.py:42
|
#: .\cookbook\views\lists.py:42
|
||||||
msgid "Import Log"
|
msgid "Import Log"
|
||||||
@@ -1840,7 +1854,7 @@ msgstr "Komentář uložen!"
|
|||||||
|
|
||||||
#: .\cookbook\views\views.py:152
|
#: .\cookbook\views\views.py:152
|
||||||
msgid "This recipe is already linked to the book!"
|
msgid "This recipe is already linked to the book!"
|
||||||
msgstr "Tento recept už v kuchařce existuje."
|
msgstr "Tento recept už v kuchařce existuje!"
|
||||||
|
|
||||||
#: .\cookbook\views\views.py:158
|
#: .\cookbook\views\views.py:158
|
||||||
msgid "Bookmark saved!"
|
msgid "Bookmark saved!"
|
||||||
|
|||||||
@@ -1471,17 +1471,17 @@ def sync_all(request):
|
|||||||
return redirect('list_recipe_import')
|
return redirect('list_recipe_import')
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
# @schema(AutoSchema()) #TODO add proper schema
|
||||||
|
@permission_classes([CustomIsUser & CustomTokenHasReadWriteScope])
|
||||||
def share_link(request, pk):
|
def share_link(request, pk):
|
||||||
if request.user.is_authenticated:
|
if request.space.allow_sharing and has_group_permission(request.user, ('user',)):
|
||||||
if request.space.allow_sharing and has_group_permission(request.user, ('user',)):
|
recipe = get_object_or_404(Recipe, pk=pk, space=request.space)
|
||||||
recipe = get_object_or_404(Recipe, pk=pk, space=request.space)
|
link = ShareLink.objects.create(recipe=recipe, created_by=request.user, space=request.space)
|
||||||
link = ShareLink.objects.create(recipe=recipe, created_by=request.user, space=request.space)
|
return JsonResponse({'pk': pk, 'share': link.uuid,
|
||||||
return JsonResponse({'pk': pk, 'share': link.uuid,
|
'link': request.build_absolute_uri(reverse('view_recipe', args=[pk, link.uuid]))})
|
||||||
'link': request.build_absolute_uri(reverse('view_recipe', args=[pk, link.uuid]))})
|
else:
|
||||||
else:
|
return JsonResponse({'error': 'sharing_disabled'}, status=403)
|
||||||
return JsonResponse({'error': 'sharing_disabled'}, status=403)
|
|
||||||
|
|
||||||
return JsonResponse({'error': 'not_authenticated'}, status=403)
|
|
||||||
|
|
||||||
|
|
||||||
@group_required('user')
|
@group_required('user')
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ This zip file can simply be imported into Tandoor.
|
|||||||
OpenEats does not provide any way to export the data using the interface. Luckily it is relatively easy to export it from the command line.
|
OpenEats does not provide any way to export the data using the interface. Luckily it is relatively easy to export it from the command line.
|
||||||
You need to run the command `python manage.py dumpdata recipe ingredient` inside of the application api container.
|
You need to run the command `python manage.py dumpdata recipe ingredient` inside of the application api container.
|
||||||
If you followed the default installation method you can use the following command `docker-compose -f docker-prod.yml run --rm --entrypoint 'sh' api ./manage.py dumpdata recipe ingredient`.
|
If you followed the default installation method you can use the following command `docker-compose -f docker-prod.yml run --rm --entrypoint 'sh' api ./manage.py dumpdata recipe ingredient`.
|
||||||
This command might also work `docker exec -it openeats_api_1 ./manage.py dumpdata recipe ingredient > recipe_ingredients.json`
|
This command might also work `docker exec -it openeats_api_1 ./manage.py dumpdata recipe ingredient rating recipe_groups > recipe_ingredients.json`
|
||||||
|
|
||||||
Store the outputted json string in a `.json` file and simply import it using the importer. The file should look something like this
|
Store the outputted json string in a `.json` file and simply import it using the importer. The file should look something like this
|
||||||
```json
|
```json
|
||||||
@@ -216,6 +216,8 @@ Store the outputted json string in a `.json` file and simply import it using the
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To import your images you'll need to create the folder `openeats-import` in your Tandoor's `recipes` media folder (which is usually found inside `/opt/recipes/mediafiles`). After that you'll need to copy the `/code/site-media/upload` folder from the openeats API docker container to the `openeats` folder you created. You should now have the file path `/opt/recipes/mediafiles/recipes/openeats-import/upload/...` in Tandoor.
|
||||||
|
|
||||||
## Plantoeat
|
## Plantoeat
|
||||||
|
|
||||||
Plan to eat allows you to export a text file containing all your recipes. Simply upload that text file to Tandoor to import all recipes
|
Plan to eat allows you to export a text file containing all your recipes. Simply upload that text file to Tandoor to import all recipes
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
SECRET_KEY = os.getenv('SECRET_KEY') if os.getenv('SECRET_KEY') else 'INSECURE_STANDARD_KEY_SET_IN_ENV'
|
SECRET_KEY = os.getenv('SECRET_KEY') if os.getenv('SECRET_KEY') else 'INSECURE_STANDARD_KEY_SET_IN_ENV'
|
||||||
|
|
||||||
DEBUG = bool(int(os.getenv('DEBUG', True)))
|
DEBUG = bool(int(os.getenv('DEBUG', True)))
|
||||||
|
DEBUG_TOOLBAR = bool(int(os.getenv('DEBUG_TOOLBAR', True)))
|
||||||
|
|
||||||
SOCIAL_DEFAULT_ACCESS = bool(int(os.getenv('SOCIAL_DEFAULT_ACCESS', False)))
|
SOCIAL_DEFAULT_ACCESS = bool(int(os.getenv('SOCIAL_DEFAULT_ACCESS', False)))
|
||||||
SOCIAL_DEFAULT_GROUP = os.getenv('SOCIAL_DEFAULT_GROUP', 'guest')
|
SOCIAL_DEFAULT_GROUP = os.getenv('SOCIAL_DEFAULT_GROUP', 'guest')
|
||||||
@@ -158,7 +159,7 @@ MIDDLEWARE = [
|
|||||||
'cookbook.helper.scope_middleware.ScopeMiddleware',
|
'cookbook.helper.scope_middleware.ScopeMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG_TOOLBAR:
|
||||||
MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||||
INSTALLED_APPS += ('debug_toolbar',)
|
INSTALLED_APPS += ('debug_toolbar',)
|
||||||
|
|
||||||
|
|||||||
482
vue/src/locales/cs.json
Normal file
482
vue/src/locales/cs.json
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
{
|
||||||
|
"warning_feature_beta": "",
|
||||||
|
"err_fetching_resource": "",
|
||||||
|
"err_creating_resource": "",
|
||||||
|
"err_updating_resource": "",
|
||||||
|
"err_deleting_resource": "",
|
||||||
|
"err_deleting_protected_resource": "",
|
||||||
|
"err_moving_resource": "",
|
||||||
|
"err_merging_resource": "",
|
||||||
|
"success_fetching_resource": "",
|
||||||
|
"success_creating_resource": "",
|
||||||
|
"success_updating_resource": "",
|
||||||
|
"success_deleting_resource": "",
|
||||||
|
"success_moving_resource": "",
|
||||||
|
"success_merging_resource": "",
|
||||||
|
"file_upload_disabled": "",
|
||||||
|
"warning_space_delete": "",
|
||||||
|
"food_inherit_info": "",
|
||||||
|
"facet_count_info": "",
|
||||||
|
"step_time_minutes": "",
|
||||||
|
"confirm_delete": "",
|
||||||
|
"import_running": "",
|
||||||
|
"all_fields_optional": "",
|
||||||
|
"convert_internal": "",
|
||||||
|
"show_only_internal": "",
|
||||||
|
"show_split_screen": "",
|
||||||
|
"Log_Recipe_Cooking": "",
|
||||||
|
"External_Recipe_Image": "",
|
||||||
|
"Add_to_Shopping": "",
|
||||||
|
"Add_to_Plan": "",
|
||||||
|
"Step_start_time": "",
|
||||||
|
"Sort_by_new": "",
|
||||||
|
"Table_of_Contents": "",
|
||||||
|
"Recipes_per_page": "",
|
||||||
|
"Show_as_header": "",
|
||||||
|
"Hide_as_header": "",
|
||||||
|
"Add_nutrition_recipe": "",
|
||||||
|
"Remove_nutrition_recipe": "",
|
||||||
|
"Copy_template_reference": "",
|
||||||
|
"Save_and_View": "",
|
||||||
|
"Manage_Books": "",
|
||||||
|
"Meal_Plan": "",
|
||||||
|
"Select_Book": "",
|
||||||
|
"Select_File": "",
|
||||||
|
"Recipe_Image": "",
|
||||||
|
"Import_finished": "",
|
||||||
|
"View_Recipes": "",
|
||||||
|
"Log_Cooking": "",
|
||||||
|
"New_Recipe": "",
|
||||||
|
"Url_Import": "",
|
||||||
|
"Reset_Search": "",
|
||||||
|
"Recently_Viewed": "",
|
||||||
|
"Load_More": "",
|
||||||
|
"New_Keyword": "",
|
||||||
|
"Delete_Keyword": "",
|
||||||
|
"Edit_Keyword": "",
|
||||||
|
"Edit_Recipe": "",
|
||||||
|
"Move_Keyword": "",
|
||||||
|
"Merge_Keyword": "",
|
||||||
|
"Hide_Keywords": "",
|
||||||
|
"Hide_Recipes": "",
|
||||||
|
"Move_Up": "",
|
||||||
|
"Move_Down": "",
|
||||||
|
"Step_Name": "",
|
||||||
|
"Step_Type": "",
|
||||||
|
"Make_Header": "",
|
||||||
|
"Make_Ingredient": "",
|
||||||
|
"Amount": "",
|
||||||
|
"Enable_Amount": "",
|
||||||
|
"Disable_Amount": "",
|
||||||
|
"Ingredient Editor": "",
|
||||||
|
"Description_Replace": "",
|
||||||
|
"Instruction_Replace": "",
|
||||||
|
"Auto_Sort": "",
|
||||||
|
"Auto_Sort_Help": "",
|
||||||
|
"Private_Recipe": "",
|
||||||
|
"Private_Recipe_Help": "",
|
||||||
|
"reusable_help_text": "",
|
||||||
|
"Add_Step": "",
|
||||||
|
"Keywords": "",
|
||||||
|
"Books": "",
|
||||||
|
"Proteins": "",
|
||||||
|
"Fats": "",
|
||||||
|
"Carbohydrates": "",
|
||||||
|
"Calories": "",
|
||||||
|
"Energy": "",
|
||||||
|
"Nutrition": "",
|
||||||
|
"Date": "",
|
||||||
|
"Share": "",
|
||||||
|
"Automation": "",
|
||||||
|
"Parameter": "",
|
||||||
|
"Export": "",
|
||||||
|
"Copy": "",
|
||||||
|
"Rating": "",
|
||||||
|
"Close": "",
|
||||||
|
"Cancel": "",
|
||||||
|
"Link": "",
|
||||||
|
"Add": "",
|
||||||
|
"New": "",
|
||||||
|
"Note": "",
|
||||||
|
"Success": "",
|
||||||
|
"Failure": "",
|
||||||
|
"Protected": "",
|
||||||
|
"Ingredients": "",
|
||||||
|
"Supermarket": "",
|
||||||
|
"Categories": "",
|
||||||
|
"Category": "",
|
||||||
|
"Selected": "",
|
||||||
|
"min": "",
|
||||||
|
"Servings": "",
|
||||||
|
"Waiting": "",
|
||||||
|
"Preparation": "",
|
||||||
|
"External": "",
|
||||||
|
"Size": "",
|
||||||
|
"Files": "",
|
||||||
|
"File": "",
|
||||||
|
"Edit": "",
|
||||||
|
"Image": "",
|
||||||
|
"Delete": "",
|
||||||
|
"Open": "",
|
||||||
|
"Ok": "",
|
||||||
|
"Save": "",
|
||||||
|
"Step": "",
|
||||||
|
"Search": "",
|
||||||
|
"Import": "",
|
||||||
|
"Print": "",
|
||||||
|
"Settings": "",
|
||||||
|
"or": "",
|
||||||
|
"and": "",
|
||||||
|
"Information": "",
|
||||||
|
"Download": "",
|
||||||
|
"Create": "",
|
||||||
|
"Search Settings": "",
|
||||||
|
"View": "",
|
||||||
|
"Recipes": "",
|
||||||
|
"Move": "",
|
||||||
|
"Merge": "",
|
||||||
|
"Parent": "",
|
||||||
|
"Copy Link": "",
|
||||||
|
"Copy Token": "",
|
||||||
|
"delete_confirmation": "",
|
||||||
|
"move_confirmation": "",
|
||||||
|
"merge_confirmation": "",
|
||||||
|
"create_rule": "",
|
||||||
|
"move_selection": "",
|
||||||
|
"merge_selection": "",
|
||||||
|
"Root": "",
|
||||||
|
"Ignore_Shopping": "",
|
||||||
|
"Shopping_Category": "",
|
||||||
|
"Shopping_Categories": "",
|
||||||
|
"Edit_Food": "",
|
||||||
|
"Move_Food": "",
|
||||||
|
"New_Food": "",
|
||||||
|
"Hide_Food": "",
|
||||||
|
"Food_Alias": "",
|
||||||
|
"Unit_Alias": "",
|
||||||
|
"Keyword_Alias": "",
|
||||||
|
"Delete_Food": "",
|
||||||
|
"No_ID": "",
|
||||||
|
"Meal_Plan_Days": "",
|
||||||
|
"merge_title": "",
|
||||||
|
"move_title": "",
|
||||||
|
"Food": "",
|
||||||
|
"Original_Text": "",
|
||||||
|
"Recipe_Book": "",
|
||||||
|
"del_confirmation_tree": "",
|
||||||
|
"delete_title": "",
|
||||||
|
"create_title": "",
|
||||||
|
"edit_title": "",
|
||||||
|
"Name": "",
|
||||||
|
"Type": "",
|
||||||
|
"Description": "",
|
||||||
|
"Recipe": "",
|
||||||
|
"tree_root": "",
|
||||||
|
"Icon": "",
|
||||||
|
"Unit": "",
|
||||||
|
"Decimals": "",
|
||||||
|
"Default_Unit": "",
|
||||||
|
"No_Results": "",
|
||||||
|
"New_Unit": "",
|
||||||
|
"Create_New_Shopping Category": "",
|
||||||
|
"Create_New_Food": "",
|
||||||
|
"Create_New_Keyword": "",
|
||||||
|
"Create_New_Unit": "",
|
||||||
|
"Create_New_Meal_Type": "",
|
||||||
|
"Create_New_Shopping_Category": "",
|
||||||
|
"and_up": "",
|
||||||
|
"and_down": "",
|
||||||
|
"Instructions": "",
|
||||||
|
"Unrated": "",
|
||||||
|
"Automate": "",
|
||||||
|
"Empty": "",
|
||||||
|
"Key_Ctrl": "",
|
||||||
|
"Key_Shift": "",
|
||||||
|
"Time": "",
|
||||||
|
"Text": "",
|
||||||
|
"Shopping_list": "",
|
||||||
|
"Added_by": "",
|
||||||
|
"Added_on": "",
|
||||||
|
"AddToShopping": "",
|
||||||
|
"IngredientInShopping": "",
|
||||||
|
"NotInShopping": "",
|
||||||
|
"OnHand": "",
|
||||||
|
"FoodOnHand": "",
|
||||||
|
"FoodNotOnHand": "",
|
||||||
|
"Undefined": "",
|
||||||
|
"Create_Meal_Plan_Entry": "",
|
||||||
|
"Edit_Meal_Plan_Entry": "",
|
||||||
|
"Title": "",
|
||||||
|
"Week": "",
|
||||||
|
"Month": "",
|
||||||
|
"Year": "",
|
||||||
|
"Planner": "",
|
||||||
|
"Planner_Settings": "",
|
||||||
|
"Period": "",
|
||||||
|
"Plan_Period_To_Show": "",
|
||||||
|
"Periods": "",
|
||||||
|
"Plan_Show_How_Many_Periods": "",
|
||||||
|
"Starting_Day": "",
|
||||||
|
"Meal_Types": "",
|
||||||
|
"Meal_Type": "",
|
||||||
|
"New_Entry": "",
|
||||||
|
"Clone": "",
|
||||||
|
"Drag_Here_To_Delete": "",
|
||||||
|
"Meal_Type_Required": "",
|
||||||
|
"Title_or_Recipe_Required": "",
|
||||||
|
"Color": "",
|
||||||
|
"New_Meal_Type": "",
|
||||||
|
"Use_Fractions": "",
|
||||||
|
"Use_Fractions_Help": "",
|
||||||
|
"AddFoodToShopping": "",
|
||||||
|
"RemoveFoodFromShopping": "",
|
||||||
|
"DeleteShoppingConfirm": "",
|
||||||
|
"IgnoredFood": "",
|
||||||
|
"Add_Servings_to_Shopping": "",
|
||||||
|
"Week_Numbers": "",
|
||||||
|
"Show_Week_Numbers": "",
|
||||||
|
"Export_As_ICal": "",
|
||||||
|
"Export_To_ICal": "",
|
||||||
|
"Cannot_Add_Notes_To_Shopping": "",
|
||||||
|
"Added_To_Shopping_List": "",
|
||||||
|
"Shopping_List_Empty": "",
|
||||||
|
"Next_Period": "",
|
||||||
|
"Previous_Period": "",
|
||||||
|
"Current_Period": "",
|
||||||
|
"Next_Day": "",
|
||||||
|
"Previous_Day": "",
|
||||||
|
"Inherit": "",
|
||||||
|
"InheritFields": "",
|
||||||
|
"FoodInherit": "",
|
||||||
|
"ShowUncategorizedFood": "",
|
||||||
|
"GroupBy": "",
|
||||||
|
"Language": "",
|
||||||
|
"Theme": "",
|
||||||
|
"SupermarketCategoriesOnly": "",
|
||||||
|
"MoveCategory": "",
|
||||||
|
"CountMore": "",
|
||||||
|
"IgnoreThis": "",
|
||||||
|
"DelayFor": "",
|
||||||
|
"Warning": "",
|
||||||
|
"NoCategory": "",
|
||||||
|
"InheritWarning": "",
|
||||||
|
"ShowDelayed": "",
|
||||||
|
"Completed": "",
|
||||||
|
"OfflineAlert": "",
|
||||||
|
"shopping_share": "",
|
||||||
|
"shopping_auto_sync": "",
|
||||||
|
"one_url_per_line": "",
|
||||||
|
"mealplan_autoadd_shopping": "",
|
||||||
|
"mealplan_autoexclude_onhand": "",
|
||||||
|
"mealplan_autoinclude_related": "",
|
||||||
|
"default_delay": "",
|
||||||
|
"plan_share_desc": "",
|
||||||
|
"shopping_share_desc": "",
|
||||||
|
"shopping_auto_sync_desc": "",
|
||||||
|
"mealplan_autoadd_shopping_desc": "",
|
||||||
|
"mealplan_autoexclude_onhand_desc": "",
|
||||||
|
"mealplan_autoinclude_related_desc": "",
|
||||||
|
"default_delay_desc": "",
|
||||||
|
"filter_to_supermarket": "",
|
||||||
|
"Coming_Soon": "",
|
||||||
|
"Auto_Planner": "",
|
||||||
|
"New_Cookbook": "",
|
||||||
|
"Hide_Keyword": "",
|
||||||
|
"Hour": "",
|
||||||
|
"Hours": "",
|
||||||
|
"Day": "",
|
||||||
|
"Days": "",
|
||||||
|
"Second": "",
|
||||||
|
"Seconds": "",
|
||||||
|
"Clear": "",
|
||||||
|
"Users": "",
|
||||||
|
"Invites": "",
|
||||||
|
"err_move_self": "",
|
||||||
|
"nothing": "",
|
||||||
|
"err_merge_self": "",
|
||||||
|
"show_sql": "",
|
||||||
|
"filter_to_supermarket_desc": "",
|
||||||
|
"CategoryName": "",
|
||||||
|
"SupermarketName": "",
|
||||||
|
"CategoryInstruction": "",
|
||||||
|
"shopping_recent_days_desc": "",
|
||||||
|
"shopping_recent_days": "",
|
||||||
|
"download_pdf": "",
|
||||||
|
"download_csv": "",
|
||||||
|
"csv_delim_help": "",
|
||||||
|
"csv_delim_label": "",
|
||||||
|
"SuccessClipboard": "",
|
||||||
|
"copy_to_clipboard": "",
|
||||||
|
"csv_prefix_help": "",
|
||||||
|
"csv_prefix_label": "",
|
||||||
|
"copy_markdown_table": "",
|
||||||
|
"in_shopping": "",
|
||||||
|
"DelayUntil": "",
|
||||||
|
"Pin": "",
|
||||||
|
"Unpin": "",
|
||||||
|
"PinnedConfirmation": "",
|
||||||
|
"UnpinnedConfirmation": "",
|
||||||
|
"mark_complete": "",
|
||||||
|
"QuickEntry": "",
|
||||||
|
"shopping_add_onhand_desc": "",
|
||||||
|
"shopping_add_onhand": "",
|
||||||
|
"related_recipes": "",
|
||||||
|
"today_recipes": "",
|
||||||
|
"sql_debug": "",
|
||||||
|
"remember_search": "",
|
||||||
|
"remember_hours": "",
|
||||||
|
"tree_select": "",
|
||||||
|
"OnHand_help": "",
|
||||||
|
"ignore_shopping_help": "",
|
||||||
|
"shopping_category_help": "",
|
||||||
|
"food_recipe_help": "",
|
||||||
|
"Foods": "",
|
||||||
|
"Account": "",
|
||||||
|
"Cosmetic": "",
|
||||||
|
"API": "",
|
||||||
|
"enable_expert": "",
|
||||||
|
"expert_mode": "",
|
||||||
|
"simple_mode": "",
|
||||||
|
"advanced": "",
|
||||||
|
"fields": "",
|
||||||
|
"show_keywords": "",
|
||||||
|
"show_foods": "",
|
||||||
|
"show_books": "",
|
||||||
|
"show_rating": "",
|
||||||
|
"show_units": "",
|
||||||
|
"show_filters": "",
|
||||||
|
"not": "",
|
||||||
|
"save_filter": "",
|
||||||
|
"filter_name": "",
|
||||||
|
"left_handed": "",
|
||||||
|
"left_handed_help": "",
|
||||||
|
"Custom Filter": "",
|
||||||
|
"shared_with": "",
|
||||||
|
"sort_by": "",
|
||||||
|
"asc": "",
|
||||||
|
"desc": "",
|
||||||
|
"date_viewed": "",
|
||||||
|
"last_cooked": "",
|
||||||
|
"times_cooked": "",
|
||||||
|
"date_created": "",
|
||||||
|
"show_sortby": "",
|
||||||
|
"search_rank": "",
|
||||||
|
"make_now": "",
|
||||||
|
"recipe_filter": "",
|
||||||
|
"book_filter_help": "",
|
||||||
|
"review_shopping": "",
|
||||||
|
"view_recipe": "",
|
||||||
|
"copy_to_new": "",
|
||||||
|
"recipe_name": "",
|
||||||
|
"paste_ingredients_placeholder": "",
|
||||||
|
"paste_ingredients": "",
|
||||||
|
"ingredient_list": "",
|
||||||
|
"explain": "",
|
||||||
|
"filter": "",
|
||||||
|
"Website": "",
|
||||||
|
"App": "",
|
||||||
|
"Message": "",
|
||||||
|
"Bookmarklet": "",
|
||||||
|
"Sticky_Nav": "",
|
||||||
|
"Sticky_Nav_Help": "",
|
||||||
|
"Nav_Color": "",
|
||||||
|
"Nav_Color_Help": "",
|
||||||
|
"Use_Kj": "",
|
||||||
|
"Comments_setting": "",
|
||||||
|
"click_image_import": "",
|
||||||
|
"no_more_images_found": "",
|
||||||
|
"import_duplicates": "",
|
||||||
|
"paste_json": "",
|
||||||
|
"Click_To_Edit": "",
|
||||||
|
"search_no_recipes": "",
|
||||||
|
"search_import_help_text": "",
|
||||||
|
"search_create_help_text": "",
|
||||||
|
"warning_duplicate_filter": "",
|
||||||
|
"reset_children": "",
|
||||||
|
"reset_children_help": "",
|
||||||
|
"reset_food_inheritance": "",
|
||||||
|
"reset_food_inheritance_info": "",
|
||||||
|
"substitute_help": "",
|
||||||
|
"substitute_siblings_help": "",
|
||||||
|
"substitute_children_help": "",
|
||||||
|
"substitute_siblings": "",
|
||||||
|
"substitute_children": "",
|
||||||
|
"SubstituteOnHand": "",
|
||||||
|
"ChildInheritFields": "",
|
||||||
|
"ChildInheritFields_help": "",
|
||||||
|
"InheritFields_help": "",
|
||||||
|
"show_ingredient_overview": "",
|
||||||
|
"Ingredient Overview": "",
|
||||||
|
"last_viewed": "",
|
||||||
|
"created_on": "",
|
||||||
|
"updatedon": "",
|
||||||
|
"Imported_From": "",
|
||||||
|
"advanced_search_settings": "",
|
||||||
|
"nothing_planned_today": "",
|
||||||
|
"no_pinned_recipes": "",
|
||||||
|
"Planned": "",
|
||||||
|
"Pinned": "",
|
||||||
|
"Imported": "",
|
||||||
|
"Quick actions": "",
|
||||||
|
"Ratings": "",
|
||||||
|
"Internal": "",
|
||||||
|
"Units": "",
|
||||||
|
"Manage_Emails": "",
|
||||||
|
"Change_Password": "",
|
||||||
|
"Social_Authentication": "",
|
||||||
|
"Random Recipes": "",
|
||||||
|
"parameter_count": "",
|
||||||
|
"select_keyword": "",
|
||||||
|
"add_keyword": "",
|
||||||
|
"select_file": "",
|
||||||
|
"select_recipe": "",
|
||||||
|
"select_unit": "",
|
||||||
|
"select_food": "",
|
||||||
|
"remove_selection": "",
|
||||||
|
"empty_list": "",
|
||||||
|
"Select": "",
|
||||||
|
"Supermarkets": "",
|
||||||
|
"User": "",
|
||||||
|
"Username": "",
|
||||||
|
"First_name": "",
|
||||||
|
"Last_name": "",
|
||||||
|
"Keyword": "",
|
||||||
|
"Advanced": "",
|
||||||
|
"Page": "",
|
||||||
|
"Single": "",
|
||||||
|
"Multiple": "",
|
||||||
|
"Reset": "",
|
||||||
|
"Disabled": "",
|
||||||
|
"Disable": "",
|
||||||
|
"Options": "",
|
||||||
|
"Create Food": "",
|
||||||
|
"create_food_desc": "",
|
||||||
|
"additional_options": "",
|
||||||
|
"Importer_Help": "",
|
||||||
|
"Documentation": "",
|
||||||
|
"Select_App_To_Import": "",
|
||||||
|
"Import_Supported": "",
|
||||||
|
"Export_Supported": "",
|
||||||
|
"Import_Not_Yet_Supported": "",
|
||||||
|
"Export_Not_Yet_Supported": "",
|
||||||
|
"Import_Result_Info": "",
|
||||||
|
"Recipes_In_Import": "",
|
||||||
|
"Toggle": "",
|
||||||
|
"Import_Error": "",
|
||||||
|
"Warning_Delete_Supermarket_Category": "",
|
||||||
|
"New_Supermarket": "",
|
||||||
|
"New_Supermarket_Category": "",
|
||||||
|
"Are_You_Sure": "",
|
||||||
|
"Valid Until": "",
|
||||||
|
"Split_All_Steps": "",
|
||||||
|
"Combine_All_Steps": "",
|
||||||
|
"Plural": "",
|
||||||
|
"plural_short": "",
|
||||||
|
"Use_Plural_Unit_Always": "",
|
||||||
|
"Use_Plural_Unit_Simple": "",
|
||||||
|
"Use_Plural_Food_Always": "",
|
||||||
|
"Use_Plural_Food_Simple": "",
|
||||||
|
"plural_usage_info": "",
|
||||||
|
"Create Recipe": "",
|
||||||
|
"Import Recipe": ""
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user