mirror of
https://github.com/StepanovPlaton/torrent_backend.git
synced 2026-04-03 20:30:38 +04:00
Code refactoring. Add support genres and actors to routes
This commit is contained in:
@@ -2,14 +2,14 @@
|
|||||||
from asyncio import run as aiorun
|
from asyncio import run as aiorun
|
||||||
import typer
|
import typer
|
||||||
|
|
||||||
import database
|
from database import Database
|
||||||
|
|
||||||
cli = typer.Typer()
|
cli = typer.Typer()
|
||||||
|
|
||||||
|
|
||||||
@cli.command(name="create")
|
@cli.command(name="create")
|
||||||
def create_database(): aiorun(database.create_all())
|
def create_database(): aiorun(Database.create_all())
|
||||||
@cli.command(name="drop")
|
@cli.command(name="drop")
|
||||||
def drop_database(): aiorun(database.drop_all())
|
def drop_database(): aiorun(Database.drop_all())
|
||||||
@cli.command(name="recreate")
|
@cli.command(name="recreate")
|
||||||
def recreate_database(): aiorun(database.recreate_all())
|
def recreate_database(): aiorun(Database.recreate_all())
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
from .crud import *
|
from .crud import *
|
||||||
from .schemas import *
|
from .schemas import *
|
||||||
from .database import get_session as get_session, \
|
from .database import Database
|
||||||
drop_all as drop_all, \
|
|
||||||
create_all as create_all, \
|
|
||||||
recreate_all as recreate_all
|
|
||||||
from .crud import *
|
from .crud import *
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
from .games import *
|
from .games import GamesCRUD as GamesCRUD
|
||||||
from .movies import *
|
from .game_genres import GameGenresCRUD as GameGenresCRUD
|
||||||
from .audiobooks import *
|
|
||||||
from .users import *
|
from .movies import MoviesCRUD as MoviesCRUD
|
||||||
|
from .movie_actors import MovieActorsCRUD as MovieActorsCRUD
|
||||||
|
from .movie_genres import MovieGenresCRUD as MovieGenresCRUD
|
||||||
|
|
||||||
|
from .audiobooks import AudiobooksCRUD as AudiobooksCRUD
|
||||||
|
from .audiobook_genres import AudiobookGenresCRUD as AudiobookGenresCRUD
|
||||||
|
|
||||||
|
from .users import UsersCRUD as UsersCRUD
|
||||||
|
|||||||
19
database/crud/audiobook_genres.py
Normal file
19
database/crud/audiobook_genres.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
|
||||||
|
|
||||||
|
class AudiobookGenresCRUD(EntityCRUD[mdl.AudiobookGenre]):
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.AudiobookGenre)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def add(db: AsyncSession,
|
||||||
|
info: sch.AudiobookGenreCreate):
|
||||||
|
audiobook_genre = mdl.AudiobookGenre(**info.model_dump())
|
||||||
|
return await Database.add(db, audiobook_genre)
|
||||||
@@ -1,45 +1,46 @@
|
|||||||
from time import strftime
|
from time import strftime
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
|
||||||
|
from database.crud.audiobook_genres import AudiobookGenresCRUD
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
from .. import models as mdl
|
from .. import models as mdl
|
||||||
from .. import schemas as sch
|
from .. import schemas as sch
|
||||||
from ..database import add_transaction
|
|
||||||
|
|
||||||
|
|
||||||
async def get_audiobooks(db: AsyncSession):
|
class AudiobooksCRUD(EntityCRUD[mdl.Audiobook]):
|
||||||
return (await db.execute(select(mdl.Audiobook))).scalars().all()
|
@staticmethod
|
||||||
|
async def get(db: AsyncSession, id: int):
|
||||||
|
return await Database.get(db, mdl.Audiobook, id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.Audiobook)
|
||||||
|
|
||||||
async def get_audiobook(db: AsyncSession, audiobook_id: int):
|
@staticmethod
|
||||||
return await db.get(mdl.Audiobook, audiobook_id)
|
async def change_genres(db: AsyncSession, audiobook: mdl.Audiobook, info: sch.AudiobookCreate):
|
||||||
|
audiobook_genres = await AudiobookGenresCRUD.get_all(db)
|
||||||
|
if (info.genres):
|
||||||
|
audiobook.genres = [
|
||||||
|
genre for genre in audiobook_genres if genre.id in info.genres]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def add_audiobook(db: AsyncSession,
|
async def add(db: AsyncSession,
|
||||||
audiobook_info: sch.AudiobookCreate,
|
info: sch.AudiobookCreate,
|
||||||
user_id: int):
|
owner_id: int):
|
||||||
audiobook = mdl.Audiobook(**audiobook_info.model_dump(),
|
audiobook = mdl.Audiobook(**info.model_dump(),
|
||||||
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
upload_date=strftime("%Y-%m-%d %H:%M:%S"),
|
owner_id=owner_id)
|
||||||
owner_id=user_id)
|
await AudiobooksCRUD.change_genres(db, audiobook, info)
|
||||||
return await add_transaction(db, audiobook)
|
return await Database.add(db, audiobook)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change(db: AsyncSession,
|
||||||
|
id: int,
|
||||||
|
info: sch.AudiobookCreate):
|
||||||
|
return await Database.change(db, mdl.Audiobook, id, info, AudiobooksCRUD.change_genres)
|
||||||
|
|
||||||
async def edit_audiobook(db: AsyncSession,
|
@staticmethod
|
||||||
audiobook_id: int,
|
async def delete(db: AsyncSession,
|
||||||
audiobook_info: sch.AudiobookCreate):
|
id: int):
|
||||||
audiobook = await db.get(mdl.Audiobook, audiobook_id)
|
return await Database.delete(db, mdl.Audiobook, id)
|
||||||
for key, value in vars(audiobook_info).items():
|
|
||||||
if (getattr(audiobook, key) != value):
|
|
||||||
setattr(audiobook, key, value)
|
|
||||||
setattr(audiobook, "update_date", strftime("%Y-%m-%d %H:%M:%S"))
|
|
||||||
await db.commit()
|
|
||||||
return audiobook
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_audiobook(db: AsyncSession,
|
|
||||||
audiobook_id: int):
|
|
||||||
audiobook = await get_audiobook(db, audiobook_id)
|
|
||||||
await db.delete(audiobook)
|
|
||||||
await db.commit()
|
|
||||||
return audiobook
|
|
||||||
|
|||||||
20
database/crud/game_genres.py
Normal file
20
database/crud/game_genres.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
|
||||||
|
|
||||||
|
class GameGenresCRUD(EntityCRUD[mdl.GameGenre]):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.GameGenre)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def add(db: AsyncSession,
|
||||||
|
info: sch.GameGenreCreate):
|
||||||
|
game_genre = mdl.GameGenre(**info.model_dump())
|
||||||
|
return await Database.add(db, game_genre)
|
||||||
@@ -1,46 +1,46 @@
|
|||||||
from time import strftime
|
from time import strftime
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
|
||||||
from sqlalchemy.orm import selectinload
|
from database.crud.game_genres import GameGenresCRUD
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
from .. import models as mdl
|
from .. import models as mdl
|
||||||
from .. import schemas as sch
|
from .. import schemas as sch
|
||||||
from ..database import add_transaction
|
|
||||||
|
|
||||||
|
|
||||||
async def get_games(db: AsyncSession):
|
class GamesCRUD(EntityCRUD[mdl.Game]):
|
||||||
return (await db.execute(select(mdl.Game))).scalars().all()
|
@staticmethod
|
||||||
|
async def get(db: AsyncSession, id: int):
|
||||||
|
return await Database.get(db, mdl.Game, id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.Game)
|
||||||
|
|
||||||
async def get_game(db: AsyncSession, game_id: int):
|
@staticmethod
|
||||||
return await db.get(mdl.Game, game_id)
|
async def change_genres(db: AsyncSession, game: mdl.Game, info: sch.GameCreate):
|
||||||
|
game_genres = await GameGenresCRUD.get_all(db)
|
||||||
|
if (info.genres):
|
||||||
|
game.genres = [
|
||||||
|
genre for genre in game_genres if genre.id in info.genres]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def add_game(db: AsyncSession,
|
async def add(db: AsyncSession,
|
||||||
game_info: sch.GameCreate,
|
info: sch.GameCreate,
|
||||||
user_id: int):
|
owner_id: int):
|
||||||
game = mdl.Game(**game_info.model_dump(),
|
game = mdl.Game(**info.model_dump(),
|
||||||
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
upload_date=strftime("%Y-%m-%d %H:%M:%S"),
|
owner_id=owner_id)
|
||||||
owner_id=user_id)
|
await GamesCRUD.change_genres(db, game, info)
|
||||||
return await add_transaction(db, game)
|
return await Database.add(db, game)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change(db: AsyncSession,
|
||||||
|
id: int,
|
||||||
|
info: sch.GameCreate):
|
||||||
|
return await Database.change(db, mdl.Game, id, info, GamesCRUD.change_genres)
|
||||||
|
|
||||||
async def edit_game(db: AsyncSession,
|
@staticmethod
|
||||||
game_id: int,
|
async def delete(db: AsyncSession,
|
||||||
game_info: sch.GameCreate):
|
id: int):
|
||||||
game = await db.get(mdl.Game, game_id)
|
return await Database.delete(db, mdl.Game, id)
|
||||||
for key, value in vars(game_info).items():
|
|
||||||
if (getattr(game, key) != value):
|
|
||||||
setattr(game, key, value)
|
|
||||||
setattr(game, "update_date", strftime("%Y-%m-%d %H:%M:%S"))
|
|
||||||
await db.commit()
|
|
||||||
return game
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_game(db: AsyncSession,
|
|
||||||
game_id: int):
|
|
||||||
game = await get_game(db, game_id)
|
|
||||||
await db.delete(game)
|
|
||||||
await db.commit()
|
|
||||||
return game
|
|
||||||
|
|||||||
19
database/crud/movie_actors.py
Normal file
19
database/crud/movie_actors.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
|
||||||
|
|
||||||
|
class MovieActorsCRUD(EntityCRUD[mdl.MovieActor]):
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.MovieActor)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def add(db: AsyncSession,
|
||||||
|
info: sch.MovieActorCreate):
|
||||||
|
movie_actor = mdl.MovieActor(**info.model_dump())
|
||||||
|
return await Database.add(db, movie_actor)
|
||||||
19
database/crud/movie_genres.py
Normal file
19
database/crud/movie_genres.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
|
||||||
|
|
||||||
|
class MovieGenresCRUD(EntityCRUD[mdl.MovieGenre]):
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.MovieGenre)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def add(db: AsyncSession,
|
||||||
|
info: sch.MovieGenreCreate):
|
||||||
|
movie_genre = mdl.MovieGenre(**info.model_dump())
|
||||||
|
return await Database.add(db, movie_genre)
|
||||||
@@ -1,45 +1,58 @@
|
|||||||
from time import strftime
|
from time import strftime
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
|
||||||
|
from database.crud.movie_actors import MovieActorsCRUD
|
||||||
|
from database.crud.movie_genres import MovieGenresCRUD
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
from .. import models as mdl
|
from .. import models as mdl
|
||||||
from .. import schemas as sch
|
from .. import schemas as sch
|
||||||
from ..database import add_transaction
|
|
||||||
|
|
||||||
|
|
||||||
async def get_movies(db: AsyncSession):
|
class MoviesCRUD(EntityCRUD[mdl.Movie]):
|
||||||
return (await db.execute(select(mdl.Movie))).scalars().all()
|
@staticmethod
|
||||||
|
async def get(db: AsyncSession, id: int):
|
||||||
|
return await Database.get(db, mdl.Movie, id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.Movie)
|
||||||
|
|
||||||
async def get_movie(db: AsyncSession, movie_id: int):
|
@staticmethod
|
||||||
return await db.get(mdl.Movie, movie_id)
|
async def change_actors(db: AsyncSession, movie: mdl.Movie, info: sch.MovieCreate):
|
||||||
|
movie_actors = await MovieActorsCRUD.get_all(db)
|
||||||
|
if (info.actors):
|
||||||
|
movie.actors = [
|
||||||
|
actor for actor in movie_actors if actor.id in info.actors]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change_genres(db: AsyncSession, movie: mdl.Movie, info: sch.MovieCreate):
|
||||||
|
movie_genres = await MovieGenresCRUD.get_all(db)
|
||||||
|
if (info.genres):
|
||||||
|
movie.genres = [
|
||||||
|
genre for genre in movie_genres if genre.id in info.genres]
|
||||||
|
|
||||||
async def add_movie(db: AsyncSession,
|
@staticmethod
|
||||||
movie_info: sch.MovieCreate,
|
async def add(db: AsyncSession,
|
||||||
user_id: int):
|
info: sch.MovieCreate,
|
||||||
movie = mdl.Movie(**movie_info.model_dump(),
|
owner_id: int):
|
||||||
|
movie = mdl.Movie(**info.model_dump(),
|
||||||
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
upload_date=strftime("%Y-%m-%d %H:%M:%S"),
|
owner_id=owner_id)
|
||||||
owner_id=user_id)
|
await MoviesCRUD.change_genres(db, movie, info)
|
||||||
return await add_transaction(db, movie)
|
await MoviesCRUD.change_actors(db, movie, info)
|
||||||
|
return await Database.add(db, movie)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change(db: AsyncSession,
|
||||||
|
id: int,
|
||||||
|
info: sch.MovieCreate):
|
||||||
|
async def additional_change(db: AsyncSession, movie: mdl.Movie, info: sch.MovieCreate):
|
||||||
|
await MoviesCRUD.change_genres(db, movie, info)
|
||||||
|
await MoviesCRUD.change_actors(db, movie, info)
|
||||||
|
return await Database.change(db, mdl.Movie, id, info, additional_change)
|
||||||
|
|
||||||
async def edit_movie(db: AsyncSession,
|
@staticmethod
|
||||||
movie_id: int,
|
async def delete(db: AsyncSession,
|
||||||
movie_info: sch.MovieCreate):
|
id: int):
|
||||||
movie = await db.get(mdl.Movie, movie_id)
|
return await Database.delete(db, mdl.Movie, id)
|
||||||
for key, value in vars(movie_info).items():
|
|
||||||
if (getattr(movie, key) != value):
|
|
||||||
setattr(movie, key, value)
|
|
||||||
setattr(movie, "update_date", strftime("%Y-%m-%d %H:%M:%S"))
|
|
||||||
await db.commit()
|
|
||||||
return movie
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_movie(db: AsyncSession,
|
|
||||||
movie_id: int):
|
|
||||||
movie = await get_movie(db, movie_id)
|
|
||||||
await db.delete(movie)
|
|
||||||
await db.commit()
|
|
||||||
return movie
|
|
||||||
|
|||||||
@@ -1,25 +1,44 @@
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.future import select
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from database.database import Database, EntityCRUD
|
||||||
|
|
||||||
from .. import models as mdl
|
from .. import models as mdl
|
||||||
from .. import schemas as sch
|
from .. import schemas as sch
|
||||||
from ..database import add_transaction
|
|
||||||
|
|
||||||
|
|
||||||
async def get_user(db: AsyncSession, username: str):
|
class UsersCRUD(EntityCRUD[mdl.User]):
|
||||||
|
@staticmethod
|
||||||
|
async def get(db: AsyncSession, username: str):
|
||||||
return (await db.execute(select(mdl.User).where(mdl.User.name == username))).scalar()
|
return (await db.execute(select(mdl.User).where(mdl.User.name == username))).scalar()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_all(db: AsyncSession):
|
||||||
|
return await Database.get_all(db, mdl.User)
|
||||||
|
|
||||||
async def add_user(db: AsyncSession,
|
@staticmethod
|
||||||
user_data: sch.UserCreate, hash_of_password: str):
|
async def add(db: AsyncSession,
|
||||||
|
info: sch.UserCreate,
|
||||||
|
hash_of_password: str):
|
||||||
user_data_db = \
|
user_data_db = \
|
||||||
{k: v for k, v in user_data.model_dump().items()
|
{k: v for k, v in info.model_dump().items()
|
||||||
if k != "password"}
|
if k != "password"}
|
||||||
user = mdl.User(**user_data_db,
|
user = mdl.User(**user_data_db,
|
||||||
hash_of_password=hash_of_password)
|
hash_of_password=hash_of_password)
|
||||||
return await add_transaction(db, user)
|
return await Database.add(db, user)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change(db: AsyncSession,
|
||||||
|
id: int,
|
||||||
|
info: sch.UserCreate):
|
||||||
|
return await Database.change(db, mdl.User, id, info)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def delete_user(db: AsyncSession,
|
||||||
|
id: int):
|
||||||
|
return await Database.delete(db, mdl.User, id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def check_email(db: AsyncSession, email: str):
|
async def check_email(db: AsyncSession, email: str):
|
||||||
users = (await db.execute(select(mdl.User)
|
users = (await db.execute(select(mdl.User)
|
||||||
.where(mdl.User.email == email))).scalars().all()
|
.where(mdl.User.email == email))).scalars().all()
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from time import strftime
|
||||||
|
from typing import Any, Callable, Coroutine, Generic, Type
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.future import select
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
||||||
|
|
||||||
@@ -15,27 +19,37 @@ async_session = sessionmaker( # type: ignore
|
|||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
class Database:
|
||||||
|
@staticmethod
|
||||||
async def get_session() -> AsyncSession: # type: ignore
|
async def get_session() -> AsyncSession: # type: ignore
|
||||||
async with async_session() as session: # type: ignore
|
async with async_session() as session: # type: ignore
|
||||||
yield session # type: ignore
|
yield session # type: ignore
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def drop_all():
|
async def drop_all():
|
||||||
async with engine.begin() as conn:
|
async with engine.begin() as conn:
|
||||||
await conn.run_sync(Base.metadata.drop_all)
|
await conn.run_sync(Base.metadata.drop_all)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def create_all():
|
async def create_all():
|
||||||
async with engine.begin() as conn:
|
async with engine.begin() as conn:
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def recreate_all():
|
async def recreate_all():
|
||||||
await drop_all()
|
await Database.drop_all()
|
||||||
await create_all()
|
await Database.create_all()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get[T](db: AsyncSession, typeof_entity: Type[T], entity_id: int) -> T | None:
|
||||||
|
return await db.get(typeof_entity, entity_id)
|
||||||
|
|
||||||
async def add_transaction[T](db: AsyncSession, entity: T) -> T:
|
@staticmethod
|
||||||
|
async def get_all[T](db: AsyncSession, typeof_entity: Type[T]) -> list[T]:
|
||||||
|
return list((await db.execute(select(typeof_entity))).scalars().all())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def add[T](db: AsyncSession, entity: T) -> T:
|
||||||
try:
|
try:
|
||||||
db.add(entity)
|
db.add(entity)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
@@ -44,3 +58,64 @@ async def add_transaction[T](db: AsyncSession, entity: T) -> T:
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
await db.rollback()
|
await db.rollback()
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def change[T, U](db: AsyncSession, typeof_entity: Type[T],
|
||||||
|
entity_id: int, info: U,
|
||||||
|
additional_change: Callable[[AsyncSession, T, U], Coroutine[Any, Any, None]] | None = None) -> T:
|
||||||
|
try:
|
||||||
|
entity = await db.get(typeof_entity, entity_id)
|
||||||
|
if (entity is None):
|
||||||
|
raise ValueError(f"Can't change entity. " +
|
||||||
|
f"{str(typeof_entity)} with id={entity_id} not found")
|
||||||
|
for key, value in vars(info).items():
|
||||||
|
try:
|
||||||
|
if (getattr(entity, key) != value):
|
||||||
|
setattr(entity, key, value)
|
||||||
|
except:
|
||||||
|
...
|
||||||
|
setattr(entity, "update_date", strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
|
if (additional_change):
|
||||||
|
await additional_change(db, entity, info)
|
||||||
|
await db.commit()
|
||||||
|
return entity
|
||||||
|
except Exception as ex:
|
||||||
|
await db.rollback()
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def delete[T](db: AsyncSession, typeof_entity: Type[T], entity_id: int) -> T:
|
||||||
|
try:
|
||||||
|
entity = await db.get(typeof_entity, entity_id)
|
||||||
|
if (entity is None):
|
||||||
|
raise ValueError(f"Can't delete entity. " +
|
||||||
|
f"{str(typeof_entity)} with id={entity_id} not found")
|
||||||
|
await db.delete(entity)
|
||||||
|
await db.commit()
|
||||||
|
return entity
|
||||||
|
except Exception as ex:
|
||||||
|
await db.rollback()
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
|
||||||
|
class EntityCRUD[T](ABC):
|
||||||
|
@staticmethod
|
||||||
|
@abstractmethod
|
||||||
|
async def get(db: AsyncSession, id: int) -> T | None: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@abstractmethod
|
||||||
|
async def get_all(db: AsyncSession) -> list[T]: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@abstractmethod
|
||||||
|
async def add(db: AsyncSession, entity: T,
|
||||||
|
owner_id: int | None = None) -> T: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@abstractmethod
|
||||||
|
async def change(db: AsyncSession, entity_id: int, info: object) -> T: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@abstractmethod
|
||||||
|
async def delete(db: AsyncSession, entity_id: int) -> T: ...
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class AudiobookGenre(Base):
|
|||||||
genre = Column(String, nullable=False, unique=True)
|
genre = Column(String, nullable=False, unique=True)
|
||||||
|
|
||||||
audiobooks = relationship("Audiobook", secondary="audiobook_to_genre",
|
audiobooks = relationship("Audiobook", secondary="audiobook_to_genre",
|
||||||
lazy="selectin")
|
lazy="selectin", viewonly=True)
|
||||||
|
|
||||||
|
|
||||||
class AudiobookToGenre(Base):
|
class AudiobookToGenre(Base):
|
||||||
|
|||||||
@@ -27,3 +27,4 @@ class Audiobook(Base):
|
|||||||
lazy="selectin")
|
lazy="selectin")
|
||||||
|
|
||||||
owner_id = Column(Integer, ForeignKey("users.id"))
|
owner_id = Column(Integer, ForeignKey("users.id"))
|
||||||
|
owner = relationship("User", lazy="selectin", viewonly=True)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class GameGenre(Base):
|
|||||||
genre = Column(String, nullable=False, unique=True)
|
genre = Column(String, nullable=False, unique=True)
|
||||||
|
|
||||||
games = relationship("Game", secondary="game_to_genre",
|
games = relationship("Game", secondary="game_to_genre",
|
||||||
lazy="selectin")
|
lazy="selectin", viewonly=True)
|
||||||
|
|
||||||
|
|
||||||
class GameToGenre(Base):
|
class GameToGenre(Base):
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class MovieActor(Base):
|
|||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
actor = Column(String, nullable=False, unique=True)
|
actor = Column(String, nullable=False, unique=True)
|
||||||
|
|
||||||
movies = relationship("Movies", secondary="movie_to_actor",
|
movies = relationship("Movie", secondary="movie_to_actor",
|
||||||
lazy="selectin")
|
lazy="selectin", viewonly=True)
|
||||||
|
|
||||||
|
|
||||||
class MovieToActor(Base):
|
class MovieToActor(Base):
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ class MovieGenre(Base):
|
|||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
genre = Column(String, nullable=False, unique=True)
|
genre = Column(String, nullable=False, unique=True)
|
||||||
|
|
||||||
movies = relationship("Movies", secondary="movie_to_genre",
|
movies = relationship("Movie", secondary="movie_to_genre",
|
||||||
lazy="selectin")
|
lazy="selectin", viewonly=True)
|
||||||
|
|
||||||
|
|
||||||
class MovieToGenre(Base):
|
class MovieToGenre(Base):
|
||||||
|
|||||||
@@ -32,3 +32,4 @@ class Movie(Base):
|
|||||||
lazy="selectin")
|
lazy="selectin")
|
||||||
|
|
||||||
owner_id = Column(Integer, ForeignKey("users.id"))
|
owner_id = Column(Integer, ForeignKey("users.id"))
|
||||||
|
owner = relationship("User", lazy="selectin", viewonly=True)
|
||||||
|
|||||||
9
main.py
9
main.py
@@ -13,10 +13,19 @@ app = FastAPI(
|
|||||||
"url": "https://github.com/StepanovPlaton"
|
"url": "https://github.com/StepanovPlaton"
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
app.include_router(startup_router)
|
app.include_router(startup_router)
|
||||||
|
|
||||||
app.include_router(games_router)
|
app.include_router(games_router)
|
||||||
|
app.include_router(game_genres_router)
|
||||||
|
|
||||||
app.include_router(movies_router)
|
app.include_router(movies_router)
|
||||||
|
app.include_router(movie_actors_router)
|
||||||
|
app.include_router(movie_genres_router)
|
||||||
|
|
||||||
app.include_router(audiobooks_router)
|
app.include_router(audiobooks_router)
|
||||||
|
app.include_router(audiobook_genres_router)
|
||||||
|
|
||||||
app.include_router(files_router)
|
app.include_router(files_router)
|
||||||
app.include_router(auth_router)
|
app.include_router(auth_router)
|
||||||
app.mount("/content", StaticFiles(directory="content"), name="content")
|
app.mount("/content", StaticFiles(directory="content"), name="content")
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
from .games import games_router as games_router
|
from .games import games_router as games_router
|
||||||
|
from .game_genres import game_genres_router as game_genres_router
|
||||||
|
|
||||||
from .movies import movies_router as movies_router
|
from .movies import movies_router as movies_router
|
||||||
|
from .movie_actors import movie_actors_router as movie_actors_router
|
||||||
|
from .movie_genres import movie_genres_router as movie_genres_router
|
||||||
|
|
||||||
from .audiobooks import audiobooks_router as audiobooks_router
|
from .audiobooks import audiobooks_router as audiobooks_router
|
||||||
|
from .audiobook_genres import audiobook_genres_router as audiobook_genres_router
|
||||||
|
|
||||||
from .files import files_router as files_router
|
from .files import files_router as files_router
|
||||||
from .startup import startup_router as startup_router
|
from .startup import startup_router as startup_router
|
||||||
from .auth import auth_router as auth_router
|
from .auth import auth_router as auth_router
|
||||||
|
|||||||
22
routes/audiobook_genres.py
Normal file
22
routes/audiobook_genres.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
from database import *
|
||||||
|
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
audiobook_genres_router = APIRouter(
|
||||||
|
prefix="/genres/audiobooks", tags=["Audiobooks", "Genres"])
|
||||||
|
|
||||||
|
|
||||||
|
@audiobook_genres_router.get("", response_model=list[AudiobookGenre])
|
||||||
|
async def get_audiobook_genres(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await AudiobookGenresCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@audiobook_genres_router.post("", response_model=AudiobookGenre)
|
||||||
|
async def add_audiobook_genre(genre: AudiobookGenreCreate,
|
||||||
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await AudiobookGenresCRUD.add(db_session, genre)
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
import database as db
|
from database import *
|
||||||
from file_handler import *
|
from file_handler import *
|
||||||
from routes.auth import get_user
|
from routes.auth import get_user
|
||||||
|
|
||||||
audiobooks_router = APIRouter(prefix="/audiobooks", tags=["Audiobooks"])
|
audiobooks_router = APIRouter(prefix="/audiobooks", tags=["Audiobooks"])
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.get("", response_model=list[db.Audiobook])
|
@audiobooks_router.get("/{audiobook_id}", response_model=Audiobook)
|
||||||
async def get_audiobooks(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_audiobook(audiobook_id: int, db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_audiobooks(db_session)
|
return await AudiobooksCRUD.get(db_session, audiobook_id)
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.post("", response_model=db.Audiobook)
|
@audiobooks_router.get("/cards", response_model=list[AudiobookCard])
|
||||||
async def add_audiobook(audiobook: db.AudiobookCreate,
|
async def get_audiobooks_cards(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
user: db.User = Depends(get_user),
|
return await AudiobooksCRUD.get_all(db_session)
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
|
||||||
return await db.add_audiobook(db_session, audiobook, user.id)
|
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.get("/cards", response_model=list[db.AudiobookCard])
|
@audiobooks_router.get("", response_model=list[Audiobook])
|
||||||
async def get_audiobooks_cards(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_audiobooks(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_audiobooks(db_session)
|
return await AudiobooksCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.get("/{audiobook_id}", response_model=db.Audiobook)
|
@audiobooks_router.post("", response_model=Audiobook)
|
||||||
async def get_audiobook(audiobook_id: int, db_session: AsyncSession = Depends(db.get_session)):
|
async def add_audiobook(audiobook: AudiobookCreate,
|
||||||
return await db.get_audiobook(db_session, audiobook_id)
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await AudiobooksCRUD.add(db_session, audiobook, user.id)
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.put("/{audiobook_id}", response_model=db.Audiobook)
|
@audiobooks_router.put("/{audiobook_id}", response_model=Audiobook)
|
||||||
async def edit_audiobook(audiobook_id: int,
|
async def edit_audiobook(audiobook_id: int,
|
||||||
audiobook: db.AudiobookCreate,
|
audiobook: AudiobookCreate,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
audiobook_db = await db.get_audiobook(db_session, audiobook_id)
|
audiobook_db = await AudiobooksCRUD.get(db_session, audiobook_id)
|
||||||
if (audiobook_db is None):
|
if (audiobook_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Audiobook with id={audiobook_id} not found")
|
detail=f"Audiobook with id={audiobook_id} not found")
|
||||||
@@ -43,14 +43,14 @@ async def edit_audiobook(audiobook_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Audiobook can only be edited "
|
detail=f"Audiobook can only be edited "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.edit_audiobook(db_session, audiobook_id, audiobook)
|
return await AudiobooksCRUD.change(db_session, audiobook_id, audiobook)
|
||||||
|
|
||||||
|
|
||||||
@audiobooks_router.delete("/{audiobook_id}", response_model=db.Audiobook)
|
@audiobooks_router.delete("/{audiobook_id}", response_model=Audiobook)
|
||||||
async def delete_audiobook(audiobook_id: int,
|
async def delete_audiobook(audiobook_id: int,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
audiobook_db = await db.get_audiobook(db_session, audiobook_id)
|
audiobook_db = await AudiobooksCRUD.get(db_session, audiobook_id)
|
||||||
if (audiobook_db is None):
|
if (audiobook_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Audiobook with id={audiobook_id} not found")
|
detail=f"Audiobook with id={audiobook_id} not found")
|
||||||
@@ -58,4 +58,4 @@ async def delete_audiobook(audiobook_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Audiobook can only be deleted "
|
detail=f"Audiobook can only be deleted "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.delete_audiobook(db_session, audiobook_id)
|
return await AudiobooksCRUD.delete(db_session, audiobook_id)
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
from typing import Annotated, Any
|
|
||||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from fastapi import APIRouter, Depends, status, HTTPException
|
from fastapi import APIRouter, Depends, status, HTTPException
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from jose import JWTError, jwt
|
from jose import jwt
|
||||||
|
|
||||||
import database as db
|
from database import *
|
||||||
from env import Env
|
from env import Env
|
||||||
|
|
||||||
SECRET_KEY = Env.get_strict("JWT_SECRET_KEY", str)
|
SECRET_KEY = Env.get_strict("JWT_SECRET_KEY", str)
|
||||||
@@ -36,7 +35,7 @@ def get_hash(password): return crypt.hash(password)
|
|||||||
|
|
||||||
|
|
||||||
async def get_user(token: str = Depends(oauth2_scheme),
|
async def get_user(token: str = Depends(oauth2_scheme),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
credentials_exception = HTTPException(
|
credentials_exception = HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="Could not validate credentials",
|
detail="Could not validate credentials",
|
||||||
@@ -48,13 +47,13 @@ async def get_user(token: str = Depends(oauth2_scheme),
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
user = await db.get_user(db_session, token_data.username)
|
user = await UsersCRUD.get(db_session, token_data.username)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def create_token(user: db.User):
|
def create_token(user: User):
|
||||||
access_token_expires = \
|
access_token_expires = \
|
||||||
timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||||
expire = datetime.now(timezone.utc) + access_token_expires
|
expire = datetime.now(timezone.utc) + access_token_expires
|
||||||
@@ -70,23 +69,23 @@ def create_token(user: db.User):
|
|||||||
|
|
||||||
@auth_router.post("/registration")
|
@auth_router.post("/registration")
|
||||||
async def registration_user(
|
async def registration_user(
|
||||||
user_data: db.UserCreate,
|
user_data: UserCreate,
|
||||||
db_session: AsyncSession = Depends(db.get_session)
|
db_session: AsyncSession = Depends(Database.get_session)
|
||||||
) -> Token:
|
) -> Token:
|
||||||
if (not await db.check_email(db_session, user_data.email)):
|
if (not await UsersCRUD.check_email(db_session, user_data.email)):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="This email is occupied by another user",
|
detail="This email is occupied by another user",
|
||||||
headers={"WWW-Authenticate": "Bearer"},
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
)
|
)
|
||||||
elif (await db.get_user(db_session, user_data.name) is not None):
|
elif (await UsersCRUD.get(db_session, user_data.name) is not None):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail="User with the same name already exists",
|
detail="User with the same name already exists",
|
||||||
headers={"WWW-Authenticate": "Bearer"},
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
user = await db.add_user(db_session, user_data,
|
user = await UsersCRUD.add(db_session, user_data,
|
||||||
get_hash(user_data.password))
|
get_hash(user_data.password))
|
||||||
return create_token(user)
|
return create_token(user)
|
||||||
|
|
||||||
@@ -94,9 +93,9 @@ async def registration_user(
|
|||||||
@auth_router.post("")
|
@auth_router.post("")
|
||||||
async def login_user(
|
async def login_user(
|
||||||
auth_data: OAuth2PasswordRequestForm = Depends(),
|
auth_data: OAuth2PasswordRequestForm = Depends(),
|
||||||
db_session: AsyncSession = Depends(db.get_session)
|
db_session: AsyncSession = Depends(Database.get_session)
|
||||||
) -> Token:
|
) -> Token:
|
||||||
user = await db.get_user(db_session, auth_data.username)
|
user = await UsersCRUD.get(db_session, auth_data.username)
|
||||||
if (user is None):
|
if (user is None):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
@@ -112,6 +111,6 @@ async def login_user(
|
|||||||
return create_token(user)
|
return create_token(user)
|
||||||
|
|
||||||
|
|
||||||
@auth_router.get("/me", response_model=db.UserOpenData)
|
@auth_router.get("/me", response_model=UserOpenData)
|
||||||
async def read_me(user: db.User = Depends(get_user)):
|
async def read_me(user: User = Depends(get_user)):
|
||||||
return user
|
return user
|
||||||
|
|||||||
22
routes/game_genres.py
Normal file
22
routes/game_genres.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
from database import *
|
||||||
|
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
game_genres_router = APIRouter(
|
||||||
|
prefix="/genres/games", tags=["Games", "Genres"])
|
||||||
|
|
||||||
|
|
||||||
|
@game_genres_router.get("", response_model=list[GameGenre])
|
||||||
|
async def get_game_genres(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await GameGenresCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@game_genres_router.post("", response_model=GameGenre)
|
||||||
|
async def add_game_genre(genre: GameGenreCreate,
|
||||||
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await GameGenresCRUD.add(db_session, genre)
|
||||||
@@ -1,41 +1,42 @@
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
import database as db
|
from database import *
|
||||||
|
|
||||||
from file_handler import *
|
from file_handler import *
|
||||||
from routes.auth import get_user
|
from routes.auth import get_user
|
||||||
|
|
||||||
games_router = APIRouter(prefix="/games", tags=["Games"])
|
games_router = APIRouter(prefix="/games", tags=["Games"])
|
||||||
|
|
||||||
|
|
||||||
@games_router.get("", response_model=list[db.Game])
|
@games_router.get("/{game_id}", response_model=Game)
|
||||||
async def get_games(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_game(game_id: int, db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_games(db_session)
|
return await GamesCRUD.get(db_session, game_id)
|
||||||
|
|
||||||
|
|
||||||
@games_router.post("", response_model=db.Game)
|
@games_router.get("/cards", response_model=list[GameCard])
|
||||||
async def add_game(game: db.GameCreate,
|
async def get_games_cards(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
user: db.User = Depends(get_user),
|
return await GamesCRUD.get_all(db_session)
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
|
||||||
return await db.add_game(db_session, game, user.id)
|
|
||||||
|
|
||||||
|
|
||||||
@games_router.get("/cards", response_model=list[db.GameCard])
|
@games_router.get("", response_model=list[Game])
|
||||||
async def get_games_cards(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_games(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_games(db_session)
|
return await GamesCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
@games_router.get("/{game_id}", response_model=db.Game)
|
@games_router.post("", response_model=Game)
|
||||||
async def get_game(game_id: int, db_session: AsyncSession = Depends(db.get_session)):
|
async def add_game(game: GameCreate,
|
||||||
return await db.get_game(db_session, game_id)
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await GamesCRUD.add(db_session, game, user.id)
|
||||||
|
|
||||||
|
|
||||||
@games_router.put("/{game_id}", response_model=db.Game)
|
@games_router.put("/{game_id}", response_model=Game)
|
||||||
async def edit_game(game_id: int,
|
async def edit_game(game_id: int,
|
||||||
game: db.GameCreate,
|
game: GameCreate,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
game_db = await db.get_game(db_session, game_id)
|
game_db = await GamesCRUD.get(db_session, game_id)
|
||||||
if (game_db is None):
|
if (game_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Game with id={game_id} not found")
|
detail=f"Game with id={game_id} not found")
|
||||||
@@ -43,14 +44,14 @@ async def edit_game(game_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Game can only be edited "
|
detail=f"Game can only be edited "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.edit_game(db_session, game_id, game)
|
return await GamesCRUD.change(db_session, game_id, game)
|
||||||
|
|
||||||
|
|
||||||
@games_router.delete("/{game_id}", response_model=db.Game)
|
@games_router.delete("/{game_id}", response_model=Game)
|
||||||
async def delete_game(game_id: int,
|
async def delete_game(game_id: int,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
game_db = await db.get_game(db_session, game_id)
|
game_db = await GamesCRUD.get(db_session, game_id)
|
||||||
if (game_db is None):
|
if (game_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Game with id={game_id} not found")
|
detail=f"Game with id={game_id} not found")
|
||||||
@@ -58,4 +59,4 @@ async def delete_game(game_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Game can only be deleted "
|
detail=f"Game can only be deleted "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.delete_game(db_session, game_id)
|
return await GamesCRUD.delete(db_session, game_id)
|
||||||
|
|||||||
22
routes/movie_actors.py
Normal file
22
routes/movie_actors.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
from database import *
|
||||||
|
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
movie_actors_router = APIRouter(
|
||||||
|
prefix="/actors", tags=["Movies", "Actors"])
|
||||||
|
|
||||||
|
|
||||||
|
@movie_actors_router.get("", response_model=list[MovieActor])
|
||||||
|
async def get_movie_actors(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await MovieActorsCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@movie_actors_router.post("", response_model=MovieActor)
|
||||||
|
async def add_movie_actor(actor: MovieActorCreate,
|
||||||
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await MovieActorsCRUD.add(db_session, actor)
|
||||||
22
routes/movie_genres.py
Normal file
22
routes/movie_genres.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
from database import *
|
||||||
|
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
movie_genres_router = APIRouter(
|
||||||
|
prefix="/genres/movies", tags=["Movies", "Genres"])
|
||||||
|
|
||||||
|
|
||||||
|
@movie_genres_router.get("", response_model=list[MovieGenre])
|
||||||
|
async def get_movie_genres(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await MovieGenresCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@movie_genres_router.post("", response_model=MovieGenre)
|
||||||
|
async def add_movie_genre(genre: MovieGenreCreate,
|
||||||
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await MovieGenresCRUD.add(db_session, genre)
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
import database as db
|
from database import *
|
||||||
from file_handler import *
|
from file_handler import *
|
||||||
from routes.auth import get_user
|
from routes.auth import get_user
|
||||||
|
|
||||||
movies_router = APIRouter(prefix="/movies", tags=["Movies"])
|
movies_router = APIRouter(prefix="/movies", tags=["Movies"])
|
||||||
|
|
||||||
|
|
||||||
@movies_router.get("", response_model=list[db.Movie])
|
@movies_router.get("/{movie_id}", response_model=Movie)
|
||||||
async def get_movies(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_movie(movie_id: int, db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_movies(db_session)
|
return await MoviesCRUD.get(db_session, movie_id)
|
||||||
|
|
||||||
|
|
||||||
@movies_router.post("", response_model=db.Movie)
|
@movies_router.get("/cards", response_model=list[MovieCard])
|
||||||
async def add_movie(movie: db.MovieCreate,
|
async def get_movies_cards(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
user: db.User = Depends(get_user),
|
return await MoviesCRUD.get_all(db_session)
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
|
||||||
return await db.add_movie(db_session, movie, user.id)
|
|
||||||
|
|
||||||
|
|
||||||
@movies_router.get("/cards", response_model=list[db.MovieCard])
|
@movies_router.get("", response_model=list[Movie])
|
||||||
async def get_movies_cards(db_session: AsyncSession = Depends(db.get_session)):
|
async def get_movies(db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
return await db.get_movies(db_session)
|
return await MoviesCRUD.get_all(db_session)
|
||||||
|
|
||||||
|
|
||||||
@movies_router.get("/{movie_id}", response_model=db.Movie)
|
@movies_router.post("", response_model=Movie)
|
||||||
async def get_movie(movie_id: int, db_session: AsyncSession = Depends(db.get_session)):
|
async def add_movie(movie: MovieCreate,
|
||||||
return await db.get_movie(db_session, movie_id)
|
user: User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
|
return await MoviesCRUD.add(db_session, movie, user.id)
|
||||||
|
|
||||||
|
|
||||||
@movies_router.put("/{movie_id}", response_model=db.Movie)
|
@movies_router.put("/{movie_id}", response_model=Movie)
|
||||||
async def edit_movie(movie_id: int,
|
async def edit_movie(movie_id: int,
|
||||||
movie: db.MovieCreate,
|
movie: MovieCreate,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
movie_db = await db.get_movie(db_session, movie_id)
|
movie_db = await MoviesCRUD.get(db_session, movie_id)
|
||||||
if (movie_db is None):
|
if (movie_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Movie with id={movie_id} not found")
|
detail=f"Movie with id={movie_id} not found")
|
||||||
@@ -43,14 +43,14 @@ async def edit_movie(movie_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Movie can only be edited "
|
detail=f"Movie can only be edited "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.edit_movie(db_session, movie_id, movie)
|
return await MoviesCRUD.change(db_session, movie_id, movie)
|
||||||
|
|
||||||
|
|
||||||
@movies_router.delete("/{movie_id}", response_model=db.Movie)
|
@movies_router.delete("/{movie_id}", response_model=Movie)
|
||||||
async def delete_movie(movie_id: int,
|
async def delete_movie(movie_id: int,
|
||||||
user: db.User = Depends(get_user),
|
user: User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(Database.get_session)):
|
||||||
movie_db = await db.get_movie(db_session, movie_id)
|
movie_db = await MoviesCRUD.get(db_session, movie_id)
|
||||||
if (movie_db is None):
|
if (movie_db is None):
|
||||||
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
detail=f"Movie with id={movie_id} not found")
|
detail=f"Movie with id={movie_id} not found")
|
||||||
@@ -58,4 +58,4 @@ async def delete_movie(movie_id: int,
|
|||||||
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=f"Movie can only be deleted "
|
detail=f"Movie can only be deleted "
|
||||||
"by the owner (creator)")
|
"by the owner (creator)")
|
||||||
return await db.delete_movie(db_session, movie_id)
|
return await MoviesCRUD.delete(db_session, movie_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user