import with image working
This commit is contained in:
@ -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 = []
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
0
openapitools.json
Normal 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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user