A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 170 lines 5.6 kB view raw
1use std::{env, ffi::OsString}; 2 3use anyhow::Error; 4use clap::{arg, Command}; 5use owo_colors::OwoColorize; 6 7use cmd::{ 8 clear::*, community::*, login::*, repl::*, run::*, scan::*, service, start::*, webui::*, 9 whoami::*, 10}; 11 12pub mod cmd; 13 14fn cli() -> Command { 15 let banner = format!( 16 "{}\nA fork of the original Rockbox project, with a focus on modernization and more features.", 17 r#" 18 __________ __ ___. 19 Open \______ \ ____ ____ | | _\_ |__ _______ ___ 20 Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 21 Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 22 Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 23 \/ \/ \/ \/ \/ 24 "# 25 .yellow() 26 ); 27 const VERSION: &str = match option_env!("TAG") { 28 Some(tag) => tag, 29 None => env!("CARGO_PKG_VERSION"), 30 }; 31 Command::new("rockbox") 32 .version(VERSION) 33 .about(&banner) 34 .arg(arg!(--rebuild -r "Rebuild index after scan")) 35 .subcommand( 36 Command::new("scan") 37 .arg(arg!(--directory -d [PATH] "path to your music library").required(false)) 38 .arg(arg!(--rebuild -r "Rebuild index after scan")) 39 .about("Scan your music library for new media files"), 40 ) 41 .subcommand( 42 Command::new("community").about("Join our community on Discord to chat with us!"), 43 ) 44 .subcommand( 45 Command::new("start") 46 .about("Start Rockbox server") 47 .arg(arg!(--rebuild -r "Rebuild index after scan")), 48 ) 49 .subcommand(Command::new("tui").about("Start Rockbox TUI")) 50 .subcommand( 51 Command::new("webui") 52 .about("Open the Rockbox web UI in your browser") 53 .visible_alias("web"), 54 ) 55 .subcommand( 56 Command::new("repl") 57 .about("Start the Rockbox REPL") 58 .visible_alias("shell"), 59 ) 60 .subcommand( 61 Command::new("run") 62 .arg(arg!(<FILE> "JavaScript or TypeScript file to run")) 63 .about("Run a JavaScript or TypeScript program") 64 .visible_alias("x"), 65 ) 66 .subcommand( 67 Command::new("service") 68 .about("Manage systemd service for Rockbox") 69 .subcommand(Command::new("install").about("Install systemd service for Rockbox")) 70 .subcommand( 71 Command::new("uninstall").about("Uninstall systemd service for Rockbox"), 72 ) 73 .subcommand( 74 Command::new("status").about("Check status of systemd service for Rockbox"), 75 ), 76 ) 77 .subcommand( 78 Command::new("login") 79 .arg(arg!(<handle> "Your BlueSky handle")) 80 .about("Login to your Rocksky account") 81 .visible_alias("auth"), 82 ) 83 .subcommand( 84 Command::new("whoami") 85 .about("Display information about the currently logged in user") 86 .visible_alias("me"), 87 ) 88 .subcommand(Command::new("clear").about("Clear current playlist")) 89} 90 91#[tokio::main] 92async fn main() -> Result<(), Error> { 93 let args = std::env::args().collect::<Vec<String>>(); 94 if args.len() > 1 && args[1] == "run" { 95 let _args = args 96 .into_iter() 97 .map(|s| match s.as_str() { 98 "rockbox" => "deno".into(), 99 _ => s.into(), 100 }) 101 .collect::<Vec<OsString>>(); 102 103 run(_args); 104 return Ok(()); 105 } 106 107 let matches = cli().get_matches(); 108 109 match matches.subcommand() { 110 Some(("scan", args)) => { 111 let directory = args.get_one::<String>("directory").map(|d| d.to_string()); 112 let rebuild_index = match args.get_flag("rebuild") { 113 true => Some(true), 114 false => None, 115 }; 116 scan(directory, rebuild_index).await?; 117 } 118 Some(("community", _)) => { 119 community(); 120 } 121 Some(("start", _)) => { 122 start(true)?; 123 } 124 Some(("webui", _)) => { 125 webui()?; 126 } 127 Some(("repl", _)) => { 128 repl(); 129 } 130 Some(("tui", _)) => { 131 rmpc::main_tui()?; 132 } 133 Some(("service", sub_m)) => match sub_m.subcommand() { 134 Some(("install", _)) => { 135 service::install()?; 136 } 137 Some(("uninstall", _)) => { 138 service::uninstall()?; 139 } 140 Some(("status", _)) => { 141 service::status()?; 142 } 143 _ => { 144 println!("Invalid subcommand. Use `rockbox service --help` for more information."); 145 } 146 }, 147 Some(("login", args)) => { 148 let handle = args.get_one::<String>("handle").unwrap(); 149 login(handle).await?; 150 } 151 Some(("whoami", _)) => { 152 whoami().await?; 153 } 154 Some(("clear", _)) => { 155 match clear() { 156 Ok(_) => {} 157 Err(e) => {} 158 }; 159 println!("✅ Rockbox Playlist Cleared"); 160 } 161 Some((_, args)) => { 162 if args.get_flag("rebuild") { 163 env::set_var("ROCKBOX_UPDATE_LIBRARY", "1"); 164 } 165 start(true)?; 166 } 167 None => start(true)?, 168 } 169 Ok(()) 170}