update
This commit is contained in:
@@ -2,12 +2,12 @@ from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from api.schemas import ProfileResponse
|
||||
from database.database import get_db
|
||||
from database.database import getDb
|
||||
from model.profile import Profile
|
||||
|
||||
router = APIRouter(prefix="/profiles", tags=["profiles"])
|
||||
|
||||
|
||||
@router.get("", response_model=list[ProfileResponse])
|
||||
def get_profiles(db: Session = Depends(get_db)):
|
||||
return Profile.get_all(db)
|
||||
def getAll(db: Session = Depends(getDb)):
|
||||
return Profile.getAll(db)
|
||||
|
||||
@@ -1,47 +1,45 @@
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class VideoCreate(BaseModel):
|
||||
title: str
|
||||
youtuber: str
|
||||
thumbnail_url: str
|
||||
youtube_url: str
|
||||
profile_id: int | None = None
|
||||
thumbnailUrl: str
|
||||
youtubeUrl: str
|
||||
profileId: int | None = None
|
||||
|
||||
|
||||
class VideoResponse(BaseModel):
|
||||
id: int
|
||||
title: str
|
||||
youtuber: str
|
||||
thumbnail_url: str
|
||||
youtube_url: str
|
||||
is_downloaded: bool
|
||||
profile_ids: list[int]
|
||||
thumbnailUrl: str
|
||||
youtubeUrl: str
|
||||
isDownloaded: bool
|
||||
profileIds: list[int]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@classmethod
|
||||
def from_model(cls, video):
|
||||
def fromModel(cls, video):
|
||||
return cls(
|
||||
id=video.id,
|
||||
title=video.title,
|
||||
youtuber=video.youtuber,
|
||||
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],
|
||||
thumbnailUrl=video.thumbnailUrl,
|
||||
youtubeUrl=video.youtubeUrl,
|
||||
isDownloaded=video.filePath is not None,
|
||||
profileIds=[p.id for p in video.profiles],
|
||||
)
|
||||
|
||||
|
||||
class CleanupRequest(BaseModel):
|
||||
profile_id: int
|
||||
exclude_ids: list[int] = []
|
||||
profileId: int
|
||||
excludeIds: list[int] = []
|
||||
|
||||
|
||||
class ProfileResponse(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@@ -7,115 +7,115 @@ from fastapi.responses import FileResponse, StreamingResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from api.schemas import CleanupRequest, VideoCreate, VideoResponse
|
||||
from database.database import SessionLocal, get_db
|
||||
from download.download_service import download_video
|
||||
from database.database import SessionLocal, getDb
|
||||
from download.download_service import downloadVideo
|
||||
from model.video import Video
|
||||
from notify.notify_clients import notify_clients
|
||||
from stream.stream_service import stream_video_live
|
||||
from notify.notify_clients import notifyClients
|
||||
from stream.stream_service import streamVideoLive
|
||||
|
||||
router = APIRouter(prefix="/videos", tags=["videos"])
|
||||
|
||||
|
||||
@router.post("", response_model=list[VideoResponse])
|
||||
async def create_videos(videos_data: list[VideoCreate], db: Session = Depends(get_db)):
|
||||
created_ids = []
|
||||
profile_ids = set()
|
||||
for video_data in reversed(videos_data):
|
||||
video_id_match = video_data.youtube_url.split("v=")[-1].split("&")[0]
|
||||
Video.delete_by_youtube_id(db, video_id_match)
|
||||
data = video_data.model_dump(exclude={"profile_id"})
|
||||
video = Video.create_from_dict(db, data, video_data.profile_id)
|
||||
created_ids.append(video.id)
|
||||
profile_ids.add(video_data.profile_id or 1)
|
||||
videos = [Video.get_by_id(db, vid) for vid in created_ids]
|
||||
@router.post("", status_code=204)
|
||||
async def create(videoData: VideoCreate, db: Session = Depends(getDb)):
|
||||
title = videoData.title
|
||||
youtuber = videoData.youtuber
|
||||
thumbnailUrl = videoData.thumbnailUrl
|
||||
youtubeUrl = videoData.youtubeUrl
|
||||
profileId = videoData.profileId
|
||||
|
||||
if profile_ids:
|
||||
await notify_clients(list(profile_ids))
|
||||
|
||||
return [VideoResponse.from_model(v) for v in videos if v]
|
||||
Video.deleteIfExists(db, youtubeUrl, profileId)
|
||||
Video.create(db, title, youtuber, thumbnailUrl, youtubeUrl, profileId)
|
||||
await notifyClients(profileId)
|
||||
|
||||
|
||||
@router.get("", response_model=list[VideoResponse])
|
||||
def get_all_videos(profile_id: Optional[int] = Query(None), db: Session = Depends(get_db)):
|
||||
videos = Video.get_all(db, profile_id=profile_id)
|
||||
return [VideoResponse.from_model(v) for v in videos]
|
||||
def getAll(
|
||||
profileId: Optional[int] = Query(None),
|
||||
db: Session = Depends(getDb),
|
||||
):
|
||||
videos = Video.getAll(db, profileId=profileId)
|
||||
return [VideoResponse.fromModel(v) for v in videos]
|
||||
|
||||
|
||||
@router.get("/downloaded", response_model=list[VideoResponse])
|
||||
def get_downloaded_videos(profile_id: Optional[int] = Query(None), db: Session = Depends(get_db)):
|
||||
videos = Video.get_downloaded(db, profile_id=profile_id)
|
||||
return [VideoResponse.from_model(v) for v in videos]
|
||||
def getDownloaded(
|
||||
profileId: Optional[int] = Query(None),
|
||||
db: Session = Depends(getDb),
|
||||
):
|
||||
videos = Video.getDownloaded(db, profileId=profileId)
|
||||
return [VideoResponse.fromModel(v) for v in videos]
|
||||
|
||||
|
||||
@router.post("/cleanup")
|
||||
def cleanup_videos(request: CleanupRequest, db: Session = Depends(get_db)):
|
||||
count = Video.delete_not_downloaded(db, request.profile_id, request.exclude_ids or None)
|
||||
def cleanup(request: CleanupRequest, db: Session = Depends(getDb)):
|
||||
count = Video.deleteNotDownloaded(db, request.profileId, request.excludeIds or None)
|
||||
return {"deleted": count}
|
||||
|
||||
|
||||
@router.post("/{video_id}/download")
|
||||
def trigger_download(video_id: int, db: Session = Depends(get_db)):
|
||||
video = Video.get_by_id(db, video_id)
|
||||
@router.post("/{videoId}/download")
|
||||
def download(videoId: int, db: Session = Depends(getDb)):
|
||||
video = Video.getById(db, videoId)
|
||||
if not video:
|
||||
raise HTTPException(status_code=404, detail="Video nicht gefunden")
|
||||
if video.file_path:
|
||||
if video.filePath:
|
||||
return {"status": "already_downloaded"}
|
||||
|
||||
thread = threading.Thread(target=download_video, args=(video.id, video.youtube_url))
|
||||
thread = threading.Thread(target=downloadVideo, args=(video.id, video.youtubeUrl))
|
||||
thread.start()
|
||||
return {"status": "download_started"}
|
||||
|
||||
|
||||
@router.get("/{video_id}/stream")
|
||||
def stream_video(video_id: int, db: Session = Depends(get_db)):
|
||||
video = Video.get_by_id(db, video_id)
|
||||
@router.get("/{videoId}/stream")
|
||||
def stream(videoId: int, db: Session = Depends(getDb)):
|
||||
video = Video.getById(db, videoId)
|
||||
if not video:
|
||||
raise HTTPException(status_code=404, detail="Video nicht gefunden")
|
||||
|
||||
if not video.file_path:
|
||||
def stream_and_save():
|
||||
output_path = f"/videos/{video_id}.mp4"
|
||||
yield from stream_video_live(video_id, video.youtube_url)
|
||||
if Path(output_path).exists():
|
||||
if not video.filePath:
|
||||
def streamAndSave():
|
||||
outputPath = f"/videos/{videoId}.mp4"
|
||||
yield from streamVideoLive(videoId, video.youtubeUrl)
|
||||
if Path(outputPath).exists():
|
||||
sdb = SessionLocal()
|
||||
try:
|
||||
Video.update_file_path(sdb, video_id, output_path)
|
||||
Video.updateFilePath(sdb, videoId, outputPath)
|
||||
finally:
|
||||
sdb.close()
|
||||
|
||||
return StreamingResponse(stream_and_save(), media_type="video/mp4")
|
||||
return StreamingResponse(streamAndSave(), media_type="video/mp4")
|
||||
|
||||
path = Path(video.file_path)
|
||||
path = Path(video.filePath)
|
||||
if not path.exists():
|
||||
raise HTTPException(status_code=404, detail="Videodatei nicht gefunden")
|
||||
|
||||
return FileResponse(path, media_type="video/mp4")
|
||||
|
||||
|
||||
@router.get("/{video_id}/file")
|
||||
def download_file(video_id: int, db: Session = Depends(get_db)):
|
||||
video = Video.get_by_id(db, video_id)
|
||||
@router.get("/{videoId}/file")
|
||||
def getFile(videoId: int, db: Session = Depends(getDb)):
|
||||
video = Video.getById(db, videoId)
|
||||
if not video:
|
||||
raise HTTPException(status_code=404, detail="Video nicht gefunden")
|
||||
if not video.file_path:
|
||||
if not video.filePath:
|
||||
raise HTTPException(status_code=404, detail="Video noch nicht heruntergeladen")
|
||||
|
||||
path = Path(video.file_path)
|
||||
path = Path(video.filePath)
|
||||
if not path.exists():
|
||||
Video.update_file_path(db, video_id, None)
|
||||
Video.updateFilePath(db, videoId, None)
|
||||
raise HTTPException(status_code=404, detail="Video noch nicht heruntergeladen")
|
||||
|
||||
return FileResponse(path, media_type="video/mp4", filename=f"{video.title}.mp4")
|
||||
|
||||
|
||||
@router.delete("/{video_id}/file")
|
||||
def delete_server_file(video_id: int, db: Session = Depends(get_db)):
|
||||
video = Video.get_by_id(db, video_id)
|
||||
@router.delete("/{videoId}/file")
|
||||
def deleteFile(videoId: int, db: Session = Depends(getDb)):
|
||||
video = Video.getById(db, videoId)
|
||||
if not video:
|
||||
raise HTTPException(status_code=404, detail="Video nicht gefunden")
|
||||
if video.file_path:
|
||||
path = Path(video.file_path)
|
||||
if video.filePath:
|
||||
path = Path(video.filePath)
|
||||
if path.exists():
|
||||
path.unlink()
|
||||
Video.update_file_path(db, video_id, None)
|
||||
Video.updateFilePath(db, videoId, None)
|
||||
return {"status": "deleted"}
|
||||
|
||||
Reference in New Issue
Block a user