Fix .gitignore: models/ was excluding backend/app/models/
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
data/
|
||||
models/
|
||||
/models/
|
||||
.env
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
import os
|
||||
|
||||
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite+aiosqlite:////data/app/bornetime.db")
|
||||
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
|
||||
async def init_db():
|
||||
async with engine.begin() as conn:
|
||||
from .tables import Video, Segment, Job
|
||||
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
|
||||
async def get_session():
|
||||
async with async_session() as session:
|
||||
yield session
|
||||
@@ -0,0 +1,64 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
import datetime
|
||||
|
||||
|
||||
class VideoOut(BaseModel):
|
||||
id: int
|
||||
filename: str
|
||||
duration: Optional[float] = None
|
||||
status: str
|
||||
output_path: Optional[str] = None
|
||||
error_message: Optional[str] = None
|
||||
created_at: datetime.datetime
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class VideoListOut(BaseModel):
|
||||
videos: list[VideoOut]
|
||||
|
||||
|
||||
class SegmentOut(BaseModel):
|
||||
id: int
|
||||
video_id: int
|
||||
speaker_label: Optional[str] = None
|
||||
start_time: float
|
||||
end_time: float
|
||||
english_text: Optional[str] = None
|
||||
danish_text: Optional[str] = None
|
||||
status: str
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class SegmentUpdate(BaseModel):
|
||||
english_text: Optional[str] = None
|
||||
danish_text: Optional[str] = None
|
||||
speaker_label: Optional[str] = None
|
||||
|
||||
|
||||
class TranscriptOut(BaseModel):
|
||||
video_id: int
|
||||
segments: list[SegmentOut]
|
||||
|
||||
|
||||
class JobOut(BaseModel):
|
||||
id: int
|
||||
video_id: int
|
||||
job_type: str
|
||||
status: str
|
||||
progress: float
|
||||
error_message: Optional[str] = None
|
||||
created_at: datetime.datetime
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class JobListOut(BaseModel):
|
||||
jobs: list[JobOut]
|
||||
|
||||
|
||||
class ProcessResponse(BaseModel):
|
||||
job_id: int
|
||||
message: str
|
||||
@@ -0,0 +1,90 @@
|
||||
import datetime
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
String,
|
||||
Float,
|
||||
Text,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Enum as SAEnum,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
from .database import Base
|
||||
import enum
|
||||
|
||||
|
||||
class VideoStatus(str, enum.Enum):
|
||||
uploaded = "uploaded"
|
||||
queued = "queued"
|
||||
processing = "processing"
|
||||
review = "review"
|
||||
generating = "generating"
|
||||
done = "done"
|
||||
error = "error"
|
||||
|
||||
|
||||
class JobType(str, enum.Enum):
|
||||
process = "process"
|
||||
generate = "generate"
|
||||
|
||||
|
||||
class JobStatus(str, enum.Enum):
|
||||
pending = "pending"
|
||||
running = "running"
|
||||
done = "done"
|
||||
failed = "failed"
|
||||
|
||||
|
||||
class Video(Base):
|
||||
__tablename__ = "videos"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
filename = Column(String(512), nullable=False)
|
||||
filepath = Column(String(1024), nullable=False)
|
||||
duration = Column(Float, nullable=True)
|
||||
status = Column(String(32), default=VideoStatus.uploaded.value)
|
||||
output_path = Column(String(1024), nullable=True)
|
||||
error_message = Column(Text, nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||
updated_at = Column(
|
||||
DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow
|
||||
)
|
||||
|
||||
segments = relationship(
|
||||
"Segment", back_populates="video", cascade="all, delete-orphan"
|
||||
)
|
||||
jobs = relationship("Job", back_populates="video", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Segment(Base):
|
||||
__tablename__ = "segments"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
video_id = Column(Integer, ForeignKey("videos.id"), nullable=False)
|
||||
speaker_label = Column(String(32), nullable=True)
|
||||
start_time = Column(Float, nullable=False)
|
||||
end_time = Column(Float, nullable=False)
|
||||
english_text = Column(Text, nullable=True)
|
||||
danish_text = Column(Text, nullable=True)
|
||||
status = Column(String(32), default="pending")
|
||||
|
||||
video = relationship("Video", back_populates="segments")
|
||||
|
||||
|
||||
class Job(Base):
|
||||
__tablename__ = "jobs"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
video_id = Column(Integer, ForeignKey("videos.id"), nullable=False)
|
||||
job_type = Column(String(32), nullable=False)
|
||||
status = Column(String(32), default=JobStatus.pending.value)
|
||||
progress = Column(Float, default=0.0)
|
||||
error_message = Column(Text, nullable=True)
|
||||
celery_task_id = Column(String(256), nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||
updated_at = Column(
|
||||
DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow
|
||||
)
|
||||
|
||||
video = relationship("Video", back_populates="jobs")
|
||||
Reference in New Issue
Block a user