Add userRating entity to mpris metadata, with 0 and 1 corresponding to unsaved/not-liked and saved/liked in Spotify, respectively.

This commit is contained in:
George Hafiz
2021-10-14 12:40:54 +01:00
committed by Henrik Friedrichsen
parent 0c69e991b8
commit 49f2d40b44
2 changed files with 46 additions and 8 deletions

View File

@@ -186,15 +186,16 @@ async fn main() -> Result<(), String> {
let queue = Arc::new(queue::Queue::new(spotify.clone(), cfg.clone())); let queue = Arc::new(queue::Queue::new(spotify.clone(), cfg.clone()));
let library = Arc::new(Library::new(&event_manager, spotify.clone(), cfg.clone()));
#[cfg(feature = "mpris")] #[cfg(feature = "mpris")]
let mpris_manager = Arc::new(mpris::MprisManager::new( let mpris_manager = Arc::new(mpris::MprisManager::new(
event_manager.clone(), event_manager.clone(),
spotify.clone(), spotify.clone(),
queue.clone(), queue.clone(),
library.clone(),
)); ));
let library = Arc::new(Library::new(&event_manager, spotify.clone(), cfg.clone()));
let mut cmd_manager = CommandManager::new( let mut cmd_manager = CommandManager::new(
spotify.clone(), spotify.clone(),
queue.clone(), queue.clone(),

View File

@@ -13,6 +13,7 @@ use log::{debug, warn};
use crate::album::Album; use crate::album::Album;
use crate::episode::Episode; use crate::episode::Episode;
use crate::events::EventManager; use crate::events::EventManager;
use crate::library::Library;
use crate::playable::Playable; use crate::playable::Playable;
use crate::playlist::Playlist; use crate::playlist::Playlist;
use crate::queue::{Queue, RepeatSetting}; use crate::queue::{Queue, RepeatSetting};
@@ -35,7 +36,7 @@ fn get_playbackstatus(spotify: Spotify) -> String {
.to_string() .to_string()
} }
fn get_metadata(playable: Option<Playable>, spotify: Spotify) -> Metadata { fn get_metadata(playable: Option<Playable>, spotify: Spotify, library: Arc<Library>) -> Metadata {
let mut hm: Metadata = HashMap::new(); let mut hm: Metadata = HashMap::new();
// Fetch full track details in case this playable is based on a SimplifiedTrack // Fetch full track details in case this playable is based on a SimplifiedTrack
@@ -146,6 +147,20 @@ fn get_metadata(playable: Option<Playable>, spotify: Spotify) -> Metadata {
.unwrap_or_default(), .unwrap_or_default(),
)), )),
); );
hm.insert(
"xesam:userRating".to_string(),
Variant(Box::new(
playable
.and_then(|p| p.track())
.map(
|t| match library.is_saved_track(&Playable::Track(t.clone())) {
true => 1.0,
false => 0.0,
},
)
.unwrap_or(0.0) as f64,
)),
);
hm hm
} }
@@ -154,6 +169,7 @@ fn run_dbus_server(
ev: EventManager, ev: EventManager,
spotify: Spotify, spotify: Spotify,
queue: Arc<Queue>, queue: Arc<Queue>,
library: Arc<Library>,
rx: mpsc::Receiver<MprisState>, rx: mpsc::Receiver<MprisState>,
) { ) {
let conn = Rc::new( let conn = Rc::new(
@@ -277,10 +293,15 @@ fn run_dbus_server(
let property_metadata = { let property_metadata = {
let spotify = spotify.clone(); let spotify = spotify.clone();
let queue = queue.clone(); let queue = queue.clone();
let library = library.clone();
f.property::<HashMap<String, Variant<Box<dyn RefArg>>>, _>("Metadata", ()) f.property::<HashMap<String, Variant<Box<dyn RefArg>>>, _>("Metadata", ())
.access(Access::Read) .access(Access::Read)
.on_get(move |iter, _| { .on_get(move |iter, _| {
let hm = get_metadata(queue.clone().get_current(), spotify.clone()); let hm = get_metadata(
queue.clone().get_current(),
spotify.clone(),
library.clone(),
);
iter.append(hm); iter.append(hm);
Ok(()) Ok(())
@@ -690,7 +711,11 @@ fn run_dbus_server(
changed.interface_name = "org.mpris.MediaPlayer2.Player".to_string(); changed.interface_name = "org.mpris.MediaPlayer2.Player".to_string();
changed.changed_properties.insert( changed.changed_properties.insert(
"Metadata".to_string(), "Metadata".to_string(),
Variant(Box::new(get_metadata(state.1, spotify.clone()))), Variant(Box::new(get_metadata(
state.1,
spotify.clone(),
library.clone(),
))),
); );
changed changed
@@ -710,21 +735,33 @@ pub struct MprisManager {
tx: mpsc::Sender<MprisState>, tx: mpsc::Sender<MprisState>,
queue: Arc<Queue>, queue: Arc<Queue>,
spotify: Spotify, spotify: Spotify,
library: Arc<Library>,
} }
impl MprisManager { impl MprisManager {
pub fn new(ev: EventManager, spotify: Spotify, queue: Arc<Queue>) -> Self { pub fn new(
ev: EventManager,
spotify: Spotify,
queue: Arc<Queue>,
library: Arc<Library>,
) -> Self {
let (tx, rx) = mpsc::channel::<MprisState>(); let (tx, rx) = mpsc::channel::<MprisState>();
{ {
let spotify = spotify.clone(); let spotify = spotify.clone();
let queue = queue.clone(); let queue = queue.clone();
let library = library.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
run_dbus_server(ev, spotify.clone(), queue.clone(), rx); run_dbus_server(ev, spotify.clone(), queue.clone(), library.clone(), rx);
}); });
} }
MprisManager { tx, queue, spotify } MprisManager {
tx,
queue,
spotify,
library,
}
} }
pub fn update(&self) { pub fn update(&self) {