mirror of
https://github.com/StepanovPlaton/torrent_backend.git
synced 2026-04-03 12:20:38 +04:00
Add audiobooks
This commit is contained in:
@@ -1,2 +1,4 @@
|
|||||||
from .games import *
|
from .games import *
|
||||||
|
from .movies import *
|
||||||
|
from .audiobooks import *
|
||||||
from .users import *
|
from .users import *
|
||||||
|
|||||||
45
database/crud/audiobooks.py
Normal file
45
database/crud/audiobooks.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
from ..database import add_transaction
|
||||||
|
|
||||||
|
|
||||||
|
async def get_audiobooks(db: AsyncSession):
|
||||||
|
return (await db.execute(select(mdl.Audiobook))).scalars().all()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_audiobook(db: AsyncSession, audiobook_id: int):
|
||||||
|
return await db.get(mdl.Audiobook, audiobook_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def add_audiobook(db: AsyncSession,
|
||||||
|
audiobook_info: sch.AudiobookCreate,
|
||||||
|
user_id: int):
|
||||||
|
audiobook = mdl.Audiobook(**audiobook_info.model_dump(),
|
||||||
|
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
upload_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
owner_id=user_id)
|
||||||
|
return await add_transaction(db, audiobook)
|
||||||
|
|
||||||
|
|
||||||
|
async def edit_audiobook(db: AsyncSession,
|
||||||
|
audiobook_id: int,
|
||||||
|
audiobook_info: sch.AudiobookCreate):
|
||||||
|
audiobook = await db.get(mdl.Audiobook, audiobook_id)
|
||||||
|
for key, value in vars(audiobook_info).items():
|
||||||
|
if (value and value is not None and 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
|
||||||
@@ -32,6 +32,7 @@ async def edit_game(db: AsyncSession,
|
|||||||
for key, value in vars(game_info).items():
|
for key, value in vars(game_info).items():
|
||||||
if (value and value is not None and getattr(game, key) != value):
|
if (value and value is not None and getattr(game, key) != value):
|
||||||
setattr(game, key, value)
|
setattr(game, key, value)
|
||||||
|
setattr(game, "update_date", strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
await db.commit()
|
await db.commit()
|
||||||
return game
|
return game
|
||||||
|
|
||||||
|
|||||||
45
database/crud/movies.py
Normal file
45
database/crud/movies.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
from time import strftime
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from .. import models as mdl
|
||||||
|
from .. import schemas as sch
|
||||||
|
from ..database import add_transaction
|
||||||
|
|
||||||
|
|
||||||
|
async def get_movies(db: AsyncSession):
|
||||||
|
return (await db.execute(select(mdl.Movie))).scalars().all()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_movie(db: AsyncSession, movie_id: int):
|
||||||
|
return await db.get(mdl.Movie, movie_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def add_movie(db: AsyncSession,
|
||||||
|
movie_info: sch.MovieCreate,
|
||||||
|
user_id: int):
|
||||||
|
movie = mdl.Movie(**movie_info.model_dump(),
|
||||||
|
update_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
upload_date=strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
owner_id=user_id)
|
||||||
|
return await add_transaction(db, movie)
|
||||||
|
|
||||||
|
|
||||||
|
async def edit_movie(db: AsyncSession,
|
||||||
|
movie_id: int,
|
||||||
|
movie_info: sch.MovieCreate):
|
||||||
|
movie = await db.get(mdl.Movie, movie_id)
|
||||||
|
for key, value in vars(movie_info).items():
|
||||||
|
if (value and value is not None and 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,2 +1,4 @@
|
|||||||
from .games import Game as Game
|
from .games import Game as Game
|
||||||
from .users import User as User
|
from .movies import Movie as Movie
|
||||||
|
from .audiobooks import Audiobook as Audiobook
|
||||||
|
from .users import User as User
|
||||||
|
|||||||
26
database/models/audiobooks.py
Normal file
26
database/models/audiobooks.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from sqlalchemy import Column, ForeignKey, Integer, String
|
||||||
|
|
||||||
|
from ..database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class Audiobook(Base):
|
||||||
|
__tablename__ = "audiobooks"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
|
||||||
|
title = Column(String, nullable=False, unique=True)
|
||||||
|
cover = Column(String)
|
||||||
|
description = Column(String)
|
||||||
|
author = Column(String)
|
||||||
|
|
||||||
|
torrent_file = Column(String, nullable=False)
|
||||||
|
upload_date = Column(String, nullable=False)
|
||||||
|
fragment = Column(String)
|
||||||
|
update_date = Column(String, nullable=False)
|
||||||
|
language = Column(String)
|
||||||
|
release_date = Column(String)
|
||||||
|
download_size = Column(String)
|
||||||
|
duration = Column(String)
|
||||||
|
reader = Column(String)
|
||||||
|
|
||||||
|
owner_id = Column(Integer, ForeignKey("users.id"))
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
from sqlalchemy import Column, ForeignKey, Integer, String
|
from sqlalchemy import Column, ForeignKey, Integer, String
|
||||||
from sqlalchemy.orm import relationship
|
|
||||||
|
|
||||||
from ..database import Base
|
from ..database import Base
|
||||||
|
|
||||||
|
|||||||
28
database/models/movies.py
Normal file
28
database/models/movies.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from sqlalchemy import Column, ForeignKey, Integer, String
|
||||||
|
|
||||||
|
from ..database import Base
|
||||||
|
|
||||||
|
|
||||||
|
class Movie(Base):
|
||||||
|
__tablename__ = "movies"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
|
||||||
|
title = Column(String, nullable=False, unique=True)
|
||||||
|
cover = Column(String)
|
||||||
|
age = Column(String)
|
||||||
|
description = Column(String)
|
||||||
|
|
||||||
|
torrent_file = Column(String, nullable=False)
|
||||||
|
upload_date = Column(String, nullable=False)
|
||||||
|
trailer = Column(String)
|
||||||
|
update_date = Column(String, nullable=False)
|
||||||
|
language = Column(String)
|
||||||
|
subtitles = Column(String)
|
||||||
|
release_date = Column(String)
|
||||||
|
download_size = Column(String)
|
||||||
|
director = Column(String)
|
||||||
|
duration = Column(String)
|
||||||
|
country = Column(String)
|
||||||
|
|
||||||
|
owner_id = Column(Integer, ForeignKey("users.id"))
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
from .games import *
|
from .games import *
|
||||||
|
from .movies import *
|
||||||
|
from .audiobooks import *
|
||||||
from .users import *
|
from .users import *
|
||||||
|
|||||||
51
database/schemas/audiobooks.py
Normal file
51
database/schemas/audiobooks.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
|
|
||||||
|
class AudiobookCardBase(BaseModel):
|
||||||
|
title: str = Field(examples=["Марсианин"])
|
||||||
|
cover: Optional[str] = \
|
||||||
|
Field(default=None, examples=["cover_filename.jpg"])
|
||||||
|
description: Optional[str] = \
|
||||||
|
Field(default=None,
|
||||||
|
examples=["Главный герой оказался в сложнейшей ситуации."
|
||||||
|
" Его жизнь висела на волоске и зависела от"
|
||||||
|
" нескольких совершенно нелогичных факторов."
|
||||||
|
" Дело в том, что его бросили на Марсе в крайне"
|
||||||
|
" затруднительном для дальнейшей жизни положении."
|
||||||
|
" Рассчитывать стоит лишь на себя и на чудо,"
|
||||||
|
" ведь ультрасовременный скафандр оказался прошит"
|
||||||
|
" антенной, а до прибытия следующей экспедиции"
|
||||||
|
" остается целая вечность."])
|
||||||
|
author: Optional[str] = \
|
||||||
|
Field(default=None, examples=["Вейр Энди"])
|
||||||
|
|
||||||
|
|
||||||
|
class AudiobookCard(AudiobookCardBase):
|
||||||
|
id: int = Field(examples=[1])
|
||||||
|
|
||||||
|
|
||||||
|
class AudiobookBase(AudiobookCardBase):
|
||||||
|
torrent_file: str = Field(examples=["torrent_filename.torrent"])
|
||||||
|
fragment: Optional[str] = \
|
||||||
|
Field(default=None, examples=[
|
||||||
|
"fragment.mp3"])
|
||||||
|
|
||||||
|
language: Optional[str] = Field(default=None, examples=["рус"])
|
||||||
|
release_date: Optional[str] = Field(default=None, examples=["2015"])
|
||||||
|
download_size: Optional[str] = Field(default=None, examples=["300Mb"])
|
||||||
|
duration: Optional[str] = Field(default=None, examples=["12:38"])
|
||||||
|
reader: Optional[str] = Field(default=None, examples=["Дмитрий Хазанович"])
|
||||||
|
|
||||||
|
|
||||||
|
class AudiobookCreate(AudiobookBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Audiobook(AudiobookBase):
|
||||||
|
id: int = Field(examples=[1])
|
||||||
|
update_date: str = Field(examples=["2024-06-14 12:00:00"])
|
||||||
|
upload_date: str = Field(examples=["2024-06-14 12:00:00"])
|
||||||
|
owner_id: int = Field(examples=[1])
|
||||||
|
|
||||||
|
model_config = ConfigDict(from_attributes=True)
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
from fastapi import Body
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
|
|
||||||
class GameCardBase(BaseModel):
|
class GameCardBase(BaseModel):
|
||||||
title: str = Field(examples=["DwarfFortress", "RimWorld"])
|
title: str = Field(examples=["DwarfFortress"])
|
||||||
cover: Optional[str] = \
|
cover: Optional[str] = \
|
||||||
Field(default=None, examples=["cover_filename.jpg"])
|
Field(default=None, examples=["cover_filename.jpg"])
|
||||||
description: Optional[str] = \
|
description: Optional[str] = \
|
||||||
|
|||||||
55
database/schemas/movies.py
Normal file
55
database/schemas/movies.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
|
|
||||||
|
class MovieCardBase(BaseModel):
|
||||||
|
title: str = Field(examples=["Интерстеллар"])
|
||||||
|
cover: Optional[str] = \
|
||||||
|
Field(default=None, examples=["cover_filename.jpg"])
|
||||||
|
description: Optional[str] = \
|
||||||
|
Field(default=None,
|
||||||
|
examples=["Когда засуха, пыльные бури и вымирание"
|
||||||
|
" растений приводят человечество к"
|
||||||
|
" продовольственному кризису, коллектив"
|
||||||
|
" исследователей и учёных отправляется"
|
||||||
|
" сквозь червоточину (которая предположительно"
|
||||||
|
" соединяет области пространства-времени"
|
||||||
|
" через большое расстояние) в путешествие,"
|
||||||
|
" чтобы превзойти прежние ограничения для"
|
||||||
|
" космических путешествий человека и найти"
|
||||||
|
" планету с подходящими для человечества условиями."])
|
||||||
|
age: Optional[str] = \
|
||||||
|
Field(default=None, examples=["18+"])
|
||||||
|
|
||||||
|
|
||||||
|
class MovieCard(MovieCardBase):
|
||||||
|
id: int = Field(examples=[1])
|
||||||
|
|
||||||
|
|
||||||
|
class MovieBase(MovieCardBase):
|
||||||
|
torrent_file: str = Field(examples=["torrent_filename.torrent"])
|
||||||
|
trailer: Optional[str] = \
|
||||||
|
Field(default=None, examples=[
|
||||||
|
"https://www.youtube.com/watch?v=6ybBuTETr3U"])
|
||||||
|
|
||||||
|
language: Optional[str] = Field(default=None, examples=["рус"])
|
||||||
|
subtitles: Optional[str] = Field(default=None, examples=["Отсутствуют"])
|
||||||
|
release_date: Optional[str] = Field(default=None, examples=["2014"])
|
||||||
|
download_size: Optional[str] = Field(default=None, examples=["32Gb"])
|
||||||
|
director: Optional[str] = Field(default=None, examples=["Кристофер Нолан"])
|
||||||
|
duration: Optional[str] = Field(default=None, examples=["02:37:58"])
|
||||||
|
country: Optional[str] = \
|
||||||
|
Field(default=None, examples=["США, Великобритания, Канада"])
|
||||||
|
|
||||||
|
|
||||||
|
class MovieCreate(MovieBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Movie(MovieBase):
|
||||||
|
id: int = Field(examples=[1])
|
||||||
|
update_date: str = Field(examples=["2024-06-11 12:00:00"])
|
||||||
|
upload_date: str = Field(examples=["2024-06-11 12:00:00"])
|
||||||
|
owner_id: int = Field(examples=[1])
|
||||||
|
|
||||||
|
model_config = ConfigDict(from_attributes=True)
|
||||||
@@ -85,3 +85,25 @@ async def save_image(cover: UploadFile, type: Literal["cover", "screenshot"]):
|
|||||||
buf, format=cover.content_type.upper().replace("IMAGE/", ""))
|
buf, format=cover.content_type.upper().replace("IMAGE/", ""))
|
||||||
await preview_file.write(buf.getbuffer())
|
await preview_file.write(buf.getbuffer())
|
||||||
return hash_filename
|
return hash_filename
|
||||||
|
|
||||||
|
|
||||||
|
async def save_audio_fragment(fragment: UploadFile):
|
||||||
|
if (fragment.filename is None):
|
||||||
|
raise ValueError("Filename not found")
|
||||||
|
if (fragment.content_type is None):
|
||||||
|
raise ValueError("File content type unknown")
|
||||||
|
|
||||||
|
hash_filename = create_hash_name(fragment.filename)
|
||||||
|
file_extension = mimetypes.guess_extension(fragment.content_type)
|
||||||
|
if (file_extension is None):
|
||||||
|
raise NameError("File extension not found")
|
||||||
|
else:
|
||||||
|
hash_filename += file_extension
|
||||||
|
|
||||||
|
async with aiofiles.open(Path() / "content" / "audio"
|
||||||
|
/ hash_filename, 'wb') as file:
|
||||||
|
fragment_data = await fragment.read()
|
||||||
|
if (isinstance(fragment_data, str)):
|
||||||
|
raise ValueError("Invalid audio file")
|
||||||
|
await file.write(fragment_data)
|
||||||
|
return hash_filename
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -15,6 +15,8 @@ app = FastAPI(
|
|||||||
)
|
)
|
||||||
app.include_router(startup_router)
|
app.include_router(startup_router)
|
||||||
app.include_router(games_router)
|
app.include_router(games_router)
|
||||||
|
app.include_router(movies_router)
|
||||||
|
app.include_router(audiobooks_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,4 +1,6 @@
|
|||||||
from .games import games_router as games_router
|
from .games import games_router as games_router
|
||||||
|
from .movies import movies_router as movies_router
|
||||||
|
from .audiobooks import audiobooks_router as audiobooks_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
|
||||||
|
|||||||
61
routes/audiobooks.py
Normal file
61
routes/audiobooks.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
import database as db
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
audiobooks_router = APIRouter(prefix="/audiobooks", tags=["Audiobooks"])
|
||||||
|
|
||||||
|
|
||||||
|
@audiobooks_router.get("", response_model=list[db.Audiobook])
|
||||||
|
async def get_audiobooks(db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_audiobooks(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@audiobooks_router.post("", response_model=db.Audiobook)
|
||||||
|
async def add_audiobook(audiobook: db.AudiobookCreate,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
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])
|
||||||
|
async def get_audiobooks_cards(db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_audiobooks(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@audiobooks_router.get("/{audiobook_id}", response_model=db.Audiobook)
|
||||||
|
async def get_audiobook(audiobook_id: int, db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_audiobook(db_session, audiobook_id)
|
||||||
|
|
||||||
|
|
||||||
|
@audiobooks_router.put("/{audiobook_id}", response_model=db.Audiobook)
|
||||||
|
async def edit_audiobook(audiobook_id: int,
|
||||||
|
audiobook: db.AudiobookCreate,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
audiobook_db = await db.get_audiobook(db_session, audiobook_id)
|
||||||
|
if (audiobook_db is None):
|
||||||
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Audiobook with id={audiobook_id} not found")
|
||||||
|
if (user.id != audiobook_db.owner_id):
|
||||||
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Audiobook can only be edited "
|
||||||
|
"by the owner (creator)")
|
||||||
|
return await db.edit_audiobook(db_session, audiobook_id, audiobook)
|
||||||
|
|
||||||
|
|
||||||
|
@audiobooks_router.delete("/{audiobook_id}", response_model=db.Audiobook)
|
||||||
|
async def delete_audiobook(audiobook_id: int,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
audiobook_db = await db.get_audiobook(db_session, audiobook_id)
|
||||||
|
if (audiobook_db is None):
|
||||||
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Audiobook with id={audiobook_id} not found")
|
||||||
|
if (user.id != audiobook_db.owner_id):
|
||||||
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Audiobook can only be deleted "
|
||||||
|
"by the owner (creator)")
|
||||||
|
return await db.delete_audiobook(db_session, audiobook_id)
|
||||||
@@ -12,7 +12,7 @@ async def upload_torrent(torrent: UploadFile):
|
|||||||
return await save_torrent_file(torrent)
|
return await save_torrent_file(torrent)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print(ex)
|
print(ex)
|
||||||
raise HTTPException(500)
|
raise HTTPException(500, detail=str(ex))
|
||||||
|
|
||||||
|
|
||||||
@files_router.post("/cover", response_model=str)
|
@files_router.post("/cover", response_model=str)
|
||||||
@@ -21,4 +21,13 @@ async def upload_cover(cover: UploadFile):
|
|||||||
return await save_image(cover, "cover")
|
return await save_image(cover, "cover")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print(ex)
|
print(ex)
|
||||||
raise HTTPException(500)
|
raise HTTPException(500, detail=str(ex))
|
||||||
|
|
||||||
|
|
||||||
|
@files_router.post("/audio", response_model=str)
|
||||||
|
async def upload_audio_fragment(fragment: UploadFile):
|
||||||
|
try:
|
||||||
|
return await save_audio_fragment(fragment)
|
||||||
|
except Exception as ex:
|
||||||
|
print(ex)
|
||||||
|
raise HTTPException(500, detail=str(ex))
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ async def delete_game(game_id: int,
|
|||||||
user: db.User = Depends(get_user),
|
user: db.User = Depends(get_user),
|
||||||
db_session: AsyncSession = Depends(db.get_session)):
|
db_session: AsyncSession = Depends(db.get_session)):
|
||||||
game_db = await db.get_game(db_session, game_id)
|
game_db = await db.get_game(db_session, game_id)
|
||||||
print(game_db)
|
|
||||||
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")
|
||||||
|
|||||||
61
routes/movies.py
Normal file
61
routes/movies.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
|
import database as db
|
||||||
|
from file_handler import *
|
||||||
|
from routes.auth import get_user
|
||||||
|
|
||||||
|
movies_router = APIRouter(prefix="/movies", tags=["Movies"])
|
||||||
|
|
||||||
|
|
||||||
|
@movies_router.get("", response_model=list[db.Movie])
|
||||||
|
async def get_movies(db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_movies(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@movies_router.post("", response_model=db.Movie)
|
||||||
|
async def add_movie(movie: db.MovieCreate,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
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])
|
||||||
|
async def get_movies_cards(db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_movies(db_session)
|
||||||
|
|
||||||
|
|
||||||
|
@movies_router.get("/{movie_id}", response_model=db.Movie)
|
||||||
|
async def get_movie(movie_id: int, db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
return await db.get_movie(db_session, movie_id)
|
||||||
|
|
||||||
|
|
||||||
|
@movies_router.put("/{movie_id}", response_model=db.Movie)
|
||||||
|
async def edit_movie(movie_id: int,
|
||||||
|
movie: db.MovieCreate,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
movie_db = await db.get_movie(db_session, movie_id)
|
||||||
|
if (movie_db is None):
|
||||||
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Movie with id={movie_id} not found")
|
||||||
|
if (user.id != movie_db.owner_id):
|
||||||
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Movie can only be edited "
|
||||||
|
"by the owner (creator)")
|
||||||
|
return await db.edit_movie(db_session, movie_id, movie)
|
||||||
|
|
||||||
|
|
||||||
|
@movies_router.delete("/{movie_id}", response_model=db.Movie)
|
||||||
|
async def delete_movie(movie_id: int,
|
||||||
|
user: db.User = Depends(get_user),
|
||||||
|
db_session: AsyncSession = Depends(db.get_session)):
|
||||||
|
movie_db = await db.get_movie(db_session, movie_id)
|
||||||
|
if (movie_db is None):
|
||||||
|
raise HTTPException(status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Movie with id={movie_id} not found")
|
||||||
|
if (user.id != movie_db.owner_id):
|
||||||
|
raise HTTPException(status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Movie can only be deleted "
|
||||||
|
"by the owner (creator)")
|
||||||
|
return await db.delete_movie(db_session, movie_id)
|
||||||
@@ -12,7 +12,8 @@ def create_folders():
|
|||||||
Path() / "content" / "images" / "cover" / "preview",
|
Path() / "content" / "images" / "cover" / "preview",
|
||||||
Path() / "content" / "images" / "screenshot" / "full_size",
|
Path() / "content" / "images" / "screenshot" / "full_size",
|
||||||
Path() / "content" / "images" / "screenshot" / "preview",
|
Path() / "content" / "images" / "screenshot" / "preview",
|
||||||
Path() / "content" / "torrent"
|
Path() / "content" / "torrent",
|
||||||
|
Path() / "content" / "audio"
|
||||||
]
|
]
|
||||||
for path in need_paths:
|
for path in need_paths:
|
||||||
path.mkdir(parents=True, exist_ok=True)
|
path.mkdir(parents=True, exist_ok=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user