import os import streamlit as st import uuid from typing import Sequence from app.adapters.aws.s3 import S3Client from app.adapters.db.base import DB from app.assets.models import GlobalParticipant, Asset, AssetMetaData from app.assets.repositories import AssetRepository, GlobalParticipantRepository from app.config import Settings from anydi import singleton import requests @singleton class AssetService: def __init__( self, db: DB, asset_repository: AssetRepository, global_participant_repository: GlobalParticipantRepository, s3_client: S3Client, settings: Settings, ) -> None: self.s3_client = s3_client self.db = db self.asset_repository = asset_repository self.global_participant_repository = global_participant_repository self.settings = settings def download_video(self, url: str, name: str, target_directory: str) -> str: local_filename = f"{name}.mp4" local_filepath = os.path.join(target_directory, local_filename) try: with requests.get(url, stream=True) as r: r.raise_for_status() with open(local_filepath, "wb") as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) except requests.exceptions.RequestException as e: raise RuntimeError(f"Failed to download video from URL: {url}. Error: {e}") if not os.path.exists(local_filepath): raise FileNotFoundError( f"Downloaded file not found at expected path: {local_filepath}" ) return local_filepath def find_all_global_participants(self) -> Sequence[GlobalParticipant]: return self.global_participant_repository.all() def add_song( self, song_name: str, key: str, artist: GlobalParticipant | None = None, artist_name: str | None = None, ) -> Asset: global_participant: GlobalParticipant | None = None if artist: global_participant = self.asset_repository.db.session.merge(artist) elif artist_name: gp_id = str(uuid.uuid4()) global_participant = GlobalParticipant(id=gp_id, name=artist_name) else: raise ValueError() new_asset_id = str(uuid.uuid4()) asset = Asset( id=new_asset_id, external_id=str(uuid.uuid4()), type="YOUTUBE_URL", s3_key=key, global_participant=global_participant, asset_meta_data=AssetMetaData( asset_id=new_asset_id, asset_name=song_name, ), ) self.asset_repository.add(asset) self.asset_repository.db.session.commit() st.session_state.asset = asset return asset