from datetime import date from flask import send_file from pathlib import Path from PIL import Image as PImage from werkzeug.exceptions import NotFound, UnprocessableEntity from werkzeug.datastructures import FileStorage from werkzeug.utils import secure_filename from flaschengeist.models.image import Image from flaschengeist.database import db from flaschengeist.config import config def check_mimetype(mime: str): return mime in config["FILES"].get("allowed_mimetypes", []) def send_image(id: int = None, image: Image = None): if image is None: image = Image.query.get(id) if not image: raise NotFound return send_file(image.path_, mimetype=image.mimetype_, download_name=image.filename_) def send_thumbnail(id: int = None, image: Image = None): if image is None: image = Image.query.get(id) if not image: raise NotFound if not image.thumbnail_: with PImage.open(image.open()) as im: im.thumbnail(tuple(config["FILES"].get("thumbnail_size"))) s = image.path_.split(".") s.insert(len(s) - 1, "thumbnail") im.save(".".join(s)) image.thumbnail_ = ".".join(s) db.session.commit() return send_file(image.thumbnail_, mimetype=image.mimetype_, download_name=image.filename_) def upload_image(file: FileStorage): if not check_mimetype(file.mimetype): raise UnprocessableEntity path = Path(config["FILES"].get("data_path")) / str(date.today().year) path.mkdir(mode=int("0700", 8), parents=True, exist_ok=True) if file.filename.count(".") < 1: name = secure_filename(file.filename + "." + file.mimetype.split("/")[-1]) else: name = secure_filename(file.filename) img = Image(mimetype_=file.mimetype, filename_=name) db.session.add(img) db.session.flush() try: img.path_ = str((path / f"{img.id}.{img.filename_.split('.')[-1]}").resolve()) file.save(img.path_) except: db.session.delete(img) raise finally: db.session.commit() return img