Remove AudioFileManager and MetadataManager since they are stateless.

This commit is contained in:
Paul Lietar 2017-05-16 01:04:10 +01:00
parent 72070b6ce0
commit d59f3eff81
5 changed files with 31 additions and 60 deletions

View file

@ -4,11 +4,6 @@ applications to use Spotify's service, without using the official but
closed-source libspotify. Additionally, it will provide extra features
which are not available in the official library.
**I will be very busy with other stuff until July, and won't be able to
dedicate much time to librespot. Please keep using it and open issues,
but it's likely I won't be able to answer them until then. Non-trivial
pull requests will probably not be reviewed either.**
## Building
Rust 1.15.0 or later is required to build librespot.

View file

@ -16,10 +16,6 @@ use util::FileId;
const CHUNK_SIZE: usize = 0x20000;
component! {
AudioFileManager : AudioFileManagerInner { }
}
pub enum AudioFile {
Cached(fs::File),
Streaming(AudioFileStreaming),
@ -127,9 +123,9 @@ impl Future for AudioFileOpenStreaming {
}
}
impl AudioFileManager {
pub fn open(&self, file_id: FileId) -> AudioFileOpen {
let cache = self.session().cache().cloned();
impl AudioFile {
pub fn open(session: &Session, file_id: FileId) -> AudioFileOpen {
let cache = session.cache().cloned();
if let Some(file) = cache.as_ref().and_then(|cache| cache.file(file_id)) {
debug!("File {} already in cache", file_id);
@ -139,10 +135,10 @@ impl AudioFileManager {
debug!("Downloading file {}", file_id);
let (complete_tx, complete_rx) = oneshot::channel();
let (headers, data) = request_chunk(&self.session(), file_id, 0).split();
let (headers, data) = request_chunk(session, file_id, 0).split();
let open = AudioFileOpenStreaming {
session: self.session(),
session: session.clone(),
file_id: file_id,
headers: headers,
@ -151,10 +147,10 @@ impl AudioFileManager {
complete_tx: Some(complete_tx),
};
let session = self.session();
self.session().spawn(move |_| {
let session_ = session.clone();
session.spawn(move |_| {
complete_rx.map(move |mut file| {
if let Some(cache) = session.cache() {
if let Some(cache) = session_.cache() {
cache.save_file(file_id, &mut file);
debug!("File {} complete, saving to cache", file_id);
} else {

View file

@ -43,11 +43,24 @@ fn parse_restrictions<'s, I>(restrictions: I, country: &str, catalogue: &str) ->
(!has_allowed || countrylist_contains(allowed.as_str(), country))
}
pub trait MetadataTrait : Send + 'static {
pub trait Metadata : Send + Sized + 'static {
type Message: protobuf::MessageStatic;
fn base_url() -> &'static str;
fn parse(msg: &Self::Message, session: &Session) -> Self;
fn get(session: &Session, id: SpotifyId) -> BoxFuture<Self, MercuryError> {
let uri = format!("{}/{}", Self::base_url(), id.to_base16());
let request = session.mercury().get(uri);
let session = session.clone();
request.and_then(move |response| {
let data = response.payload.first().expect("Empty payload");
let msg: Self::Message = protobuf::parse_from_bytes(data).unwrap();
Ok(Self::parse(&msg, &session))
}).boxed()
}
}
#[derive(Debug, Clone)]
@ -77,7 +90,7 @@ pub struct Artist {
pub top_tracks: Vec<SpotifyId>,
}
impl MetadataTrait for Track {
impl Metadata for Track {
type Message = protocol::metadata::Track;
fn base_url() -> &'static str {
@ -120,7 +133,7 @@ impl MetadataTrait for Track {
}
}
impl MetadataTrait for Album {
impl Metadata for Album {
type Message = protocol::metadata::Album;
fn base_url() -> &'static str {
@ -163,7 +176,7 @@ impl MetadataTrait for Album {
}
impl MetadataTrait for Artist {
impl Metadata for Artist {
type Message = protocol::metadata::Artist;
fn base_url() -> &'static str {
@ -191,22 +204,3 @@ impl MetadataTrait for Artist {
}
}
component! {
MetadataManager : MetadataManagerInner { }
}
impl MetadataManager {
pub fn get<T: MetadataTrait>(&self, id: SpotifyId) -> BoxFuture<T, MercuryError> {
let session = self.session();
let uri = format!("{}/{}", T::base_url(), id.to_base16());
let request = session.mercury().get(uri);
request.and_then(move |response| {
let data = response.payload.first().expect("Empty payload");
let msg: T::Message = protobuf::parse_from_bytes(data).unwrap();
Ok(T::parse(&msg, &session))
}).boxed()
}
}

View file

@ -11,7 +11,7 @@ use vorbis::{self, VorbisError};
use audio_backend::Sink;
use audio_decrypt::AudioDecrypt;
use audio_file::AudioFile;
use metadata::{FileFormat, Track};
use metadata::{FileFormat, Track, Metadata};
use session::Session;
use mixer::AudioFilter;
use util::{self, SpotifyId, Subfile};
@ -338,7 +338,7 @@ impl PlayerInternal {
let alternatives = track.alternatives
.iter()
.map(|alt_id| {
self.session.metadata().get::<Track>(*alt_id)
Track::get(&self.session, *alt_id)
});
let alternatives = future::join_all(alternatives).wait().unwrap();
@ -347,7 +347,7 @@ impl PlayerInternal {
}
fn load_track(&self, track_id: SpotifyId, position: i64) -> Option<Decoder> {
let track = self.session.metadata().get::<Track>(track_id).wait().unwrap();
let track = Track::get(&self.session, track_id).wait().unwrap();
info!("Loading track \"{}\"", track.name);
@ -375,10 +375,9 @@ impl PlayerInternal {
let key = self.session.audio_key().request(track.id, file_id).wait().unwrap();
let open = self.session.audio_file().open(file_id);
let encrypted_file = open.wait().unwrap();
let encrypted_file = AudioFile::open(&self.session, file_id).wait().unwrap();
let audio_file = Subfile::new(AudioDecrypt::new(key, encrypted_file), 0xa7);
let mut decoder = vorbis::Decoder::new(audio_file).unwrap();
match vorbis_time_seek_ms(&mut decoder, position) {

View file

@ -18,8 +18,6 @@ use config::SessionConfig;
use audio_key::AudioKeyManager;
use channel::ChannelManager;
use mercury::MercuryManager;
use metadata::MetadataManager;
use audio_file::AudioFileManager;
pub struct SessionData {
country: String,
@ -33,10 +31,8 @@ pub struct SessionInternal {
tx_connection: mpsc::UnboundedSender<(u8, Vec<u8>)>,
audio_key: Lazy<AudioKeyManager>,
audio_file: Lazy<AudioFileManager>,
channel: Lazy<ChannelManager>,
mercury: Lazy<MercuryManager>,
metadata: Lazy<MetadataManager>,
cache: Option<Arc<Cache>>,
handle: Remote,
@ -62,6 +58,7 @@ impl Session {
{
let access_point = apresolve_or_fallback::<io::Error>(&handle);
let handle_ = handle.clone();
let connection = access_point.and_then(move |addr| {
info!("Connecting to AP \"{}\"", addr);
@ -114,10 +111,8 @@ impl Session {
cache: cache.map(Arc::new),
audio_key: Lazy::new(),
audio_file: Lazy::new(),
channel: Lazy::new(),
mercury: Lazy::new(),
metadata: Lazy::new(),
handle: handle.remote().clone(),
@ -139,10 +134,6 @@ impl Session {
self.0.audio_key.get(|| AudioKeyManager::new(self.weak()))
}
pub fn audio_file(&self) -> &AudioFileManager {
self.0.audio_file.get(|| AudioFileManager::new(self.weak()))
}
pub fn channel(&self) -> &ChannelManager {
self.0.channel.get(|| ChannelManager::new(self.weak()))
}
@ -151,10 +142,6 @@ impl Session {
self.0.mercury.get(|| MercuryManager::new(self.weak()))
}
pub fn metadata(&self) -> &MetadataManager {
self.0.metadata.get(|| MetadataManager::new(self.weak()))
}
pub fn spawn<F, R>(&self, f: F)
where F: FnOnce(&Handle) -> R + Send + 'static,
R: IntoFuture<Item=(), Error=()>,