backend optimizations + redundant commits cleanup
This commit is contained in:
@@ -40,6 +40,10 @@ from logger import logger
|
||||
UPLOAD_DIR = Path("static/web_uploads")
|
||||
ALLOWED_EXTENSIONS = frozenset({".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".mp4", ".webm"})
|
||||
MAX_FILE_SIZE = 100 * 1024 * 1024
|
||||
_IMAGE_RESIZE_EXTENSIONS = frozenset({".png", ".jpg", ".jpeg", ".webp"})
|
||||
_IMAGE_MAX_SIDE = 2048
|
||||
_IMAGE_JPEG_QUALITY = 85
|
||||
_IMAGE_WEBP_QUALITY = 85
|
||||
|
||||
_SLUG_RE = re.compile(r"^[a-z0-9][a-z0-9\-]*$")
|
||||
|
||||
@@ -55,6 +59,39 @@ EXTENSION_CONTENT_TYPES: dict[str, frozenset[str]] = {
|
||||
}
|
||||
|
||||
|
||||
def _optimize_image_bytes(data: bytes, ext: str) -> bytes:
|
||||
"""Уменьшает большие картинки до _IMAGE_MAX_SIDE и пережимает с разумным качеством."""
|
||||
try:
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image, ImageOps
|
||||
|
||||
with Image.open(BytesIO(data)) as img:
|
||||
img = ImageOps.exif_transpose(img)
|
||||
w, h = img.size
|
||||
if max(w, h) <= _IMAGE_MAX_SIDE and len(data) < 500_000:
|
||||
return data
|
||||
if max(w, h) > _IMAGE_MAX_SIDE:
|
||||
img.thumbnail((_IMAGE_MAX_SIDE, _IMAGE_MAX_SIDE), Image.Resampling.LANCZOS)
|
||||
buffer = BytesIO()
|
||||
save_kwargs: dict = {}
|
||||
if ext in (".jpg", ".jpeg"):
|
||||
if img.mode not in ("RGB", "L"):
|
||||
img = img.convert("RGB")
|
||||
save_kwargs = {"format": "JPEG", "quality": _IMAGE_JPEG_QUALITY, "optimize": True, "progressive": True}
|
||||
elif ext == ".webp":
|
||||
save_kwargs = {"format": "WEBP", "quality": _IMAGE_WEBP_QUALITY, "method": 6}
|
||||
elif ext == ".png":
|
||||
save_kwargs = {"format": "PNG", "optimize": True}
|
||||
else:
|
||||
return data
|
||||
img.save(buffer, **save_kwargs)
|
||||
optimized = buffer.getvalue()
|
||||
return optimized if len(optimized) < len(data) else data
|
||||
except Exception:
|
||||
return data
|
||||
|
||||
|
||||
def _sanitize_svg(data: bytes) -> bytes:
|
||||
import re as _re
|
||||
|
||||
@@ -529,6 +566,10 @@ async def upload_media(
|
||||
file_data = b"".join(chunks)
|
||||
if ext == ".svg":
|
||||
file_data = _sanitize_svg(file_data)
|
||||
elif ext in _IMAGE_RESIZE_EXTENSIONS:
|
||||
from core.executor import run_cpu
|
||||
|
||||
file_data = await run_cpu(_optimize_image_bytes, file_data, ext)
|
||||
with open(path, "wb") as f:
|
||||
f.write(file_data)
|
||||
url = f"/api/web/uploads/{name}"
|
||||
|
||||
Reference in New Issue
Block a user