Files
LLM-infa/api/db/video.py
jze9 bf854f2d6e Разделы, фильтры и просмотр текстов в UI; опция «не хранить видео»
- таблица sections (дерево через parent_id), у видео section_id
- API: CRUD /sections, фильтры /videos (поиск, раздел с потомками, метод),
  GET /videos/{id}/text, PATCH раздела, DELETE вместе с файлами
- pipeline: keep_video=false удаляет mp4 после расшифровки, section_id
- UI: панель разделов с вложенностью и счётчиками, поиск, фильтр по методу,
  диалоги полного текста/выжимки, привязка к разделу, удаление,
  переключатель «Сохранять видео на диске»
- compose: bind-mount ./web для правок без пересборки

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 12:07:55 +05:00

83 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from sqlalchemy import select
from api.db.connection import SessionLocal
from api.models.video import Video
async def create_video(
*,
uuid: str,
source_url: str,
title: str,
video_path: str,
text_full_path: str,
text_summary_path: str,
transcription_method: str,
section_id: int | None = None,
) -> Video:
async with SessionLocal() as session:
v = Video(
uuid=uuid,
source_url=source_url,
section_id=section_id,
title=title or "",
video_path=video_path or "",
text_full_path=text_full_path or "",
text_summary_path=text_summary_path or "",
transcription_method=transcription_method or "",
)
session.add(v)
await session.commit()
await session.refresh(v)
return v
async def get_video(video_uuid: str) -> Video | None:
async with SessionLocal() as session:
res = await session.execute(select(Video).where(Video.uuid == video_uuid))
return res.scalars().first()
async def list_videos(
*,
q: str | None = None,
section_ids: list[int] | None = None,
method: str | None = None,
) -> list[Video]:
"""Каталог с фильтрами: поиск по названию/URL, разделы (уже с потомками), метод."""
stmt = select(Video)
if q:
pattern = f"%{q}%"
stmt = stmt.where(Video.title.ilike(pattern) | Video.source_url.ilike(pattern))
if section_ids is not None:
stmt = stmt.where(Video.section_id.in_(section_ids))
if method:
stmt = stmt.where(Video.transcription_method.ilike(f"{method}%"))
stmt = stmt.order_by(Video.created_at.desc())
async with SessionLocal() as session:
res = await session.execute(stmt)
return list(res.scalars().all())
async def set_video_section(video_uuid: str, section_id: int | None) -> Video | None:
async with SessionLocal() as session:
res = await session.execute(select(Video).where(Video.uuid == video_uuid))
v = res.scalars().first()
if not v:
return None
v.section_id = section_id
await session.commit()
await session.refresh(v)
return v
async def delete_video(video_uuid: str) -> bool:
async with SessionLocal() as session:
res = await session.execute(select(Video).where(Video.uuid == video_uuid))
v = res.scalars().first()
if not v:
return False
await session.delete(v)
await session.commit()
return True