86 lines
2.6 KiB
Python
86 lines
2.6 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ..core.authx import auth
|
|
from ..core.config import TEMPLATES_DIR
|
|
from ..core.db import get_db
|
|
from ..models.video_model import Channel, Playlist, Video
|
|
from ..schemas.channel_schemas import ChannelOut, ChannelsOut
|
|
|
|
router = APIRouter()
|
|
templates = Jinja2Templates(directory=TEMPLATES_DIR)
|
|
|
|
|
|
@router.get("/channels", response_model=ChannelsOut, dependencies=[Depends(auth.access_token_required)])
|
|
async def channels(session: AsyncSession = Depends(get_db)): # noqa: B008
|
|
|
|
stmt = (
|
|
select(Channel.id, Channel.name, func.count(Video.id).label("video_count"))
|
|
.outerjoin(Channel.videos)
|
|
.group_by(Channel.id, Channel.name)
|
|
.order_by(Channel.name)
|
|
)
|
|
rows = (await session.execute(stmt)).all()
|
|
|
|
return {
|
|
"channels": [
|
|
{"id": r.id, "name": r.name, "videos_count": r.video_count} for r in rows
|
|
]
|
|
}
|
|
|
|
|
|
@router.get("/channel", response_model=ChannelOut, dependencies=[Depends(auth.access_token_required)])
|
|
async def channel(
|
|
session: AsyncSession = Depends(get_db), # noqa: B008
|
|
id: int = Query(...),
|
|
page: int = Query(1, ge=1),
|
|
per_page: int = Query(24, ge=1),
|
|
):
|
|
offset = (page - 1) * per_page
|
|
|
|
query = (
|
|
select(Video)
|
|
.join(Channel, Channel.id == Video.channel_id)
|
|
.where(Channel.id == id, Video.playlist == None)
|
|
.order_by(Video.id)
|
|
.offset(offset)
|
|
.limit(per_page)
|
|
)
|
|
videos = (await session.execute(query)).scalars().all()
|
|
videos_count = len(videos)
|
|
|
|
channel_name = (
|
|
await session.execute(select(Channel.name).where(Channel.id == id))
|
|
).scalar()
|
|
|
|
p_query = (
|
|
select(Playlist, func.min(Video.preview_path).label("preview_path"))
|
|
.outerjoin(Video, Video.playlist_id == Playlist.id)
|
|
.where(Playlist.channel_id == id)
|
|
.group_by(Playlist.id)
|
|
.order_by(Playlist.id)
|
|
)
|
|
playlists_rows = (await session.execute(p_query)).all()
|
|
|
|
return {
|
|
"videos": [
|
|
{
|
|
"id": v.id,
|
|
"title": getattr(v, "title", None),
|
|
"path": v.path,
|
|
"preview_path": v.preview_path,
|
|
"date": v.date,
|
|
}
|
|
for v in videos
|
|
],
|
|
"channel_name": channel_name,
|
|
"playlists": [
|
|
{"id": p.id, "name": p.name, "preview_path": prev}
|
|
for p, prev in playlists_rows
|
|
],
|
|
"videos_count": videos_count,
|
|
"playlists_count": len(playlists_rows),
|
|
}
|