mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Make cache directory optional.
If the -c argument is omitted, librespot will run without a cache, and download tracks overtime they are played.
This commit is contained in:
parent
0e911fbb59
commit
a5453de572
3 changed files with 32 additions and 29 deletions
|
@ -103,7 +103,7 @@ impl AudioFileLoading {
|
||||||
let bitmap = shared.bitmap.lock().unwrap();
|
let bitmap = shared.bitmap.lock().unwrap();
|
||||||
if bitmap.len() >= shared.chunk_count {
|
if bitmap.len() >= shared.chunk_count {
|
||||||
drop(bitmap);
|
drop(bitmap);
|
||||||
AudioFileLoading::store(session, &shared, &mut write_file);
|
AudioFileLoading::persist_to_cache(session, &shared, &mut write_file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,14 +150,14 @@ impl AudioFileLoading {
|
||||||
shared.cond.notify_all();
|
shared.cond.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store(session: &Session, shared: &AudioFileShared, write_file: &mut NamedTempFile) {
|
fn persist_to_cache(session: &Session, shared: &AudioFileShared, write_file: &mut NamedTempFile) {
|
||||||
|
if let Some(path) = AudioFileManager::cache_path(session, shared.file_id) {
|
||||||
write_file.seek(SeekFrom::Start(0)).unwrap();
|
write_file.seek(SeekFrom::Start(0)).unwrap();
|
||||||
|
mkdir_existing(path.parent().unwrap()).unwrap();
|
||||||
|
|
||||||
mkdir_existing(&AudioFileManager::cache_dir(session, shared.file_id)).unwrap();
|
let mut cache_file = fs::File::create(path).unwrap();
|
||||||
|
io::copy(write_file, &mut cache_file).unwrap();
|
||||||
let mut f = fs::File::create(AudioFileManager::cache_path(session, shared.file_id))
|
}
|
||||||
.unwrap();
|
|
||||||
io::copy(write_file, &mut f).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,20 +217,19 @@ impl AudioFileManager {
|
||||||
AudioFileManager
|
AudioFileManager
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
|
pub fn cache_path(session: &Session, file_id: FileId) -> Option<PathBuf> {
|
||||||
|
session.config().cache_location.as_ref().map(|cache| {
|
||||||
let name = file_id.to_base16();
|
let name = file_id.to_base16();
|
||||||
session.config().cache_location.join(&name[0..2])
|
cache.join(&name[0..2]).join(&name[2..])
|
||||||
}
|
})
|
||||||
|
|
||||||
pub fn cache_path(session: &Session, file_id: FileId) -> PathBuf {
|
|
||||||
let name = file_id.to_base16();
|
|
||||||
AudioFileManager::cache_dir(session, file_id).join(&name[2..])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(&mut self, session: &Session, file_id: FileId) -> AudioFile {
|
pub fn request(&mut self, session: &Session, file_id: FileId) -> AudioFile {
|
||||||
match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
|
let cache_path = AudioFileManager::cache_path(session, file_id);
|
||||||
Ok(f) => AudioFile::Direct(f),
|
let cache_file = cache_path.and_then(|p| fs::File::open(p).ok());
|
||||||
Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id)),
|
|
||||||
}
|
cache_file.map(AudioFile::Direct).unwrap_or_else(|| {
|
||||||
|
AudioFile::Loading(AudioFileLoading::new(session, file_id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -33,7 +33,7 @@ fn main() {
|
||||||
opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY")
|
opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY")
|
||||||
.optopt("u", "username", "Username to sign in with (optional)", "USERNAME")
|
.optopt("u", "username", "Username to sign in with (optional)", "USERNAME")
|
||||||
.optopt("p", "password", "Password (optional)", "PASSWORD")
|
.optopt("p", "password", "Password (optional)", "PASSWORD")
|
||||||
.reqopt("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");
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let username = matches.opt_str("u");
|
let username = matches.opt_str("u");
|
||||||
let cache_location = PathBuf::from(matches.opt_str("c").unwrap());
|
let cache_location = matches.opt_str("c").map(PathBuf::from);
|
||||||
let name = matches.opt_str("n").unwrap();
|
let name = matches.opt_str("n").unwrap();
|
||||||
|
|
||||||
let credentials = username.map(|u| {
|
let credentials = username.map(|u| {
|
||||||
|
@ -91,21 +91,23 @@ fn main() {
|
||||||
|
|
||||||
let session = Session::new(config);
|
let session = Session::new(config);
|
||||||
|
|
||||||
let credentials_path = cache_location.join("credentials.json");
|
let credentials_path = cache_location.map(|c| c.join("credentials.json"));
|
||||||
|
|
||||||
let credentials = credentials.map(|(username, password)| {
|
let credentials = credentials.map(|(username, password)| {
|
||||||
Credentials::with_password(username, password)
|
Credentials::with_password(username, password)
|
||||||
}).or_else(|| {
|
}).or_else(|| {
|
||||||
File::open(&credentials_path).map(|file| {
|
credentials_path.as_ref()
|
||||||
Credentials::from_reader(file)
|
.and_then(|p| File::open(p).ok())
|
||||||
}).ok()
|
.map(Credentials::from_reader)
|
||||||
}).unwrap_or_else(|| {
|
}).unwrap_or_else(|| {
|
||||||
let mut discovery = DiscoveryManager::new(session.clone());
|
let mut discovery = DiscoveryManager::new(session.clone());
|
||||||
discovery.run()
|
discovery.run()
|
||||||
});
|
});
|
||||||
|
|
||||||
let reusable_credentials = session.login(credentials).unwrap();
|
let reusable_credentials = session.login(credentials).unwrap();
|
||||||
reusable_credentials.save_to_file(credentials_path);
|
if let Some(path) = credentials_path {
|
||||||
|
reusable_credentials.save_to_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
let player = Player::new(session.clone(), || DefaultSink::open());
|
let player = Player::new(session.clone(), || DefaultSink::open());
|
||||||
let spirc = SpircManager::new(session.clone(), player);
|
let spirc = SpircManager::new(session.clone(), player);
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub struct Config {
|
||||||
pub application_key: Vec<u8>,
|
pub application_key: Vec<u8>,
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
pub device_name: String,
|
pub device_name: String,
|
||||||
pub cache_location: PathBuf,
|
pub cache_location: Option<PathBuf>,
|
||||||
pub bitrate: Bitrate,
|
pub bitrate: Bitrate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,9 @@ pub struct Session(pub Arc<SessionInternal>);
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
pub fn new(config: Config) -> Session {
|
pub fn new(config: Config) -> Session {
|
||||||
mkdir_existing(&config.cache_location).unwrap();
|
if let Some(cache_location) = config.cache_location.as_ref() {
|
||||||
|
mkdir_existing(cache_location).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let device_id = {
|
let device_id = {
|
||||||
let mut h = Sha1::new();
|
let mut h = Sha1::new();
|
||||||
|
|
Loading…
Reference in a new issue