sandwitches 1.0.3__py3-none-any.whl → 1.2.0__py3-none-any.whl

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.
@@ -1,31 +1,50 @@
1
1
  {% extends "base_pico.html" %}
2
2
  {% block title %}{{ recipe.title }} — Sandwitch{% endblock %}
3
-
4
3
  {% block content %}
5
4
 
6
- {% load markdown_extras %}
5
+ {% load i18n markdown_extras %}
7
6
  <nav aria-label="breadcrumb" class="container">
8
- <a href="{% url 'index' %}">&larr; Back to all</a>
7
+ <a href="{% url 'index' %}">&larr; {% trans "Back to all" %}</a>
9
8
  </nav>
10
9
 
11
10
  <div class="grid">
12
11
  <article class="card">
13
12
  <figure>
14
13
  {% if recipe.image %}
15
- <img src="{{ recipe.image.url }}" alt="{{ recipe.title }}">
14
+ <img src="{{ recipe.image_large.url }}"
15
+ srcset="{{ recipe.image_medium.url }} 700w, {{ recipe.image_large.url }} 1200w"
16
+ sizes="(max-width: 768px) 95vw, 900px"
17
+ alt="{{ recipe.title }}"
18
+ loading="lazy">
16
19
  {% endif %}
17
20
  </figure>
21
+ {% trans "Description" %}
18
22
  <header>
19
23
  {{ recipe.title }}
24
+ {% if recipe.uploaded_by %}
25
+ <small>{% trans "Uploaded by" %}: {{ recipe.uploaded_by.get_full_name|default:recipe.uploaded_by.username }}</small>
26
+ {% endif %}
20
27
  </header>
21
- <h4>Description</h4>
22
- {{ recipe.description|convert_markdown|safe|default:"No description yet." }}
28
+ <h4>{% trans "Description" %}</h4>
29
+ {% if recipe.description %}
30
+ {{ recipe.description|convert_markdown|safe }}
31
+ {% else %}
32
+ <p>{% trans "No description yet." %}</p>
33
+ {% endif %}
23
34
 
24
- <h4>Ingredients</h4>
25
- {{ recipe.ingredients|convert_markdown|safe|default:"No ingredients listed." }}
35
+ <h4>{% trans "Ingredients" %}</h4>
36
+ {% if recipe.ingredients %}
37
+ {{ recipe.ingredients|convert_markdown|safe }}
38
+ {% else %}
39
+ <p>{% trans "No ingredients listed." %}</p>
40
+ {% endif %}
26
41
 
27
- <h4>Instructions</h4>
28
- {{ recipe.instructions|convert_markdown|safe|default:"No instructions yet." }}
42
+ <h4>{% trans "Instructions" %}</h4>
43
+ {% if recipe.instructions %}
44
+ {{ recipe.instructions|convert_markdown|safe }}
45
+ {% else %}
46
+ <p>{% trans "No instructions yet." %}</p>
47
+ {% endif %}
29
48
 
30
49
  <div class="tags-row">
31
50
  <div style="margin-top:12px;">
@@ -34,6 +53,66 @@
34
53
  {% endfor %}
35
54
  </div>
36
55
  </div>
56
+
57
+ <div style="margin-top:1rem;">
58
+ <h4>{% trans "Rating" %}</h4>
59
+ {% if rating_count %}
60
+ <p>{% trans "Average:" %} {{ avg_rating|floatformat:1 }} ({{ rating_count }} {% trans "vote" %}{% if rating_count %}s{% endif %})</p>
61
+ {% else %}
62
+ <p>{% trans "No ratings yet." %}</p>
63
+ {% endif %}
64
+
65
+ {% if user.is_authenticated %}
66
+ {% if user_rating %}
67
+ <p>{% trans "Your rating:" %} {{ user_rating.score }}</p>
68
+ {% else %}
69
+ <form method="post" action="{% url 'recipe_rate' pk=recipe.pk %}">
70
+ {% csrf_token %}
71
+
72
+ <fieldset>
73
+ <legend>{% trans "What would you rate this sandwich?" %}</legend>
74
+
75
+ {% if rating_form.score.errors %}
76
+ <div class="card-panel" role="alert">
77
+ <ul>
78
+ {% for err in rating_form.score.errors %}
79
+ <li>{{ err }}</li>
80
+ {% endfor %}
81
+ </ul>
82
+ </div>
83
+ {% endif %}
84
+
85
+ <div class="row">
86
+ {% for i in "12345"|make_list %}
87
+ <div class="col-sm-2">
88
+ <label class="form-check">
89
+ <input
90
+ type="radio"
91
+ name="{{ rating_form.score.name }}"
92
+ id="rating-{{ i }}"
93
+ value="{{ i }}"
94
+ {% if user_rating and user_rating.score|stringformat:"s" == i %}
95
+ checked
96
+ {% elif rating_form.score.value == i %}
97
+ checked
98
+ {% endif %}
99
+ />
100
+ <span>{{ i }}</span>
101
+ </label>
102
+ </div>
103
+ {% endfor %}
104
+ </div>
105
+ </fieldset>
106
+ <p style="margin-top:0.5rem;">
107
+ <button type="submit">{% if user_rating %}{% trans "Update" %}{% else %}{% trans "Rate" %}{% endif %}</button>
108
+ </p>
109
+ </form>
110
+ {% endif %}
111
+ {% else %}
112
+ <p><a href="{% url 'admin:login' %}">{% trans "Log in" %}</a> {% trans "to rate this recipe." %}</p>
113
+ {% endif %}
114
+ </div>
115
+
37
116
  {% if user.is_authenticated and user.is_staff %}
38
117
  <footer>
39
118
  <a href="/admin/sandwitches/recipe/{{ recipe.pk }}/change/">Edit</a>
@@ -2,14 +2,15 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <title>Edit</title>
5
+ <title>{% trans "Edit" %}</title>
6
6
  </head>
7
7
  <body>
8
- <h1>Edit Recipe: {{ recipe.title }}</h1>
8
+ {% load i18n %}
9
+ <h1>{% trans "Edit Recipe:" %} {{ recipe.title }}</h1>
9
10
  <form method="post" enctype="multipart/form-data">
10
11
  {% csrf_token %} {{ form.as_p }}
11
- <button type="submit">Save</button>
12
- <a href="{% url 'recipes:admin_list' %}">Cancel</a>
12
+ <button type="submit">{% trans "Save" %}</button>
13
+ <a href="{% url 'recipes:admin_list' %}">{% trans "Cancel" %}</a>
13
14
  </form>
14
15
  </body>
15
16
  </html>
@@ -1,15 +1,15 @@
1
- {% extends "base_pico.html" %}
1
+ {% extends "base_pico.html" %} {% load i18n static %}
2
2
 
3
3
  {% block title %}Sandwitches{% endblock %}
4
4
 
5
5
  {% block content %}
6
6
  <div class="grid search-row">
7
7
  <div>
8
- <h4>Sandwitches: sandwiches so good, they haunt you!</h4>
8
+ <h4>{% trans 'Sandwitches: sandwiches so good, they haunt you!' %}</h4>
9
9
  </div>
10
10
  <div>
11
11
  <form role="search" onsubmit="return false;">
12
- <input id="search" type="search" placeholder="Search by title or tag" aria-label="Search">
12
+ <input id="search" type="search" placeholder="{% trans "Search by title or tag" %}" aria-label="{% trans "Search" %}">
13
13
  </form>
14
14
  </div>
15
15
  </div>
@@ -19,7 +19,11 @@
19
19
  <article class="card" onclick="location.href='{% url 'recipe_detail' recipe.slug %}';" style="cursor:pointer;">
20
20
  {% if recipe.image %}
21
21
  <figure class="recipe-figure">
22
- <img src="{{ recipe.image.url }}" alt="{{ recipe.title }}">
22
+ <img src="{{ recipe.image_medium.url }}"
23
+ srcset="{{ recipe.image_thumbnail.url }} 150w, {{ recipe.image_medium.url }} 700w"
24
+ sizes="(max-width: 640px) 90vw, 45vw"
25
+ alt="{{ recipe.title }}"
26
+ loading="lazy">
23
27
  </figure>
24
28
  {% endif %}
25
29
 
@@ -35,7 +39,7 @@
35
39
 
36
40
  {% if user.is_authenticated and user.is_staff %}
37
41
  <footer>
38
- <a href="/admin/sandwitches/recipe/{{ recipe.pk }}/change/" rel="noopener">Edit</a>
42
+ <a href="/admin/sandwitches/recipe/{{ recipe.pk }}/change/" rel="noopener">{% trans "Edit" %}</a>
39
43
  </footer>
40
44
  {% endif %}
41
45
  </article>
@@ -43,7 +47,7 @@
43
47
  {% empty %}
44
48
  <article class="card">
45
49
  <div class="card-body">
46
- <p>No sandwitches yet, please stay tuned.</p>
50
+ <p>{% trans "No sandwitches yet, please stay tuned." %}</p>
47
51
  </div>
48
52
  </article>
49
53
  {% endfor %}
@@ -1,15 +1,17 @@
1
1
  {% extends "base_pico.html" %}
2
- {% load static %}
3
- {% block title %}Initial setup — Create admin{% endblock %}
2
+ {% load static i18n %}
3
+ {% block title %}{% trans "Initial setup — Create admin" %}{% endblock %}
4
4
 
5
5
  {% block content %}
6
6
  <div class="container" style="max-width:720px; margin:2rem auto;">
7
7
  <article class="card">
8
8
  <div class="card-body">
9
- <h2>Create initial administrator</h2>
9
+ <h2>{% trans "Create initial administrator" %}</h2>
10
10
  <p>
11
- This page is only available when there are no admin users in the database.
12
- After creating the account you will be logged in and redirected to the admin.
11
+ {% trans "This page is only available when there are no admin users in the database." %}
12
+ </p>
13
+ <p>
14
+ {% trans "After creating the account you will be logged in and redirected to the admin." %}
13
15
  </p>
14
16
 
15
17
  <form method="post" novalidate>
@@ -43,8 +45,8 @@
43
45
  {{ form.password2 }}
44
46
 
45
47
  <p style="margin-top:1rem;">
46
- <button type="submit">Create admin</button>
47
- <a class="contrast" href="{% url 'index' %}">Cancel</a>
48
+ <button type="submit">{% trans "Create admin" %}</button>
49
+ <a class="contrast" href="{% url 'index' %}">{% trans "Cancel" %}</a>
48
50
  </p>
49
51
  </form>
50
52
  </div>
@@ -0,0 +1,50 @@
1
+ {% extends "base_pico.html" %}
2
+ {% load static i18n %}
3
+ {% block title %}{% trans "Sign Up" %}{% endblock %}
4
+
5
+ {% block content %}
6
+ <div class="container" style="max-width:720px; margin:2rem auto;">
7
+ <article class="card">
8
+ <div class="card-body">
9
+ <h2>{% trans "Sign up" %}</h2>
10
+
11
+ <form method="post" novalidate>
12
+ {% csrf_token %}
13
+ {% if form.non_field_errors %}
14
+ <div class="card-panel" role="alert">
15
+ <ul>
16
+ {% for err in form.non_field_errors %}
17
+ <li>{{ err }}</li>
18
+ {% endfor %}
19
+ </ul>
20
+ </div>
21
+ {% endif %}
22
+
23
+ <label for="{{ form.username.id_for_label }}">{% trans "Username" %}</label>
24
+ {{ form.username }}
25
+
26
+ <label for="{{ form.email.id_for_label }}">{% trans "Email (optional)" %}</label>
27
+ {{ form.email }}
28
+
29
+ <label for="{{ form.first_name.id_for_label }}">{% trans "First name" %}</label>
30
+ {{ form.first_name }}
31
+
32
+ <label for="{{ form.last_name.id_for_label }}">{% trans "Last name" %}</label>
33
+ {{ form.last_name }}
34
+
35
+ <label for="{{ form.password1.id_for_label }}">{% trans "Password" %}</label>
36
+ {{ form.password1 }}
37
+
38
+ <label for="{{ form.password2.id_for_label }}">{% trans "Confirm password" %}</label>
39
+ {{ form.password2 }}
40
+
41
+ <p style="margin-top:1rem;">
42
+ <button type="submit">{% trans "Sign Up" %}</button>
43
+ <a class="contrast" href="{% url 'index' %}">{% trans "Cancel" %}</a>
44
+ </p>
45
+ </form>
46
+ </div>
47
+ </article>
48
+ </div>
49
+
50
+ {% endblock %}
sandwitches/urls.py CHANGED
@@ -16,22 +16,31 @@ Including another URLconf
16
16
  """
17
17
 
18
18
  from django.contrib import admin
19
- from django.urls import path
19
+ from django.urls import path, include
20
20
  from . import views
21
+ from .api import api
22
+ from django.conf.urls.i18n import i18n_patterns
23
+
21
24
 
22
- from django.conf import settings
23
- from django.conf.urls.static import static
24
- from debug_toolbar.toolbar import debug_toolbar_urls
25
25
  import os
26
26
  import sys
27
27
 
28
28
 
29
29
  urlpatterns = [
30
- path("", views.index, name="index"),
30
+ path("i18n/", include("django.conf.urls.i18n")),
31
+ path("signup/", views.signup, name="signup"),
31
32
  path("admin/", admin.site.urls),
33
+ path("api/", api.urls),
34
+ path("media/<path:file_path>", views.media, name="media"),
35
+ path("", views.index, name="index"),
36
+ ]
37
+
38
+ urlpatterns += i18n_patterns(
32
39
  path("recipes/<slug:slug>/", views.recipe_detail, name="recipe_detail"),
33
40
  path("setup/", views.setup, name="setup"),
34
- ]
41
+ path("recipes/<int:pk>/rate/", views.recipe_rate, name="recipe_rate"),
42
+ prefix_default_language=True,
43
+ )
35
44
 
36
45
  if "test" not in sys.argv or "PYTEST_VERSION" in os.environ:
37
46
  from debug_toolbar.toolbar import debug_toolbar_urls
@@ -39,7 +48,3 @@ if "test" not in sys.argv or "PYTEST_VERSION" in os.environ:
39
48
  urlpatterns = [
40
49
  *urlpatterns,
41
50
  ] + debug_toolbar_urls()
42
-
43
-
44
- if settings.DEBUG:
45
- urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
sandwitches/views.py CHANGED
@@ -3,9 +3,15 @@ from django.urls import reverse
3
3
  from django.contrib import messages
4
4
  from django.contrib.auth import login
5
5
  from django.contrib.auth import get_user_model
6
-
7
- from .models import Recipe
8
- from .forms import RecipeForm, AdminSetupForm
6
+ from django.contrib.auth.decorators import login_required
7
+ from django.utils.translation import gettext as _
8
+ from .models import Recipe, Rating
9
+ from .forms import RecipeForm, AdminSetupForm, UserSignupForm, RatingForm
10
+ from django.http import HttpResponseBadRequest
11
+ from django.conf import settings
12
+ from django.http import FileResponse, Http404
13
+ from pathlib import Path
14
+ import mimetypes
9
15
 
10
16
  User = get_user_model()
11
17
 
@@ -24,13 +30,56 @@ def recipe_edit(request, pk):
24
30
 
25
31
  def recipe_detail(request, slug):
26
32
  recipe = get_object_or_404(Recipe, slug=slug)
27
- return render(request, "detail.html", {"recipe": recipe})
33
+ avg = recipe.average_rating()
34
+ count = recipe.rating_count()
35
+ user_rating = None
36
+ rating_form = None
37
+ if request.user.is_authenticated:
38
+ try:
39
+ user_rating = Rating.objects.get(recipe=recipe, user=request.user) # ty:ignore[unresolved-attribute]
40
+ except Rating.DoesNotExist: # ty:ignore[unresolved-attribute]
41
+ user_rating = None
42
+ # show form prefilled when possible
43
+ initial = {"score": str(user_rating.score)} if user_rating else None
44
+ rating_form = RatingForm(initial=initial)
45
+ return render(
46
+ request,
47
+ "detail.html",
48
+ {
49
+ "recipe": recipe,
50
+ "avg_rating": avg,
51
+ "rating_count": count,
52
+ "user_rating": user_rating,
53
+ "rating_form": rating_form,
54
+ },
55
+ )
56
+
57
+
58
+ @login_required
59
+ def recipe_rate(request, pk):
60
+ """
61
+ Create or update a rating for the given recipe by the logged-in user.
62
+ """
63
+ recipe = get_object_or_404(Recipe, pk=pk)
64
+ if request.method != "POST":
65
+ return redirect("recipe_detail", slug=recipe.slug)
66
+
67
+ form = RatingForm(request.POST)
68
+ if form.is_valid():
69
+ score = int(form.cleaned_data["score"])
70
+ Rating.objects.update_or_create( # ty:ignore[unresolved-attribute]
71
+ recipe=recipe, user=request.user, defaults={"score": score}
72
+ )
73
+ messages.success(request, _("Your rating has been saved."))
74
+ else:
75
+ messages.error(request, _("Could not save rating."))
76
+ return redirect("recipe_detail", slug=recipe.slug)
28
77
 
29
78
 
30
79
  def index(request):
31
80
  if not User.objects.filter(is_superuser=True).exists():
32
81
  return redirect("setup")
33
- recipes = Recipe.objects.order_by("-created_at")
82
+ recipes = Recipe.objects.order_by("-created_at") # ty:ignore[unresolved-attribute]
34
83
  return render(request, "index.html", {"recipes": recipes})
35
84
 
36
85
 
@@ -47,12 +96,53 @@ def setup(request):
47
96
  form = AdminSetupForm(request.POST)
48
97
  if form.is_valid():
49
98
  user = form.save()
50
- # log in the newly created admin
51
99
  user.backend = "django.contrib.auth.backends.ModelBackend"
52
100
  login(request, user)
53
- messages.success(request, "Admin account created and signed in.")
101
+ messages.success(request, _("Admin account created and signed in."))
54
102
  return redirect(reverse("admin:index"))
55
103
  else:
56
104
  form = AdminSetupForm()
57
105
 
58
106
  return render(request, "setup.html", {"form": form})
107
+
108
+
109
+ def signup(request):
110
+ """
111
+ User signup page: create new regular user accounts.
112
+ """
113
+ if request.method == "POST":
114
+ form = UserSignupForm(request.POST)
115
+ if form.is_valid():
116
+ user = form.save()
117
+ # log in the newly created user
118
+ user.backend = "django.contrib.auth.backends.ModelBackend"
119
+ login(request, user)
120
+ messages.success(request, _("Account created and signed in."))
121
+ return redirect("index")
122
+ else:
123
+ form = UserSignupForm()
124
+
125
+ return render(request, "signup.html", {"form": form})
126
+
127
+
128
+ def media(request, file_path=None):
129
+ media_root = getattr(settings, "MEDIA_ROOT", None)
130
+ if not media_root:
131
+ return HttpResponseBadRequest("Invalid Media Root Configuration")
132
+ if not file_path:
133
+ return HttpResponseBadRequest("Invalid File Path")
134
+
135
+ base_path = Path(media_root).resolve()
136
+ full_path = base_path.joinpath(file_path).resolve()
137
+ if base_path not in full_path.parents:
138
+ return HttpResponseBadRequest("Access Denied")
139
+
140
+ if not full_path.exists() or not full_path.is_file():
141
+ raise Http404("File not found")
142
+
143
+ content_type, _ = mimetypes.guess_type(full_path)
144
+ if not content_type or not content_type.startswith("image/"):
145
+ return HttpResponseBadRequest("Access Denied: Only image files are allowed.")
146
+
147
+ response = FileResponse(open(full_path, "rb"), as_attachment=True)
148
+ return response
@@ -1,18 +1,21 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sandwitches
3
- Version: 1.0.3
3
+ Version: 1.2.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
+ Requires-Dist: django-imagekit>=6.0.0
10
+ Requires-Dist: django-ninja>=1.5.1
9
11
  Requires-Dist: django-simple-history>=3.10.1
10
- Requires-Dist: django>=5.2.7
11
- Requires-Dist: djangorestframework>=3.16.1
12
+ Requires-Dist: django-tasks>=0.10.0
13
+ Requires-Dist: django>=6.0.0
12
14
  Requires-Dist: gunicorn>=23.0.0
13
15
  Requires-Dist: markdown>=3.10
14
16
  Requires-Dist: pillow>=12.0.0
15
- Requires-Dist: uwsgi>=2.0.31
17
+ Requires-Dist: uvicorn>=0.40.0
18
+ Requires-Dist: whitenoise[brotli]>=6.11.0
16
19
  Requires-Python: >=3.12
17
20
  Description-Content-Type: text/markdown
18
21
 
@@ -0,0 +1,33 @@
1
+ sandwitches/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ sandwitches/admin.py,sha256=IIVQOr_CIXsdFXDPQoZ_c83DuqbHVnw4Ht9tAtmvLM0,870
3
+ sandwitches/api.py,sha256=r4HrlEv9IQMuvlr-WravamzTbUWcn85zS1e-iReHEuU,1968
4
+ sandwitches/asgi.py,sha256=cygnXdXSSVspM7ZXuj47Ef6oz7HSTw4D7BPzgE2PU5w,399
5
+ sandwitches/forms.py,sha256=NeGUi3xPzQpgw2cVWpo2ZKpYUXsCuJ3SzgGUkvxdV2A,2610
6
+ sandwitches/locale/nl/LC_MESSAGES/django.mo,sha256=GgZ4aNmU-v0FStt7mafi_UCR4hC0PC06W0mIUPPWtUE,2906
7
+ sandwitches/locale/nl/LC_MESSAGES/django.po,sha256=uk2W5ai6tyhKlA-rcucv5NpZfBrHNBev6Rp5wKWirqc,2843
8
+ sandwitches/migrations/0001_initial.py,sha256=01IfkFbUyYMpTHV5GaBxJEKjzRIdUdPR5sY3AUTODww,2546
9
+ sandwitches/migrations/0002_historicalrecipe.py,sha256=yU2KYssfjYhPXRYN6C8IMRFr-4QUGJozz-O167XuabM,2499
10
+ sandwitches/migrations/0003_rating.py,sha256=iKk9M9lcBS5LwsJkMYsmYfHKqKs2QRTILgINbnilASM,1857
11
+ sandwitches/migrations/0004_add_uploaded_by.py,sha256=gZawakGU-H0Abnn2Bw_Mswy9ngipzUC-BHRXRByKVZo,720
12
+ sandwitches/migrations/0005_historicalrecipe_uploaded_by.py,sha256=xmYDXgBxjrQkbEtorQlDzW0K1Z70UNxRrUk75WjYdEI,766
13
+ sandwitches/migrations/0006_profile.py,sha256=gzmxZWXmjldimYRdovuNouc2Y2idihg8UvEaU0ad_Ds,1558
14
+ sandwitches/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ sandwitches/models.py,sha256=7Upm6abkEZjmk5rIzViW7M_4a3ai03-9tLWLkCty2hs,6390
16
+ sandwitches/settings.py,sha256=5Qg0Wd-X1Kj1Fm7Teh0SRO8jOmVSUkpnUXfZRe1TjwI,5604
17
+ sandwitches/storage.py,sha256=HIiOEDa_LhpsbhCUBNO-SlCZDUJOoANUbyDIbspEcoE,2325
18
+ sandwitches/tasks.py,sha256=aGLpTE42mCZbh2Pyt7fXIjbELm9lD727ir_2bto-wWw,3241
19
+ sandwitches/templates/base.html,sha256=C9tUPfMKRvvdMqdDpE8ww21DH25bNktcVIwdrDEhajw,570
20
+ sandwitches/templates/base_pico.html,sha256=yeWlWlrCfI9yVLStSyODvcNtSmxXvWm4SZORZN-31R4,8273
21
+ sandwitches/templates/detail.html,sha256=p7FikXyse1bYxRCFCYH3GSwgNXHS7D9O6j4fUmmDkWQ,4592
22
+ sandwitches/templates/form.html,sha256=S4yUq9p2v7vWifhA5xj_Z4ObpMoaqUq2w08TDw3vk0o,449
23
+ sandwitches/templates/index.html,sha256=tgZFplcedG1r4s8pBc_qvJDXECPqrESPOSw56FnnCkw,2606
24
+ sandwitches/templates/setup.html,sha256=btid1XtR0MO_qSWriWX7LeWUtNFA7rDB4zt5Md9UNhU,1787
25
+ sandwitches/templates/signup.html,sha256=3qOdDMUHMshe2FoaQzR07lIm3Wbrzorb_h9Fp8Og-Eg,1585
26
+ sandwitches/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ sandwitches/templatetags/markdown_extras.py,sha256=0ibmRzxE3r85x4k7kK71R-9UT0CgeegYF7MHzj3juTI,344
28
+ sandwitches/urls.py,sha256=maKaIDfb_kNmMwrpS495TymuFnJJ6fbLoi5QRLjrFds,1582
29
+ sandwitches/views.py,sha256=Av9dfTAygGkFkHO47NK6RDjprMTVRpDa4c63X_h9ur8,5192
30
+ sandwitches/wsgi.py,sha256=Eyncpnahq_4s3Lr9ruB-R3Lu9j9zBXqgPbUj7qhIbwU,399
31
+ sandwitches-1.2.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
32
+ sandwitches-1.2.0.dist-info/METADATA,sha256=psetHwoaKHYa-_anYOLXOaBdi1UumZwg5lR8uStEg_I,731
33
+ sandwitches-1.2.0.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- sandwitches/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- sandwitches/admin.py,sha256=8QyK9xOUvGGPz30-7p2phyc-Ks9VKD_K1kCAagisPwA,120
3
- sandwitches/asgi.py,sha256=cygnXdXSSVspM7ZXuj47Ef6oz7HSTw4D7BPzgE2PU5w,399
4
- sandwitches/forms.py,sha256=EHTENN49BZRm0Ba2sU4Or9NVrO6GhkOaW-rsKcGjClA,1984
5
- sandwitches/migrations/0001_initial.py,sha256=01IfkFbUyYMpTHV5GaBxJEKjzRIdUdPR5sY3AUTODww,2546
6
- sandwitches/migrations/0002_historicalrecipe.py,sha256=yU2KYssfjYhPXRYN6C8IMRFr-4QUGJozz-O167XuabM,2499
7
- sandwitches/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- sandwitches/models.py,sha256=HiPeh9OF1WoqWTjK5uUNuS5eLbtZBHfuXyg8h9Stb2M,3066
9
- sandwitches/settings.py,sha256=vPk91YEhXlda2ADDla0EcReV_e0gpRsAJylkZI_GS34,3498
10
- sandwitches/storage.py,sha256=XrzMw8mcUowEoV5hYjP-ZI27C3vfk010UkukA5SrGDk,917
11
- sandwitches/templates/base.html,sha256=gUOxxwD7G8VeBranSYp40PCWsJ-ywf8e7Qyv8VoqRP4,494
12
- sandwitches/templates/base_pico.html,sha256=ZjE04fUCQU3iLiJts38qQ-Lkg4tbnwnJ0YfzUB8PVlc,7378
13
- sandwitches/templates/detail.html,sha256=1hOxlMbj7N6tK_u4t06iETe9lmKF0XSXv2fFp8Yr1hA,1242
14
- sandwitches/templates/form.html,sha256=XgrQfb_ZEJfnAou7z3gxcj7wqZ4fwFANplvYdzXg80A,373
15
- sandwitches/templates/index.html,sha256=fnsU5N5dPaa3BXOoIUvgD-9a3EPz0Fs25M0p_eQnf5w,2307
16
- sandwitches/templates/setup.html,sha256=Y45l96Tl6ln9Mb5gCC4JnT1bf-zuQOpYYL1JL3k-1T0,1677
17
- sandwitches/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- sandwitches/templatetags/markdown_extras.py,sha256=0ibmRzxE3r85x4k7kK71R-9UT0CgeegYF7MHzj3juTI,344
19
- sandwitches/urls.py,sha256=VsN-bLzAPgYAHm_sCJ36F5y_-eMHuPzGT9Trw7dGSSU,1398
20
- sandwitches/views.py,sha256=_-s7vtJ-n5fnCTnzytFvKK-CMY6Wz5xCb5RKnbI1T4Y,1940
21
- sandwitches/wsgi.py,sha256=Eyncpnahq_4s3Lr9ruB-R3Lu9j9zBXqgPbUj7qhIbwU,399
22
- sandwitches-1.0.3.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
23
- sandwitches-1.0.3.dist-info/METADATA,sha256=5W8DYgzufZh4dcTLpWwJ2MpM5pPuWRUEqcUntv-sqMY,621
24
- sandwitches-1.0.3.dist-info/RECORD,,