Files
Kyle DammannandClaude Opus 5.5 60785e2437 Add phase 5: link import, Instagram fallback and share target
- 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]>
2026-10-30 21:53:28 +01:00

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"),
]