sandwitches 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sandwitches-1.3.1/PKG-INFO +24 -0
- sandwitches-1.3.1/README.md +3 -0
- sandwitches-1.3.1/pyproject.toml +45 -0
- sandwitches-1.3.1/src/sandwitches/__init__.py +0 -0
- sandwitches-1.3.1/src/sandwitches/admin.py +26 -0
- sandwitches-1.3.1/src/sandwitches/api.py +101 -0
- sandwitches-1.3.1/src/sandwitches/asgi.py +16 -0
- sandwitches-1.3.1/src/sandwitches/forms.py +93 -0
- sandwitches-1.3.1/src/sandwitches/locale/nl/LC_MESSAGES/django.mo +0 -0
- sandwitches-1.3.1/src/sandwitches/locale/nl/LC_MESSAGES/django.po +360 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0001_initial.py +75 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0002_historicalrecipe.py +61 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0003_rating.py +57 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0004_add_uploaded_by.py +25 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0005_historicalrecipe_uploaded_by.py +27 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0006_profile.py +48 -0
- sandwitches-1.3.1/src/sandwitches/migrations/0007_alter_rating_score.py +23 -0
- sandwitches-1.3.1/src/sandwitches/migrations/__init__.py +0 -0
- sandwitches-1.3.1/src/sandwitches/models.py +194 -0
- sandwitches-1.3.1/src/sandwitches/settings.py +207 -0
- sandwitches-1.3.1/src/sandwitches/storage.py +82 -0
- sandwitches-1.3.1/src/sandwitches/tasks.py +115 -0
- sandwitches-1.3.1/src/sandwitches/templates/base.html +15 -0
- sandwitches-1.3.1/src/sandwitches/templates/base_pico.html +260 -0
- sandwitches-1.3.1/src/sandwitches/templates/detail.html +121 -0
- sandwitches-1.3.1/src/sandwitches/templates/form.html +16 -0
- sandwitches-1.3.1/src/sandwitches/templates/index.html +75 -0
- sandwitches-1.3.1/src/sandwitches/templates/setup.html +55 -0
- sandwitches-1.3.1/src/sandwitches/templates/signup.html +50 -0
- sandwitches-1.3.1/src/sandwitches/templatetags/__init__.py +0 -0
- sandwitches-1.3.1/src/sandwitches/templatetags/markdown_extras.py +17 -0
- sandwitches-1.3.1/src/sandwitches/urls.py +50 -0
- sandwitches-1.3.1/src/sandwitches/views.py +148 -0
- sandwitches-1.3.1/src/sandwitches/wsgi.py +16 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: sandwitches
|
|
3
|
+
Version: 1.3.1
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author: Martyn van Dijke
|
|
6
|
+
Author-email: Martyn van Dijke <martijnvdijke600@gmail.com>
|
|
7
|
+
Requires-Dist: django-debug-toolbar>=6.1.0
|
|
8
|
+
Requires-Dist: django-filter>=25.2
|
|
9
|
+
Requires-Dist: django-imagekit>=6.0.0
|
|
10
|
+
Requires-Dist: django-ninja>=1.5.1
|
|
11
|
+
Requires-Dist: django-simple-history>=3.10.1
|
|
12
|
+
Requires-Dist: django-tasks>=0.10.0
|
|
13
|
+
Requires-Dist: django>=6.0.0
|
|
14
|
+
Requires-Dist: gunicorn>=23.0.0
|
|
15
|
+
Requires-Dist: markdown>=3.10
|
|
16
|
+
Requires-Dist: pillow>=12.0.0
|
|
17
|
+
Requires-Dist: uvicorn>=0.40.0
|
|
18
|
+
Requires-Dist: whitenoise[brotli]>=6.11.0
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# broodjes.vandijke.xyz
|
|
23
|
+
|
|
24
|
+
Website files for broodjes.vandijke.xyz
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sandwitches"
|
|
3
|
+
version = "1.3.1"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Martyn van Dijke", email = "martijnvdijke600@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
|
|
12
|
+
dependencies = [
|
|
13
|
+
"django-debug-toolbar>=6.1.0",
|
|
14
|
+
"django-filter>=25.2",
|
|
15
|
+
"django-imagekit>=6.0.0",
|
|
16
|
+
"django-ninja>=1.5.1",
|
|
17
|
+
"django-simple-history>=3.10.1",
|
|
18
|
+
"django-tasks>=0.10.0",
|
|
19
|
+
"django>=6.0.0",
|
|
20
|
+
"gunicorn>=23.0.0",
|
|
21
|
+
"markdown>=3.10",
|
|
22
|
+
"pillow>=12.0.0",
|
|
23
|
+
"uvicorn>=0.40.0",
|
|
24
|
+
"whitenoise[brotli]>=6.11.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["uv_build>=0.8.19,<0.9.0"]
|
|
30
|
+
build-backend = "uv_build"
|
|
31
|
+
|
|
32
|
+
[dependency-groups]
|
|
33
|
+
dev = [
|
|
34
|
+
"invoke>=2.2.1",
|
|
35
|
+
"pytest-django>=4.11.1",
|
|
36
|
+
"pytest>=8.4.2",
|
|
37
|
+
"ruff>=0.14.3",
|
|
38
|
+
"ty>=0.0.1a26",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[tool.uv]
|
|
42
|
+
package = true
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
DJANGO_SETTINGS_MODULE = "sandwitches.settings"
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
from .models import Recipe, Tag, Rating, Profile
|
|
3
|
+
from django.utils.html import format_html
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@admin.register(Recipe)
|
|
7
|
+
class RecipeAdmin(admin.ModelAdmin):
|
|
8
|
+
list_display = ("title", "uploaded_by", "created_at", "show_url")
|
|
9
|
+
readonly_fields = ("created_at", "updated_at")
|
|
10
|
+
|
|
11
|
+
def save_model(self, request, obj, form, change):
|
|
12
|
+
# set uploaded_by automatically when creating in admin
|
|
13
|
+
if not change and not obj.uploaded_by:
|
|
14
|
+
obj.uploaded_by = request.user
|
|
15
|
+
super().save_model(request, obj, form, change)
|
|
16
|
+
|
|
17
|
+
def show_url(self, obj):
|
|
18
|
+
url = obj.get_absolute_url()
|
|
19
|
+
return format_html("<a href='{url}'>{url}</a>", url=url)
|
|
20
|
+
|
|
21
|
+
show_url.short_description = "Recipe Link" # ty:ignore[unresolved-attribute]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
admin.site.register(Tag)
|
|
25
|
+
admin.site.register(Rating)
|
|
26
|
+
admin.site.register(Profile)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from ninja import NinjaAPI
|
|
2
|
+
from .models import Recipe, Tag
|
|
3
|
+
|
|
4
|
+
from ninja import ModelSchema
|
|
5
|
+
from ninja import Schema
|
|
6
|
+
from django.contrib.auth.models import User
|
|
7
|
+
from django.shortcuts import get_object_or_404
|
|
8
|
+
from datetime import date
|
|
9
|
+
import random
|
|
10
|
+
|
|
11
|
+
from ninja.security import django_auth
|
|
12
|
+
|
|
13
|
+
from __init__ import __version__
|
|
14
|
+
|
|
15
|
+
api = NinjaAPI(version=__version__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RecipeSchema(ModelSchema):
|
|
19
|
+
class Meta:
|
|
20
|
+
model = Recipe
|
|
21
|
+
fields = "__all__"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TagSchema(ModelSchema):
|
|
25
|
+
class Meta:
|
|
26
|
+
model = Tag
|
|
27
|
+
fields = "__all__"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class UserSchema(ModelSchema):
|
|
31
|
+
class Meta:
|
|
32
|
+
model = User
|
|
33
|
+
exclude = ["password", "last_login", "user_permissions"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Error(Schema):
|
|
37
|
+
message: str
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class RatingResponseSchema(Schema):
|
|
41
|
+
average: float
|
|
42
|
+
count: int
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@api.get("ping")
|
|
46
|
+
def ping(request):
|
|
47
|
+
return {"status": "ok", "message": "pong"}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@api.get("v1/me", response={200: UserSchema, 403: Error})
|
|
51
|
+
def me(request):
|
|
52
|
+
if not request.user.is_authenticated:
|
|
53
|
+
return 403, {"message": "Please sign in first"}
|
|
54
|
+
return request.user
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@api.get("v1/users", auth=django_auth, response=list[UserSchema])
|
|
58
|
+
def users(request):
|
|
59
|
+
return User.objects.all()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@api.get("v1/recipes", response=list[RecipeSchema])
|
|
63
|
+
def get_recipes(request):
|
|
64
|
+
return Recipe.objects.all() # ty:ignore[unresolved-attribute]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@api.get("v1/recipes/{recipe_id}", response=RecipeSchema)
|
|
68
|
+
def get_recipe(request, recipe_id: int):
|
|
69
|
+
recipe = get_object_or_404(Recipe, id=recipe_id)
|
|
70
|
+
return recipe
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@api.get("v1/recipe-of-the-day", response=RecipeSchema)
|
|
74
|
+
def get_recipe_of_the_day(request):
|
|
75
|
+
recipes = list(Recipe.objects.all()) # ty:ignore[unresolved-attribute]
|
|
76
|
+
if not recipes:
|
|
77
|
+
return None
|
|
78
|
+
today = date.today()
|
|
79
|
+
random.seed(today.toordinal())
|
|
80
|
+
recipe = random.choice(recipes)
|
|
81
|
+
return recipe
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@api.get("v1/recipes/{recipe_id}/rating", response=RatingResponseSchema)
|
|
85
|
+
def get_recipe_rating(request, recipe_id: int):
|
|
86
|
+
recipe = get_object_or_404(Recipe, id=recipe_id)
|
|
87
|
+
return {
|
|
88
|
+
"average": recipe.average_rating(),
|
|
89
|
+
"count": recipe.rating_count(),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@api.get("v1/tags", response=list[TagSchema])
|
|
94
|
+
def get_tags(request):
|
|
95
|
+
return Tag.objects.all() # ty:ignore[unresolved-attribute]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@api.get("v1/tags/{tag_id}", response=TagSchema)
|
|
99
|
+
def get_tag(request, tag_id: int):
|
|
100
|
+
tag = get_object_or_404(Tag, id=tag_id)
|
|
101
|
+
return tag
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ASGI config for sandwitches project.
|
|
3
|
+
|
|
4
|
+
It exposes the ASGI callable as a module-level variable named ``application``.
|
|
5
|
+
|
|
6
|
+
For more information on this file, see
|
|
7
|
+
https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
from django.core.asgi import get_asgi_application
|
|
13
|
+
|
|
14
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sandwitches.settings")
|
|
15
|
+
|
|
16
|
+
application = get_asgi_application()
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.contrib.auth import get_user_model
|
|
3
|
+
from django.contrib.auth.forms import UserCreationForm
|
|
4
|
+
from django.utils.translation import gettext_lazy as _
|
|
5
|
+
from .models import Recipe
|
|
6
|
+
|
|
7
|
+
User = get_user_model()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BaseUserFormMixin:
|
|
11
|
+
"""Mixin to handle common password validation and user field processing."""
|
|
12
|
+
|
|
13
|
+
def clean_passwords(self, cleaned_data):
|
|
14
|
+
p1 = cleaned_data.get("password1")
|
|
15
|
+
p2 = cleaned_data.get("password2")
|
|
16
|
+
if p1 and p2 and p1 != p2:
|
|
17
|
+
raise forms.ValidationError(_("Passwords do not match."))
|
|
18
|
+
return cleaned_data
|
|
19
|
+
|
|
20
|
+
def _set_user_attributes(self, user, data):
|
|
21
|
+
"""Helper to apply optional name fields."""
|
|
22
|
+
user.first_name = data.get("first_name", "")
|
|
23
|
+
user.last_name = data.get("last_name", "")
|
|
24
|
+
user.save()
|
|
25
|
+
return user
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AdminSetupForm(forms.ModelForm, BaseUserFormMixin):
|
|
29
|
+
password1 = forms.CharField(widget=forms.PasswordInput, label=_("Password"))
|
|
30
|
+
password2 = forms.CharField(widget=forms.PasswordInput, label=_("Confirm Password"))
|
|
31
|
+
|
|
32
|
+
class Meta:
|
|
33
|
+
model = User
|
|
34
|
+
fields = ("username", "first_name", "last_name", "email")
|
|
35
|
+
|
|
36
|
+
def clean(self):
|
|
37
|
+
cleaned_data = super().clean()
|
|
38
|
+
return self.clean_passwords(cleaned_data)
|
|
39
|
+
|
|
40
|
+
def save(self, commit=True):
|
|
41
|
+
data = self.cleaned_data
|
|
42
|
+
user = User.objects.create_superuser(
|
|
43
|
+
username=data["username"], email=data["email"], password=data["password1"]
|
|
44
|
+
)
|
|
45
|
+
return self._set_user_attributes(user, data)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class UserSignupForm(UserCreationForm, BaseUserFormMixin):
|
|
49
|
+
"""Refactored Regular User Form inheriting from Django's UserCreationForm"""
|
|
50
|
+
|
|
51
|
+
class Meta(UserCreationForm.Meta):
|
|
52
|
+
model = User
|
|
53
|
+
fields = ("username", "first_name", "last_name", "email")
|
|
54
|
+
|
|
55
|
+
def clean(self):
|
|
56
|
+
return super().clean()
|
|
57
|
+
|
|
58
|
+
def save(self, commit=True):
|
|
59
|
+
user = super().save(commit=False)
|
|
60
|
+
user.is_superuser = False
|
|
61
|
+
user.is_staff = False
|
|
62
|
+
if commit:
|
|
63
|
+
user.save()
|
|
64
|
+
return user
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class RecipeForm(forms.ModelForm):
|
|
68
|
+
class Meta:
|
|
69
|
+
model = Recipe
|
|
70
|
+
fields = [
|
|
71
|
+
"title",
|
|
72
|
+
"description",
|
|
73
|
+
"ingredients",
|
|
74
|
+
"instructions",
|
|
75
|
+
"image",
|
|
76
|
+
"tags",
|
|
77
|
+
]
|
|
78
|
+
widgets = {
|
|
79
|
+
"tags": forms.TextInput(attrs={"placeholder": "tag1,tag2"}),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class RatingForm(forms.Form):
|
|
84
|
+
"""Form for rating recipes (0-10)."""
|
|
85
|
+
|
|
86
|
+
score = forms.FloatField(
|
|
87
|
+
min_value=0.0,
|
|
88
|
+
max_value=10.0,
|
|
89
|
+
widget=forms.NumberInput(
|
|
90
|
+
attrs={"step": "0.1", "min": "0", "max": "10", "class": "slider"}
|
|
91
|
+
),
|
|
92
|
+
label=_("Your rating"),
|
|
93
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# Dutch translations for Sandwitches project
|
|
2
|
+
msgid ""
|
|
3
|
+
msgstr ""
|
|
4
|
+
"Project-Id-Version: sandwitches 1.0\n"
|
|
5
|
+
"Report-Msgid-Bugs-To: \n"
|
|
6
|
+
"POT-Creation-Date: 2025-12-31 13:39+0000\n"
|
|
7
|
+
"PO-Revision-Date: 2025-01-01 00:00+0000\n"
|
|
8
|
+
"Language: nl\n"
|
|
9
|
+
"MIME-Version: 1.0\n"
|
|
10
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
11
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
12
|
+
|
|
13
|
+
#: src/sandwitches/forms.py:17
|
|
14
|
+
msgid "Passwords do not match."
|
|
15
|
+
msgstr "Wachtwoorden komen niet overeen."
|
|
16
|
+
|
|
17
|
+
#: src/sandwitches/forms.py:29 src/sandwitches/templates/setup.html:41
|
|
18
|
+
#: src/sandwitches/templates/signup.html:35
|
|
19
|
+
msgid "Password"
|
|
20
|
+
msgstr "Wachtwoord"
|
|
21
|
+
|
|
22
|
+
#: src/sandwitches/forms.py:30
|
|
23
|
+
msgid "Confirm Password"
|
|
24
|
+
msgstr "Bevestig wachtwoord"
|
|
25
|
+
|
|
26
|
+
#: src/sandwitches/forms.py:92
|
|
27
|
+
msgid "Your rating"
|
|
28
|
+
msgstr "Jouw beoordeling"
|
|
29
|
+
|
|
30
|
+
#: src/sandwitches/tasks.py:52
|
|
31
|
+
#, python-format
|
|
32
|
+
msgid ""
|
|
33
|
+
"\n"
|
|
34
|
+
" Hungry? We just added <strong>%(title)s</strong> to our collection.\n"
|
|
35
|
+
" \n"
|
|
36
|
+
" It's a delicious recipe that you won't want to miss!\n"
|
|
37
|
+
" %(description)s\n"
|
|
38
|
+
"\n"
|
|
39
|
+
" Check out the full recipe, ingredients, and steps here:\n"
|
|
40
|
+
" %(url)s\n"
|
|
41
|
+
"\n"
|
|
42
|
+
" Happy Cooking!\n"
|
|
43
|
+
"\n"
|
|
44
|
+
" The Sandwitches Team\n"
|
|
45
|
+
" "
|
|
46
|
+
msgstr ""
|
|
47
|
+
"\n"
|
|
48
|
+
" Trek? We hebben zojuist <strong>%(title)s</strong> toegevoegd aan onze collectie.\n"
|
|
49
|
+
" \n"
|
|
50
|
+
" Het is een heerlijk recept dat je niet wilt missen!\n"
|
|
51
|
+
" %(description)s\n"
|
|
52
|
+
"\n"
|
|
53
|
+
" Bekijk het volledige recept, ingrediënten en stappen hier:\n"
|
|
54
|
+
" %(url)s\n"
|
|
55
|
+
"\n"
|
|
56
|
+
" Veel kookplezier!\n"
|
|
57
|
+
"\n"
|
|
58
|
+
" Het Sandwitches Team\n"
|
|
59
|
+
" "
|
|
60
|
+
|
|
61
|
+
#: src/sandwitches/tasks.py:76
|
|
62
|
+
#, python-format
|
|
63
|
+
msgid ""
|
|
64
|
+
"\n"
|
|
65
|
+
" <div style=\"font-family: 'Helvetica', sans-serif; max-width: 600px; "
|
|
66
|
+
"margin: auto; border: 1px solid #eee; padding: 20px;\">\n"
|
|
67
|
+
" <h2 style=\"color: #d35400; text-align: center;\">New Recipe: "
|
|
68
|
+
"%(title)s by %(uploaded_by)s</h2>\n"
|
|
69
|
+
" <div style=\"text-align: center; margin: 20px 0;\">\n"
|
|
70
|
+
" <img src=\"%(image_url)s\" alt=\"%(title)s\" style=\"width: "
|
|
71
|
+
"100%%; border-radius: 8px;\">\n"
|
|
72
|
+
" </div>\n"
|
|
73
|
+
" <p style=\"font-size: 16px; line-height: 1.5; color: #333;\">\n"
|
|
74
|
+
" Hungry? We just added <strong>%(title)s</strong> to our "
|
|
75
|
+
"collection.\n"
|
|
76
|
+
" <br>\n"
|
|
77
|
+
" It's a delicious recipe that you won't want to miss!\n"
|
|
78
|
+
" <br>\n"
|
|
79
|
+
" %(description)s\n"
|
|
80
|
+
" <br>\n"
|
|
81
|
+
" Check out the full recipe, ingredients, and steps here:\n"
|
|
82
|
+
" Click the button below to see how to make it!\n"
|
|
83
|
+
" <br>\n"
|
|
84
|
+
" Happy Cooking!\n"
|
|
85
|
+
" <br>\n"
|
|
86
|
+
" The Sandwitches Team\n"
|
|
87
|
+
" </p>\n"
|
|
88
|
+
" <div style=\"text-align: center; margin-top: 30px;\">\n"
|
|
89
|
+
" <a href=\"%(url)s\" style=\"background-color: #e67e22; color: "
|
|
90
|
+
"white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-"
|
|
91
|
+
"weight: bold;\">VIEW RECIPE</a>\n"
|
|
92
|
+
" </div>\n"
|
|
93
|
+
" </div>\n"
|
|
94
|
+
" "
|
|
95
|
+
msgstr ""
|
|
96
|
+
"\n"
|
|
97
|
+
" <div style=\"font-family: 'Helvetica', sans-serif; max-width: 600px; "
|
|
98
|
+
"margin: auto; border: 1px solid #eee; padding: 20px;\">\n"
|
|
99
|
+
" <h2 style=\"color: #d35400; text-align: center;\">Nieuw recept: "
|
|
100
|
+
"%(title)s door %(uploaded_by)s</h2>\n"
|
|
101
|
+
" <div style=\"text-align: center; margin: 20px 0;\">\n"
|
|
102
|
+
" <img src=\"%(image_url)s\" alt=\"%(title)s\" style=\"width: "
|
|
103
|
+
"100%%; border-radius: 8px;\">\n"
|
|
104
|
+
" </div>\n"
|
|
105
|
+
" <p style=\"font-size: 16px; line-height: 1.5; color: #333;\">\n"
|
|
106
|
+
" Trek? We hebben zojuist <strong>%(title)s</strong> toegevoegd aan onze "
|
|
107
|
+
"collectie.\n"
|
|
108
|
+
" <br>\n"
|
|
109
|
+
" Het is een heerlijk recept dat je niet wilt missen!\n"
|
|
110
|
+
" <br>\n"
|
|
111
|
+
" %(description)s\n"
|
|
112
|
+
" <br>\n"
|
|
113
|
+
" Bekijk het volledige recept, ingrediënten en stappen hier:\n"
|
|
114
|
+
" Klik op de knop hieronder om te zien hoe je het maakt!\n"
|
|
115
|
+
" <br>\n"
|
|
116
|
+
" Veel kookplezier!\n"
|
|
117
|
+
" <br>\n"
|
|
118
|
+
" Het Sandwitches Team\n"
|
|
119
|
+
" </p>\n"
|
|
120
|
+
" <div style=\"text-align: center; margin-top: 30px;\">\n"
|
|
121
|
+
" <a href=\"%(url)s\" style=\"background-color: #e67e22; color: "
|
|
122
|
+
"white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-"
|
|
123
|
+
"weight: bold;\">BEKIJK RECEPT</a>\n"
|
|
124
|
+
" </div>\n"
|
|
125
|
+
" </div>\n"
|
|
126
|
+
" "
|
|
127
|
+
|
|
128
|
+
#: src/sandwitches/tasks.py:104
|
|
129
|
+
#, python-format
|
|
130
|
+
msgid "Sandwitches - New Recipe: %(title)s by %(uploaded_by)s"
|
|
131
|
+
msgstr "Sandwitches - Nieuw recept: %(title)s door %(uploaded_by)s"
|
|
132
|
+
|
|
133
|
+
#: src/sandwitches/templates/base_pico.html:175
|
|
134
|
+
msgid "Language"
|
|
135
|
+
msgstr "Taal"
|
|
136
|
+
|
|
137
|
+
#: src/sandwitches/templates/base_pico.html:185
|
|
138
|
+
msgid "Docs"
|
|
139
|
+
msgstr "Documentatie"
|
|
140
|
+
|
|
141
|
+
#: src/sandwitches/templates/base_pico.html:187
|
|
142
|
+
msgid "Admin"
|
|
143
|
+
msgstr "Beheer"
|
|
144
|
+
|
|
145
|
+
#: src/sandwitches/templates/base_pico.html:188
|
|
146
|
+
msgid "Logout"
|
|
147
|
+
msgstr "Uitloggen"
|
|
148
|
+
|
|
149
|
+
#: src/sandwitches/templates/base_pico.html:190
|
|
150
|
+
msgid "Login"
|
|
151
|
+
msgstr "Inloggen"
|
|
152
|
+
|
|
153
|
+
#: src/sandwitches/templates/base_pico.html:191
|
|
154
|
+
#: src/sandwitches/templates/signup.html:9
|
|
155
|
+
msgid "Sign up"
|
|
156
|
+
msgstr "Aanmelden"
|
|
157
|
+
|
|
158
|
+
#: src/sandwitches/templates/detail.html:7
|
|
159
|
+
msgid "Back to all"
|
|
160
|
+
msgstr "Terug naar alles"
|
|
161
|
+
|
|
162
|
+
#: src/sandwitches/templates/detail.html:21
|
|
163
|
+
#: src/sandwitches/templates/detail.html:28
|
|
164
|
+
msgid "Description"
|
|
165
|
+
msgstr "Beschrijving"
|
|
166
|
+
|
|
167
|
+
#: src/sandwitches/templates/detail.html:25
|
|
168
|
+
msgid "Uploaded by"
|
|
169
|
+
msgstr "Geüpload door"
|
|
170
|
+
|
|
171
|
+
#: src/sandwitches/templates/detail.html:32
|
|
172
|
+
msgid "No description yet."
|
|
173
|
+
msgstr "Nog geen beschrijving."
|
|
174
|
+
|
|
175
|
+
#: src/sandwitches/templates/detail.html:35
|
|
176
|
+
msgid "Ingredients"
|
|
177
|
+
msgstr "Ingrediënten"
|
|
178
|
+
|
|
179
|
+
#: src/sandwitches/templates/detail.html:39
|
|
180
|
+
msgid "No ingredients listed."
|
|
181
|
+
msgstr "Geen ingrediënten vermeld."
|
|
182
|
+
|
|
183
|
+
#: src/sandwitches/templates/detail.html:42
|
|
184
|
+
msgid "Instructions"
|
|
185
|
+
msgstr "Instructies"
|
|
186
|
+
|
|
187
|
+
#: src/sandwitches/templates/detail.html:46
|
|
188
|
+
msgid "No instructions yet."
|
|
189
|
+
msgstr "Nog geen instructies."
|
|
190
|
+
|
|
191
|
+
#: src/sandwitches/templates/detail.html:58
|
|
192
|
+
msgid "Rating"
|
|
193
|
+
msgstr "Beoordeling"
|
|
194
|
+
|
|
195
|
+
#: src/sandwitches/templates/detail.html:60
|
|
196
|
+
msgid "Average:"
|
|
197
|
+
msgstr "Gemiddelde:"
|
|
198
|
+
|
|
199
|
+
#: src/sandwitches/templates/detail.html:60
|
|
200
|
+
msgid "vote"
|
|
201
|
+
msgstr "stem"
|
|
202
|
+
|
|
203
|
+
#: src/sandwitches/templates/detail.html:62
|
|
204
|
+
msgid "No ratings yet."
|
|
205
|
+
msgstr "Nog geen beoordelingen."
|
|
206
|
+
|
|
207
|
+
#: src/sandwitches/templates/detail.html:67
|
|
208
|
+
msgid "Your rating:"
|
|
209
|
+
msgstr "Jouw beoordeling:"
|
|
210
|
+
|
|
211
|
+
#: src/sandwitches/templates/detail.html:73
|
|
212
|
+
msgid "What would you rate this sandwich?"
|
|
213
|
+
msgstr "Wat zou je dit broodje geven?"
|
|
214
|
+
|
|
215
|
+
#: src/sandwitches/templates/detail.html:88
|
|
216
|
+
msgid "Score (0-10):"
|
|
217
|
+
msgstr "Score (0-10):"
|
|
218
|
+
|
|
219
|
+
#: src/sandwitches/templates/detail.html:105
|
|
220
|
+
msgid "Update"
|
|
221
|
+
msgstr "Bijwerken"
|
|
222
|
+
|
|
223
|
+
#: src/sandwitches/templates/detail.html:105
|
|
224
|
+
msgid "Rate"
|
|
225
|
+
msgstr "Beoordeel"
|
|
226
|
+
|
|
227
|
+
#: src/sandwitches/templates/detail.html:110
|
|
228
|
+
msgid "Log in"
|
|
229
|
+
msgstr "Inloggen"
|
|
230
|
+
|
|
231
|
+
#: src/sandwitches/templates/detail.html:110
|
|
232
|
+
msgid "to rate this recipe."
|
|
233
|
+
msgstr "om dit recept te beoordelen."
|
|
234
|
+
|
|
235
|
+
#: src/sandwitches/templates/detail.html:116
|
|
236
|
+
#: src/sandwitches/templates/form.html:5
|
|
237
|
+
#: src/sandwitches/templates/index.html:42
|
|
238
|
+
msgid "Edit"
|
|
239
|
+
msgstr "Bewerk"
|
|
240
|
+
|
|
241
|
+
#: src/sandwitches/templates/form.html:9
|
|
242
|
+
msgid "Edit Recipe:"
|
|
243
|
+
msgstr "Recept bewerken:"
|
|
244
|
+
|
|
245
|
+
#: src/sandwitches/templates/form.html:12
|
|
246
|
+
msgid "Save"
|
|
247
|
+
msgstr "Opslaan"
|
|
248
|
+
|
|
249
|
+
#: src/sandwitches/templates/form.html:13
|
|
250
|
+
#: src/sandwitches/templates/setup.html:49
|
|
251
|
+
#: src/sandwitches/templates/signup.html:43
|
|
252
|
+
msgid "Cancel"
|
|
253
|
+
msgstr "Annuleren"
|
|
254
|
+
|
|
255
|
+
#: src/sandwitches/templates/index.html:8
|
|
256
|
+
msgid "Sandwitches: sandwiches so good, they haunt you!"
|
|
257
|
+
msgstr "Sandwitches: broodjes zo lekker, dat ze je achtervolgen!"
|
|
258
|
+
|
|
259
|
+
#: src/sandwitches/templates/index.html:12
|
|
260
|
+
msgid "Search by title or tag"
|
|
261
|
+
msgstr "Zoek op titel of tag"
|
|
262
|
+
|
|
263
|
+
#: src/sandwitches/templates/index.html:12
|
|
264
|
+
msgid "Search"
|
|
265
|
+
msgstr "Zoeken"
|
|
266
|
+
|
|
267
|
+
#: src/sandwitches/templates/index.html:50
|
|
268
|
+
msgid "No sandwitches yet, please stay tuned."
|
|
269
|
+
msgstr "Nog geen broodjes, kom later terug."
|
|
270
|
+
|
|
271
|
+
#: src/sandwitches/templates/setup.html:3
|
|
272
|
+
msgid "Initial setup — Create admin"
|
|
273
|
+
msgstr "Eerste installatie — Beheerder aanmaken"
|
|
274
|
+
|
|
275
|
+
#: src/sandwitches/templates/setup.html:9
|
|
276
|
+
msgid "Create initial administrator"
|
|
277
|
+
msgstr "Maak de eerste beheerder"
|
|
278
|
+
|
|
279
|
+
#: src/sandwitches/templates/setup.html:11
|
|
280
|
+
msgid ""
|
|
281
|
+
"This page is only available when there are no admin users in the database."
|
|
282
|
+
msgstr ""
|
|
283
|
+
"Deze pagina is alleen beschikbaar als er nog geen beheerders in de database "
|
|
284
|
+
"zijn."
|
|
285
|
+
|
|
286
|
+
#: src/sandwitches/templates/setup.html:14
|
|
287
|
+
msgid ""
|
|
288
|
+
"After creating the account you will be logged in and redirected to the admin."
|
|
289
|
+
msgstr ""
|
|
290
|
+
"Na aanmaken wordt u ingelogd en doorgestuurd naar het beheerpaneel."
|
|
291
|
+
|
|
292
|
+
#: src/sandwitches/templates/setup.html:29
|
|
293
|
+
#: src/sandwitches/templates/signup.html:23
|
|
294
|
+
msgid "Username"
|
|
295
|
+
msgstr "Gebruikersnaam"
|
|
296
|
+
|
|
297
|
+
#: src/sandwitches/templates/setup.html:32
|
|
298
|
+
#: src/sandwitches/templates/signup.html:26
|
|
299
|
+
msgid "Email (optional)"
|
|
300
|
+
msgstr "E-mail (optioneel)"
|
|
301
|
+
|
|
302
|
+
#: src/sandwitches/templates/setup.html:35
|
|
303
|
+
#: src/sandwitches/templates/signup.html:29
|
|
304
|
+
msgid "First name"
|
|
305
|
+
msgstr "Voornaam"
|
|
306
|
+
|
|
307
|
+
#: src/sandwitches/templates/setup.html:38
|
|
308
|
+
#: src/sandwitches/templates/signup.html:32
|
|
309
|
+
msgid "Last name"
|
|
310
|
+
msgstr "Achternaam"
|
|
311
|
+
|
|
312
|
+
#: src/sandwitches/templates/setup.html:44
|
|
313
|
+
#: src/sandwitches/templates/signup.html:38
|
|
314
|
+
msgid "Confirm password"
|
|
315
|
+
msgstr "Bevestig wachtwoord"
|
|
316
|
+
|
|
317
|
+
#: src/sandwitches/templates/setup.html:48
|
|
318
|
+
msgid "Create admin"
|
|
319
|
+
msgstr "Maak beheerder"
|
|
320
|
+
|
|
321
|
+
#: src/sandwitches/templates/signup.html:3
|
|
322
|
+
#: src/sandwitches/templates/signup.html:42
|
|
323
|
+
msgid "Sign Up"
|
|
324
|
+
msgstr "Aanmelden"
|
|
325
|
+
|
|
326
|
+
#: src/sandwitches/views.py:73
|
|
327
|
+
msgid "Your rating has been saved."
|
|
328
|
+
msgstr "Je beoordeling is opgeslagen."
|
|
329
|
+
|
|
330
|
+
#: src/sandwitches/views.py:75
|
|
331
|
+
msgid "Could not save rating."
|
|
332
|
+
msgstr "Kon de beoordeling niet opslaan."
|
|
333
|
+
|
|
334
|
+
#: src/sandwitches/views.py:101
|
|
335
|
+
msgid "Admin account created and signed in."
|
|
336
|
+
msgstr "Beheerderaccount aangemaakt en ingelogd."
|
|
337
|
+
|
|
338
|
+
#: src/sandwitches/views.py:120
|
|
339
|
+
msgid "Account created and signed in."
|
|
340
|
+
msgstr "Account aangemaakt en ingelogd."
|
|
341
|
+
|
|
342
|
+
#: src/sandwitches/views.py:131
|
|
343
|
+
msgid "Invalid Media Root Configuration"
|
|
344
|
+
msgstr "Ongeldige Media Root Configuratie"
|
|
345
|
+
|
|
346
|
+
#: src/sandwitches/views.py:133
|
|
347
|
+
msgid "Invalid File Path"
|
|
348
|
+
msgstr "Ongeldig bestandspad"
|
|
349
|
+
|
|
350
|
+
#: src/sandwitches/views.py:138
|
|
351
|
+
msgid "Access Denied"
|
|
352
|
+
msgstr "Toegang geweigerd"
|
|
353
|
+
|
|
354
|
+
#: src/sandwitches/views.py:141
|
|
355
|
+
msgid "File not found"
|
|
356
|
+
msgstr "Bestand niet gevonden"
|
|
357
|
+
|
|
358
|
+
#: src/sandwitches/views.py:145
|
|
359
|
+
msgid "Access Denied: Only image files are allowed."
|
|
360
|
+
msgstr "Toegang geweigerd: Alleen afbeeldingsbestanden zijn toegestaan."
|