Small fixes

This commit is contained in:
2024-05-10 16:44:46 +04:00
parent a45c2dfee2
commit fd5b19e6a9
12 changed files with 94 additions and 61 deletions

View File

@@ -6,6 +6,7 @@ import database
cli = typer.Typer()
@cli.command(name="create")
def create_database(): aiorun(database.create_all())
@cli.command(name="drop")

View File

@@ -1,4 +1,7 @@
from .crud import *
from .schemas import *
from .database import get_session, drop_all, create_all, recreate_all
from .database import get_session as get_session, \
drop_all as drop_all, \
create_all as create_all, \
recreate_all as recreate_all
from .crud import *

View File

@@ -5,14 +5,17 @@ from .. import models as mdl
from .. import schemas as sch
from ..database import add_transaction
async def add_game(db: AsyncSession,
game_info: sch.GameCreate,
user_id: int):
game = mdl.Game(**game_info.model_dump(), owner_id=user_id)
return await add_transaction(db, game)
async def get_games(db: AsyncSession):
return (await db.execute(select(mdl.Game))).scalars().all()
async def get_game(db: AsyncSession, game_id: int):
return await db.get(mdl.Game, game_id)

View File

@@ -1,7 +1,6 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
DATABASE_URL = "sqlite+aiosqlite:///./dev_database.db"
# DATABASE_URL = "postgresql://user:password@postgresserver/db"
@@ -9,27 +8,31 @@ DATABASE_URL = "sqlite+aiosqlite:///./dev_database.db"
engine = create_async_engine(
DATABASE_URL, connect_args={"check_same_thread": False}, echo=True
)
async_session = sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False)
async_session = sessionmaker( # type: ignore
engine, class_=AsyncSession, expire_on_commit=False) # type: ignore
Base = declarative_base()
async def get_session() -> AsyncSession: # type: ignore
# Dependency
async with async_session() as session: # type: ignore
yield session
async def drop_all():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
async def create_all():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async def recreate_all():
await drop_all()
await create_all()
async def add_transaction[T](db: AsyncSession, entity: T) -> T:
try:
db.add(entity)

View File

@@ -7,36 +7,51 @@ import aiofiles
from fastapi import UploadFile
from PIL import Image
def create_hash_name(filename: str):
return str(hashlib.sha1(filename.encode()).hexdigest())
async def save_torrent_file(torrent: UploadFile):
if(torrent.filename is None): raise ValueError("Filename not found")
hash_filename = create_hash_name(torrent.filename)+".torrent"
async with aiofiles.open(Path() / "content" / "torrent"
/ hash_filename, 'wb') as file:
await file.write(await torrent.read())
/ hash_filename, 'wb') as file:
torrent_data = await torrent.read()
if (isinstance(torrent_data, str)):
raise ValueError("Invalid torrent file")
await file.write(torrent_data)
return hash_filename
async def save_image(cover: UploadFile, type: Literal["cover", "screenshot"]):
hash_filename = create_hash_name(cover.filename) \
+ mimetypes.guess_extension(cover.content_type)
if(cover.filename is None): raise ValueError("Filename not found")
if(cover.content_type is None): raise ValueError("File content type unknown")
hash_filename = create_hash_name(cover.filename)
file_extension = mimetypes.guess_extension(cover.content_type)
if (file_extension is None): raise NameError("File extension not found")
else: hash_filename += file_extension
async with aiofiles.open(Path() / "content" / "images" / type / "full_size"
/ hash_filename, 'wb') as full_size_file, \
aiofiles.open(Path() / "content" / "images" / type /
"preview" / hash_filename, 'wb') as preview_file:
/ hash_filename, 'wb') as full_size_file, \
aiofiles.open(Path() / "content" / "images" / type /
"preview" / hash_filename, 'wb') as preview_file:
cover_data = await cover.read()
if (isinstance(cover_data, str)):
raise ValueError("Invalid image file")
await full_size_file.write(cover_data)
image = Image.open(BytesIO(cover_data))
compressed_coefficient = (image.size[0] * image.size[1]) / (1280*720/4)
if(compressed_coefficient < 1): compressed_coefficient = 1
if (compressed_coefficient < 1):
compressed_coefficient = 1
compressed_image = image.resize(
( int(image.size[0] / compressed_coefficient),
int(image.size[1] / compressed_coefficient) )
(int(image.size[0] / compressed_coefficient),
int(image.size[1] / compressed_coefficient))
)
buf = BytesIO()
compressed_image.save(buf, format=
cover.content_type.upper().replace("IMAGE/", ""))
compressed_image.save(
buf, format=cover.content_type.upper().replace("IMAGE/", ""))
await preview_file.write(buf.getbuffer())
return hash_filename

View File

@@ -1,5 +1,4 @@
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import FastAPI
import typer
import cli_commands
@@ -13,4 +12,5 @@ app.include_router(files_router)
cli = typer.Typer()
cli.add_typer(cli_commands.cli, name="database")
if(__name__ == "__main__"): cli()
if (__name__ == "__main__"):
cli()

View File

@@ -4,3 +4,4 @@ SQLAlchemy==2.0.30
aiosqlite==0.20.0
typer==0.12.3
aiofiles==23.2.1
Pillow==10.3.0

View File

@@ -1,3 +1,3 @@
from .games import router as games_router
from .files import router as files_router
from .startup import router as startup_router
from .games import games_router as games_router
from .files import files_router as files_router
from .startup import startup_router as startup_router

View File

@@ -1,20 +1,24 @@
from fastapi import APIRouter, Depends, HTTPException, UploadFile
from fastapi import APIRouter, HTTPException, UploadFile
from database import *
from file_handler import *
router = APIRouter(prefix="/files", tags=["Files"])
files_router = APIRouter(prefix="/files", tags=["Files"])
@router.post("/torrent", response_model=str)
@files_router.post("/torrent", response_model=str)
async def upload_torrent(torrent: UploadFile):
try: return await save_torrent_file(torrent)
try:
return await save_torrent_file(torrent)
except Exception as ex:
print(ex)
raise HTTPException(500)
@router.post("/cover", response_model=str)
@files_router.post("/cover", response_model=str)
async def upload_cover(cover: UploadFile):
try: return await save_image(cover, "cover")
try:
return await save_image(cover, "cover")
except Exception as ex:
print(ex)
raise HTTPException(500)

View File

@@ -1,27 +1,29 @@
from fastapi import APIRouter, Depends, HTTPException, UploadFile
from fastapi import APIRouter, Depends, HTTPException
from database import *
from file_handler import *
router = APIRouter(prefix="/games", tags=["Games"])
games_router = APIRouter(prefix="/games", tags=["Games"])
@router.get("/", response_model=list[Game])
@games_router.get("/", response_model=list[Game])
async def get_games(db: AsyncSession = Depends(get_session)):
try: return await crud.get_games(db)
except Exception as ex: raise HTTPException(500)
try:
return await crud.get_games(db)
except Exception:
raise HTTPException(500)
@router.get("/{game_id}", response_model=Game)
@games_router.get("/{game_id}", response_model=Game)
async def get_game(game_id: int, db: AsyncSession = Depends(get_session)):
return await crud.get_game(db, game_id)
@router.post("/", response_model=Game)
@games_router.post("/", response_model=Game)
async def add_game(game: GameCreate,
user_id: int,
db:AsyncSession = Depends(get_session)):
db: AsyncSession = Depends(get_session)):
try:
torrent_filename = save_torrent_file(torrent, game.title)
cover_filename = save_image(cover, game.title, "cover")
return await crud.add_game(db, game, user_id)
except Exception as ex:
except Exception:
raise HTTPException(500)

View File

@@ -1,9 +1,10 @@
from fastapi import APIRouter
from pathlib import Path
router = APIRouter()
startup_router = APIRouter()
@router.on_event("startup")
@startup_router.on_event("startup")
def startup():
need_paths = [
Path() / "content" / "images" / "cover" / "full_size",