173 lines
5.8 KiB
Python
173 lines
5.8 KiB
Python
import json
|
|
from datetime import datetime
|
|
from io import BytesIO
|
|
|
|
import requests
|
|
from PIL import Image
|
|
from django.contrib import messages
|
|
from django.core.files import File
|
|
from django.utils.translation import gettext as _
|
|
from django.http import HttpResponseRedirect, HttpResponse
|
|
from django.shortcuts import redirect, render
|
|
from django.urls import reverse
|
|
from django.utils.translation import ngettext
|
|
from django_tables2 import RequestConfig
|
|
|
|
from cookbook.forms import SyncForm, BatchEditForm
|
|
from cookbook.helper.permission_helper import group_required, has_group_permission
|
|
from cookbook.models import *
|
|
from cookbook.tables import SyncTable
|
|
|
|
|
|
@group_required('user')
|
|
def sync(request):
|
|
if request.method == "POST":
|
|
if not has_group_permission(request.user, ['admin']):
|
|
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
|
|
return HttpResponseRedirect(reverse('data_sync'))
|
|
form = SyncForm(request.POST)
|
|
if form.is_valid():
|
|
new_path = Sync()
|
|
new_path.path = form.cleaned_data['path']
|
|
new_path.storage = form.cleaned_data['storage']
|
|
new_path.last_checked = datetime.now()
|
|
new_path.save()
|
|
return redirect('data_sync')
|
|
else:
|
|
form = SyncForm()
|
|
|
|
monitored_paths = SyncTable(Sync.objects.all())
|
|
RequestConfig(request, paginate={'per_page': 25}).configure(monitored_paths)
|
|
|
|
return render(request, 'batch/monitor.html', {'form': form, 'monitored_paths': monitored_paths})
|
|
|
|
|
|
@group_required('user')
|
|
def sync_wait(request):
|
|
return render(request, 'batch/waiting.html')
|
|
|
|
|
|
@group_required('user')
|
|
def batch_import(request):
|
|
imports = RecipeImport.objects.all()
|
|
for new_recipe in imports:
|
|
recipe = Recipe(name=new_recipe.name, file_path=new_recipe.file_path, storage=new_recipe.storage, file_uid=new_recipe.file_uid, created_by=request.user)
|
|
recipe.save()
|
|
new_recipe.delete()
|
|
|
|
return redirect('list_recipe_import')
|
|
|
|
|
|
@group_required('user')
|
|
def batch_edit(request):
|
|
if request.method == "POST":
|
|
form = BatchEditForm(request.POST)
|
|
if form.is_valid():
|
|
word = form.cleaned_data['search']
|
|
keywords = form.cleaned_data['keywords']
|
|
|
|
recipes = Recipe.objects.filter(name__icontains=word)
|
|
count = 0
|
|
for recipe in recipes:
|
|
edit = False
|
|
if keywords.__sizeof__() > 0:
|
|
recipe.keywords.add(*list(keywords))
|
|
edit = True
|
|
if edit:
|
|
count = count + 1
|
|
|
|
recipe.save()
|
|
|
|
msg = ngettext(
|
|
'Batch edit done. %(count)d recipe was updated.',
|
|
'Batch edit done. %(count)d Recipes where updated.',
|
|
count) % {
|
|
'count': count,
|
|
}
|
|
messages.add_message(request, messages.SUCCESS, msg)
|
|
|
|
return redirect('data_batch_edit')
|
|
else:
|
|
form = BatchEditForm()
|
|
|
|
return render(request, 'batch/edit.html', {'form': form})
|
|
|
|
|
|
@group_required('user')
|
|
def import_url(request):
|
|
if request.method == 'POST':
|
|
data = json.loads(request.body)
|
|
|
|
recipe = Recipe.objects.create(
|
|
name=data['name'],
|
|
instructions=data['recipeInstructions'],
|
|
waiting_time=data['cookTime'],
|
|
working_time=data['prepTime'],
|
|
internal=True,
|
|
created_by=request.user,
|
|
)
|
|
|
|
for kw in data['keywords']:
|
|
if kw['id'] != "null" and (k := Keyword.objects.filter(id=kw['id']).first()):
|
|
recipe.keywords.add(k)
|
|
elif data['all_keywords']:
|
|
k = Keyword.objects.create(name=kw['text'])
|
|
recipe.keywords.add(k)
|
|
|
|
for ing in data['recipeIngredient']:
|
|
i, i_created = Food.objects.get_or_create(name=ing['ingredient']['text'])
|
|
if ing['unit']:
|
|
u, u_created = Unit.objects.get_or_create(name=ing['unit']['text'])
|
|
else:
|
|
u = Unit.objects.get(name=request.user.userpreference.default_unit)
|
|
|
|
if isinstance(ing['amount'], str):
|
|
try:
|
|
ing['amount'] = float(ing['amount'].replace(',', '.'))
|
|
except ValueError:
|
|
# TODO return proper error
|
|
pass
|
|
|
|
RecipeIngredient.objects.create(recipe=recipe, ingredient=i, unit=u, amount=ing['amount'])
|
|
|
|
if data['image'] != '':
|
|
response = requests.get(data['image'])
|
|
img = Image.open(BytesIO(response.content))
|
|
|
|
# todo move image processing to dedicated function
|
|
basewidth = 720
|
|
wpercent = (basewidth / float(img.size[0]))
|
|
hsize = int((float(img.size[1]) * float(wpercent)))
|
|
img = img.resize((basewidth, hsize), Image.ANTIALIAS)
|
|
|
|
im_io = BytesIO()
|
|
img.save(im_io, 'PNG', quality=70)
|
|
recipe.image = File(im_io, name=f'{uuid.uuid4()}_{recipe.pk}.png')
|
|
recipe.save()
|
|
|
|
return HttpResponse(reverse('view_recipe', args=[recipe.pk]))
|
|
|
|
return render(request, 'url_import.html', {})
|
|
|
|
|
|
class Object(object):
|
|
pass
|
|
|
|
|
|
@group_required('user')
|
|
def statistics(request):
|
|
counts = Object()
|
|
counts.recipes = Recipe.objects.count()
|
|
counts.keywords = Keyword.objects.count()
|
|
counts.recipe_import = RecipeImport.objects.count()
|
|
counts.units = Unit.objects.count()
|
|
counts.ingredients = Food.objects.count()
|
|
counts.comments = Comment.objects.count()
|
|
|
|
counts.recipes_internal = Recipe.objects.filter(internal=True).count()
|
|
counts.recipes_external = counts.recipes - counts.recipes_internal
|
|
|
|
counts.recipes_no_keyword = Recipe.objects.filter(keywords=None).count()
|
|
|
|
return render(request, 'stats.html', {'counts': counts})
|