This commit is contained in:
Marek
2026-04-05 20:43:35 +02:00
parent f8de245e45
commit f269271c6e
16 changed files with 237 additions and 32 deletions

View File

@@ -1,8 +1,9 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from database import create_tables
from routes.videos import router as videos_router
from database import SessionLocal, create_tables
from models import Profile
from routes.videos import profiles_router, router as videos_router
app = FastAPI()
@@ -14,11 +15,17 @@ app.add_middleware(
)
app.include_router(videos_router)
app.include_router(profiles_router)
@app.on_event("startup")
def startup():
create_tables()
db = SessionLocal()
if db.query(Profile).count() == 0:
db.add(Profile(name="Standard"))
db.commit()
db.close()
@app.get("/")

View File

@@ -1,7 +1,22 @@
from sqlalchemy import Column, Integer, String
from sqlalchemy import Column, ForeignKey, Integer, String, Table
from sqlalchemy.orm import relationship
from database import Base
video_profiles = Table(
"video_profiles",
Base.metadata,
Column("video_id", Integer, ForeignKey("videos.id", ondelete="CASCADE")),
Column("profile_id", Integer, ForeignKey("profiles.id", ondelete="CASCADE")),
)
class Profile(Base):
__tablename__ = "profiles"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False, unique=True)
class Video(Base):
__tablename__ = "videos"
@@ -12,3 +27,4 @@ class Video(Base):
thumbnail_url = Column(String, nullable=False)
youtube_url = Column(String, nullable=False)
file_path = Column(String, nullable=True)
profiles = relationship("Profile", secondary=video_profiles, backref="videos")

View File

@@ -1,12 +1,13 @@
import threading
from pathlib import Path
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import FileResponse, StreamingResponse
from sqlalchemy.orm import Session
from database import get_db
from schemas import VideoCreate, VideoResponse
from schemas import ProfileResponse, VideoCreate, VideoResponse
from services import video_service
from services.download_service import download_video
from services.stream_service import stream_video_live
@@ -27,14 +28,14 @@ def create_videos(videos_data: list[VideoCreate], db: Session = Depends(get_db))
@router.get("", response_model=list[VideoResponse])
def get_all_videos(db: Session = Depends(get_db)):
videos = video_service.get_all_videos(db)
def get_all_videos(profile_id: Optional[int] = Query(None), db: Session = Depends(get_db)):
videos = video_service.get_all_videos(db, profile_id=profile_id)
return [VideoResponse.from_model(v) for v in videos]
@router.get("/downloaded", response_model=list[VideoResponse])
def get_downloaded_videos(db: Session = Depends(get_db)):
videos = video_service.get_downloaded_videos(db)
def get_downloaded_videos(profile_id: Optional[int] = Query(None), db: Session = Depends(get_db)):
videos = video_service.get_downloaded_videos(db, profile_id=profile_id)
return [VideoResponse.from_model(v) for v in videos]
@@ -88,3 +89,11 @@ def download_file(video_id: int, db: Session = Depends(get_db)):
raise HTTPException(status_code=404, detail="Videodatei nicht gefunden")
return FileResponse(path, media_type="video/mp4", filename=f"{video.title}.mp4")
profiles_router = APIRouter(prefix="/profiles", tags=["profiles"])
@profiles_router.get("", response_model=list[ProfileResponse])
def get_profiles(db: Session = Depends(get_db)):
return video_service.get_all_profiles(db)

View File

@@ -6,6 +6,7 @@ class VideoCreate(BaseModel):
youtuber: str
thumbnail_url: str
youtube_url: str
profile_id: int | None = None
class VideoResponse(BaseModel):
@@ -15,6 +16,7 @@ class VideoResponse(BaseModel):
thumbnail_url: str
youtube_url: str
is_downloaded: bool
profile_ids: list[int]
class Config:
from_attributes = True
@@ -28,4 +30,13 @@ class VideoResponse(BaseModel):
thumbnail_url=video.thumbnail_url,
youtube_url=video.youtube_url,
is_downloaded=video.file_path is not None,
profile_ids=[p.id for p in video.profiles],
)
class ProfileResponse(BaseModel):
id: int
name: str
class Config:
from_attributes = True

View File

@@ -1,23 +1,35 @@
from sqlalchemy.orm import Session
from models import Video
from models import Profile, Video, video_profiles
from schemas import VideoCreate
def create_video(db: Session, video_data: VideoCreate) -> Video:
video = Video(**video_data.model_dump())
profile_id = video_data.profile_id
data = video_data.model_dump(exclude={"profile_id"})
video = Video(**data)
if profile_id:
profile = db.query(Profile).filter(Profile.id == profile_id).first()
if profile:
video.profiles.append(profile)
db.add(video)
db.commit()
db.refresh(video)
return video
def get_all_videos(db: Session) -> list[Video]:
return db.query(Video).order_by(Video.id.desc()).all()
def get_all_videos(db: Session, profile_id: int | None = None) -> list[Video]:
query = db.query(Video)
if profile_id:
query = query.filter(Video.profiles.any(Profile.id == profile_id))
return query.order_by(Video.id.desc()).all()
def get_downloaded_videos(db: Session) -> list[Video]:
return db.query(Video).filter(Video.file_path.isnot(None)).order_by(Video.id.desc()).all()
def get_downloaded_videos(db: Session, profile_id: int | None = None) -> list[Video]:
query = db.query(Video).filter(Video.file_path.isnot(None))
if profile_id:
query = query.filter(Video.profiles.any(Profile.id == profile_id))
return query.order_by(Video.id.desc()).all()
def get_video(db: Session, video_id: int) -> Video | None:
@@ -34,3 +46,7 @@ def update_file_path(db: Session, video_id: int, path: str):
if video:
video.file_path = path
db.commit()
def get_all_profiles(db: Session) -> list[Profile]:
return db.query(Profile).all()