Spotify URL support for MPRIS OpenUri function (#314)
* Added OpenUri D-BUS MPRIS support. Removed "user:" from URIType check because Spotify doesn't always provide it. * Added tags to .gitignore * Changed mpris metadata to actually return the track's url instead of the Spotify URI so that it matches the functionality of the official Spotify client. * Changed mpris:trackid and xesam:url to not use static naming so it can support podcasts. * Changed xesam:url to default to an empty string instead of "0" * Added possibility to start playing Shows and Episodes via MPRIS. Added possibility to search for Podcast Episodes. * Fixed mpris:trackid not returning the id in the correct format. MPRIS OpenUri function now supports Spotify url links. * return result directly instead of mut string * handle artist URLs/URIs Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
This commit is contained in:
33
src/mpris.rs
33
src/mpris.rs
@@ -21,6 +21,7 @@ use crate::show::Show;
|
||||
use crate::spotify::{PlayerEvent, Spotify, URIType};
|
||||
use crate::track::Track;
|
||||
use crate::traits::ListItem;
|
||||
use regex::Regex;
|
||||
|
||||
type Metadata = HashMap<String, Variant<Box<dyn RefArg>>>;
|
||||
|
||||
@@ -41,12 +42,7 @@ fn get_metadata(playable: Option<Playable>) -> Metadata {
|
||||
|
||||
hm.insert(
|
||||
"mpris:trackid".to_string(),
|
||||
Variant(Box::new(Path::from(format!(
|
||||
"/org/ncspot/{}",
|
||||
playable
|
||||
.map(|t| t.uri().replace(':', "/"))
|
||||
.unwrap_or_else(|| "0".to_string())
|
||||
)))),
|
||||
Variant(Box::new(playable.map(|t| t.uri()).unwrap_or_default())),
|
||||
);
|
||||
hm.insert(
|
||||
"mpris:length".to_string(),
|
||||
@@ -481,11 +477,22 @@ fn run_dbus_server(spotify: Arc<Spotify>, queue: Arc<Queue>, rx: mpsc::Receiver<
|
||||
f.method("OpenUri", (), move |m| {
|
||||
let uri_data: Option<&str> = m.msg.get1();
|
||||
let uri = match uri_data {
|
||||
Some(s) => s,
|
||||
None => "",
|
||||
Some(s) => {
|
||||
let spotify_uri = if s.contains("open.spotify.com") {
|
||||
let regex = Regex::new(r"https?://open\.spotify\.com(/user)?/(album|track|playlist|show|episode)/(.+)(\?si=\S+)?").unwrap();
|
||||
let captures = regex.captures(s).unwrap();
|
||||
let uri_type = &captures[2];
|
||||
let id = &captures[3];
|
||||
format!("spotify:{}:{}", uri_type, id)
|
||||
}else {
|
||||
s.to_string()
|
||||
};
|
||||
spotify_uri
|
||||
}
|
||||
None => "".to_string(),
|
||||
};
|
||||
let id = &uri[uri.rfind(':').unwrap_or(0) + 1..uri.len()];
|
||||
let uri_type = URIType::from_uri(uri);
|
||||
let uri_type = URIType::from_uri(&uri);
|
||||
match uri_type {
|
||||
Some(URIType::Album) => {
|
||||
if let Some(a) = spotify.album(&id) {
|
||||
@@ -548,7 +555,13 @@ fn run_dbus_server(spotify: Arc<Spotify>, queue: Arc<Queue>, rx: mpsc::Receiver<
|
||||
queue.play(0, false, false)
|
||||
}
|
||||
}
|
||||
Some(URIType::Artist) => {}
|
||||
Some(URIType::Artist) => {
|
||||
if let Some(a) = spotify.artist_top_tracks(&id) {
|
||||
queue.clear();
|
||||
queue.append_next(a.iter().map(|track| Playable::Track(track.clone())).collect());
|
||||
queue.play(0, false, false)
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Ok(vec![m.msg.method_return()])
|
||||
|
||||
@@ -822,8 +822,8 @@ impl Spotify {
|
||||
self.api_with_retry(|api| api.user_playlist_follow_playlist(&owner_id, &id, true))
|
||||
}
|
||||
|
||||
pub fn artist_top_tracks(&self, id: String) -> Option<Vec<Track>> {
|
||||
self.api_with_retry(|api| api.artist_top_tracks(&id, None))
|
||||
pub fn artist_top_tracks(&self, id: &str) -> Option<Vec<Track>> {
|
||||
self.api_with_retry(|api| api.artist_top_tracks(id, None))
|
||||
.map(|ft| ft.tracks.iter().map(|t| t.into()).collect())
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ impl ArtistView {
|
||||
let library = library.clone();
|
||||
thread::spawn(move || {
|
||||
if let Some(id) = id {
|
||||
if let Some(tracks) = spotify.artist_top_tracks(id) {
|
||||
if let Some(tracks) = spotify.artist_top_tracks(&id) {
|
||||
top_tracks.write().unwrap().extend(tracks);
|
||||
library.trigger_redraw();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user