Files
ev-charger-as/backend/utils.py
byun 9f0f4326fe 기능 개선 — 사진 업로드, HEIC 지원, 재조치 흐름, 신고 순번, 모바일 UI
- 이미지 압축: 삼성/네이버 브라우저 호환, URL.createObjectURL 방식으로 메모리 절감,
  대용량 PNG/HEIC 처리, blob 유효성 검증, 순차 압축으로 모바일 OOM 방지
- HEIC/HEIF 지원: pillow-heif 서버사이드 변환, Pillow 12.2.0 업그레이드
- 조치 페이지: '조치 완료 저장' 단일 버튼으로 단순화
- 재조치 흐름: 관리자 재조치 요청 시 이전 조치 이력을 번호 카드로 순차 표시
- 신고 순번: 전체 기준 ROW_NUMBER(oldest=1) 순번 표시, 삭제 gap 제거
- 모바일 탭바: position:fixed 적용으로 nav 하단 흰 여백 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 05:38:33 +09:00

59 lines
2.1 KiB
Python

import os, uuid, io, qrcode
from PIL import Image
from fastapi import UploadFile
# HEIC/HEIF 지원 등록 (pillow-heif)
try:
from pillow_heif import register_heif_opener
register_heif_opener()
_HEIF_SUPPORTED = True
except ImportError:
_HEIF_SUPPORTED = False
UPLOAD_DIR = os.getenv("UPLOAD_DIR", "/uploads")
# 브라우저에서 표시 불가능한 포맷 → 서버에서 JPEG 변환
_CONVERT_EXTS = {".heic", ".heif", ".avif"}
def save_upload(file: UploadFile, sub_dir: str = "general") -> str:
"""파일을 저장하고 /uploads 기준 상대 경로 반환.
HEIC/HEIF 등 브라우저 비호환 포맷은 JPEG로 변환 후 저장."""
raw = file.file.read()
ext = os.path.splitext(file.filename or "file")[1].lower() or ".jpg"
folder = os.path.join(UPLOAD_DIR, sub_dir)
os.makedirs(folder, exist_ok=True)
if ext in _CONVERT_EXTS:
# HEIC/HEIF → JPEG 변환
try:
img = Image.open(io.BytesIO(raw))
if img.mode in ("RGBA", "P", "LA"):
img = img.convert("RGB")
elif img.mode != "RGB":
img = img.convert("RGB")
buf = io.BytesIO()
img.save(buf, format="JPEG", quality=88, optimize=True)
raw = buf.getvalue()
ext = ".jpg"
except Exception:
pass # 변환 실패 시 원본 그대로 저장
filename = f"{uuid.uuid4().hex}{ext}"
filepath = os.path.join(folder, filename)
with open(filepath, "wb") as f:
f.write(raw)
return f"/uploads/{sub_dir}/{filename}"
def generate_qr(charger_id: str, domain: str) -> str:
"""QR 이미지를 저장하고 /uploads 기준 경로 반환"""
url = f"https://{domain}/report/{charger_id}"
qr = qrcode.QRCode(version=1, box_size=10, border=4)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
folder = os.path.join(UPLOAD_DIR, "qr")
os.makedirs(folder, exist_ok=True)
filepath = os.path.join(folder, f"{charger_id}.png")
img.save(filepath)
return f"/uploads/qr/{charger_id}.png"