- SSRF-safe fetcher: public IPs only, connects to the checked address, redirects re-validated, size/time limits, honest user agent - schema.org/Recipe JSON-LD extraction (graphs, HowToSections, ISO durations, yields, keywords, images) without extra dependencies; AI fallback on plain page text when no structured recipe exists - Instagram: one login-free request to the public embed page; when Instagram withholds the caption, the import page explains how to paste the text or import a screenshot instead - Suggested source photo can be downloaded and attached on save - Text import works without AI (text becomes the description) - Installable PWA with manifest, icons and Android share target - Offline tests for SSRF rules, parsers, Instagram and import views Co-Authored-By: Claude Opus 5.5 <[email protected]>
27 lines
1.5 KiB
Python
27 lines
1.5 KiB
Python
from django.urls import path
|
|
|
|
from . import import_views, views
|
|
|
|
app_name = "recipes"
|
|
|
|
urlpatterns = [
|
|
path("", views.recipe_list, name="list"),
|
|
path("rezepte/neu/", views.recipe_create, name="create"),
|
|
path("rezepte/import/", import_views.import_start, name="import"),
|
|
path("rezepte/import/foto/", import_views.import_photo, name="import_photo"),
|
|
path("rezepte/import/text/", import_views.import_text, name="import_text"),
|
|
path("rezepte/import/link/", import_views.import_link, name="import_link"),
|
|
path("teilen/", import_views.share_target, name="share"),
|
|
path("rezepte/<int:pk>/", views.recipe_detail, name="detail"),
|
|
path("rezepte/<int:pk>/bearbeiten/", views.recipe_edit, name="edit"),
|
|
path("rezepte/<int:pk>/loeschen/", views.recipe_delete, name="delete"),
|
|
path("rezepte/<int:pk>/kochen/", views.cook_mode, name="cook"),
|
|
path("rezepte/<int:pk>/kommentare/", views.comment_create, name="comment_create"),
|
|
path("rezepte/<int:pk>/kommentare/<int:comment_id>/loeschen/", views.comment_delete, name="comment_delete"),
|
|
path("rezepte/<int:pk>/favorit/", views.favorite_toggle, name="favorite"),
|
|
path("rezepte/<int:pk>/fotos/", views.photo_upload, name="photo_upload"),
|
|
path("rezepte/<int:pk>/fotos/<int:image_id>/titelbild/", views.photo_cover, name="photo_cover"),
|
|
path("rezepte/<int:pk>/fotos/<int:image_id>/loeschen/", views.photo_delete, name="photo_delete"),
|
|
path("bilder/<uuid:image_uuid>/<str:size>.webp", views.photo_serve, name="photo"),
|
|
]
|