64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
from PIL import Image, ImageDraw
|
|
from pillow_heif import register_heif_opener
|
|
from werkzeug.datastructures import FileStorage
|
|
from werkzeug.utils import secure_filename
|
|
|
|
register_heif_opener()
|
|
|
|
|
|
def allowed_file(filename: str, allowed_extensions: set[str]) -> bool:
|
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in allowed_extensions
|
|
|
|
|
|
def _apply_image_ops(image: Image.Image, rotate: int = 0, crop_box: tuple[int, int, int, int] | None = None, scale_percent: int = 100) -> Image.Image:
|
|
if image.mode not in ('RGB', 'RGBA'):
|
|
image = image.convert('RGB')
|
|
if rotate:
|
|
image = image.rotate(-rotate, expand=True)
|
|
if crop_box:
|
|
x, y, w, h = crop_box
|
|
if w > 0 and h > 0:
|
|
image = image.crop((x, y, x + w, y + h))
|
|
if scale_percent and scale_percent != 100:
|
|
width = max(1, int(image.width * (scale_percent / 100)))
|
|
height = max(1, int(image.height * (scale_percent / 100)))
|
|
image = image.resize((width, height))
|
|
return image
|
|
|
|
|
|
def _pdf_placeholder(preview_path: Path, original_name: str) -> None:
|
|
image = Image.new('RGB', (800, 1100), color='white')
|
|
draw = ImageDraw.Draw(image)
|
|
draw.text((40, 40), f'PDF preview\n{original_name}', fill='black')
|
|
image.save(preview_path, 'WEBP', quality=80)
|
|
|
|
|
|
def save_document(file: FileStorage, upload_dir: Path, preview_dir: Path, rotate: int = 0, crop_box: tuple[int, int, int, int] | None = None, scale_percent: int = 100) -> tuple[str, str]:
|
|
upload_dir.mkdir(parents=True, exist_ok=True)
|
|
preview_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
original_name = secure_filename(file.filename or 'document')
|
|
extension = original_name.rsplit('.', 1)[1].lower() if '.' in original_name else 'bin'
|
|
stem = re.sub(r'[^a-zA-Z0-9_-]+', '-', Path(original_name).stem).strip('-') or 'document'
|
|
unique_name = f'{stem}-{uuid4().hex}.{extension}'
|
|
saved_path = upload_dir / unique_name
|
|
file.save(saved_path)
|
|
|
|
preview_name = f'{stem}-{uuid4().hex}.webp'
|
|
preview_path = preview_dir / preview_name
|
|
if extension in {'jpg', 'jpeg', 'png', 'heic'}:
|
|
image = Image.open(saved_path)
|
|
image = _apply_image_ops(image, rotate=rotate, crop_box=crop_box, scale_percent=scale_percent)
|
|
image.save(preview_path, 'WEBP', quality=80)
|
|
elif extension == 'pdf':
|
|
_pdf_placeholder(preview_path, original_name)
|
|
else:
|
|
preview_name = ''
|
|
return unique_name, preview_name
|