mirror of
https://github.com/talwat/lowfi
synced 2025-12-07 23:47:46 +00:00
129 lines
3.4 KiB
Rust
129 lines
3.4 KiB
Rust
//! An extremely simple lofi player.
|
|
pub mod error;
|
|
use std::path::PathBuf;
|
|
|
|
use clap::{Parser, Subcommand};
|
|
mod tests;
|
|
pub use error::{Error, Result};
|
|
pub mod message;
|
|
pub mod ui;
|
|
use futures_util::TryFutureExt;
|
|
pub use message::Message;
|
|
|
|
use crate::player::Player;
|
|
pub mod audio;
|
|
pub mod bookmark;
|
|
pub mod download;
|
|
pub mod player;
|
|
pub mod tracks;
|
|
pub mod volume;
|
|
|
|
#[cfg(feature = "scrape")]
|
|
mod scrapers;
|
|
|
|
#[cfg(feature = "scrape")]
|
|
use crate::scrapers::Source;
|
|
|
|
/// An extremely simple lofi player.
|
|
#[derive(Parser, Clone)]
|
|
#[command(about, version)]
|
|
#[allow(clippy::struct_excessive_bools)]
|
|
pub struct Args {
|
|
/// Use an alternate terminal screen.
|
|
#[clap(long, short)]
|
|
alternate: bool,
|
|
|
|
/// Hide the bottom control bar.
|
|
#[clap(long, short)]
|
|
minimalist: bool,
|
|
|
|
/// Exclude borders in UI.
|
|
#[clap(long, short)]
|
|
borderless: bool,
|
|
|
|
/// Start lowfi paused.
|
|
#[clap(long, short)]
|
|
paused: bool,
|
|
|
|
/// FPS of the UI.
|
|
#[clap(long, short, default_value_t = 12)]
|
|
fps: u8,
|
|
|
|
/// Timeout in seconds for music downloads.
|
|
#[clap(long, default_value_t = 16)]
|
|
timeout: u64,
|
|
|
|
/// Include ALSA & other logs.
|
|
#[clap(long, short)]
|
|
debug: bool,
|
|
|
|
/// Width of the player, from 0 to 32.
|
|
#[clap(long, short, default_value_t = 3)]
|
|
width: usize,
|
|
|
|
/// Track list to play music from
|
|
#[clap(long, short, alias = "list", alias = "tracks", short_alias = 'l', default_value_t = String::from("chillhop"))]
|
|
track_list: String,
|
|
|
|
/// Internal song buffer size.
|
|
#[clap(long, short = 's', alias = "buffer", default_value_t = 5, value_parser = clap::value_parser!(u32).range(2..))]
|
|
buffer_size: u32,
|
|
|
|
/// The command that was ran.
|
|
/// This is [None] if no command was specified.
|
|
#[command(subcommand)]
|
|
command: Option<Commands>,
|
|
}
|
|
|
|
/// Defines all of the extra commands lowfi can run.
|
|
#[derive(Subcommand, Clone)]
|
|
enum Commands {
|
|
/// Scrapes a music source for files.
|
|
#[cfg(feature = "scrape")]
|
|
Scrape {
|
|
// The source to scrape from.
|
|
source: scrapers::Source,
|
|
},
|
|
}
|
|
|
|
/// Returns the application data directory used for persistency.
|
|
///
|
|
/// The function returns the platform-specific user data directory with
|
|
/// a `lowfi` subfolder. Callers may use this path to store config,
|
|
/// bookmarks, and other persistent files.
|
|
pub fn data_dir() -> crate::Result<PathBuf> {
|
|
let dir = dirs::data_dir().unwrap().join("lowfi");
|
|
|
|
Ok(dir)
|
|
}
|
|
|
|
/// Program entry point.
|
|
///
|
|
/// Parses CLI arguments, initializes the audio stream and player, then
|
|
/// runs the main event loop. On exit it performs cleanup of the UI and
|
|
/// returns the inner result.
|
|
#[tokio::main(flavor = "current_thread")]
|
|
async fn main() -> eyre::Result<()> {
|
|
let args = Args::parse();
|
|
|
|
#[cfg(feature = "scrape")]
|
|
if let Some(command) = &args.command {
|
|
match command {
|
|
Commands::Scrape { source } => match source {
|
|
Source::Archive => scrapers::archive::scrape().await?,
|
|
Source::Lofigirl => scrapers::lofigirl::scrape().await?,
|
|
Source::Chillhop => scrapers::chillhop::scrape().await?,
|
|
},
|
|
}
|
|
}
|
|
|
|
let stream = audio::stream()?;
|
|
let environment = ui::Environment::ready(args.alternate)?;
|
|
let result = Player::init(args, environment, stream.mixer())
|
|
.and_then(Player::run)
|
|
.await;
|
|
|
|
environment.cleanup(result.is_ok())?;
|
|
Ok(result?)
|
|
}
|