Merge branch 'develop' of https://github.com/vabene1111/recipes into develop

This commit is contained in:
smilerz
2021-02-16 07:45:22 -06:00
96 changed files with 13251 additions and 10154 deletions

View File

@@ -5,26 +5,26 @@ DEBUG=0
# hosts the application can run under e.g. recipes.mydomain.com,cooking.mydomain.com,...
ALLOWED_HOSTS=*
# random secret key, use for example base64 /dev/urandom | head -c50 to generate one
# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
SECRET_KEY=
# your default timezone
# your default timezone See https://timezonedb.com/time-zones for a list of timezones
TIMEZONE=Europe/Berlin
# add only a database password if you want to run with the default postgres, otherwise change settings accordingly
DB_ENGINE=django.db.backends.postgresql
POSTGRES_HOST=db_recipes
POSTGRES_PORT=5432
POSTGRES_USER=djangodb
POSTGRES_USER=djangouser
POSTGRES_PASSWORD=
POSTGRES_DB=djangodb
# the default value for the user preference 'fractions' (enable/disable fraction support)
# when unset: 0 (disabled)
# default: disabled=0
FRACTION_PREF_DEFAULT=0
# the default value for the user preference 'comments' (enable/disable commenting system)
# when unset: 1 (true)
# default comments enabled=1
COMMENT_PREF_DEFAULT=1
# Users can set a amount of time after which the shopping list is refreshed when they are in viewing mode
@@ -47,13 +47,13 @@ SHOPPING_MIN_AUTOSYNC_INTERVAL=5
# when unset: 1 (true) - this is temporary until an appropriate amount of time has passed for everyone to migrate
GUNICORN_MEDIA=0
# allow authentication via reverse proxy (e.g. authelia), leave of if you dont know what you are doing
# allow authentication via reverse proxy (e.g. authelia), leave off if you dont know what you are doing
# see docs for more information https://vabene1111.github.io/recipes/features/authentication/
# when unset: 0 (false)
REVERSE_PROXY_AUTH=0
# allows you to setup o auth providers
# allows you to setup OAuth providers
# see docs for more information https://vabene1111.github.io/recipes/features/authentication/
# SOCIAL_PROVIDERS = allauth.socialaccount.providers.github, allauth.socialaccount.providers.nextcloud,

View File

@@ -2,9 +2,12 @@
<dictionary name="vabene1111-PC">
<words>
<w>autosync</w>
<w>chowdown</w>
<w>csrftoken</w>
<w>gunicorn</w>
<w>ical</w>
<w>mealie</w>
<w>safron</w>
<w>traefik</w>
</words>
</dictionary>

View File

@@ -1,13 +1,27 @@
# Recipes
![CI](https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=develop)
![Stars](https://img.shields.io/github/stars/vabene1111/recipes)
![Forks](https://img.shields.io/github/forks/vabene1111/recipes)
![Docker Pulls](https://img.shields.io/docker/pulls/vabene1111/recipes)
<h1 align="center">
<br>
<a href="https://app.tandoor.dev"><img src="https://github.com/vabene1111/recipes/raw/develop/docs/logo_color.svg" height="256px" width="256px"></a>
<br>
Tandoor Recipes
<br>
</h1>
Recipes is a Django application to manage, tag and search recipes using either built-in models or
external storage providers hosting PDF's, images or other files.
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
[Installation Instructions](https://vabene1111.github.io/recipes/install/docker/) - [Documentation](https://vabene1111.github.io/recipes/) - [More (slightly outdated) Screenshots](https://imgur.com/a/V01151p)
<p align="center">
<img src="https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=develop" >
<img src="https://img.shields.io/github/stars/vabene1111/recipes" >
<img src="https://img.shields.io/github/forks/vabene1111/recipes" >
<img src="https://img.shields.io/docker/pulls/vabene1111/recipes" >
</p>
<p align="center">
<a href="https://docs.tandoor.dev/install/docker/" target="_blank" rel="noopener noreferrer">Installation</a> •
<a href="https://docs.tandoor.dev/" target="_blank" rel="noopener noreferrer">Documentation</a> •
<a href="https://app.tandoor.dev/" target="_blank" rel="noopener noreferrer">Demo</a>
</p>
![Preview](docs/preview.png)
@@ -32,14 +46,10 @@ external storage providers hosting PDF's, images or other files.
This application is meant for people with a collection of recipes they want to share with family and friends or simply
store them in a nicely organized way. A basic permission system exists but this application is not meant to be run as
a public page.
Documentation can be found [here](https://github.com/vabene1111/recipes/wiki).
Documentation can be found [here](https://docs.tandoor.dev/).
While this application has been around for a while and is actively used by many (including myself), it is still considered
**beta** software that has a lot of rough edges and unpolished parts.
## Documentation
Please refer to the [documentation](https://vabene1111.github.io/recipes/) for everything you need to know.
## License
Beginning with version 0.10.0 the code in this repository is licensed under the [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.de.html) license with an

View File

@@ -135,8 +135,14 @@ class ImportExportBase(forms.Form):
DEFAULT = 'DEFAULT'
PAPRIKA = 'PAPRIKA'
NEXTCLOUD = 'NEXTCLOUD'
MEALIE = 'MEALIE'
CHOWDOWN = 'CHOWDOWN'
SAFRON = 'SAFRON'
type = forms.ChoiceField(choices=((DEFAULT, _('Default')), (PAPRIKA, _('Paprika')), (NEXTCLOUD, _('Nextcloud Cookbook')),))
type = forms.ChoiceField(choices=(
(DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'),
(MEALIE, 'Mealie'), (CHOWDOWN, 'Chowdown'), (SAFRON, 'Safron'),
))
class ImportForm(ImportExportBase):

View File

@@ -28,7 +28,7 @@ def parse_amount(x):
and (
x[end] in string.digits
or (
(x[end] == '.' or x[end] == ',')
(x[end] == '.' or x[end] == ',' or x[end] == '/')
and end + 1 < len(x)
and x[end + 1] in string.digits
)
@@ -36,7 +36,10 @@ def parse_amount(x):
):
end += 1
if end > 0:
amount = float(x[:end].replace(',', '.'))
if "/" in x[:end]:
amount = parse_fraction(x[:end])
else:
amount = float(x[:end].replace(',', '.'))
else:
amount = parse_fraction(x[0])
end += 1

View File

@@ -224,7 +224,7 @@ def find_recipe_json(ld_json, url):
ld_json['servings'] = int(re.findall(r'\b\d+\b', ld_json['recipeYield'])[0])
except Exception as e:
print(e)
ld_json['servings'] = 0
ld_json['servings'] = 1
for key in list(ld_json):
if key not in [

View File

@@ -0,0 +1,79 @@
import json
import re
from io import BytesIO
from zipfile import ZipFile
from cookbook.helper.ingredient_parser import parse
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Food, Unit, Ingredient, Keyword
class Chowdown(Integration):
def import_file_name_filter(self, zip_info_object):
print("testing", zip_info_object.filename)
return re.match(r'^_recipes/([A-Za-z\d\s-])+.md$', zip_info_object.filename)
def get_recipe_from_file(self, file):
ingredient_mode = False
direction_mode = False
description_mode = False
ingredients = []
directions = []
descriptions = []
for fl in file.readlines():
line = fl.decode("utf-8")
if 'title:' in line:
title = line.replace('title:', '').replace('"', '').strip()
if 'image:' in line:
image = line.replace('image:', '').strip()
if 'tags:' in line:
tags = line.replace('tags:', '').strip()
if ingredient_mode:
if len(line) > 2 and 'directions:' not in line:
ingredients.append(line[2:])
if '---' in line and direction_mode:
direction_mode = False
description_mode = True
if direction_mode:
if len(line) > 2:
directions.append(line[2:])
if 'ingredients:' in line:
ingredient_mode = True
if 'directions:' in line:
ingredient_mode = False
direction_mode = True
if description_mode and len(line) > 3 and '---' not in line:
descriptions.append(line)
recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, )
for k in tags.split(','):
keyword, created = Keyword.objects.get_or_create(name=k.strip())
recipe.keywords.add(keyword)
step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n' + '\n'.join(descriptions)
)
for ingredient in ingredients:
amount, unit, ingredient, note = parse(ingredient)
f, created = Food.objects.get_or_create(name=ingredient)
u, created = Unit.objects.get_or_create(name=unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note
))
recipe.steps.add(step)
for f in self.files:
if '.zip' in f.name:
import_zip = ZipFile(f.file)
for z in import_zip.filelist:
if re.match(f'^images/{image}$', z.filename):
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
return recipe
def get_file_from_recipe(self, recipe):
raise NotImplementedError('Method not implemented in storage integration')

View File

@@ -0,0 +1,52 @@
import json
import re
from io import BytesIO
from zipfile import ZipFile
from cookbook.helper.ingredient_parser import parse
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Food, Unit, Ingredient
class Mealie(Integration):
def import_file_name_filter(self, zip_info_object):
return re.match(r'^recipes/([A-Za-z\d-])+.json$', zip_info_object.filename)
def get_recipe_from_file(self, file):
recipe_json = json.loads(file.getvalue().decode("utf-8"))
recipe = Recipe.objects.create(
name=recipe_json['name'].strip(), description=recipe_json['description'].strip(),
created_by=self.request.user, internal=True)
# TODO parse times (given in PT2H3M )
ingredients_added = False
for s in recipe_json['recipeInstructions']:
step = Step.objects.create(
instruction=s['text']
)
if not ingredients_added:
ingredients_added = True
for ingredient in recipe_json['recipeIngredient']:
amount, unit, ingredient, note = parse(ingredient)
f, created = Food.objects.get_or_create(name=ingredient)
u, created = Unit.objects.get_or_create(name=unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note
))
recipe.steps.add(step)
for f in self.files:
if '.zip' in f.name:
import_zip = ZipFile(f.file)
for z in import_zip.filelist:
if re.match(f'^images/{recipe_json["slug"]}.jpg$', z.filename):
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
return recipe
def get_file_from_recipe(self, recipe):
raise NotImplementedError('Method not implemented in storage integration')

View File

@@ -3,18 +3,14 @@ import re
from io import BytesIO
from zipfile import ZipFile
from rest_framework.renderers import JSONRenderer
from cookbook.helper.ingredient_parser import parse
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Food, Unit, Ingredient
from cookbook.serializer import RecipeExportSerializer
class NextcloudCookbook(Integration):
def import_file_name_filter(self, zip_info_object):
print("testing", zip_info_object.filename)
return re.match(r'^Recipes/([A-Za-z\d\s])+/recipe.json$', zip_info_object.filename)
def get_recipe_from_file(self, file):
@@ -26,6 +22,7 @@ class NextcloudCookbook(Integration):
servings=recipe_json['recipeYield'])
# TODO parse times (given in PT2H3M )
# TODO parse keywords
ingredients_added = False
for s in recipe_json['recipeInstructions']:
@@ -54,6 +51,4 @@ class NextcloudCookbook(Integration):
return recipe
def get_file_from_recipe(self, recipe):
export = RecipeExportSerializer(recipe).data
return 'recipe.json', JSONRenderer().render(export).decode("utf-8")
raise NotImplementedError('Method not implemented in storage integration')

View File

@@ -1,6 +1,10 @@
import json
import re
from io import BytesIO
from zipfile import ZipFile
import microdata
from bs4 import BeautifulSoup
from cookbook.helper.recipe_url_import import find_recipe_json
from cookbook.integration.integration import Integration
@@ -9,6 +13,10 @@ from cookbook.models import Recipe, Step, Food, Ingredient, Unit
class Paprika(Integration):
def import_file_name_filter(self, zip_info_object):
print("testing", zip_info_object.filename)
return re.match(r'^Recipes/([A-Za-z\s])+.html$', zip_info_object.filename)
def get_file_from_recipe(self, recipe):
raise NotImplementedError('Method not implemented in storage integration')
@@ -33,4 +41,16 @@ class Paprika(Integration):
))
recipe.steps.add(step)
soup = BeautifulSoup(html_text, "html.parser")
image = soup.find('img')
image_name = image.attrs['src'].strip().replace('Images/', '')
for f in self.files:
if '.zip' in f.name:
import_zip = ZipFile(f.file)
for z in import_zip.filelist:
if re.match(f'^Recipes/Images/{image_name}$', z.filename):
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
return recipe

View File

@@ -0,0 +1,60 @@
from django.utils.translation import gettext as _
from cookbook.helper.ingredient_parser import parse
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Food, Unit, Ingredient
class Safron(Integration):
def get_recipe_from_file(self, file):
ingredient_mode = False
direction_mode = False
ingredients = []
directions = []
for fl in file.readlines():
line = fl.decode("utf-8")
if 'Title:' in line:
title = line.replace('Title:', '').strip()
if 'Description:' in line:
description = line.replace('Description:', '').strip()
if 'Yield:' in line:
directions.append(_('Servings') + ' ' + line.replace('Yield:', '').strip() + '\n')
if 'Cook:' in line:
directions.append(_('Waiting time') + ' ' + line.replace('Cook:', '').strip() + '\n')
if 'Prep:' in line:
directions.append(_('Preparation Time') + ' ' + line.replace('Prep:', '').strip() + '\n')
if 'Cookbook:' in line:
directions.append(_('Cookbook') + ' ' + line.replace('Cookbook:', '').strip() + '\n')
if 'Section:' in line:
directions.append(_('Section') + ' ' + line.replace('Section:', '').strip() + '\n')
if ingredient_mode:
if len(line) > 2 and 'Instructions:' not in line:
ingredients.append(line.strip())
if direction_mode:
if len(line) > 2:
directions.append(line.strip())
if 'Ingredients:' in line:
ingredient_mode = True
if 'Instructions:' in line:
ingredient_mode = False
direction_mode = True
recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, )
step = Step.objects.create(instruction='\n'.join(directions))
for ingredient in ingredients:
amount, unit, ingredient, note = parse(ingredient)
f, created = Food.objects.get_or_create(name=ingredient)
u, created = Unit.objects.get_or_create(name=unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note
))
recipe.steps.add(step)
return recipe
def get_file_from_recipe(self, recipe):
raise NotImplementedError('Method not implemented in storage integration')

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="Logo" transform="matrix(0.637323,0,0,0.637323,-243.095,-716.725)">
<g id="Kreis" transform="matrix(1.44936,0,0,1.50279,387.258,1039.34)">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584" style="fill:url(#_Linear1);"/>
<clipPath id="_clip2">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584"/>
</clipPath>
<g clip-path="url(#_clip2)">
<g id="Shadow" transform="matrix(1.10322,0,0,1.064,-5.58287,50.5786)">
<path d="M156.285,427.208L389.554,660.477L668.803,495.551L374.012,200.761L156.285,427.208Z" style="fill:rgb(22,22,22);"/>
<g transform="matrix(1,0,0,1,-4.22105,0.775864)">
<path d="M208.628,178.613L485.935,455.919L590.027,364.63L296.923,71.526L294.175,138.989L208.628,178.613Z" style="fill:rgb(22,22,22);"/>
</g>
<g transform="matrix(1,0,0,1,-85.3876,27.8512)">
<path d="M310.385,145.641L587.692,422.948L590.392,361.357L297.288,68.253L294.175,138.989L310.385,145.641Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
</g>
</g>
<g transform="matrix(1.471,0,0,1.471,406.537,1149.69)">
<path d="M256.049,220C286.222,219.994 312.656,207.31 329.388,194.134C346.35,180.754 370.899,183.406 384.611,200.1C407.129,227.376 420.598,261.944 420.598,299.53C420.598,361.08 382.604,437.101 329.764,463.706C307.035,475.15 283.466,480.586 256.098,480.599L256.098,480.599L256.049,480.599L256,480.599L256,480.599C228.632,480.586 205.063,475.15 182.334,463.706C129.494,437.101 91.5,361.08 91.5,299.53C91.5,261.944 104.969,227.376 127.487,200.1C141.199,183.406 165.748,180.754 182.71,194.134C199.442,207.31 225.876,219.994 256.049,220Z" style="fill:rgb(255,203,118);"/>
</g>
<g id="Flame-2" serif:id="Flame 2" transform="matrix(0.965725,0,0,0.89175,164.497,436.391)">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z" style="fill:rgb(255,111,0);"/>
<clipPath id="_clip3">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z"/>
</clipPath>
<g clip-path="url(#_clip3)">
<g transform="matrix(1.28784,-0.270602,0.285942,1.59598,247.349,825.209)">
<path d="M255.004,46.957C279.547,58.545 306,85.447 313.307,120.161C325.437,177.791 291.571,193.789 262.496,192.403C215.889,190.181 200.194,153.246 231.326,108.9C250.631,81.401 232.663,36.408 255.004,46.957Z" style="fill:rgb(255,209,0);"/>
</g>
</g>
</g>
<g id="Hut" transform="matrix(1.521,0,0,1.521,393.566,1149.06)">
<path d="M228.197,408.524C222.698,408.524 217.813,406.688 214.024,403.619C211.776,401.794 210.92,398.752 211.888,396.024C212.856,393.295 215.437,391.472 218.332,391.472C232.214,391.4 256.112,391.396 256.112,391.396C256.112,391.396 280.009,391.4 293.891,391.472C296.786,391.472 299.367,393.295 300.335,396.024C301.303,398.752 300.447,401.794 298.199,403.619C294.41,406.688 289.526,408.524 284.027,408.524L228.197,408.524ZM217.24,378.877C214.208,378.877 211.3,377.671 209.158,375.525C207.015,373.379 205.814,370.469 205.82,367.436C205.831,361.119 205.842,354.539 205.842,354.539C205.842,350.423 203.097,346.814 199.131,345.714C185.313,341.841 175.2,329.468 175.2,314.823C175.2,297.07 190.059,282.657 208.362,282.657C208.362,282.657 208.362,282.657 208.362,282.657C215.401,282.657 221.675,278.218 224.017,271.581C227.243,262.39 236.411,252.015 256,251.998L256,251.998L256.223,251.998L256.223,251.998C275.812,252.015 284.98,262.39 288.206,271.581C290.549,278.218 296.822,282.657 303.861,282.657C303.861,282.657 303.861,282.657 303.861,282.657C322.164,282.657 337.023,297.07 337.023,314.823C337.023,329.468 326.911,341.841 313.093,345.714C309.127,346.814 306.382,350.423 306.381,354.539C306.381,354.539 306.386,361.127 306.391,367.447C306.394,370.478 305.191,373.385 303.049,375.529C300.907,377.672 298.001,378.877 294.971,378.877C275.615,378.877 236.604,378.877 217.24,378.877Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2e-06,0,0,2e-06,3755.77,81.7179)"><stop offset="0" style="stop-color:rgb(39,39,39);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(108,108,108);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="Logo" transform="matrix(0.637323,0,0,0.637323,-243.095,-716.725)">
<g id="Kreis" transform="matrix(1.44936,0,0,1.50279,387.258,1039.34)">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584" style="fill:url(#_Linear1);"/>
<clipPath id="_clip2">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584"/>
</clipPath>
<g clip-path="url(#_clip2)">
<g id="Shadow" transform="matrix(1.10322,0,0,1.064,-5.58287,50.5786)">
<path d="M156.285,427.208L389.554,660.477L668.803,495.551L374.012,200.761L156.285,427.208Z" style="fill:rgb(22,22,22);"/>
<g transform="matrix(1,0,0,1,-4.22105,0.775864)">
<path d="M208.628,178.613L485.935,455.919L590.027,364.63L296.923,71.526L294.175,138.989L208.628,178.613Z" style="fill:rgb(22,22,22);"/>
</g>
<g transform="matrix(1,0,0,1,-85.3876,27.8512)">
<path d="M310.385,145.641L587.692,422.948L590.392,361.357L297.288,68.253L294.175,138.989L310.385,145.641Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
</g>
</g>
<g transform="matrix(1.471,0,0,1.471,406.537,1149.69)">
<path d="M256.049,220C286.222,219.994 312.656,207.31 329.388,194.134C346.35,180.754 370.899,183.406 384.611,200.1C407.129,227.376 420.598,261.944 420.598,299.53C420.598,361.08 382.604,437.101 329.764,463.706C307.035,475.15 283.466,480.586 256.098,480.599L256.098,480.599L256.049,480.599L256,480.599L256,480.599C228.632,480.586 205.063,475.15 182.334,463.706C129.494,437.101 91.5,361.08 91.5,299.53C91.5,261.944 104.969,227.376 127.487,200.1C141.199,183.406 165.748,180.754 182.71,194.134C199.442,207.31 225.876,219.994 256.049,220Z" style="fill:rgb(255,203,118);"/>
</g>
<g id="Flame-2" serif:id="Flame 2" transform="matrix(0.965725,0,0,0.89175,164.497,436.391)">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z" style="fill:rgb(255,111,0);"/>
<clipPath id="_clip3">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z"/>
</clipPath>
<g clip-path="url(#_clip3)">
<g transform="matrix(1.28784,-0.270602,0.285942,1.59598,247.349,825.209)">
<path d="M255.004,46.957C279.547,58.545 306,85.447 313.307,120.161C325.437,177.791 291.571,193.789 262.496,192.403C215.889,190.181 200.194,153.246 231.326,108.9C250.631,81.401 232.663,36.408 255.004,46.957Z" style="fill:rgb(255,209,0);"/>
</g>
</g>
</g>
<g id="Hut" transform="matrix(1.521,0,0,1.521,393.566,1149.06)">
<path d="M228.197,408.524C222.698,408.524 217.813,406.688 214.024,403.619C211.776,401.794 210.92,398.752 211.888,396.024C212.856,393.295 215.437,391.472 218.332,391.472C232.214,391.4 256.112,391.396 256.112,391.396C256.112,391.396 280.009,391.4 293.891,391.472C296.786,391.472 299.367,393.295 300.335,396.024C301.303,398.752 300.447,401.794 298.199,403.619C294.41,406.688 289.526,408.524 284.027,408.524L228.197,408.524ZM217.24,378.877C214.208,378.877 211.3,377.671 209.158,375.525C207.015,373.379 205.814,370.469 205.82,367.436C205.831,361.119 205.842,354.539 205.842,354.539C205.842,350.423 203.097,346.814 199.131,345.714C185.313,341.841 175.2,329.468 175.2,314.823C175.2,297.07 190.059,282.657 208.362,282.657C208.362,282.657 208.362,282.657 208.362,282.657C215.401,282.657 221.675,278.218 224.017,271.581C227.243,262.39 236.411,252.015 256,251.998L256,251.998L256.223,251.998L256.223,251.998C275.812,252.015 284.98,262.39 288.206,271.581C290.549,278.218 296.822,282.657 303.861,282.657C303.861,282.657 303.861,282.657 303.861,282.657C322.164,282.657 337.023,297.07 337.023,314.823C337.023,329.468 326.911,341.841 313.093,345.714C309.127,346.814 306.382,350.423 306.381,354.539C306.381,354.539 306.386,361.127 306.391,367.447C306.394,370.478 305.191,373.385 303.049,375.529C300.907,377.672 298.001,378.877 294.971,378.877C275.615,378.877 236.604,378.877 217.24,378.877Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2e-06,0,0,2e-06,3755.77,81.7179)"><stop offset="0" style="stop-color:rgb(39,39,39);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(108,108,108);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="book" class="svg-inline--fa fa-book fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M128 152v-32c0-4.4 3.6-8 8-8h208c4.4 0 8 3.6 8 8v32c0 4.4-3.6 8-8 8H136c-4.4 0-8-3.6-8-8zm8 88h208c4.4 0 8-3.6 8-8v-32c0-4.4-3.6-8-8-8H136c-4.4 0-8 3.6-8 8v32c0 4.4 3.6 8 8 8zm299.1 159.7c-4.2 13-4.2 51.6 0 64.6 7.3 1.4 12.9 7.9 12.9 15.7v16c0 8.8-7.2 16-16 16H80c-44.2 0-80-35.8-80-80V80C0 35.8 35.8 0 80 0h352c8.8 0 16 7.2 16 16v368c0 7.8-5.5 14.2-12.9 15.7zm-41.1.3H80c-17.6 0-32 14.4-32 32 0 17.7 14.3 32 32 32h314c-2.7-17.3-2.7-46.7 0-64zm6-352H80c-17.7 0-32 14.3-32 32v278.7c9.8-4.3 20.6-6.7 32-6.7h320V48z"></path></svg>

Before

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -11,17 +11,17 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" type="image/x-icon" href="{% static 'favicon.png' %}">
<link rel="shortcut icon" href="{% static 'favicon.png' %}">
<link rel="icon" type="image/png" href="{% static 'favicon.png' %}" sizes="32x32">
<link rel="icon" type="image/png" href="{% static 'favicon.png' %}" sizes="96x96">
<link rel="apple-touch-icon" href="{% static 'favicon.png' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon.png' %}">
<link rel="apple-touch-icon" sizes="152x152" href="{% static 'favicon.png' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon.png' %}">
<link rel="apple-touch-icon" sizes="167x167" href="{% static 'favicon.png' %}">
<link rel="shortcut icon" type="image/x-icon" href="{% static 'assets/favicon.svg' %}">
<link rel="shortcut icon" href="{% static 'assets/favicon.svg' %}">
<link rel="icon" type="image/png" href="{% static 'assets/favicon.svg' %}" sizes="32x32">
<link rel="icon" type="image/png" href="{% static 'assets/favicon.svg' %}" sizes="96x96">
<link rel="apple-touch-icon" href="{% static 'assets/favicon.svg' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'assets/favicon.svg' %}">
<link rel="apple-touch-icon" sizes="152x152" href="{% static 'assets/favicon.svg' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'assets/favicon.svg' %}">
<link rel="apple-touch-icon" sizes="167x167" href="{% static 'assets/favicon.svg' %}">
<link rel="manifest" href="{% static 'manifest/webmanifest' %}">
<link rel="manifest" href="{% url 'web_manifest' %}">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/mstile-144x144.png">

View File

@@ -1,51 +1,48 @@
{
"name": "Recipes",
"name": "Tandoor Recipes",
"short_name" : "Tandoor",
"description": "Application to manage, tag and search recipes.",
"icons": [
{
"src": "/static/manifest/icon-192.png",
"src": "/static/assets/logo_color144.png",
"type": "image/png",
"sizes": "192x192"
"sizes": "144x144"
},
{
"src": "/static/manifest/icon-512.png",
"src": "/static/assets/logo_color512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/search",
"background_color": "#18BC9C",
"background_color": "#ffcb76",
"display": "standalone",
"scope": "/",
"theme_color": "#18BC9C",
"theme_color": "#ffcb76",
"shortcuts": [
{
"name": "Plan",
"short_name": "Plan",
"description": "View your meal Plan",
"url": "/plan",
"icons": [{ "src": "/static/manifest/icon-192.png", "sizes": "192x192" }]
"url": "/plan"
},
{
"name": "Books",
"short_name": "Cookbooks",
"description": "View your cookbooks",
"url": "/books",
"icons": [{ "src": "/static/manifest/icon-192.png", "sizes": "192x192" }]
"url": "/books"
},
{
"name": "Shopping",
"short_name": "Shopping",
"description": "View your shopping lists",
"url": "/list/shopping-list/",
"icons": [{ "src": "/static/manifest/shopping-cart-192.png", "sizes": "192x192" }]
"url": "/list/shopping-list/"
},
{
"name": "Latest Shopping List",
"short_name": "Shopping List",
"description": "View the latest shopping list",
"url": "/shopping/latest/",
"icons": [{ "src": "/static/manifest/shopping-cart-192.png", "sizes": "192x192" }]
"url": "/shopping/latest/"
}
]
}

View File

@@ -129,7 +129,7 @@
[](https://github.com/vabene1111/recipes)
[GitHub](https://github.com/vabene1111/recipes)
![{% trans 'This will become an image' %}]({% static 'favicon.png' %})
![{% trans 'This will become an image' %}]({% static 'assets/favicon.svg' %})
</code></pre>
<div style="text-align: center">
@@ -142,7 +142,7 @@
<div class="card-body">
<a href="https://github.com/vabene1111/recipes">https://github.com/vabene1111/recipes</a> <br/>
<a href="https://github.com/vabene1111/recipes">GitHub</a> <br/>
<img src="{% static 'favicon.png' %}" class="img-fluid" alt="{% trans 'This will become an image' %}"
<img src="{% static 'assets/favicon.svg' %}" class="img-fluid" alt="{% trans 'This will become an image' %}"
style="height: 3vw">
</div>

View File

@@ -19,7 +19,7 @@
<img src=" {{ row.cells.image }}" alt="{% trans 'Recipe Image' %}"
class="card-img" style="object-fit: cover;height: 130px">
{% else %}
<img src="{% static 'recipe_no_image.svg' %}"
<img src="{% static 'assets/recipe_no_image.svg' %}"
alt="{% trans 'Recipe Image' %}"
class="card-img d-none d-md-block"
style="object-fit: cover; height: 130px">

View File

@@ -681,7 +681,7 @@
Promise.allSettled(recipe_promises).then(() => {
console.log("proceeding to update shopping list", this.shopping_list)
if (this.shopping_list_id === null) {
if (this.shopping_list.id === undefined) {
return this.$http.post("{% url 'api:shoppinglist-list' %}", this.shopping_list, {}).then((response) => {
console.log(response)
this.makeToast(gettext('Updated'), gettext('Object created successfully!'), 'success')
@@ -697,7 +697,7 @@
this.loading = false
})
} else {
return this.$http.put("{% url 'api:shoppinglist-detail' shopping_list_id %}", this.shopping_list, {}).then((response) => {
return this.$http.put("{% url 'api:shoppinglist-detail' 123456 %}".replace('123456', this.shopping_list.id), this.shopping_list, {}).then((response) => {
console.log(response)
this.shopping_list = response.body
this.makeToast(gettext('Updated'), gettext('Changes saved successfully!'), 'success')

View File

@@ -86,6 +86,8 @@ def page_help(page_name):
help_pages = {
'edit_storage': 'https://vabene1111.github.io/recipes/features/external_recipes/',
'view_shopping': 'https://vabene1111.github.io/recipes/features/shopping/',
'view_import': 'https://vabene1111.github.io/recipes/features/import_export/',
'view_export': 'https://vabene1111.github.io/recipes/features/import_export/',
}
link = help_pages.get(page_name, '')

View File

@@ -33,6 +33,7 @@ class TestEditsRecipe(TestBase):
expectations = {
"2¼ l Wasser": (2.25, "l", "Wasser", ""),
"2¼l Wasser": (2.25, "l", "Wasser", ""),
"¼ l Wasser": (0.25, "l", "Wasser", ""),
"3l Wasser": (3, "l", "Wasser", ""),
"4 l Wasser": (4, "l", "Wasser", ""),
"½l Wasser": (0.5, "l", "Wasser", ""),
@@ -43,6 +44,10 @@ class TestEditsRecipe(TestBase):
"1 Zwiebel(n)": (1, "", "Zwiebel(n)", ""),
"4 1/2 Zwiebeln": (4.5, "", "Zwiebeln", ""),
"4 ½ Zwiebeln": (4.5, "", "Zwiebeln", ""),
"1/2 EL Mehl": (0.5, "EL", "Mehl", ""),
"1/2 Zwiebel": (0.5, "", "Zwiebel", ""),
"1/5g Mehl, gesiebt": (0.2, "g", "Mehl", "gesiebt"),
"1/2 Zitrone, ausgepresst": (0.5, "", "Zitrone", "ausgepresst"),
"etwas Mehl": (0, "", "etwas Mehl", ""),
"Öl zum Anbraten": (0, "", "Öl zum Anbraten", ""),
"n. B. Knoblauch, zerdrückt": (0, "", "n. B. Knoblauch", "zerdrückt"),

View File

@@ -105,8 +105,10 @@ urlpatterns = [
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('offline/', views.offline, name='view_offline'),
path('service-worker.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='service_worker'),
path('service-worker.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='service_worker'),
path('manifest.json', (TemplateView.as_view(template_name="manifest.json", content_type='application/json', )), name='web_manifest'),
]
generic_models = (

View File

@@ -6,9 +6,12 @@ from django.utils.translation import gettext as _
from cookbook.forms import ExportForm, ImportForm, ImportExportBase
from cookbook.helper.permission_helper import group_required
from cookbook.integration.chowdown import Chowdown
from cookbook.integration.default import Default
from cookbook.integration.mealie import Mealie
from cookbook.integration.nextcloud_cookbook import NextcloudCookbook
from cookbook.integration.paprika import Paprika
from cookbook.integration.safron import Safron
from cookbook.models import Recipe
@@ -19,6 +22,12 @@ def get_integration(request, export_type):
return Paprika(request)
if export_type == ImportExportBase.NEXTCLOUD:
return NextcloudCookbook(request)
if export_type == ImportExportBase.MEALIE:
return Mealie(request)
if export_type == ImportExportBase.CHOWDOWN:
return Chowdown(request)
if export_type == ImportExportBase.SAFRON:
return Safron(request)
@group_required('user')

View File

@@ -30,9 +30,7 @@ def keyword(request):
@group_required('admin')
def sync_log(request):
table = ImportLogTable(
SyncLog.objects.all().order_by(
Lower('created_at').desc()
)
SyncLog.objects.all().order_by('-created_at')
)
RequestConfig(request, paginate={'per_page': 25}).configure(table)

1
docs/CNAME Normal file
View File

@@ -0,0 +1 @@
docs.tandoor.dev

View File

@@ -7,12 +7,12 @@ integrations to allow you to both import and export your recipes into whatever f
Feel like there is an important integration missing ? Just take a look at the [integration issues](https://github.com/vabene1111/recipes/issues?q=is%3Aissue+is%3Aopen+label%3Aintegration) or open a new one
if your favorite one is missing.
!!! warning "WIP"
Please note that this feature is relatively new and many integrations are missing.
Additionally, many recipe applications provide formats that are not structured in an easily machine-readable way
and thus require a lot of work to integrate even tough the module is very versatile.
If you are good at writing parsers feel free to add new integrations for your favorite services.
!!! info "Export"
I strongly believe in everyone's right to use their data as they please and therefore want to give you
the most possible flexibility with your recipes.
That said for most of the people getting this application running with their recipes is the biggest priority.
Because of this importing as many formats as possible is prioritized over exporting.
Exporter for the different formats will follow over time.
## Default
The default integration is the build in (and preferred) way to import and export recipes.
@@ -36,7 +36,7 @@ You will get a `Recipes.zip` file. Simply upload the file and choose the Nextclo
!!! warning "Folder Structure"
Importing only works if the folder structure is correct. If you do not use the standard path or create the
zip file in any other way make sure the strucutre is as follows
zip file in any other way make sure the structure is as follows
```
Recipes.zip/
└── Recipes/
@@ -48,12 +48,57 @@ You will get a `Recipes.zip` file. Simply upload the file and choose the Nextclo
└── full.jpg
```
## Mealie
Mealie provides structured data similar to nextcloud.
To migrate your recipes
1. Go to you Mealie settings and create a new Backup
2. Download the backup by clicking on it and pressing download (this wasn't working for me, so I had to manually pull it from the server)
3. Upload the entire `.zip` file to the importer page and import everything
## Chowdown
Chowdown stores all your recipes in plain text markdown files in a directory called `_recipes`.
Images are saved in a directory called `images`.
In order to import your Chowdown recipes simply create a `.zip` file from those two folders and import them.
The folder structure should look as follows
```
Recipes.zip/
├── _recipes/
│ ├── recipe one.md
│ ├── recipe two.md
│ └── ...
└── images/
├── image-name.jpg
├── second-image-name.jpg
└── ...
```
## Safron
Go to you safron settings page and export your recipes.
Then simply upload the entire `.zip` file to the importer.
!!! warning "Images"
Safron exports do not contain any images. They will be lost during import.
## Paprika
Paprika can create two types of export. The first is a proprietary `.paprikarecipes` file in some kind of binarized format.
The second one is HTML files containing at least a bit of microdata.
If you want to import your Paprika recipes create a html export. Then import the individual recipes HTML files.
Due to the lack of structure not all fields can be imported.
Even tough images are present in the export they cannot be imported atm. This is technically possible and might be
added in the future.
If you want to import your Paprika recipes follow these steps
1. create a html export
2. Create a `.zip` file from the `Recipes` folder (next to the `index.html`) the structure should look like this
```
Recipes.zip/
└── Recipes/
├── recipe one.html
├── recipe two.thml
└── Images/
├── 5D5E09CD-8F88-4F61-8121-0727DD3E0E89/
│ └── 5D5E09CD-8F88-4F61-8121-0727DD3E0E89.jpg
└── 7CEE2AC6-DF60-4464-9B61-4F5E347EB90C/
└── 7CEE2AC6-DF60-4464-9B61-4F5E347EB90C.jpg
```
3. Upload the zip file in the import module and import it

View File

@@ -1,6 +1,27 @@
# Welcome to Recipes Documentation
<h1 align="center">
<br>
<a href="https://app.tandoor.dev"><img src="https://github.com/vabene1111/recipes/raw/develop/docs/logo_color.svg" height="256px" width="256px"></a>
<br>
Tandoor Recipes
<br>
</h1>
The recipe manager that allows you to manage your ever growing collection of digital recipes.
<h4 align="center">The recipe manager that allows you to manage your ever growing collection of digital recipes.</h4>
<p align="center">
<img src="https://github.com/vabene1111/recipes/workflows/Continous%20Integration/badge.svg?branch=develop" >
<img src="https://img.shields.io/github/stars/vabene1111/recipes" >
<img src="https://img.shields.io/github/forks/vabene1111/recipes" >
<img src="https://img.shields.io/docker/pulls/vabene1111/recipes" >
</p>
<p align="center">
<a href="https://docs.tandoor.dev/install/docker/" target="_blank" rel="noopener noreferrer">Installation</a> •
<a href="https://docs.tandoor.dev/" target="_blank" rel="noopener noreferrer">Documentation</a> •
<a href="https://app.tandoor.dev/" target="_blank" rel="noopener noreferrer">Demo</a>
</p>
![Preview](preview.png)

43
docs/logo_color.svg Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="Logo" transform="matrix(0.637323,0,0,0.637323,-243.095,-716.725)">
<g id="Kreis" transform="matrix(1.44936,0,0,1.50279,387.258,1039.34)">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584" style="fill:url(#_Linear1);"/>
<clipPath id="_clip2">
<ellipse cx="273.123" cy="324.015" rx="259.822" ry="250.584"/>
</clipPath>
<g clip-path="url(#_clip2)">
<g id="Shadow" transform="matrix(1.10322,0,0,1.064,-5.58287,50.5786)">
<path d="M156.285,427.208L389.554,660.477L668.803,495.551L374.012,200.761L156.285,427.208Z" style="fill:rgb(22,22,22);"/>
<g transform="matrix(1,0,0,1,-4.22105,0.775864)">
<path d="M208.628,178.613L485.935,455.919L590.027,364.63L296.923,71.526L294.175,138.989L208.628,178.613Z" style="fill:rgb(22,22,22);"/>
</g>
<g transform="matrix(1,0,0,1,-85.3876,27.8512)">
<path d="M310.385,145.641L587.692,422.948L590.392,361.357L297.288,68.253L294.175,138.989L310.385,145.641Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
</g>
</g>
<g transform="matrix(1.471,0,0,1.471,406.537,1149.69)">
<path d="M256.049,220C286.222,219.994 312.656,207.31 329.388,194.134C346.35,180.754 370.899,183.406 384.611,200.1C407.129,227.376 420.598,261.944 420.598,299.53C420.598,361.08 382.604,437.101 329.764,463.706C307.035,475.15 283.466,480.586 256.098,480.599L256.098,480.599L256.049,480.599L256,480.599L256,480.599C228.632,480.586 205.063,475.15 182.334,463.706C129.494,437.101 91.5,361.08 91.5,299.53C91.5,261.944 104.969,227.376 127.487,200.1C141.199,183.406 165.748,180.754 182.71,194.134C199.442,207.31 225.876,219.994 256.049,220Z" style="fill:rgb(255,203,118);"/>
</g>
<g id="Flame-2" serif:id="Flame 2" transform="matrix(0.965725,0,0,0.89175,164.497,436.391)">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z" style="fill:rgb(255,111,0);"/>
<clipPath id="_clip3">
<path d="M604.408,844.314C601.981,840.845 601.962,836.056 604.362,832.565C606.763,829.074 611.005,827.721 614.769,829.246C633.87,836.869 658.833,848.629 678.207,864.452C718.526,897.381 729.55,919.407 738.552,942.091C749.208,968.943 750.785,996.68 748.515,1016.08C742.018,1071.61 700.355,1117.5 641.034,1117.5C581.713,1117.5 534.493,1072.05 533.553,1016.08C532.986,982.372 543.985,955.443 555.988,936.22C558.982,931.437 564.594,929.469 569.609,931.444C574.623,933.419 577.757,938.831 577.215,944.58C575.493,956.716 574.362,969.372 574.932,979.484C576.863,1013.7 597.171,1022.5 618.083,1022.29C640.371,1022.08 662.925,1003.17 654.797,954.895C647.69,912.681 622.362,870.194 604.408,844.314Z"/>
</clipPath>
<g clip-path="url(#_clip3)">
<g transform="matrix(1.28784,-0.270602,0.285942,1.59598,247.349,825.209)">
<path d="M255.004,46.957C279.547,58.545 306,85.447 313.307,120.161C325.437,177.791 291.571,193.789 262.496,192.403C215.889,190.181 200.194,153.246 231.326,108.9C250.631,81.401 232.663,36.408 255.004,46.957Z" style="fill:rgb(255,209,0);"/>
</g>
</g>
</g>
<g id="Hut" transform="matrix(1.521,0,0,1.521,393.566,1149.06)">
<path d="M228.197,408.524C222.698,408.524 217.813,406.688 214.024,403.619C211.776,401.794 210.92,398.752 211.888,396.024C212.856,393.295 215.437,391.472 218.332,391.472C232.214,391.4 256.112,391.396 256.112,391.396C256.112,391.396 280.009,391.4 293.891,391.472C296.786,391.472 299.367,393.295 300.335,396.024C301.303,398.752 300.447,401.794 298.199,403.619C294.41,406.688 289.526,408.524 284.027,408.524L228.197,408.524ZM217.24,378.877C214.208,378.877 211.3,377.671 209.158,375.525C207.015,373.379 205.814,370.469 205.82,367.436C205.831,361.119 205.842,354.539 205.842,354.539C205.842,350.423 203.097,346.814 199.131,345.714C185.313,341.841 175.2,329.468 175.2,314.823C175.2,297.07 190.059,282.657 208.362,282.657C208.362,282.657 208.362,282.657 208.362,282.657C215.401,282.657 221.675,278.218 224.017,271.581C227.243,262.39 236.411,252.015 256,251.998L256,251.998L256.223,251.998L256.223,251.998C275.812,252.015 284.98,262.39 288.206,271.581C290.549,278.218 296.822,282.657 303.861,282.657C303.861,282.657 303.861,282.657 303.861,282.657C322.164,282.657 337.023,297.07 337.023,314.823C337.023,329.468 326.911,341.841 313.093,345.714C309.127,346.814 306.382,350.423 306.381,354.539C306.381,354.539 306.386,361.127 306.391,367.447C306.394,370.478 305.191,373.385 303.049,375.529C300.907,377.672 298.001,378.877 294.971,378.877C275.615,378.877 236.604,378.877 217.24,378.877Z" style="fill:rgb(22,22,22);"/>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2e-06,0,0,2e-06,3755.77,81.7179)"><stop offset="0" style="stop-color:rgb(39,39,39);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(108,108,108);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

View File

@@ -0,0 +1,19 @@
:root {
--md-primary-fg-color: #ffcb76;
--md-accent-fg-color: #FF6F00;
--md-primary-fg-color--light: #ffcb76;
/* not working part, has no effect */
--md-primary-bg-color: #272727;
--md-default-bg-color: #272727;
--md-default-bg-color--light: #272727;
--md-default-bg-color--lighter: #272727;
--md-default-bg-color--lightest: #272727;
}
/*
flame dark orange #FF6F00
background dark #272727
tandoor #ffcb76
*/

View File

@@ -1,3 +1,3 @@
CALL venv\Scripts\activate.bat
python manage.py makemessages -i venv -a
python manage.py makemessages -i venv -l ca -l de -l en -l es -l fr -l hu_HU -l it -l lv -l nl -l pt -l rn -l tr -l zh_CN
python manage.py makemessages -i venv -a -l de -d djangojs

View File

@@ -1,18 +1,20 @@
site_name: Recipes
site_description: Documentation for Recipes
site_name: Tandoor Recipes
site_description: Tandoor Recipe Documentation
site_author: vabene1111
repo_url: https://github.com/vabene1111/recipes
edit_uri: https://github.com/vabene1111/recipes/tree/develop/docs
extra_css:
- stylesheets/extra.css
theme:
name: material
repo: fontawesome/brands/github
logo: logo_color.svg
favicon: logo_color.svg
palette:
scheme: slate
primary: green
accent: deep orange
logo: cookbook/static/favicon.png
favicon: cookbook/static/favicon.ico
icon:
repo: fontawesome/brands/github
markdown_extensions:
- admonition
@@ -29,7 +31,7 @@ nav:
- Manual: install/manual.md
- Other setups: install/other.md
- Features:
- Tempalating: features/templating.md
- Templating: features/templating.md
- Shopping: features/shopping.md
- Authentication: features/authentication.md
- Storages and Sync: features/external_recipes.md

View File

@@ -10,7 +10,7 @@ server {
}
# pass requests for dynamic content to gunicorn
location / {
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_pass http://web_recipes:8080;
}
}
}

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,35 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-13 23:31+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,34 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\recipes\settings.py:196
#: .\recipes\settings.py:214
msgid "English"
msgstr "Englisch"
#: .\recipes\settings.py:197
#: .\recipes\settings.py:215
msgid "German"
msgstr "Deutsch"
#: .\recipes\settings.py:198
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: .\recipes\settings.py:199
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: .\recipes\settings.py:200
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: .\recipes\settings.py:201
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: .\recipes\settings.py:202
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:203
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,30 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,35 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,30 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,34 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,35 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -2,13 +2,13 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-31 18:41+0200\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,34 +19,34 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : "
"2);\n"
#: .\recipes\settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: .\recipes\settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: .\recipes\settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: .\recipes\settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: .\recipes\settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: .\recipes\settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: .\recipes\settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:182
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,30 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,30 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,34 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,30 +18,34 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-26 13:48+0100\n"
"POT-Creation-Date: 2021-02-09 18:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,30 +17,34 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: recipes/settings.py:175
#: .\recipes\settings.py:214
msgid "English"
msgstr ""
#: recipes/settings.py:176
#: .\recipes\settings.py:215
msgid "German"
msgstr ""
#: recipes/settings.py:177
#: .\recipes\settings.py:216
msgid "Dutch"
msgstr ""
#: recipes/settings.py:178
#: .\recipes\settings.py:217
msgid "French"
msgstr ""
#: recipes/settings.py:179
#: .\recipes\settings.py:218
msgid "Catalan"
msgstr ""
#: recipes/settings.py:180
#: .\recipes\settings.py:219
msgid "Spanish"
msgstr ""
#: recipes/settings.py:181
#: .\recipes\settings.py:220
msgid "Italian"
msgstr ""
#: .\recipes\settings.py:221
msgid "Latvian"
msgstr ""

View File

@@ -219,14 +219,15 @@ USE_L10N = True
USE_TZ = True
LANGUAGES = [
('en', _('English')),
('de', _('German')),
('nl', _('Dutch')),
('fr', _('French')),
('ca', _('Catalan')),
('es', _('Spanish')),
('cs', _('Czech')),
('nl', _('Dutch')),
('en', _('English')),
('fr', _('French')),
('de', _('German')),
('it', _('Italian')),
('lv', _('Latvian')),
('es', _('Spanish')),
]
# Static files (CSS, JavaScript, Images)