archive-backend/routers/channel.py
2026-11-07 11:40:36 +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),
}