Quellcode durchsuchen

Make cache directory optional.

If the -c argument is omitted, librespot will run without a cache, and
download tracks overtime they are played.
Paul Lietar vor 9 Jahren
Ursprung
Commit
a5453de572
3 geänderte Dateien mit 32 neuen und 29 gelöschten Zeilen
  1. 19 20
      src/audio_file.rs
  2. 9 7
      src/main.rs
  3. 4 2
      src/session.rs

+ 19 - 20
src/audio_file.rs

@@ -103,7 +103,7 @@ impl AudioFileLoading {
             let bitmap = shared.bitmap.lock().unwrap();
             if bitmap.len() >= shared.chunk_count {
                 drop(bitmap);
-                AudioFileLoading::store(session, &shared, &mut write_file);
+                AudioFileLoading::persist_to_cache(session, &shared, &mut write_file);
                 break;
             }
 
@@ -150,14 +150,14 @@ impl AudioFileLoading {
         shared.cond.notify_all();
     }
 
-    fn store(session: &Session, shared: &AudioFileShared, write_file: &mut NamedTempFile) {
-        write_file.seek(SeekFrom::Start(0)).unwrap();
+    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();
+            mkdir_existing(path.parent().unwrap()).unwrap();
 
-        mkdir_existing(&AudioFileManager::cache_dir(session, shared.file_id)).unwrap();
-
-        let mut f = fs::File::create(AudioFileManager::cache_path(session, shared.file_id))
-                        .unwrap();
-        io::copy(write_file, &mut f).unwrap();
+            let mut cache_file = fs::File::create(path).unwrap();
+            io::copy(write_file, &mut cache_file).unwrap();
+        }
     }
 }
 
@@ -217,20 +217,19 @@ impl AudioFileManager {
         AudioFileManager
     }
 
-    pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
-        let name = file_id.to_base16();
-        session.config().cache_location.join(&name[0..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 cache_path(session: &Session, file_id: FileId) -> Option<PathBuf> {
+        session.config().cache_location.as_ref().map(|cache| {
+            let name = file_id.to_base16();
+            cache.join(&name[0..2]).join(&name[2..])
+        })
     }
 
     pub fn request(&mut self, session: &Session, file_id: FileId) -> AudioFile {
-        match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
-            Ok(f) => AudioFile::Direct(f),
-            Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id)),
-        }
+        let cache_path = AudioFileManager::cache_path(session, file_id);
+        let cache_file = cache_path.and_then(|p| fs::File::open(p).ok());
+
+        cache_file.map(AudioFile::Direct).unwrap_or_else(|| {
+            AudioFile::Loading(AudioFileLoading::new(session, file_id))
+        })
     }
 }

+ 9 - 7
src/main.rs

@@ -33,7 +33,7 @@ fn main() {
     opts.reqopt("a", "appkey", "Path to a spotify appkey", "APPKEY")
         .optopt("u", "username", "Username to sign in with (optional)", "USERNAME")
         .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")
         .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 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 credentials = username.map(|u| {
@@ -91,21 +91,23 @@ fn main() {
 
     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)| {
         Credentials::with_password(username, password)
     }).or_else(|| {
-        File::open(&credentials_path).map(|file| {
-            Credentials::from_reader(file)
-        }).ok()
+        credentials_path.as_ref()
+                        .and_then(|p| File::open(p).ok())
+                        .map(Credentials::from_reader)
     }).unwrap_or_else(|| {
         let mut discovery = DiscoveryManager::new(session.clone());
         discovery.run()
     });
 
     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 spirc = SpircManager::new(session.clone(), player);

+ 4 - 2
src/session.rs

@@ -34,7 +34,7 @@ pub struct Config {
     pub application_key: Vec<u8>,
     pub user_agent: String,
     pub device_name: String,
-    pub cache_location: PathBuf,
+    pub cache_location: Option<PathBuf>,
     pub bitrate: Bitrate,
 }
 
@@ -62,7 +62,9 @@ pub struct Session(pub Arc<SessionInternal>);
 
 impl 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 mut h = Sha1::new();