use flow::Flow; use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, sync::Arc, }; use warp::Filter; use music_player::{ audio::TrackInfo, core::Core, database::{MemoryIndex, MusicIndex}, music_scanner::FileScanner, }; fn tracks(index: &Arc) -> Vec { match index.list_tracks() { Flow::Ok(tracks) => tracks, Flow::Err(err) => panic!("error: {}", err), Flow::Fatal(err) => panic!("fatal: {}", err), } } enum Bundle { Index, App, Styles, } impl Bundle { fn read(self, root: PathBuf) -> String { let mut path = root; match self { Bundle::Index => path.push(PathBuf::from("index.html")), Bundle::App => path.push(PathBuf::from("bundle.js")), Bundle::Styles => path.push(PathBuf::from("styles.css")), }; println!("path: {:?}", path); std::fs::read_to_string(path).expect("to find the file") } } #[tokio::main] pub async fn main() { let dev = std::env::var("DEV") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(false); let bundle_root = std::env::var("BUNDLE_ROOT") .map(|b| PathBuf::from(b)) .unwrap(); let music_root = std::env::var("MUSIC_ROOT") .map(|b| PathBuf::from(b)) .unwrap(); let index = Arc::new(MemoryIndex::new()); let scanner = FileScanner::new(vec![music_root.clone()]); let _core = match Core::new(index.clone(), scanner) { Flow::Ok(core) => core, Flow::Err(error) => panic!("error: {}", error), Flow::Fatal(error) => panic!("fatal: {}", error), }; println!("config: {:?} {:?} {:?}", dev, bundle_root, music_root); let root = warp::path!().and(warp::get()).map({ let bundle_root = bundle_root.clone(); move || { warp::http::Response::builder() .header("content-type", "text/html") .body(Bundle::Index.read(bundle_root.clone())) } }); let app = warp::path!("bundle.js").and(warp::get()).map({ let bundle_root = bundle_root.clone(); move || { warp::http::Response::builder() .header("content-type", "text/javascript") .body(Bundle::App.read(bundle_root.clone())) } }); let styles = warp::path!("styles.css").and(warp::get()).map({ let bundle_root = bundle_root.clone(); move || { warp::http::Response::builder() .header("content-type", "text/css") .body(Bundle::Styles.read(bundle_root.clone())) } }); /* let devices = warp::path!("api" / "v1" / "devices") .and(warp::get()) .map(|| { let conn = Connection::new_session().expect("to connect to dbus"); warp::reply::json(&list_devices(conn)) }); */ let track_list = warp::path!("api" / "v1" / "tracks").and(warp::get()).map({ let index = index.clone(); move || warp::reply::json(&tracks(&index)) }); /* let tracks_for_artist = warp::path!("api" / "v1" / "artist" / String) .and(warp::get()) .map(|_artist: String| warp::reply::json(&tracks())); let tracks_for_album = warp::path!("api" / "v1" / "album" / String) .and(warp::get()) .map(|_album: String| warp::reply::json(&tracks())); let queue = warp::path!("api" / "v1" / "queue") .and(warp::get()) .map(|| { let conn = Connection::new_session().expect("to connect to dbus"); warp::reply::json(&list_tracks(conn)) }); let playing_status = warp::path!("api" / "v1" / "play-pause") .and(warp::get()) .map(|| warp::reply::json(&PlayPause::Paused)); let routes = devices .or(track_list) .or(tracks_for_album) .or(tracks_for_artist) .or(queue) .or(playing_status); */ let routes = root.or(app).or(styles).or(track_list); let server = warp::serve(routes); server .run(SocketAddr::new( IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8002, )) .await; }