mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Support building with the application key statically included in the binary.
This commit is contained in:
parent
a5453de572
commit
aa1d466e92
2 changed files with 23 additions and 11 deletions
|
@ -54,4 +54,5 @@ json_macros = { git = "https://github.com/plietar/json_macros" }
|
||||||
discovery = ["dns-sd"]
|
discovery = ["dns-sd"]
|
||||||
with-syntex = ["syntex", "protobuf_macros/with-syntex", "json_macros/with-syntex"]
|
with-syntex = ["syntex", "protobuf_macros/with-syntex", "json_macros/with-syntex"]
|
||||||
with-tremor = ["tremor"]
|
with-tremor = ["tremor"]
|
||||||
|
static-appkey = []
|
||||||
default = ["with-syntex"]
|
default = ["with-syntex"]
|
||||||
|
|
31
src/main.rs
31
src/main.rs
|
@ -2,12 +2,11 @@ extern crate getopts;
|
||||||
extern crate librespot;
|
extern crate librespot;
|
||||||
extern crate rpassword;
|
extern crate rpassword;
|
||||||
|
|
||||||
use getopts::Options;
|
|
||||||
use rpassword::read_password;
|
use rpassword::read_password;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdout, Read, Write};
|
use std::io::{stdout, Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use librespot::audio_sink::DefaultSink;
|
use librespot::audio_sink::DefaultSink;
|
||||||
|
@ -20,23 +19,33 @@ use librespot::util::version::version_string;
|
||||||
|
|
||||||
static PASSWORD_ENV_NAME: &'static str = "SPOTIFY_PASSWORD";
|
static PASSWORD_ENV_NAME: &'static str = "SPOTIFY_PASSWORD";
|
||||||
|
|
||||||
fn usage(program: &str, opts: &Options) -> String {
|
fn usage(program: &str, opts: &getopts::Options) -> String {
|
||||||
let brief = format!("Usage: {} [options]", program);
|
let brief = format!("Usage: {} [options]", program);
|
||||||
format!("{}", opts.usage(&brief))
|
format!("{}", opts.usage(&brief))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "static-appkey")]
|
||||||
|
static APPKEY: Option<&'static [u8]> = Some(include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/spotify_appkey.key")));
|
||||||
|
#[cfg(not(feature = "static-appkey"))]
|
||||||
|
static APPKEY: Option<&'static [u8]> = None;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
let program = args[0].clone();
|
let program = args[0].clone();
|
||||||
|
|
||||||
let mut opts = Options::new();
|
let mut opts = getopts::Options::new();
|
||||||
opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY")
|
opts.optopt("u", "username", "Username to sign in with", "USERNAME")
|
||||||
.optopt("u", "username", "Username to sign in with (optional)", "USERNAME")
|
.optopt("p", "password", "Password", "PASSWORD")
|
||||||
.optopt("p", "password", "Password (optional)", "PASSWORD")
|
|
||||||
.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
|
.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
|
||||||
.reqopt("n", "name", "Device name", "NAME")
|
.reqopt("n", "name", "Device name", "NAME")
|
||||||
.optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE");
|
.optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE");
|
||||||
|
|
||||||
|
if APPKEY.is_none() {
|
||||||
|
opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY");
|
||||||
|
} else {
|
||||||
|
opts.optopt("a", "appkey", "Path to a spotify appkey", "APPKEY");
|
||||||
|
};
|
||||||
|
|
||||||
let matches = match opts.parse(&args[1..]) {
|
let matches = match opts.parse(&args[1..]) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => {
|
Err(f) => {
|
||||||
|
@ -45,15 +54,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let appkey = {
|
let appkey = matches.opt_str("a").map(|appkey_path| {
|
||||||
let mut file = File::open(Path::new(&*matches.opt_str("a").unwrap()))
|
let mut file = File::open(appkey_path)
|
||||||
.expect("Could not open app key.");
|
.expect("Could not open app key.");
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
file.read_to_end(&mut data).unwrap();
|
file.read_to_end(&mut data).unwrap();
|
||||||
|
|
||||||
data
|
data
|
||||||
};
|
}).or_else(|| APPKEY.map(ToOwned::to_owned)).unwrap();
|
||||||
|
|
||||||
let username = matches.opt_str("u");
|
let username = matches.opt_str("u");
|
||||||
let cache_location = matches.opt_str("c").map(PathBuf::from);
|
let cache_location = matches.opt_str("c").map(PathBuf::from);
|
||||||
|
@ -100,6 +109,8 @@ fn main() {
|
||||||
.and_then(|p| File::open(p).ok())
|
.and_then(|p| File::open(p).ok())
|
||||||
.map(Credentials::from_reader)
|
.map(Credentials::from_reader)
|
||||||
}).unwrap_or_else(|| {
|
}).unwrap_or_else(|| {
|
||||||
|
println!("No username provided and no stored credentials, starting discovery ...");
|
||||||
|
|
||||||
let mut discovery = DiscoveryManager::new(session.clone());
|
let mut discovery = DiscoveryManager::new(session.clone());
|
||||||
discovery.run()
|
discovery.run()
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue