archive-backend/routers/channel.py
2026-11-07 19:35:15 +00:00

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),
}