2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2024-11-25 16:51:54 +00:00
troggle/core/views/editor_helpers.py

146 lines
6.8 KiB
Python
Raw Normal View History

2023-01-19 18:35:56 +00:00
import io
import re
from pathlib import Path
2023-01-19 18:35:56 +00:00
import django.forms as forms
from django.http import (Http404, HttpResponse, HttpResponseRedirect,
JsonResponse)
from django.shortcuts import redirect, render
from django.template import Context, loader
2023-01-19 18:35:56 +00:00
from django.urls import resolve, reverse
from django.views.decorators.csrf import ensure_csrf_cookie
from PIL import Image
2023-01-19 18:35:56 +00:00
import troggle.settings as settings
2023-01-19 18:35:56 +00:00
from troggle.core.utils import WriteAndCommitError, write_and_commit
from .auth import login_required_if_public
MAX_IMAGE_WIDTH = 1000
2022-06-25 23:36:53 +01:00
MAX_IMAGE_HEIGHT = 800
THUMBNAIL_WIDTH = 200
2022-06-25 23:36:53 +01:00
THUMBNAIL_HEIGHT = 200
def get_dir(path):
"From a path sent from urls.py, determine the directory."
if "/" in path:
return path.rsplit('/', 1)[0]
else:
return ""
def image_selector(request, path):
'''Returns available images'''
directory = get_dir(path)
thumbnailspath = Path(settings.EXPOWEB) / directory / "t"
thumbnails = []
if thumbnailspath.is_dir():
for f in thumbnailspath.iterdir():
if f.is_file():
if directory:
base = f"{directory}/"
else:
base = ""
thumbnail_url = reverse('expopage', args=[f"{base}t/{f.name}"])
name_base = f.name.rsplit('.', 1)[0]
page_path_base = Path(settings.EXPOWEB) / directory / "l"
if ((page_path_base / (f"{name_base}.htm")).is_file()):
page_url = reverse('expopage', args=[f"{base}l/{name_base}.htm"])
else:
page_url = reverse('expopage', args=[f"{base}/l/{name_base}.html"])
thumbnails.append({"thumbnail_url": thumbnail_url, "page_url": page_url})
return render(request, 'image_selector.html', {'thumbnails': thumbnails})
@login_required_if_public
@ensure_csrf_cookie
def new_image_form(request, path):
'''Manages a form to upload new images'''
directory = get_dir(path)
if request.method == 'POST':
form = NewWebImageForm(request.POST, request.FILES, directory = directory)
if form.is_valid():
f = request.FILES["file_"]
binary_data = io.BytesIO()
for chunk in f.chunks():
binary_data.write(chunk)
i = Image.open(binary_data)
width, height = i.size
2022-06-25 23:36:53 +01:00
if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT:
scale = max(width / MAX_IMAGE_WIDTH, height / MAX_IMAGE_HEIGHT)
i = i.resize((int(width / scale), int(height / scale)), Image.ANTIALIAS)
2022-06-25 23:36:53 +01:00
tscale = max(width / THUMBNAIL_WIDTH, height / THUMBNAIL_HEIGHT)
thumbnail = i.resize((int(width / tscale), int(height / tscale)), Image.ANTIALIAS)
ib = io.BytesIO()
i.save(ib, format="png")
tb = io.BytesIO()
thumbnail.save(tb, format="png")
image_rel_path, thumb_rel_path, desc_rel_path = form.get_rel_paths()
image_page_template = loader.get_template('image_page_template.html')
image_page = image_page_template.render({'header': form.cleaned_data["header"], 'description': form.cleaned_data["description"],
'photographer': form.cleaned_data["photographer"], 'year': form.cleaned_data["year"],
'filepath': f'/{image_rel_path}'
})
image_path, thumb_path, desc_path = form.get_full_paths()
# Create directories if required
for full_path in image_path, thumb_path, desc_path:
print(full_path, full_path.parent)
full_path.parent.mkdir(parents=False, exist_ok=True)
try:
change_message = form.cleaned_data["change_message"]
2022-07-18 16:06:23 +01:00
write_and_commit([(desc_path, image_page, "utf-8"),
(image_path, ib.getbuffer(), False),
(thumb_path, tb.getbuffer(), False)],
f'{change_message} - online adding of an image')
2022-07-18 16:06:23 +01:00
except WriteAndCommitError as e:
return JsonResponse({"error": e.message})
linked_image_template = loader.get_template('linked_image_template.html')
html_snippet = linked_image_template.render({'thumbnail_url': f'/{thumb_rel_path}', 'page_url': f'/{desc_rel_path}'}, request)
return JsonResponse({"html": html_snippet})
else:
form = NewWebImageForm(directory = directory)
template = loader.get_template('new_image_form.html')
htmlform = template.render({'form': form, 'path': path}, request)
return JsonResponse({"form": htmlform})
class NewWebImageForm(forms.Form):
'''The form used by the editexpopage function
'''
header = forms.CharField(widget=forms.TextInput(attrs={'size':'60', 'placeholder': "Enter title (displayed as a header and in the tab)"}))
file_ = forms.FileField()
description = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20, 'placeholder': "Describe the photo (using HTML)"}))
photographer = forms.CharField(widget=forms.TextInput(attrs={'size':'60', 'placeholder': "Photographers name"}), required = False)
year = forms.CharField(widget=forms.TextInput(attrs={'size':'60', 'placeholder': "Year photo was taken"}), required = False)
change_message = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":3, 'placeholder': "Descibe the change made (for git)"}))
def __init__(self, *args, **kwargs):
self.directory = Path(kwargs.pop('directory'))
super(forms.Form, self).__init__(*args, **kwargs)
def get_rel_paths(self):
f = self.cleaned_data['file_']
return [self.directory / "i" / (f.name.rsplit('.', 1)[0] + ".png"),
self.directory / "t" / (f.name.rsplit('.', 1)[0] + ".png"),
self.directory / "l" / (f.name.rsplit('.', 1)[0] + ".html")]
def get_full_paths(self):
return [Path(settings.EXPOWEB) / x for x in self.get_rel_paths()]
def clean_file_(self):
for rel_path, full_path in zip(self.get_rel_paths(), self.get_full_paths()):
if full_path.exists():
raise forms.ValidationError(f"File already exists in {rel_path}")
return self.cleaned_data['file_']
class HTMLarea(forms.Textarea):
template_name = "widgets/HTMLarea.html"
def __init__(self, *args, **kwargs):
self.preview = kwargs.pop('preview', False)
super(forms.Textarea, self).__init__(*args, **kwargs)
def get_context(self, name, value, attrs):
c = super(forms.Textarea, self).get_context(name, value, attrs)
c["preview"] = self.preview
return c