import with image working

This commit is contained in:
vabene1111
2022-02-21 15:59:30 +01:00
parent c06c511dc9
commit e04d672750
7 changed files with 94 additions and 38 deletions

View File

@ -58,18 +58,6 @@ def get_recipe_from_source(text, url, request):
})
return kid_list
recipe_json = {
'name': '',
'url': '',
'description': '',
'image': '',
'keywords': [],
'recipeIngredient': [],
'recipeInstructions': '',
'servings': '',
'prepTime': '',
'cookTime': ''
}
recipe_tree = []
parse_list = []
html_data = []

View File

@ -131,9 +131,7 @@ def get_from_scraper(scrape, request):
recipe_json['steps'][0]['ingredients'].append(
{
'amount': 0,
'unit': {
'name': '',
},
'unit': None,
'food': {
'name': x,
},
@ -275,9 +273,9 @@ def parse_keywords(keyword_json, space):
kw = normalize_string(kw)
if len(kw) != 0:
if k := Keyword.objects.filter(name=kw, space=space).first():
keywords.append({'name': str(k)})
keywords.append({'label': str(k), 'name': k.name, 'id': k.id})
else:
keywords.append({'name': kw})
keywords.append({'label': kw, 'name': kw})
return keywords

View File

@ -621,9 +621,12 @@ class RecipeSerializer(RecipeBaseSerializer):
class RecipeImageSerializer(WritableNestedModelSerializer):
image = serializers.ImageField(required=False, allow_null=True)
image_url = serializers.CharField(max_length=4096, required=False, allow_null=True)
class Meta:
model = Recipe
fields = ['image', ]
fields = ['image', 'image_url', ]
class RecipeImportSerializer(SpacedModelSerializer):

View File

@ -5,6 +5,7 @@ import uuid
from collections import OrderedDict
import requests
from PIL import UnidentifiedImageError
from annoying.decorators import ajax_request
from annoying.functions import get_object_or_None
from django.contrib import messages
@ -23,6 +24,7 @@ from django.utils.translation import gettext as _
from django_scopes import scopes_disabled
from icalendar import Calendar, Event
from recipe_scrapers import NoSchemaFoundInWildMode, WebsiteNotImplementedError, scrape_me
from requests.exceptions import MissingSchema
from rest_framework import decorators, status, viewsets
from rest_framework.exceptions import APIException, PermissionDenied
from rest_framework.pagination import PageNumberPagination
@ -706,20 +708,33 @@ class RecipeViewSet(viewsets.ModelViewSet):
serializer = self.serializer_class(obj, data=request.data, partial=True)
if self.request.space.demo:
raise PermissionDenied(detail='Not available in demo', code=None)
if serializer.is_valid():
serializer.save()
image = None
if serializer.validated_data == {}:
obj.image = None
else:
img, filetype = handle_image(request, obj.image)
if 'image' in serializer.validated_data:
image = obj.image
elif 'image_url' in serializer.validated_data:
try:
response = requests.get(serializer.validated_data['image_url'])
image = File(io.BytesIO(response.content))
print('test')
except UnidentifiedImageError as e:
print(e)
pass
except MissingSchema as e:
print(e)
pass
except Exception as e:
print(e)
pass
if image is not None:
img, filetype = handle_image(request, image)
obj.image = File(img, name=f'{uuid.uuid4()}_{obj.pk}{filetype}')
obj.save()
return Response(serializer.data)
return Response(serializer.errors, 400)
# TODO: refactor API to use post/put/delete or leave as put and change VUE to use list_recipe after creating

0
openapitools.json Normal file
View File

View File

@ -34,9 +34,37 @@
<div class="row">
<div class="col col-md-12" v-if="recipe_json !== undefined">
Images
<div class="row">
<div class="col col-md-12 text-center">
<b-img rounded fluid :src="recipe_json.image"
style="max-height: 30vh"></b-img>
</div>
</div>
<div class="row mt-1">
<div class="col col-md-12 text-center">
<small class="text-muted">Click the image you want to import for this
recipe</small> <!-- TODO localize -->
</div>
<div class="col col-md-12 text-center">
<b-img v-for="i in recipe_images" rounded thumbnail fluid :src="i"
style="max-height: 10vh" v-bind:key="i"
@click="recipe_json.image = i"></b-img>
</div>
</div>
Keywords
<ul>
<li v-for="k in recipe_json.keywords" v-bind:key="k">{{k}}</li>
<li v-for="k in recipe_json.keywords" v-bind:key="k.name">{{ k.label }}</li>
</ul>
unused
<ul>
<li v-for="k in recipe_json.unused_keywords" v-bind:key="k.name">{{
k.label
}}
</li>
</ul>
Steps
<ul>
@ -119,8 +147,14 @@ export default {
importRecipe: function () {
let apiFactory = new ApiApiFactory()
apiFactory.createRecipe(this.recipe_json).then(response => {
let recipe = response.data
apiFactory.imageRecipe(response.data.id, undefined, this.recipe_json.image).then(response => {
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
window.location = resolveDjangoUrl('edit_recipe', response.data.id)
window.location = resolveDjangoUrl('edit_recipe', recipe.id)
}).catch(e => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_UPDATE)
window.location = resolveDjangoUrl('edit_recipe', recipe.id)
})
}).catch(err => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_CREATE)
})
@ -154,6 +188,10 @@ export default {
'mode': this.mode
},).then((response) => {
this.recipe_json = response.data['recipe_json'];
this.$set(this.recipe_json, 'unused_keywords', this.recipe_json.keywords.filter(k => k.id === undefined))
this.$set(this.recipe_json, 'keywords', this.recipe_json.keywords.filter(k => k.id !== undefined))
this.recipe_tree = response.data['recipe_tree'];
this.recipe_html = response.data['recipe_html'];
this.recipe_images = response.data['recipe_images']; //todo change on backend as well after old view is deprecated

View File

@ -1856,6 +1856,12 @@ export interface RecipeImage {
* @memberof RecipeImage
*/
image?: any | null;
/**
*
* @type {string}
* @memberof RecipeImage
*/
image_url?: string | null;
}
/**
*
@ -5227,10 +5233,11 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
*
* @param {string} id A unique integer value identifying this recipe.
* @param {any} [image]
* @param {string} [imageUrl]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
imageRecipe: async (id: string, image?: any, options: any = {}): Promise<RequestArgs> => {
imageRecipe: async (id: string, image?: any, imageUrl?: string, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('imageRecipe', 'id', id)
const localVarPath = `/api/recipe/{id}/image/`
@ -5252,6 +5259,10 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
localVarFormParams.append('image', image as any);
}
if (imageUrl !== undefined) {
localVarFormParams.append('image_url', imageUrl as any);
}
localVarHeaderParameter['Content-Type'] = 'multipart/form-data';
@ -10341,11 +10352,12 @@ export const ApiApiFp = function(configuration?: Configuration) {
*
* @param {string} id A unique integer value identifying this recipe.
* @param {any} [image]
* @param {string} [imageUrl]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async imageRecipe(id: string, image?: any, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RecipeImage>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.imageRecipe(id, image, options);
async imageRecipe(id: string, image?: any, imageUrl?: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RecipeImage>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.imageRecipe(id, image, imageUrl, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
@ -12174,11 +12186,12 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
*
* @param {string} id A unique integer value identifying this recipe.
* @param {any} [image]
* @param {string} [imageUrl]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
imageRecipe(id: string, image?: any, options?: any): AxiosPromise<RecipeImage> {
return localVarFp.imageRecipe(id, image, options).then((request) => request(axios, basePath));
imageRecipe(id: string, image?: any, imageUrl?: string, options?: any): AxiosPromise<RecipeImage> {
return localVarFp.imageRecipe(id, image, imageUrl, options).then((request) => request(axios, basePath));
},
/**
*
@ -13992,12 +14005,13 @@ export class ApiApi extends BaseAPI {
*
* @param {string} id A unique integer value identifying this recipe.
* @param {any} [image]
* @param {string} [imageUrl]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public imageRecipe(id: string, image?: any, options?: any) {
return ApiApiFp(this.configuration).imageRecipe(id, image, options).then((request) => request(this.axios, this.basePath));
public imageRecipe(id: string, image?: any, imageUrl?: string, options?: any) {
return ApiApiFp(this.configuration).imageRecipe(id, image, imageUrl, options).then((request) => request(this.axios, this.basePath));
}
/**