feat: load settings from a configuration file
Co-authored-by: aider (gemini/gemini-2.5-pro-preview-05-06) <aider@aider.chat>
This commit is contained in:
parent
8d58e50847
commit
c740e0df0e
2 changed files with 41 additions and 16 deletions
|
|
@ -8,5 +8,8 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.82"
|
anyhow = "1.0.82"
|
||||||
clap = { version = "4.5.4", features = ["derive"] }
|
clap = { version = "4.5.4", features = ["derive"] }
|
||||||
|
config = "0.14.0"
|
||||||
|
dirs = "5.0.1"
|
||||||
fs_extra = "1.3.0"
|
fs_extra = "1.3.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tempfile = "3.10.1"
|
tempfile = "3.10.1"
|
||||||
|
|
|
||||||
54
src/main.rs
54
src/main.rs
|
|
@ -1,15 +1,18 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use serde::Deserialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
// ==== CONFIGURATION ====
|
#[derive(Debug, Deserialize)]
|
||||||
const NAS_HOST: &str = "(localaddress)";
|
struct Settings {
|
||||||
const NAS_USER: &str = "ssh_user";
|
nas_host: String,
|
||||||
const NAS_PATH: &str = "/path/to/files/on/nas";
|
nas_user: String,
|
||||||
const COOKIES_FILE: &str = "/location/of/apple-music-cookies-file.txt";
|
nas_path: String,
|
||||||
|
cookies_file: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
|
|
@ -22,6 +25,22 @@ struct Args {
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let config_path = dirs::config_dir()
|
||||||
|
.context("Could not find config directory")?
|
||||||
|
.join("jamdl/config.toml");
|
||||||
|
|
||||||
|
if !config_path.exists() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"Config file not found. Please create it at: {}",
|
||||||
|
config_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let settings = config::Config::builder()
|
||||||
|
.add_source(config::File::from(config_path))
|
||||||
|
.build()?
|
||||||
|
.try_deserialize::<Settings>()?;
|
||||||
|
|
||||||
// Create temp directory
|
// Create temp directory
|
||||||
let temp_dir = TempDir::new().context("Failed to create temporary directory")?;
|
let temp_dir = TempDir::new().context("Failed to create temporary directory")?;
|
||||||
let temp_path = temp_dir.path();
|
let temp_path = temp_dir.path();
|
||||||
|
|
@ -30,26 +49,26 @@ fn main() -> Result<()> {
|
||||||
temp_path.display()
|
temp_path.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
download_media(&args.url, temp_path)?;
|
download_media(&args.url, temp_path, &settings)?;
|
||||||
transfer_files(temp_path)?;
|
transfer_files(temp_path, &settings)?;
|
||||||
|
|
||||||
// Cleanup is handled by TempDir's Drop trait
|
// Cleanup is handled by TempDir's Drop trait
|
||||||
println!("[INFO] Cleaning up...");
|
println!("[INFO] Cleaning up...");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download_media(video_url: &str, download_path: &Path) -> Result<()> {
|
fn download_media(video_url: &str, download_path: &Path, settings: &Settings) -> Result<()> {
|
||||||
let mut cmd: Command;
|
let mut cmd: Command;
|
||||||
|
|
||||||
if video_url.contains("music.apple.com") {
|
if video_url.contains("music.apple.com") {
|
||||||
println!("[INFO] Apple Music link detected. Using gamdl...");
|
println!("[INFO] Apple Music link detected. Using gamdl...");
|
||||||
cmd = Command::new("gamdl");
|
cmd = Command::new("gamdl");
|
||||||
if Path::new(COOKIES_FILE).exists() {
|
if Path::new(&settings.cookies_file).exists() {
|
||||||
cmd.args(["--cookies-path", COOKIES_FILE, video_url]);
|
cmd.args(["--cookies-path", &settings.cookies_file, video_url]);
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
"[WARN] cookies.txt not found at {} — running gamdl without it",
|
"[WARN] cookies.txt not found at {} — running gamdl without it",
|
||||||
COOKIES_FILE
|
settings.cookies_file
|
||||||
);
|
);
|
||||||
cmd.arg(video_url);
|
cmd.arg(video_url);
|
||||||
}
|
}
|
||||||
|
|
@ -75,15 +94,15 @@ fn download_media(video_url: &str, download_path: &Path) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_files(source_path: &Path) -> Result<()> {
|
fn transfer_files(source_path: &Path, settings: &Settings) -> Result<()> {
|
||||||
let is_empty = fs::read_dir(source_path)?.next().is_none();
|
let is_empty = fs::read_dir(source_path)?.next().is_none();
|
||||||
|
|
||||||
if !is_empty {
|
if !is_empty {
|
||||||
if NAS_HOST == "localhost" {
|
if settings.nas_host == "localhost" {
|
||||||
println!("[INFO] NAS_HOST is localhost, copying files locally...");
|
println!("[INFO] NAS_HOST is localhost, copying files locally...");
|
||||||
let mut options = fs_extra::dir::CopyOptions::new();
|
let mut options = fs_extra::dir::CopyOptions::new();
|
||||||
options.content_only = true;
|
options.content_only = true;
|
||||||
fs_extra::dir::copy(source_path, NAS_PATH, &options)
|
fs_extra::dir::copy(source_path, &settings.nas_path, &options)
|
||||||
.context("Failed to copy files locally")?;
|
.context("Failed to copy files locally")?;
|
||||||
} else {
|
} else {
|
||||||
println!("[INFO] Transferring files to NAS via scp...");
|
println!("[INFO] Transferring files to NAS via scp...");
|
||||||
|
|
@ -92,7 +111,10 @@ fn transfer_files(source_path: &Path) -> Result<()> {
|
||||||
"{}/.",
|
"{}/.",
|
||||||
source_path.to_str().context("Invalid source path")?
|
source_path.to_str().context("Invalid source path")?
|
||||||
);
|
);
|
||||||
let destination = format!("{}@{}:{}", NAS_USER, NAS_HOST, NAS_PATH);
|
let destination = format!(
|
||||||
|
"{}@{}:{}",
|
||||||
|
settings.nas_user, settings.nas_host, settings.nas_path
|
||||||
|
);
|
||||||
scp_cmd.args(["-r", &source, &destination]);
|
scp_cmd.args(["-r", &source, &destination]);
|
||||||
|
|
||||||
let status = scp_cmd.status().context("Failed to execute scp")?;
|
let status = scp_cmd.status().context("Failed to execute scp")?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue