fixed external recipes not sharable

This commit is contained in:
vabene1111
2025-06-09 11:05:54 +02:00
parent 97aa3301ea
commit 78e2ee6631
5 changed files with 42 additions and 15 deletions

View File

@@ -5,7 +5,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>PDF</title> <title>PDF</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PDF</title> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF</title>
<style> <style>
html, body { html, body {
height: 100%; height: 100%;
@@ -23,9 +24,13 @@
</style> </style>
</head> </head>
<body > <body>
<iframe src="{% static 'pdfjs/web/viewer.html' %}?file={% url 'api_get_recipe_file' recipe_id %}" ></iframe> {% if share %}
<iframe src="{% static 'pdfjs/web/viewer.html' %}?file={% url 'api_get_recipe_file' recipe_id %}?share={{ share }}"></iframe>
{% else %}
<iframe src="{% static 'pdfjs/web/viewer.html' %}?file={% url 'api_get_recipe_file' recipe_id %}"></iframe>
{% endif %}
</body> </body>
</html> </html>

View File

@@ -114,8 +114,8 @@ urlpatterns = [
path('api/import/', api.AppImportView.as_view(), name='view_import'), path('api/import/', api.AppImportView.as_view(), name='view_import'),
path('api/export/', api.AppExportView.as_view(), name='api_export'), path('api/export/', api.AppExportView.as_view(), name='api_export'),
path('data/import/url', data.import_url, name='data_import_url'), path('data/import/url', data.import_url, name='data_import_url'),
path('api/get_external_file_link/<int:recipe_id>/', api.get_external_file_link, name='api_get_external_file_link'), path('api/get_external_file_link/<int:pk>/', api.get_external_file_link, name='api_get_external_file_link'),
path('api/get_recipe_file/<int:recipe_id>/', api.get_recipe_file, name='api_get_recipe_file'), path('api/get_recipe_file/<int:pk>/', api.get_recipe_file, name='api_get_recipe_file'),
path('api/sync_all/', api.sync_all, name='api_sync'), path('api/sync_all/', api.sync_all, name='api_sync'),
path('api/recipe-from-source/', api.RecipeUrlImportView.as_view(), name='api_recipe_from_source'), path('api/recipe-from-source/', api.RecipeUrlImportView.as_view(), name='api_recipe_from_source'),
path('api/ai-import/', api.AiImportView.as_view(), name='api_ai_import'), path('api/ai-import/', api.AiImportView.as_view(), name='api_ai_import'),

View File

@@ -2283,8 +2283,8 @@ def get_recipe_provider(recipe):
) )
@api_view(['GET']) @api_view(['GET'])
@permission_classes([CustomIsUser & CustomTokenHasReadWriteScope]) @permission_classes([CustomIsUser & CustomTokenHasReadWriteScope])
def get_external_file_link(request, recipe_id): def get_external_file_link(request, pk):
recipe = get_object_or_404(Recipe, pk=recipe_id, space=request.space) recipe = get_object_or_404(Recipe, pk=pk, space=request.space)
if not recipe.link: if not recipe.link:
recipe.link = get_recipe_provider(recipe).get_share_link(recipe) recipe.link = get_recipe_provider(recipe).get_share_link(recipe)
recipe.save() recipe.save()
@@ -2297,9 +2297,9 @@ def get_external_file_link(request, recipe_id):
responses=None, responses=None,
) )
@api_view(['GET']) @api_view(['GET'])
@permission_classes([(CustomIsGuest | CustomIsUser) & CustomTokenHasReadWriteScope]) @permission_classes([CustomRecipePermission & CustomTokenHasReadWriteScope])
def get_recipe_file(request, recipe_id): def get_recipe_file(request, pk):
recipe = get_object_or_404(Recipe, pk=recipe_id, space=request.space) recipe = get_object_or_404(Recipe, pk=pk) # space check handled by CustomRecipePermission
if recipe.storage: if recipe.storage:
return FileResponse(get_recipe_provider(recipe).get_file(recipe), filename=f'{recipe.name}.pdf') return FileResponse(get_recipe_provider(recipe).get_file(recipe), filename=f'{recipe.name}.pdf')
else: else:

View File

@@ -24,6 +24,7 @@ from django.utils.datetime_safe import date
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_scopes import scopes_disabled from django_scopes import scopes_disabled
from drf_spectacular.views import SpectacularRedocView, SpectacularSwaggerView from drf_spectacular.views import SpectacularRedocView, SpectacularSwaggerView
from rest_framework.response import Response
from cookbook.forms import CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm, SpaceJoinForm, User, UserCreateForm, UserPreference from cookbook.forms import CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm, SpaceJoinForm, User, UserCreateForm, UserPreference
from cookbook.helper.HelperFunctions import str2bool from cookbook.helper.HelperFunctions import str2bool
@@ -197,10 +198,14 @@ def meal_plan(request):
return render(request, 'meal_plan.html', {}) return render(request, 'meal_plan.html', {})
@group_required('guest')
def recipe_pdf_viewer(request, pk): def recipe_pdf_viewer(request, pk):
recipe = get_object_or_404(Recipe, pk=pk, space=request.space) with scopes_disabled():
return render(request, 'pdf_viewer.html', {'recipe_id': pk}) recipe = get_object_or_404(Recipe, pk=pk)
if share_link_valid(recipe, request.GET.get('share', None)) or (has_group_permission(
request.user, ['guest']) and recipe.space == request.space):
return render(request, 'pdf_viewer.html', {'recipe_id': pk, 'share': request.GET.get('share', None)})
return HttpResponseRedirect(reverse('index'))
@group_required('guest') @group_required('guest')

View File

@@ -1,8 +1,8 @@
<template> <template>
<v-card class="mt-1 h-100"> <v-card class="mt-1 h-100">
<iframe width="100%" height="700px" :src="`${getDjangoUrl('/view-recipe-pdf/')}${props.recipe.id}/`" v-if="isPdf"></iframe> <iframe width="100%" height="700px" :src="externalUrl" v-if="isPdf"></iframe>
<v-img :src="`${getDjangoUrl('/api/get_recipe_file/')}${props.recipe.id}/`" v-if="isImage"></v-img> <v-img :src="externalUrl" v-if="isImage"></v-img>
</v-card> </v-card>
</template> </template>
@@ -10,12 +10,14 @@
import {computed, PropType} from "vue"; import {computed, PropType} from "vue";
import {Recipe} from "@/openapi"; import {Recipe} from "@/openapi";
import {useDjangoUrls} from "@/composables/useDjangoUrls"; import {useDjangoUrls} from "@/composables/useDjangoUrls";
import {useUrlSearchParams} from "@vueuse/core";
const props = defineProps({ const props = defineProps({
recipe: {type: {} as PropType<Recipe>, required: true} recipe: {type: {} as PropType<Recipe>, required: true}
}) })
const params = useUrlSearchParams('history')
const {getDjangoUrl} = useDjangoUrls() const {getDjangoUrl} = useDjangoUrls()
/** /**
@@ -40,6 +42,21 @@ const isImage = computed(() => {
return false return false
}) })
const externalUrl = computed(() => {
let url = ''
if (isImage.value) {
url = `${getDjangoUrl('/api/get_recipe_file/')}${props.recipe.id}/`
} else if (isPdf.value) {
url = `${getDjangoUrl('/view-recipe-pdf/')}${props.recipe.id}/`
}
if (params.share && typeof params.share == "string") {
url += `?share=${params.share}`
}
return url
})
</script> </script>