diff options
Diffstat (limited to 'core/views')
-rw-r--r-- | core/views/editor_helpers.py | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/core/views/editor_helpers.py b/core/views/editor_helpers.py index c00d6e5..11d8e3a 100644 --- a/core/views/editor_helpers.py +++ b/core/views/editor_helpers.py @@ -1,18 +1,22 @@ import io import re +import shutil +import piexif from pathlib import Path import django.forms as forms -import piexif +from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile from django.http import JsonResponse from django.shortcuts import render from django.template import loader from django.urls import reverse +from django.conf import settings as django_settings + from PIL import Image import troggle.settings as settings -from troggle.core.utils import COOKIE_MAX_AGE, WriteAndCommitError, get_cookie, git_string, write_and_commit, current_expo +from troggle.core.utils import COOKIE_MAX_AGE, WriteAndCommitError, get_cookie, git_string, write_binary_file, write_and_commit, current_expo from .auth import login_required_if_public @@ -113,13 +117,14 @@ def new_image_form(request, path): 0: full resolution, 1: reduced resolution """ - year = current_expo() # replace with year from photo exif if possible THUMB_QUALITY = 70 IMAGE_QUALITY = 85 directory = get_dir(path) print(f"new_image_form(): {directory=} {path=}") editor = get_cookie(request) + print(f"{django_settings.FILE_UPLOAD_MAX_MEMORY_SIZE=}") + FILE_UPLOAD_MAX_MEMORY_SIZE = 0 # force uploaded files to be temporary in /tmp, not in-memory if request.method == "POST": # print(f"new_image_form(): POST ") form = NewWebImageForm(request.POST, request.FILES, directory=directory) @@ -137,6 +142,7 @@ def new_image_form(request, path): for chunk in f.chunks(): binary_data.write(chunk) i = Image.open(binary_data) + i_original = i if "exif" in i.info: exif_dict = piexif.load(i.info["exif"]) gps_data = exif_dict['GPS'] @@ -153,7 +159,10 @@ def new_image_form(request, path): if not descrip: # date and time from exif data descrip = f"{exif_dict['Exif'][36867].decode()} {exif_dict['Exif'][36880].decode()}" + if not year: + year = exif_dict['Exif'][36867].decode()[:4] else: + year = current_expo() # replace with year from photo exif if possible exif = None width, height = i.size @@ -216,23 +225,24 @@ def new_image_form(request, path): editor # this works, a new who_are_you typed on the Image form is used as the git comment ) except WriteAndCommitError as e: - print(f"new_image_form(): WriteAndCommitError: {e.message}") - return JsonResponse({"error": e.message}) + print(f"new_image_form(): WriteAndCommitError: {e}") + return JsonResponse({"error": e}) except Exception as e: - print(f"new_image_form(): EXCEPTION: {e.message}") - return JsonResponse({"error": e.message}) + print(f"new_image_form(): EXCEPTION: {e}") + return JsonResponse({"error": e}) 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 ) + save_original_in_expofiles(f, year, form.cleaned_data["photographer"]) j_response = JsonResponse({"html": html_snippet}) j_response.set_cookie('editor_id', editor, max_age=COOKIE_MAX_AGE) # does NOT seem to work updating who_are_you cookie return j_response else: # print(f"new_image_form(): not POST ") initial={"who_are_you":editor, - "year": year, "photographer": extract_git_name(editor), + "year": "", "photographer": extract_git_name(editor), "change_message": "Uploading photo"} form = NewWebImageForm(directory=directory, initial=initial ) # print(f"new_image_form(): POST and not POST ") @@ -246,8 +256,37 @@ def extract_git_name(git_str): if match: return match.group(1).strip() return "Anon." - +def save_original_in_expofiles(f, year, photographer): + """Moves the uploaded file from /tmp to EXPOFILES + + This may be redundant, if the original was already in EXPOFILES, but this + will catch photos uploaded directly from phones which otherwise never + get recorded properly in original format. + + Django does small files in memory, which is a pain. + """ + if photographer: + photographer = photographer.strip().replace(" ","") + else: + photographer = "Anonymous" + directory = settings.EXPOFILES / "photos" / year / photographer / "expoweb_originals" + filepath = (directory / f.name) + + if isinstance(f, InMemoryUploadedFile): + print("In-memory file content:", f,f.content_type, f.size, f.charset, f.content_type_extra, f.read()) + content = f.read() + print(f"In-memory file content: content read: {len(content)}") + # THIS DOES NOT WORK, which is why we force all uploads to use a temporary file not in-memory + write_binary_file(filepath, content) + elif isinstance(f, TemporaryUploadedFile): + dest = shutil.move(f.temporary_file_path(), filepath) + else: + msg = f"Unknown uploaded file type: {f}, should be a temporary file or in-memory." + print(msg) + raise TypeError(msg) + return + class NewWebImageForm(forms.Form): """The form used by the editexpopage function""" |