From 67deb072501abadec29bf41658b5047ee04ce8d1 Mon Sep 17 00:00:00 2001 From: michaelherger Date: Fri, 30 Jun 2017 08:43:11 +0200 Subject: [PATCH] Add --disable-audio-cache startup parameter (#204) Disable caching of downloaded audio files at runtime. Comes in handy when running librespot on a small device with SD card or other small storage. --- src/cache/default_cache.rs | 101 ------------------------------------- src/cache/mod.rs | 16 +++--- src/main.rs | 4 +- 3 files changed, 13 insertions(+), 108 deletions(-) delete mode 100644 src/cache/default_cache.rs diff --git a/src/cache/default_cache.rs b/src/cache/default_cache.rs deleted file mode 100644 index 5c7412ad..00000000 --- a/src/cache/default_cache.rs +++ /dev/null @@ -1,101 +0,0 @@ -use std::path::PathBuf; -use std::io::Read; -use std::fs::File; - -use util::{SpotifyId, FileId, ReadSeek, mkdir_existing}; -use authentication::Credentials; -use audio_key::AudioKey; - -use super::Cache; - -pub struct DefaultCache { - environment: lmdb::Environment, - root: PathBuf, -} - -impl DefaultCache { - pub fn new(location: PathBuf) -> Result { - let env = lmdb::EnvBuilder::new().max_dbs(5).open(&location.join("db"), 0o755).unwrap(); - - mkdir_existing(&location).unwrap(); - mkdir_existing(&location.join("files")).unwrap(); - - Ok(DefaultCache { - environment: env, - root: location - }) - } - - fn audio_keys(&self) -> MdbResult { - self.environment.create_db("audio-keys", lmdb::DbFlags::empty()) - } - - fn file_path(&self, file: FileId) -> PathBuf { - let name = file.to_base16(); - self.root.join("files").join(&name[0..2]).join(&name[2..]) - } - - fn credentials_path(&self) -> PathBuf { - self.root.join("credentials.json") - } -} - -impl Cache for DefaultCache { - fn get_audio_key(&self, track: SpotifyId, file: FileId) -> Option { - let reader = self.environment.get_reader().unwrap(); - let handle = self.audio_keys().unwrap(); - let db = reader.bind(&handle); - - let mut key = Vec::new(); - key.extend_from_slice(&track.to_raw()); - key.extend_from_slice(&file.0); - - let value : Option> = db.get(&key).ok(); - value.and_then(|value| if value.len() == 16 { - let mut result = [0u8; 16]; - result.clone_from_slice(&value); - Some(AudioKey(result)) - } else { - None - }) - } - - fn put_audio_key(&self, track: SpotifyId, file: FileId, audio_key: AudioKey) { - let xact = self.environment.new_transaction().unwrap(); - let handle = self.audio_keys().unwrap(); - - { - let db = xact.bind(&handle); - - let mut key = Vec::new(); - key.extend_from_slice(&track.to_raw()); - key.extend_from_slice(&file.0); - - db.set(&key, &audio_key.0.as_ref()).unwrap(); - } - - xact.commit().unwrap(); - } - - fn get_credentials(&self) -> Option { - let path = self.credentials_path(); - Credentials::from_file(path) - } - fn put_credentials(&self, cred: &Credentials) { - let path = self.credentials_path(); - cred.save_to_file(&path); - } - - fn get_file(&self, file: FileId) -> Option> { - File::open(self.file_path(file)).ok().map(|f| Box::new(f) as Box) - } - - fn put_file(&self, file: FileId, contents: &mut Read) { - let path = self.file_path(file); - - mkdir_existing(path.parent().unwrap()).unwrap(); - - let mut cache_file = File::create(path).unwrap(); - ::std::io::copy(contents, &mut cache_file).unwrap(); - } -} diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 6e8f8631..28b787ff 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -8,15 +8,17 @@ use authentication::Credentials; #[derive(Clone)] pub struct Cache { root: PathBuf, + use_audio_cache: bool, } impl Cache { - pub fn new(location: PathBuf) -> Cache { + pub fn new(location: PathBuf, use_audio_cache: bool) -> Cache { mkdir_existing(&location).unwrap(); mkdir_existing(&location.join("files")).unwrap(); Cache { - root: location + root: location, + use_audio_cache: use_audio_cache } } } @@ -48,11 +50,13 @@ impl Cache { } pub fn save_file(&self, file: FileId, contents: &mut Read) { - let path = self.file_path(file); + if self.use_audio_cache { + let path = self.file_path(file); - mkdir_existing(path.parent().unwrap()).unwrap(); + mkdir_existing(path.parent().unwrap()).unwrap(); - let mut cache_file = File::create(path).unwrap(); - ::std::io::copy(contents, &mut cache_file).unwrap(); + let mut cache_file = File::create(path).unwrap(); + ::std::io::copy(contents, &mut cache_file).unwrap(); + } } } diff --git a/src/main.rs b/src/main.rs index 38c57fd3..abab6483 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,6 +86,7 @@ struct Setup { fn setup(args: &[String]) -> Setup { let mut opts = getopts::Options::new(); opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE") + .optflag("", "disable-audio-cache", "Disable caching of the audio data.") .reqopt("n", "name", "Device name", "NAME") .optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE") .optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM") @@ -133,9 +134,10 @@ fn setup(args: &[String]) -> Setup { let name = matches.opt_str("name").unwrap(); let device_id = librespot::session::device_id(&name); + let use_audio_cache = !matches.opt_present("disable-audio-cache"); let cache = matches.opt_str("c").map(|cache_location| { - Cache::new(PathBuf::from(cache_location)) + Cache::new(PathBuf::from(cache_location), use_audio_cache) }); let cached_credentials = cache.as_ref().and_then(Cache::credentials);