feat(storage): add S3 image storage support with file-based config and migration script
This commit is contained in:
@@ -16,7 +16,7 @@ from app.auth import (
|
||||
redirect_if_not_logged_in,
|
||||
verify_password,
|
||||
)
|
||||
from app.config import SECRET_KEY, SESSION_COOKIE_NAME, UPLOAD_DIR
|
||||
from app.config import SECRET_KEY, SESSION_COOKIE_NAME
|
||||
from app.database import get_db
|
||||
from random import choice
|
||||
from string import ascii_letters, digits
|
||||
@@ -86,6 +86,10 @@ def _translate_filter(key: str, lang: str = "zh") -> str:
|
||||
|
||||
templates.env.filters["t"] = _translate_filter
|
||||
|
||||
# image URL resolver: bare key → full URL (local /uploads/... or S3 public URL)
|
||||
from app.storage import resolve_url as _resolve_image_url
|
||||
templates.env.filters["image_url"] = lambda v: _resolve_image_url(v) if v else ""
|
||||
|
||||
from app.i18n import get_languages as _get_languages
|
||||
templates.env.globals["available_languages"] = _get_languages()
|
||||
|
||||
@@ -188,7 +192,7 @@ def api_public_cards(
|
||||
"page": page,
|
||||
"has_more": start + limit < total,
|
||||
"cards": [{
|
||||
"image_front": c.image_front,
|
||||
"image_front": _resolve_image_url(c.image_front),
|
||||
"country_from": c.country_from,
|
||||
"country_to": c.country_to,
|
||||
"status": c.status,
|
||||
@@ -230,7 +234,7 @@ def api_public_cards_user(
|
||||
"page": page,
|
||||
"has_more": start + limit < total,
|
||||
"cards": [{
|
||||
"image_front": c.image_front,
|
||||
"image_front": _resolve_image_url(c.image_front),
|
||||
"country_from": c.country_from,
|
||||
"country_to": c.country_to,
|
||||
} for c in batch],
|
||||
@@ -959,12 +963,13 @@ async def upload_image(
|
||||
)
|
||||
if not pc:
|
||||
return _redirect("/profiles")
|
||||
from app.storage import get_storage
|
||||
storage = get_storage()
|
||||
ext = Path(file.filename or "upload.jpg").suffix or ".jpg"
|
||||
filename = f"{uuid4().hex}{ext}"
|
||||
dest = UPLOAD_DIR / filename
|
||||
key = f"{uuid4().hex}{ext}"
|
||||
content = await file.read()
|
||||
dest.write_bytes(content)
|
||||
setattr(pc, f"image_{side}", f"/uploads/{filename}")
|
||||
storage.put(key, content)
|
||||
setattr(pc, f"image_{side}", key)
|
||||
db.commit()
|
||||
return _redirect(f"/postcards/{postcard_id}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user