sandwitches 1.3.0__tar.gz → 1.4.0__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.
Files changed (37) hide show
  1. {sandwitches-1.3.0 → sandwitches-1.4.0}/PKG-INFO +2 -1
  2. {sandwitches-1.3.0 → sandwitches-1.4.0}/pyproject.toml +2 -1
  3. sandwitches-1.4.0/src/sandwitches/admin.py +49 -0
  4. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/forms.py +5 -4
  5. sandwitches-1.4.0/src/sandwitches/locale/nl/LC_MESSAGES/django.mo +0 -0
  6. sandwitches-1.4.0/src/sandwitches/locale/nl/LC_MESSAGES/django.po +360 -0
  7. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/models.py +0 -21
  8. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/settings.py +1 -0
  9. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/tasks.py +30 -14
  10. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/detail.html +2 -2
  11. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/setup.html +6 -6
  12. sandwitches-1.3.0/src/sandwitches/admin.py +0 -26
  13. sandwitches-1.3.0/src/sandwitches/locale/nl/LC_MESSAGES/django.mo +0 -0
  14. sandwitches-1.3.0/src/sandwitches/locale/nl/LC_MESSAGES/django.po +0 -139
  15. {sandwitches-1.3.0 → sandwitches-1.4.0}/README.md +0 -0
  16. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/__init__.py +0 -0
  17. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/api.py +0 -0
  18. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/asgi.py +0 -0
  19. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0001_initial.py +0 -0
  20. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0002_historicalrecipe.py +0 -0
  21. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0003_rating.py +0 -0
  22. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0004_add_uploaded_by.py +0 -0
  23. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0005_historicalrecipe_uploaded_by.py +0 -0
  24. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0006_profile.py +0 -0
  25. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/0007_alter_rating_score.py +0 -0
  26. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/migrations/__init__.py +0 -0
  27. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/storage.py +0 -0
  28. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/base.html +0 -0
  29. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/base_pico.html +0 -0
  30. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/form.html +0 -0
  31. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/index.html +0 -0
  32. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templates/signup.html +0 -0
  33. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templatetags/__init__.py +0 -0
  34. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/templatetags/markdown_extras.py +0 -0
  35. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/urls.py +0 -0
  36. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/views.py +0 -0
  37. {sandwitches-1.3.0 → sandwitches-1.4.0}/src/sandwitches/wsgi.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sandwitches
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Add your description here
5
5
  Author: Martyn van Dijke
6
6
  Author-email: Martyn van Dijke <martijnvdijke600@gmail.com>
7
7
  Requires-Dist: django-debug-toolbar>=6.1.0
8
8
  Requires-Dist: django-filter>=25.2
9
9
  Requires-Dist: django-imagekit>=6.0.0
10
+ Requires-Dist: django-import-export>=4.3.14
10
11
  Requires-Dist: django-ninja>=1.5.1
11
12
  Requires-Dist: django-simple-history>=3.10.1
12
13
  Requires-Dist: django-tasks>=0.10.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sandwitches"
3
- version = "1.3.0"
3
+ version = "1.4.0"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -13,6 +13,7 @@ dependencies = [
13
13
  "django-debug-toolbar>=6.1.0",
14
14
  "django-filter>=25.2",
15
15
  "django-imagekit>=6.0.0",
16
+ "django-import-export>=4.3.14",
16
17
  "django-ninja>=1.5.1",
17
18
  "django-simple-history>=3.10.1",
18
19
  "django-tasks>=0.10.0",
@@ -0,0 +1,49 @@
1
+ from django.contrib import admin
2
+ from .models import Recipe, Tag, Rating
3
+ from django.utils.html import format_html
4
+ from import_export import resources
5
+ from import_export.admin import ImportExportModelAdmin
6
+
7
+
8
+ class RecipeResource(resources.ModelResource):
9
+ class Meta:
10
+ model = Recipe
11
+
12
+
13
+ class TagResource(resources.ModelResource):
14
+ class Meta:
15
+ model = Tag
16
+
17
+
18
+ class RatingResource(resources.ModelResource):
19
+ class Meta:
20
+ model = Rating
21
+
22
+
23
+ @admin.register(Recipe)
24
+ class RecipeAdmin(ImportExportModelAdmin):
25
+ resource_classes = [RecipeResource]
26
+ list_display = ("title", "uploaded_by", "created_at", "show_url")
27
+ readonly_fields = ("created_at", "updated_at")
28
+
29
+ def save_model(self, request, obj, form, change):
30
+ # set uploaded_by automatically when creating in admin
31
+ if not change and not obj.uploaded_by:
32
+ obj.uploaded_by = request.user
33
+ super().save_model(request, obj, form, change)
34
+
35
+ def show_url(self, obj):
36
+ url = obj.get_absolute_url()
37
+ return format_html("<a href='{url}'>{url}</a>", url=url)
38
+
39
+ show_url.short_description = "Recipe Link" # ty:ignore[unresolved-attribute, inconsistent-mro]
40
+
41
+
42
+ @admin.register(Tag)
43
+ class TagAdmin(ImportExportModelAdmin):
44
+ resource_classes = [TagResource]
45
+
46
+
47
+ @admin.register(Rating)
48
+ class RatingAdmin(ImportExportModelAdmin):
49
+ resource_classes = [RatingResource]
@@ -1,6 +1,7 @@
1
1
  from django import forms
2
2
  from django.contrib.auth import get_user_model
3
3
  from django.contrib.auth.forms import UserCreationForm
4
+ from django.utils.translation import gettext_lazy as _
4
5
  from .models import Recipe
5
6
 
6
7
  User = get_user_model()
@@ -13,7 +14,7 @@ class BaseUserFormMixin:
13
14
  p1 = cleaned_data.get("password1")
14
15
  p2 = cleaned_data.get("password2")
15
16
  if p1 and p2 and p1 != p2:
16
- raise forms.ValidationError("Passwords do not match.")
17
+ raise forms.ValidationError(_("Passwords do not match."))
17
18
  return cleaned_data
18
19
 
19
20
  def _set_user_attributes(self, user, data):
@@ -25,8 +26,8 @@ class BaseUserFormMixin:
25
26
 
26
27
 
27
28
  class AdminSetupForm(forms.ModelForm, BaseUserFormMixin):
28
- password1 = forms.CharField(widget=forms.PasswordInput, label="Password")
29
- password2 = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")
29
+ password1 = forms.CharField(widget=forms.PasswordInput, label=_("Password"))
30
+ password2 = forms.CharField(widget=forms.PasswordInput, label=_("Confirm Password"))
30
31
 
31
32
  class Meta:
32
33
  model = User
@@ -88,5 +89,5 @@ class RatingForm(forms.Form):
88
89
  widget=forms.NumberInput(
89
90
  attrs={"step": "0.1", "min": "0", "max": "10", "class": "slider"}
90
91
  ),
91
- label="Your rating",
92
+ label=_("Your rating"),
92
93
  )
@@ -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."
@@ -18,27 +18,6 @@ hashed_storage = HashedFilenameStorage()
18
18
  User = get_user_model()
19
19
 
20
20
 
21
- class Profile(models.Model):
22
- user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
23
- avatar = models.ImageField(upload_to="avatars", blank=True, null=True)
24
- avatar_thumbnail = ImageSpecField(
25
- source="avatar",
26
- processors=[ResizeToFill(100, 50)],
27
- format="JPEG",
28
- options={"quality": 60},
29
- )
30
- bio = models.TextField(blank=True)
31
- created_at = models.DateTimeField(auto_now_add=True)
32
- updated_at = models.DateTimeField(auto_now=True)
33
-
34
- class Meta:
35
- verbose_name = "Profile"
36
- verbose_name_plural = "Profiles"
37
-
38
- def __str__(self):
39
- return f"{self.user.username}'s Profile" # ty:ignore[possibly-missing-attribute]
40
-
41
-
42
21
  class Tag(models.Model):
43
22
  name = models.CharField(max_length=50, unique=True)
44
23
  slug = models.SlugField(max_length=60, unique=True, blank=True)
@@ -65,6 +65,7 @@ INSTALLED_APPS = [
65
65
  "django_tasks.backends.database",
66
66
  "debug_toolbar",
67
67
  "imagekit",
68
+ "import_export",
68
69
  "simple_history",
69
70
  ]
70
71
 
@@ -7,6 +7,7 @@ from django.contrib.auth import get_user_model
7
7
 
8
8
  from django.core.mail import EmailMultiAlternatives
9
9
  from django.conf import settings
10
+ from django.utils.translation import gettext as _
10
11
 
11
12
 
12
13
  import textwrap
@@ -48,33 +49,44 @@ def send_emails(recipe_id, emails):
48
49
  else "http://localhost"
49
50
  ).rstrip("/")
50
51
 
51
- raw_message = f"""
52
- Hungry? We just added <strong>{recipe.title}</strong> to our collection.
52
+ raw_message_fmt = _("""
53
+ Hungry? We just added <strong>%(title)s</strong> to our collection.
53
54
 
54
55
  It's a delicious recipe that you won't want to miss!
55
- {recipe.description}
56
+ %(description)s
56
57
 
57
58
  Check out the full recipe, ingredients, and steps here:
58
- {base_url}{recipe_slug}
59
+ %(url)s
59
60
 
60
61
  Happy Cooking!
61
62
 
62
63
  The Sandwitches Team
63
- """
64
- wrapped_message = textwrap.fill(textwrap.dedent(raw_message), width=70)
64
+ """)
65
+
66
+ context_data = {
67
+ "title": recipe.title,
68
+ "uploaded_by": recipe.uploaded_by,
69
+ "description": recipe.description,
70
+ "url": f"{base_url}{recipe_slug}",
71
+ "image_url": f"{base_url}{recipe.image.url}" if recipe.image else "",
72
+ }
73
+
74
+ wrapped_message = textwrap.fill(
75
+ textwrap.dedent(raw_message_fmt) % context_data, width=70
76
+ )
65
77
 
66
- html_content = f"""
78
+ html_content_fmt = _("""
67
79
  <div style="font-family: 'Helvetica', sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 20px;">
68
- <h2 style="color: #d35400; text-align: center;">New Recipe: {recipe.title} by {recipe.uploaded_by}</h2>
80
+ <h2 style="color: #d35400; text-align: center;">New Recipe: %(title)s by %(uploaded_by)s</h2>
69
81
  <div style="text-align: center; margin: 20px 0;">
70
- <img src="{base_url}{recipe.image.url}" alt="{recipe.title}" style="width: 100%; border-radius: 8px;">
82
+ <img src="%(image_url)s" alt="%(title)s" style="width: 100%%; border-radius: 8px;">
71
83
  </div>
72
84
  <p style="font-size: 16px; line-height: 1.5; color: #333;">
73
- Hungry? We just added <strong>{recipe.title}</strong> to our collection.
85
+ Hungry? We just added <strong>%(title)s</strong> to our collection.
74
86
  <br>
75
87
  It's a delicious recipe that you won't want to miss!
76
88
  <br>
77
- {recipe.description}
89
+ %(description)s
78
90
  <br>
79
91
  Check out the full recipe, ingredients, and steps here:
80
92
  Click the button below to see how to make it!
@@ -84,13 +96,17 @@ def send_emails(recipe_id, emails):
84
96
  The Sandwitches Team
85
97
  </p>
86
98
  <div style="text-align: center; margin-top: 30px;">
87
- <a href="{base_url}{recipe_slug}" style="background-color: #e67e22; color: white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-weight: bold;">VIEW RECIPE</a>
99
+ <a href="%(url)s" style="background-color: #e67e22; color: white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-weight: bold;">VIEW RECIPE</a>
88
100
  </div>
89
101
  </div>
90
- """
102
+ """)
103
+
104
+ html_content = html_content_fmt % context_data
105
+
106
+ subject = _("Sandwitches - New Recipe: %(title)s by %(uploaded_by)s") % context_data
91
107
 
92
108
  msg = EmailMultiAlternatives(
93
- subject=f"Sandwitches - New Recipe: {recipe.title} by {recipe.uploaded_by}",
109
+ subject=subject,
94
110
  body=wrapped_message,
95
111
  from_email=from_email,
96
112
  bbc=emails,
@@ -85,7 +85,7 @@
85
85
  <div class="row">
86
86
  <div class="col-sm-12">
87
87
  <label for="{{ rating_form.score.id_for_label }}">
88
- Score (0-10): <span id="score-output">{{ rating_form.score.value|default:"5.0" }}</span>
88
+ {% trans "Score (0-10):" %} <span id="score-output">{{ rating_form.score.value|default:"5.0" }}</span>
89
89
  </label>
90
90
  <input
91
91
  type="range"
@@ -113,7 +113,7 @@
113
113
 
114
114
  {% if user.is_authenticated and user.is_staff %}
115
115
  <footer>
116
- <a href="/admin/sandwitches/recipe/{{ recipe.pk }}/change/">Edit</a>
116
+ <a href="/admin/sandwitches/recipe/{{ recipe.pk }}/change/">{% trans "Edit" %}</a>
117
117
  </footer>
118
118
  {% endif %}
119
119
  </article>
@@ -26,22 +26,22 @@
26
26
  </div>
27
27
  {% endif %}
28
28
 
29
- <label for="{{ form.username.id_for_label }}">Username</label>
29
+ <label for="{{ form.username.id_for_label }}">{% trans "Username" %}</label>
30
30
  {{ form.username }}
31
31
 
32
- <label for="{{ form.email.id_for_label }}">Email (optional)</label>
32
+ <label for="{{ form.email.id_for_label }}">{% trans "Email (optional)" %}</label>
33
33
  {{ form.email }}
34
34
 
35
- <label for="{{ form.first_name.id_for_label }}">First name</label>
35
+ <label for="{{ form.first_name.id_for_label }}">{% trans "First name" %}</label>
36
36
  {{ form.first_name }}
37
37
 
38
- <label for="{{ form.last_name.id_for_label }}">Last name</label>
38
+ <label for="{{ form.last_name.id_for_label }}">{% trans "Last name" %}</label>
39
39
  {{ form.last_name }}
40
40
 
41
- <label for="{{ form.password1.id_for_label }}">Password</label>
41
+ <label for="{{ form.password1.id_for_label }}">{% trans "Password" %}</label>
42
42
  {{ form.password1 }}
43
43
 
44
- <label for="{{ form.password2.id_for_label }}">Confirm password</label>
44
+ <label for="{{ form.password2.id_for_label }}">{% trans "Confirm password" %}</label>
45
45
  {{ form.password2 }}
46
46
 
47
47
  <p style="margin-top:1rem;">
@@ -1,26 +0,0 @@
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)
@@ -1,139 +0,0 @@
1
- # Dutch translations for Sandwitches project
2
- msgid ""
3
- msgstr ""
4
- "Project-Id-Version: sandwitches 1.0\n"
5
- "POT-Creation-Date: 2025-01-01 00:00+0000\n"
6
- "PO-Revision-Date: 2025-01-01 00:00+0000\n"
7
- "Language: nl\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=UTF-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
-
12
- msgid "Sign up"
13
- msgstr "Aanmelden"
14
-
15
- msgid "Sign Up"
16
- msgstr "Aanmelden"
17
-
18
- msgid "Cancel"
19
- msgstr "Annuleren"
20
-
21
- msgid "Username"
22
- msgstr "Gebruikersnaam"
23
-
24
- msgid "Email (optional)"
25
- msgstr "E-mail (optioneel)"
26
-
27
- msgid "First name"
28
- msgstr "Voornaam"
29
-
30
- msgid "Last name"
31
- msgstr "Achternaam"
32
-
33
- msgid "Password"
34
- msgstr "Wachtwoord"
35
-
36
- msgid "Confirm password"
37
- msgstr "Bevestig wachtwoord"
38
-
39
- msgid "Back to all"
40
- msgstr "Terug naar alles"
41
-
42
- msgid "Description"
43
- msgstr "Beschrijving"
44
-
45
- msgid "Ingredients"
46
- msgstr "Ingrediënten"
47
-
48
- msgid "Instructions"
49
- msgstr "Instructies"
50
-
51
- msgid "No description yet."
52
- msgstr "Nog geen beschrijving."
53
-
54
- msgid "No ingredients listed."
55
- msgstr "Geen ingrediënten vermeld."
56
-
57
- msgid "No instructions yet."
58
- msgstr "Nog geen instructies."
59
-
60
- msgid "Rating"
61
- msgstr "Beoordeling"
62
-
63
- msgid "Average:"
64
- msgstr "Gemiddelde:"
65
-
66
- msgid "No ratings yet."
67
- msgstr "Nog geen beoordelingen."
68
-
69
- msgid "Your rating:"
70
- msgstr "Jouw beoordeling:"
71
-
72
- msgid "What would you rate this sandwich?"
73
- msgstr "Wat zou je dit broodje geven?"
74
-
75
- msgid "Update"
76
- msgstr "Bijwerken"
77
-
78
- msgid "Rate"
79
- msgstr "Beoordeel"
80
-
81
- msgid "Login"
82
- msgstr "Inloggen"
83
-
84
- msgid "to rate this recipe."
85
- msgstr "om dit recept te beoordelen."
86
-
87
- msgid "Docs"
88
- msgstr "Docs"
89
-
90
- msgid "Admin"
91
- msgstr "Beheer"
92
-
93
- msgid "Logout"
94
- msgstr "Uitloggen"
95
-
96
- msgid "Initial setup — Create admin"
97
- msgstr "Eerste installatie — Beheerder aanmaken"
98
-
99
- msgid "Create initial administrator"
100
- msgstr "Maak de eerste beheerder"
101
-
102
- msgid "This page is only available when there are no admin users in the database."
103
- msgstr "Deze pagina is alleen beschikbaar als er nog geen beheerders in de database zijn."
104
-
105
- msgid "After creating the account you will be logged in and redirected to the admin."
106
- msgstr "Na aanmaken wordt u ingelogd en doorgestuurd naar het beheerpaneel."
107
-
108
- msgid "Create admin"
109
- msgstr "Maak beheerder"
110
-
111
- msgid "Account created and signed in."
112
- msgstr "Account aangemaakt en ingelogd."
113
-
114
- msgid "Admin account created and signed in."
115
- msgstr "Beheerderaccount aangemaakt en ingelogd."
116
-
117
- msgid "Your rating has been saved."
118
- msgstr "Je beoordeling is opgeslagen."
119
-
120
- msgid "Could not save rating."
121
- msgstr "Kon de beoordeling niet opslaan."
122
-
123
- msgid "Uploaded by"
124
- msgstr "Geüpload door"
125
-
126
- msgid "Search by title or tag"
127
- msgstr "Zoek op titel of tag"
128
-
129
- msgid "Search"
130
- msgstr "Zoeken"
131
-
132
- msgid "No sandwitches yet, please stay tuned."
133
- msgstr "Nog geen broodjes, kom later terug."
134
-
135
- msgid "Edit"
136
- msgstr "Bewerk"
137
-
138
- msgid "Sandwitches: sandwiches so good, they haunt you!"
139
- msgstr "Sandwitches: broodjes zo lekker, dat ze je achtervolgen!"
File without changes