add profile picture support and rearrange things to be slightly more sane
This commit is contained in:
parent
9148e2068f
commit
15e1018476
6 changed files with 100 additions and 10 deletions
|
|
@ -1,21 +1,13 @@
|
||||||
from fastapi import FastAPI, UploadFile, Request, Depends
|
from fastapi import FastAPI, UploadFile, Request, Depends
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from minio import Minio
|
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import re
|
|
||||||
|
|
||||||
from .auth import JWTBearer
|
from .auth import JWTBearer
|
||||||
from .sql import SessionMaker, Uploads
|
from .sql import SessionMaker, Uploads
|
||||||
from . import util
|
from . import util
|
||||||
import config
|
import config
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from . import endpoints
|
||||||
|
|
||||||
minioClient = Minio(
|
|
||||||
config.MINIO_ADDR,
|
|
||||||
access_key=config.MINIO_ACCESS_KEY,
|
|
||||||
secret_key=config.MINIO_SECRET_KEY,
|
|
||||||
)
|
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
|
|
@ -26,6 +18,8 @@ app.add_middleware(
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
app.include_router(endpoints.router)
|
||||||
|
|
||||||
@app.post("/upload", dependencies=[Depends(JWTBearer())])
|
@app.post("/upload", dependencies=[Depends(JWTBearer())])
|
||||||
async def upload(file: UploadFile, request: Request):
|
async def upload(file: UploadFile, request: Request):
|
||||||
if file.size > config.MAX_FILE_SIZE:
|
if file.size > config.MAX_FILE_SIZE:
|
||||||
|
|
@ -40,11 +34,12 @@ async def upload(file: UploadFile, request: Request):
|
||||||
existing.expiry = datetime.now() + timedelta(days=7)
|
existing.expiry = datetime.now() + timedelta(days=7)
|
||||||
else:
|
else:
|
||||||
mime = mimetypes.guess_type(safeFilename)
|
mime = mimetypes.guess_type(safeFilename)
|
||||||
minioClient.put_object("uploads", sha, file.file, file.size, content_type=mime[0])
|
util.minioClient.put_object("uploads", sha, file.file, file.size, content_type=mime[0])
|
||||||
up = Uploads(hash=sha)
|
up = Uploads(hash=sha)
|
||||||
session.add(up)
|
session.add(up)
|
||||||
session.commit()
|
session.commit()
|
||||||
return {"url": f"https://{config.MINIO_ADDR}/uploads/{sha}/{safeFilename}"}
|
return {"url": f"https://{config.MINIO_ADDR}/uploads/{sha}/{safeFilename}"}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["sql", "auth", "util"]
|
__all__ = ["sql", "auth", "util"]
|
||||||
9
cef_3M/endpoints/__init__.py
Normal file
9
cef_3M/endpoints/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
from fastapi import APIRouter
|
||||||
|
import os
|
||||||
|
import importlib
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
for module in os.listdir(os.path.dirname(__file__)):
|
||||||
|
if module == '__init__.py' or module[-3:] != '.py':
|
||||||
|
continue
|
||||||
|
importlib.import_module("."+module[:-3], package="cef_3M.endpoints")
|
||||||
66
cef_3M/endpoints/pfp.py
Normal file
66
cef_3M/endpoints/pfp.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import mimetypes
|
||||||
|
import time
|
||||||
|
|
||||||
|
from . import router
|
||||||
|
from fastapi import UploadFile, Request, Depends
|
||||||
|
|
||||||
|
from ..util import minioClient
|
||||||
|
from ..auth import JWTBearer
|
||||||
|
import config
|
||||||
|
|
||||||
|
from pywuffs import ImageDecoderType
|
||||||
|
from pywuffs.aux import (
|
||||||
|
ImageDecoder,
|
||||||
|
ImageDecoderConfig,
|
||||||
|
)
|
||||||
|
pfpConfig = ImageDecoderConfig()
|
||||||
|
pfpConfig.max_incl_dimension = 400
|
||||||
|
pfpConfig.enabled_decoders = [
|
||||||
|
ImageDecoderType.GIF,
|
||||||
|
ImageDecoderType.PNG,
|
||||||
|
ImageDecoderType.JPEG,
|
||||||
|
]
|
||||||
|
|
||||||
|
iconConfig = ImageDecoderConfig()
|
||||||
|
iconConfig.max_incl_dimension = 24
|
||||||
|
iconConfig.enabled_decoders = [
|
||||||
|
ImageDecoderType.PNG,
|
||||||
|
]
|
||||||
|
|
||||||
|
@router.post("/pfp/upload", dependencies=[Depends(JWTBearer())])
|
||||||
|
async def pfpUpload(file: UploadFile, request: Request):
|
||||||
|
if file.size > config.MAX_PFP_SIZE:
|
||||||
|
return {"error": "file too big"}
|
||||||
|
whoami = request.state.jwt
|
||||||
|
username = whoami["account"].lower()
|
||||||
|
|
||||||
|
# It's not the path I exactly wanted, but this will have to do - WUFFS ensures that the file is valid then we just save it to the server
|
||||||
|
# I hope there's no issue in doing that...
|
||||||
|
decoder = ImageDecoder(pfpConfig)
|
||||||
|
data = await file.read()
|
||||||
|
decoded = decoder.decode(data)
|
||||||
|
if decoded.error_message:
|
||||||
|
return {"error": "invalid file"}
|
||||||
|
file.file.seek(0)
|
||||||
|
|
||||||
|
mime = mimetypes.guess_type(file.filename)
|
||||||
|
minioClient.put_object("pfp", username, file.file, file.size, content_type=mime[0])
|
||||||
|
return {"url": f"https://{config.MINIO_ADDR}/pfp/{username}?{time.time():.0f}"}
|
||||||
|
|
||||||
|
@router.post("/pfp/uploadIcon", dependencies=[Depends(JWTBearer())])
|
||||||
|
async def pfpUpload(file: UploadFile, request: Request):
|
||||||
|
if file.size > config.MAX_PFP_SIZE:
|
||||||
|
return {"error": "file too big"}
|
||||||
|
whoami = request.state.jwt
|
||||||
|
username = whoami["account"].lower()
|
||||||
|
|
||||||
|
decoder = ImageDecoder(iconConfig)
|
||||||
|
data = await file.read()
|
||||||
|
decoded = decoder.decode(data)
|
||||||
|
if decoded.error_message:
|
||||||
|
return {"error": "invalid file"}
|
||||||
|
file.file.seek(0)
|
||||||
|
|
||||||
|
mime = mimetypes.guess_type(file.filename)
|
||||||
|
minioClient.put_object("pfp", username+"/icon", file.file, file.size, content_type=mime[0])
|
||||||
|
return {"url": f"https://{config.MINIO_ADDR}/pfp/{username}/icon?{time.time():.0f}"}
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
import re
|
import re
|
||||||
|
import config
|
||||||
|
from minio import Minio
|
||||||
|
|
||||||
|
|
||||||
from fastapi import UploadFile
|
from fastapi import UploadFile
|
||||||
|
|
||||||
|
|
@ -13,3 +16,9 @@ async def SHA256(f: UploadFile) -> str:
|
||||||
sha.update(data)
|
sha.update(data)
|
||||||
await f.seek(0)
|
await f.seek(0)
|
||||||
return sha.hexdigest()
|
return sha.hexdigest()
|
||||||
|
|
||||||
|
minioClient = Minio(
|
||||||
|
config.MINIO_ADDR,
|
||||||
|
access_key=config.MINIO_ACCESS_KEY,
|
||||||
|
secret_key=config.MINIO_SECRET_KEY,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,9 @@ MINIO_ACCESS_KEY = "access-key-goes-here"
|
||||||
MINIO_SECRET_KEY = "secret-key-goes-here"
|
MINIO_SECRET_KEY = "secret-key-goes-here"
|
||||||
|
|
||||||
MAX_FILE_SIZE = 1024*1024*20
|
MAX_FILE_SIZE = 1024*1024*20
|
||||||
|
MAX_PFP_SIZE = 1024*1024*1.5
|
||||||
|
# It's a 24x24 image, you can fit that in 32k
|
||||||
|
MAX_ICON_SIZE = 1024*32
|
||||||
|
|
||||||
# Need to figure out how to make this cooperate more
|
# Need to figure out how to make this cooperate more
|
||||||
ALLOWED_DOMAINS = ["*"]
|
ALLOWED_DOMAINS = ["*"]
|
||||||
|
|
@ -15,14 +15,18 @@ httpcore==1.0.5
|
||||||
httptools==0.6.1
|
httptools==0.6.1
|
||||||
httpx==0.27.0
|
httpx==0.27.0
|
||||||
idna==3.4
|
idna==3.4
|
||||||
|
inflect==7.2.1
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.4
|
||||||
Mako==1.3.5
|
Mako==1.3.5
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py==3.0.0
|
||||||
MarkupSafe==2.1.5
|
MarkupSafe==2.1.5
|
||||||
mdurl==0.1.2
|
mdurl==0.1.2
|
||||||
minio==7.1.17
|
minio==7.1.17
|
||||||
|
more-itertools==10.2.0
|
||||||
mysqlclient==2.2.4
|
mysqlclient==2.2.4
|
||||||
|
numpy==1.26.4
|
||||||
orjson==3.10.3
|
orjson==3.10.3
|
||||||
|
pillow==10.3.0
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
pydantic==2.4.2
|
pydantic==2.4.2
|
||||||
pydantic_core==2.10.1
|
pydantic_core==2.10.1
|
||||||
|
|
@ -31,12 +35,15 @@ PyJWT==2.8.0
|
||||||
PyMySQL==1.1.0
|
PyMySQL==1.1.0
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
python-multipart==0.0.9
|
python-multipart==0.0.9
|
||||||
|
pywuffs==1.2.1
|
||||||
PyYAML==6.0.1
|
PyYAML==6.0.1
|
||||||
rich==13.7.1
|
rich==13.7.1
|
||||||
shellingham==1.5.4
|
shellingham==1.5.4
|
||||||
sniffio==1.3.0
|
sniffio==1.3.0
|
||||||
|
sqlacodegen @ git+https://github.com/agronholm/sqlacodegen@2a6053224d28da27c9b89aa611b9dd4c27637fe6
|
||||||
SQLAlchemy==2.0.30
|
SQLAlchemy==2.0.30
|
||||||
starlette==0.37.2
|
starlette==0.37.2
|
||||||
|
typeguard==4.2.1
|
||||||
typer==0.12.3
|
typer==0.12.3
|
||||||
typing_extensions==4.8.0
|
typing_extensions==4.8.0
|
||||||
ujson==5.10.0
|
ujson==5.10.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue