Compare commits
2
Commits
1c53209acf
...
b0e69fc123
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0e69fc123 | ||
|
|
8771d105bb |
No files matched your search
+7
-9
@@ -1,8 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import FastAPI, Request, Response
|
from fastapi import FastAPI
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
|
||||||
|
|
||||||
from app.config import UPLOAD_DIR
|
from app.config import UPLOAD_DIR
|
||||||
from app.database import init_db
|
from app.database import init_db
|
||||||
@@ -11,20 +10,19 @@ from app.routers import web, api
|
|||||||
app = FastAPI(title="Mailova 星笺")
|
app = FastAPI(title="Mailova 星笺")
|
||||||
|
|
||||||
UPLOAD_DIR.mkdir(exist_ok=True)
|
UPLOAD_DIR.mkdir(exist_ok=True)
|
||||||
app.mount("/static", StaticFiles(directory=str(Path(__file__).resolve().parent / "static")), name="static")
|
|
||||||
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
|
|
||||||
|
|
||||||
|
|
||||||
# Browser cache: 30 days for uploaded images (they never change)
|
# Cache-Control for uploaded images (30 days, immutable — filenames contain UUID)
|
||||||
class CacheControlMiddleware(BaseHTTPMiddleware):
|
@app.middleware("http")
|
||||||
async def dispatch(self, request: Request, call_next):
|
async def cache_control_middleware(request, call_next):
|
||||||
response: Response = await call_next(request)
|
response = await call_next(request)
|
||||||
if request.url.path.startswith("/uploads/"):
|
if request.url.path.startswith("/uploads/"):
|
||||||
response.headers["Cache-Control"] = "public, max-age=2592000, immutable"
|
response.headers["Cache-Control"] = "public, max-age=2592000, immutable"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
app.add_middleware(CacheControlMiddleware)
|
app.mount("/static", StaticFiles(directory=str(Path(__file__).resolve().parent / "static")), name="static")
|
||||||
|
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
|
||||||
|
|
||||||
app.include_router(web.router)
|
app.include_router(web.router)
|
||||||
app.include_router(api.router)
|
app.include_router(api.router)
|
||||||
|
|||||||
@@ -88,7 +88,13 @@ class S3Storage:
|
|||||||
region: str = "auto",
|
region: str = "auto",
|
||||||
public_url: str = "",
|
public_url: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
|
try:
|
||||||
import boto3
|
import boto3
|
||||||
|
except ImportError:
|
||||||
|
raise ImportError(
|
||||||
|
"boto3 is required for S3 storage. "
|
||||||
|
"Install it with: pip install boto3"
|
||||||
|
)
|
||||||
|
|
||||||
self.bucket = bucket
|
self.bucket = bucket
|
||||||
self.public_url = public_url.rstrip("/")
|
self.public_url = public_url.rstrip("/")
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ jinja2
|
|||||||
bcrypt
|
bcrypt
|
||||||
python-jose[cryptography]
|
python-jose[cryptography]
|
||||||
aiofiles
|
aiofiles
|
||||||
|
boto3
|
||||||
Reference in New Issue
Block a user