feat: Print location of created config file on first run (#87)
Co-authored-by: 0xnf <0xnf@winetech.com>
This commit is contained in:
parent
d91b5dd5ad
commit
86ecd08b28
5 changed files with 94 additions and 32 deletions
43
Cargo.lock
generated
43
Cargo.lock
generated
|
|
@ -577,6 +577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
|
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -591,6 +592,18 @@ dependencies = [
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
|
@ -1235,6 +1248,12 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
|
@ -1663,7 +1682,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot"
|
name = "librespot"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea4c9952ef48968f8184a4a87f8576982426ebe623342d5a28f7d9c4978e4a44"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
|
|
@ -1689,7 +1709,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-audio"
|
name = "librespot-audio"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c176a31355e1ea8e0b9c4ced19df4947bfe4770661c25c142b6fba2365940d9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-ctr",
|
"aes-ctr",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
|
@ -1704,7 +1725,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-connect"
|
name = "librespot-connect"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ffafb6a443e9445ccb3d5d591573b5b1da3c89a9b8846c63ba2c3710210d3ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
|
@ -1724,7 +1746,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-core"
|
name = "librespot-core"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "046349f25888e644bf02d9c5de0164b2a493d29aa4ce18e1ad0b756da9b55d6d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
|
|
@ -1764,7 +1787,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-discovery"
|
name = "librespot-discovery"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2aa877d18f6150364012cb4be5682d62d7c712c88bae2d0d01720fd7c15e2f06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-ctr",
|
"aes-ctr",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
|
|
@ -1785,7 +1809,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-metadata"
|
name = "librespot-metadata"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b80361fcbcb5092056fd47c08c34d5d51b08385d8efb6941c0d3e46d032c21c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
|
@ -1798,7 +1823,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-playback"
|
name = "librespot-playback"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5190a0b9bcc7f70ee4196a6b4a1c731d405ca130d4a6fcd4c561cfdde8b7cfb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cpal",
|
"cpal",
|
||||||
|
|
@ -1823,7 +1849,8 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librespot-protocol"
|
name = "librespot-protocol"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "git+ssh://git@github.com/oSumAtrIX/free-librespot.git#f28fa264528dc85f8f325c18e8461b0f2b43dca1"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d6d3ac6196ac0ea67bbe039f56d6730a5d8b31502ef9bce0f504ed729dcb39f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"protobuf 2.28.0",
|
"protobuf 2.28.0",
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ build = "build.rs"
|
||||||
winres = "0.1"
|
winres = "0.1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "4.2.1"
|
clap = { version = "4.2.1", features = ["cargo", "derive"] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
url = "2.2"
|
url = "2.2"
|
||||||
protobuf = "3.1"
|
protobuf = "3.1"
|
||||||
|
|
|
||||||
29
src/arg.rs
Normal file
29
src/arg.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::settings;
|
||||||
|
use clap::{crate_authors, crate_version, Args as ClapArgs, Command, FromArgMatches, Parser};
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
pub struct Args {
|
||||||
|
#[arg(
|
||||||
|
long_help = "Track / Album / Playlist / Artist / Podcast / Episode / Show / User URL, ID or search term\nFor example, \'Ariana Grande\', \'spotify:track:0KjAxsrYSvN0xGuh3cKPxD\', or \'https://open.spotify.com/playlist/37i9dQZF1DXcxvFzl58uP7\'"
|
||||||
|
)]
|
||||||
|
pub input: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Args {
|
||||||
|
pub fn from_cli() -> Self {
|
||||||
|
let cli = get_command();
|
||||||
|
Self::from_arg_matches(&cli.get_matches()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_command() -> Command {
|
||||||
|
let cli = Command::new(clap::crate_name!())
|
||||||
|
.author(crate_authors!())
|
||||||
|
.version(crate_version!())
|
||||||
|
.about(format!(
|
||||||
|
"Settings file located at: {}",
|
||||||
|
settings::get_config_settings_path().to_string_lossy()
|
||||||
|
));
|
||||||
|
let cli = Args::augment_args(cli);
|
||||||
|
cli
|
||||||
|
}
|
||||||
24
src/main.rs
24
src/main.rs
|
|
@ -1,6 +1,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
mod arg;
|
||||||
mod converter;
|
mod converter;
|
||||||
mod downloader;
|
mod downloader;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
@ -8,6 +9,7 @@ mod settings;
|
||||||
mod spotify;
|
mod spotify;
|
||||||
mod tag;
|
mod tag;
|
||||||
|
|
||||||
|
use arg::Args;
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use downloader::{DownloadState, Downloader};
|
use downloader::{DownloadState, Downloader};
|
||||||
|
|
@ -35,6 +37,8 @@ async fn main() {
|
||||||
async fn start() {
|
async fn start() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
|
let args = Args::from_cli();
|
||||||
|
|
||||||
let settings = match Settings::load().await {
|
let settings = match Settings::load().await {
|
||||||
Ok(settings) => {
|
Ok(settings) => {
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -52,10 +56,11 @@ async fn start() {
|
||||||
);
|
);
|
||||||
let default_settings = Settings::new("username", "password", "client_id", "secret");
|
let default_settings = Settings::new("username", "password", "client_id", "secret");
|
||||||
match default_settings.save().await {
|
match default_settings.save().await {
|
||||||
Ok(_) => {
|
Ok(path) => {
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}{}",
|
||||||
"..but default settings have been created successfully. Edit them and run the program again.".green()
|
"..but default settings have been created successfully. Edit them and run the program again.\nFind the settings file at: ".green(),
|
||||||
|
path.to_string_lossy()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -70,15 +75,6 @@ async fn start() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
|
||||||
if args.len() <= 1 {
|
|
||||||
println!(
|
|
||||||
"Usage:\n{} <search_term> | <track_url> | <album_url> | <playlist_url> | <artist_url>",
|
|
||||||
args[0]
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let spotify = match Spotify::new(
|
let spotify = match Spotify::new(
|
||||||
&settings.username,
|
&settings.username,
|
||||||
&settings.password,
|
&settings.password,
|
||||||
|
|
@ -101,10 +97,8 @@ async fn start() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let input = args[1..].join(" ");
|
|
||||||
|
|
||||||
let downloader = Downloader::new(settings.downloader, spotify);
|
let downloader = Downloader::new(settings.downloader, spotify);
|
||||||
match downloader.handle_input(&input).await {
|
match downloader.handle_input(&args.input).await {
|
||||||
Ok(search_results) => {
|
Ok(search_results) => {
|
||||||
if let Some(search_results) = search_results {
|
if let Some(search_results) = search_results {
|
||||||
print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
|
print!("{esc}[2J{esc}[1;1H", esc = 27 as char);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,15 @@ fn get_config_folder_path() -> PathBuf {
|
||||||
Path::new(&env::var("APPDATA").unwrap()).join("down_on_spot")
|
Path::new(&env::var("APPDATA").unwrap()).join("down_on_spot")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the full path to the Settings json
|
||||||
|
///
|
||||||
|
/// Windows: `%APPDATA%\down_on_spot\settings.json`
|
||||||
|
///
|
||||||
|
/// Unix-like: `~/.config/down_on_spot/settings.json`
|
||||||
|
pub fn get_config_settings_path() -> PathBuf {
|
||||||
|
get_config_folder_path().join("settings.json")
|
||||||
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
// Create new instance
|
// Create new instance
|
||||||
pub fn new(username: &str, password: &str, client_id: &str, client_secret: &str) -> Settings {
|
pub fn new(username: &str, password: &str, client_id: &str, client_secret: &str) -> Settings {
|
||||||
|
|
@ -53,25 +62,28 @@ impl Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save config
|
/// Save config
|
||||||
pub async fn save(&self) -> Result<(), SpotifyError> {
|
///
|
||||||
|
/// Returns the path of the written file if successful
|
||||||
|
pub async fn save(&self) -> Result<PathBuf, SpotifyError> {
|
||||||
// Get and create config folder path, generate config file path
|
// Get and create config folder path, generate config file path
|
||||||
let config_folder_path = get_config_folder_path();
|
let config_file_path = get_config_settings_path();
|
||||||
|
let config_folder_path = config_file_path
|
||||||
|
.parent()
|
||||||
|
.expect("Configuration file path should have a parent component");
|
||||||
create_dir_all(&config_folder_path).await?;
|
create_dir_all(&config_folder_path).await?;
|
||||||
let config_file_path = config_folder_path.join("settings.json");
|
|
||||||
|
|
||||||
// Serialize the settings to a json file
|
// Serialize the settings to a json file
|
||||||
let data = serde_json::to_string_pretty(self)?;
|
let data = serde_json::to_string_pretty(self)?;
|
||||||
let mut file = File::create(config_file_path).await?;
|
let mut file = File::create(&config_file_path).await?;
|
||||||
file.write_all(data.as_bytes()).await?;
|
file.write_all(data.as_bytes()).await?;
|
||||||
Ok(())
|
Ok(config_file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
pub async fn load() -> Result<Settings, SpotifyError> {
|
pub async fn load() -> Result<Settings, SpotifyError> {
|
||||||
// Get config folder path, generate config file path
|
// Get config folder path, generate config file path
|
||||||
let config_folder_path = get_config_folder_path();
|
let config_file_path = get_config_settings_path();
|
||||||
let config_file_path = config_folder_path.join("settings.json");
|
|
||||||
|
|
||||||
// Deserialize the settings from a json file
|
// Deserialize the settings from a json file
|
||||||
let mut file = File::open(config_file_path).await?;
|
let mut file = File::open(config_file_path).await?;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue