Skip to content

Commit 9ebccd3

Browse files
committed
Upgrade almost everything except for dbus_mpris
1 parent d6b1ea5 commit 9ebccd3

8 files changed

+1371
-1079
lines changed

Cargo.lock

+1,239-967
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,26 @@ daemonize = "0.4"
1414
dbus = { version = "0.6", optional = true }
1515
dbus-tokio = { version = "0.2", optional = true }
1616
fern = { version = "0.6.0", features = ["syslog-4"] }
17-
futures = "0.1"
17+
futures = "0.3.15"
1818
gethostname = "0.2.0"
1919
hex = "0.4"
2020
keyring = { version = "0.10.1", optional = true }
2121
libc = "0.2.82"
2222
log = "0.4.6"
2323
percent-encoding = "2.1.0"
24+
reqwest = "0.11.3"
2425
rspotify = "0.8.0"
2526
serde = { version = "1.0.115", features = ["derive"] }
2627
sha-1 = "0.9"
2728
structopt = "0.3.17"
2829
syslog = "4"
29-
tokio-core = "0.1"
30-
tokio-io = "0.1"
31-
tokio-signal = "0.1"
30+
tokio = "1.6.1"
31+
tokio-compat = { version = "0.1.6", features = ["rt-current-thread"] }
32+
tokio-compat-02 = "0.2.0"
33+
tokio-stream = "0.1.7"
3234
url = "1.7"
3335
xdg = "2.2"
34-
librespot = { version = "0.1.5", default-features = false, features = ["with-tremor"] }
36+
librespot = { version = "0.2.0", default-features = false, features = ["with-tremor"] }
3537
toml = "0.5.8"
3638
color-eyre = "0.5"
3739

src/config.rs

+28-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use serde::{de::Error, de::Unexpected, Deserialize, Deserializer};
1414
use sha1::{Digest, Sha1};
1515
use std::{fmt, fs, path::PathBuf, str::FromStr, string::ToString};
1616
use structopt::{clap::AppSettings, StructOpt};
17-
use url::Url;
17+
use reqwest::Url;
1818

1919
const CONFIG_FILE_NAME: &str = "spotifyd.conf";
2020

@@ -128,10 +128,12 @@ impl From<LSDeviceType> for DeviceType {
128128
LSDeviceType::Tablet => DeviceType::Tablet,
129129
LSDeviceType::Smartphone => DeviceType::Smartphone,
130130
LSDeviceType::Speaker => DeviceType::Speaker,
131-
LSDeviceType::TV => DeviceType::TV,
132-
LSDeviceType::AVR => DeviceType::AVR,
133-
LSDeviceType::STB => DeviceType::STB,
131+
LSDeviceType::Tv => DeviceType::TV,
132+
LSDeviceType::Avr => DeviceType::AVR,
133+
LSDeviceType::Stb => DeviceType::STB,
134134
LSDeviceType::AudioDongle => DeviceType::AudioDongle,
135+
// TODO: Implement new LibreSpot device types in Spotifyd
136+
_ => DeviceType::Unknown,
135137
}
136138
}
137139
}
@@ -144,9 +146,9 @@ impl From<&DeviceType> for LSDeviceType {
144146
DeviceType::Tablet => LSDeviceType::Tablet,
145147
DeviceType::Smartphone => LSDeviceType::Smartphone,
146148
DeviceType::Speaker => LSDeviceType::Speaker,
147-
DeviceType::TV => LSDeviceType::TV,
148-
DeviceType::AVR => LSDeviceType::AVR,
149-
DeviceType::STB => LSDeviceType::STB,
149+
DeviceType::TV => LSDeviceType::Tv,
150+
DeviceType::AVR => LSDeviceType::Avr,
151+
DeviceType::STB => LSDeviceType::Stb,
150152
DeviceType::AudioDongle => LSDeviceType::AudioDongle,
151153
}
152154
}
@@ -419,7 +421,7 @@ impl fmt::Debug for SharedConfigValues {
419421
None => None,
420422
}
421423
};
422-
};
424+
}
423425

424426
let password_value = extract_credential!(&self.password);
425427

@@ -576,7 +578,9 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
576578
.shared_config
577579
.cache_path
578580
.map(PathBuf::from)
579-
.map(|path| Cache::new(path, audio_cache));
581+
// TODO: plumb size limits, check audio_cache?
582+
// TODO: rather than silently disabling cache if constructor fails, maybe we should handle the error?
583+
.map(|path| Cache::new(Some(path.clone()), if audio_cache { Some(path.clone()) } else { None }, None).ok()).flatten();
580584

581585
let bitrate: LSBitrate = config
582586
.shared_config
@@ -676,6 +680,19 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
676680
},
677681
None => info!("No proxy specified"),
678682
}
683+
684+
// TODO: when we were on librespot 0.1.5, all PlayerConfig values were available in the
685+
// Spotifyd config. The upgrade to librespot 0.2.0 introduces new config variables, and we
686+
// should consider adding them to Spotifyd's config system.
687+
let pc = {
688+
let mut pc = PlayerConfig::default();
689+
pc.bitrate = bitrate;
690+
pc.normalisation = config.shared_config.volume_normalisation;
691+
pc.normalisation_pregain = normalisation_pregain;
692+
pc.gapless = true;
693+
pc
694+
};
695+
679696
SpotifydConfig {
680697
username,
681698
password,
@@ -689,14 +706,9 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
689706
volume_controller,
690707
initial_volume,
691708
device_name,
692-
player_config: PlayerConfig {
693-
bitrate,
694-
normalisation: config.shared_config.volume_normalisation,
695-
normalisation_pregain,
696-
gapless: true,
697-
},
709+
player_config: pc,
698710
session_config: SessionConfig {
699-
user_agent: version::version_string(),
711+
user_agent: version::VERSION_STRING.to_string(),
700712
device_id,
701713
proxy: proxy_url,
702714
ap_port: Some(443),

src/dbus_mpris.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use dbus_tokio::{
88
tree::{AFactory, ATree, ATreeServer},
99
AConnection,
1010
};
11-
use futures::{sync::oneshot, Async, Future, Poll, Stream};
11+
use futures::{self, Future, FutureExt};
12+
use futures::channel::oneshot;
1213
use librespot::{
1314
connect::spirc::Spirc,
1415
core::{
@@ -24,15 +25,15 @@ use rspotify::spotify::{
2425
util::datetime_to_timestamp,
2526
};
2627
use std::{collections::HashMap, env, rc::Rc, thread};
27-
use tokio_core::reactor::Handle;
28+
use std::pin::Pin;
29+
use futures::task::{Context, Poll};
2830

2931
pub struct DbusServer {
3032
session: Session,
31-
handle: Handle,
3233
spirc: Rc<Spirc>,
3334
api_token: RspotifyToken,
34-
token_request: Option<Box<dyn Future<Item = LibrespotToken, Error = MercuryError>>>,
35-
dbus_future: Option<Box<dyn Future<Item = (), Error = ()>>>,
35+
token_request: Option<Pin<Box<dyn Future<Output=Result<LibrespotToken, MercuryError>>>>>,
36+
dbus_future: Option<Pin<Box<dyn Future<Output = ()>>>>,
3637
device_name: String,
3738
}
3839

@@ -47,13 +48,11 @@ const SCOPE: &str = "user-read-playback-state,user-read-private,\
4748
impl DbusServer {
4849
pub fn new(
4950
session: Session,
50-
handle: Handle,
5151
spirc: Rc<Spirc>,
5252
device_name: String,
5353
) -> DbusServer {
5454
DbusServer {
5555
session,
56-
handle,
5756
spirc,
5857
api_token: RspotifyToken::default(),
5958
token_request: None,
@@ -72,20 +71,18 @@ impl DbusServer {
7271
}
7372

7473
impl Future for DbusServer {
75-
type Error = ();
76-
type Item = ();
74+
type Output = ();
7775

78-
fn poll(&mut self) -> Poll<(), ()> {
76+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
7977
let mut got_new_token = false;
8078
if self.is_token_expired() {
8179
if let Some(ref mut fut) = self.token_request {
82-
if let Async::Ready(token) = fut.poll().unwrap() {
80+
if let Poll::Ready(Ok(token)) = fut.as_mut().poll(cx) {
8381
self.api_token = RspotifyToken::default()
8482
.access_token(&token.access_token)
8583
.expires_in(token.expires_in)
8684
.expires_at(datetime_to_timestamp(token.expires_in));
8785
self.dbus_future = Some(create_dbus_server(
88-
self.handle.clone(),
8986
self.api_token.clone(),
9087
self.spirc.clone(),
9188
self.device_name.clone(),
@@ -96,17 +93,17 @@ impl Future for DbusServer {
9693
// This is more meant as a fast hotfix than anything else!
9794
let client_id =
9895
env::var("SPOTIFYD_CLIENT_ID").unwrap_or_else(|_| CLIENT_ID.to_string());
99-
self.token_request = Some(get_token(&self.session, &client_id, SCOPE));
96+
self.token_request = Some(Box::pin(get_token(&self.session.clone(), &client_id, SCOPE)));
10097
}
10198
} else if let Some(ref mut fut) = self.dbus_future {
102-
return fut.poll();
99+
return fut.as_mut().poll(cx);
103100
}
104101

105102
if got_new_token {
106103
self.token_request = None;
107104
}
108105

109-
Ok(Async::NotReady)
106+
Poll::Pending
110107
}
111108
}
112109

@@ -115,29 +112,31 @@ fn create_spotify_api(token: &RspotifyToken) -> Spotify {
115112
}
116113

117114
fn create_dbus_server(
118-
handle: Handle,
119115
api_token: RspotifyToken,
120116
spirc: Rc<Spirc>,
121117
device_name: String,
122-
) -> Box<dyn Future<Item = (), Error = ()>> {
118+
) -> Pin<Box<dyn Future<Output = ()>>> {
123119
macro_rules! spotify_api_method {
124120
([ $sp:ident, $device:ident $(, $m:ident: $t:ty)*] $f:expr) => {
125121
{
126122
let device_name = utf8_percent_encode(&device_name, NON_ALPHANUMERIC).to_string();
127123
let token = api_token.clone();
128124
move |m| {
129-
let (p, c) = oneshot::channel();
125+
let (tx, rx) = oneshot::channel();
130126
let token = token.clone();
131127
let device_name = device_name.clone();
132128
$(let $m: Result<$t,_> = m.msg.read1();)*
133129
thread::spawn(move || {
134130
let $sp = create_spotify_api(&token);
135131
let $device = Some(device_name);
136132
let _ = $f;
137-
let _ = p.send(());
133+
let _ = tx.send(());
138134
});
139135
let mret = m.msg.method_return();
140-
c.map_err(|e| MethodErr::failed(&e)).map(|_| vec![mret])
136+
rx.map(|val| match val {
137+
Ok(_) => Ok(vec![mret]),
138+
Err(e) => Err(MethodErr::failed(&e)),
139+
}).into()
141140
}
142141
}
143142
}
@@ -638,6 +637,8 @@ fn create_dbus_server(
638637
tree.set_registered(&connection, true)
639638
.expect("Failed to register tree");
640639

640+
//let handle = tokio_compat::runtime::Handle::current();
641+
641642
let async_connection = AConnection::new(connection.clone(), handle)
642643
.expect("Failed to create async dbus connection");
643644

@@ -649,7 +650,7 @@ fn create_dbus_server(
649650
.expect("Failed to unwrap async messages"),
650651
);
651652

652-
Box::new(server.for_each(|message| {
653+
Box::pin(server.for_each(|message| {
653654
warn!("Unhandled DBus message: {:?}", message);
654655
Ok(())
655656
}))

src/main.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use daemonize::Daemonize;
66
use log::{error, info, trace, LevelFilter};
77
use std::panic;
88
use structopt::StructOpt;
9-
use tokio_core::reactor::Core;
9+
use tokio::runtime::Runtime;
1010

1111
#[cfg(feature = "alsa_backend")]
1212
mod alsa_mixer;
@@ -104,11 +104,11 @@ fn main() -> Result<(), Report> {
104104
);
105105
}));
106106

107-
let mut core = Core::new().unwrap();
108-
let handle = core.handle();
109-
110-
let initial_state = setup::initial_state(handle, internal_config);
111-
core.run(initial_state).unwrap();
107+
let runtime = Runtime::new().unwrap();
108+
runtime.block_on(async {
109+
let initial_state = setup::initial_state(internal_config);
110+
initial_state.await;
111+
});
112112

113113
Ok(())
114114
}

0 commit comments

Comments
 (0)