use std::{path::PathBuf, process::Command};
use clap::{ArgAction, Subcommand};
use music_exporter::{MusicExporter, PlatformType};
use serde::{Deserialize, Serialize};
use tokio::runtime::Runtime;
use crate::{
config::Config,
config_path,
errors::GeneralError,
utils::{input_no, input_path},
};
#[derive(Deserialize, Serialize, Default)]
pub struct MusicCliCommand {
pub music_file: Option<String>,
pub env_path: Option<String>,
}
#[derive(Subcommand, Debug, Clone)]
pub enum MusicSubcommand {
Sync,
Open {
#[arg(short = 'p', long = "path", action = ArgAction::SetTrue)]
show_path_only: bool,
},
}
impl MusicSubcommand {
pub fn invoke(self, config: &mut Config) -> Result<(), GeneralError> {
match self {
MusicSubcommand::Sync => MusicCliCommand::sync_music(config, None),
MusicSubcommand::Open { show_path_only } => {
MusicCliCommand::open_music_file(config, show_path_only)
}
}
}
}
impl MusicCliCommand {
pub fn get_music_file_path(config: &mut Config) -> Result<PathBuf, GeneralError> {
let path = config_path!(
config,
music,
MusicCliCommand,
music_file,
"the file for music"
);
Ok(path)
}
pub fn open_music_file(config: &mut Config, print_path: bool) -> Result<(), GeneralError> {
let music_file = MusicCliCommand::get_music_file_path(config)?;
if print_path {
println!("{}", music_file.display());
return Ok(());
}
println!("Opening music file at {}", music_file.display());
Command::new("vi").arg(&music_file).spawn()?.wait()?;
Ok(())
}
pub fn sync_music(config: &mut Config, sync_all: Option<bool>) -> Result<(), GeneralError> {
let rt = Runtime::new()?;
let music_file = MusicCliCommand::get_music_file_path(config)?;
let env_path = config_path!(config, music, MusicCliCommand, env_path, "the env path");
println!("music file: '{}'", music_file.display());
if let Some(true) = sync_all {
let platforms = vec![
PlatformType::Deezer,
PlatformType::Spotify,
PlatformType::Youtube,
];
rt.block_on(async {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
MusicExporter::new_from_vars(music_file, Some(env_path), &platforms)
.run_main()
.await
.map_err(|e| ("Error with music-exporter", e))
})?;
} else {
for platform in [
PlatformType::Deezer,
PlatformType::Spotify,
PlatformType::Youtube,
] {
if input_no(format!("Should we sync platform: {platform}?"))? {
println!("Skipping platform: {platform}");
continue;
}
rt.block_on(async {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
MusicExporter::new_from_vars(
music_file.clone(),
Some(env_path.clone()),
&[platform],
)
.run_main()
.await
.map_err(|e| ("Error with music-exporter", e))
})?;
}
}
Ok(())
}
}