use crate::video::actors::{PlaylistGenerator, StreamActor, VideoPlaylistManager}; use actix::{Actor, Addr}; use std::{env, sync::Arc}; pub struct AppState { pub stream_manager: Arc>, pub playlist_manager: Arc>, pub base_path: String, pub thumbnail_path: String, pub video_path: String, pub gif_path: String, pub excluded_dirs: Vec, } impl AppState { pub fn new( stream_manager: Arc>, base_path: String, thumbnail_path: String, video_path: String, gif_path: String, excluded_dirs: Vec, ) -> Self { let playlist_generator = PlaylistGenerator::new(); let video_playlist_manager = VideoPlaylistManager::new(video_path.clone(), playlist_generator.start()); Self { stream_manager, playlist_manager: Arc::new(video_playlist_manager.start()), base_path, thumbnail_path, video_path, gif_path, excluded_dirs, } } /// Parse excluded directories from environment variable fn parse_excluded_dirs() -> Vec { env::var("EXCLUDED_DIRS") .unwrap_or_default() .split(',') .filter(|dir| !dir.trim().is_empty()) .map(|dir| dir.trim().to_string()) .collect() } } impl Default for AppState { fn default() -> Self { Self::new( Arc::new(StreamActor {}.start()), env::var("BASE_PATH").expect("BASE_PATH was not set in the env"), env::var("THUMBNAILS").expect("THUMBNAILS was not set in the env"), env::var("VIDEO_PATH").expect("VIDEO_PATH was not set in the env"), env::var("GIFS_DIRECTORY").expect("GIFS_DIRECTORY was not set in the env"), Self::parse_excluded_dirs(), ) } } #[cfg(test)] impl AppState { /// Creates an AppState instance for testing with temporary directories pub fn test_state() -> Self { use actix::Actor; // Create a base temporary directory let temp_dir = tempfile::tempdir().expect("Failed to create temp directory"); let base_path = temp_dir.path().to_path_buf(); // Create subdirectories for thumbnails, videos, and gifs let thumbnail_path = create_test_subdir(&base_path, "thumbnails"); let video_path = create_test_subdir(&base_path, "videos"); let gif_path = create_test_subdir(&base_path, "gifs"); // Create the AppState with the temporary paths AppState::new( std::sync::Arc::new(crate::video::actors::StreamActor {}.start()), base_path.to_string_lossy().to_string(), thumbnail_path.to_string_lossy().to_string(), video_path.to_string_lossy().to_string(), gif_path.to_string_lossy().to_string(), Vec::new(), // No excluded directories for test state ) } } /// Helper function to create a subdirectory inside the base directory for testing #[cfg(test)] fn create_test_subdir(base_path: &std::path::Path, name: &str) -> std::path::PathBuf { let dir_path = base_path.join(name); std::fs::create_dir_all(&dir_path) .unwrap_or_else(|_| panic!("Failed to create {} directory", name)); dir_path }