Add support for an MPD password
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Sijmen 2023-05-06 21:10:15 +02:00
parent 4455b9013b
commit ef46017ed8
Signed by: vijfhoek
GPG Key ID: DAF7821E067D9C48
3 changed files with 64 additions and 27 deletions

View File

@ -11,11 +11,12 @@
## Configuration ## Configuration
Empede is configured using environment variables: Empede is configured using environment variables:
| Name | Default | Description | | Name | Default | Description |
| --------------- | ------------ | --------------------------------- | | ---------------- | ------------ | --------------------------------- |
| **MPD_HOST** | localhost | MPD server host | | **MPD_HOST** | localhost | MPD server host |
| **MPD_PORT** | 6600 | MPD server port | | **MPD_PORT** | 6600 | MPD server port |
| **EMPEDE_BIND** | 0.0.0.0:8080 | Address for Empede to bind to | | **MPD_PASSWORD** | | MPD server password |
| **EMPEDE_BIND** | 0.0.0.0:8080 | Address for Empede to bind to |
## Running ## Running
### Linux ### Linux

View File

@ -165,8 +165,10 @@ async fn sse(_req: tide::Request<()>, sender: tide::sse::Sender) -> tide::Result
sender.send("playlist", "", None).await?; sender.send("playlist", "", None).await?;
sender.send("player", "", None).await?; sender.send("player", "", None).await?;
let mut mpd = mpd::Mpd::connect().await?;
loop { loop {
let systems = mpd::idle(&["playlist", "player", "database"]).await?; let systems = mpd.idle(&["playlist", "player", "database"]).await?;
for system in systems { for system in systems {
sender.send(&system, "", None).await?; sender.send(&system, "", None).await?;
} }

View File

@ -14,7 +14,14 @@ pub(crate) fn host() -> String {
} }
pub(crate) fn connect() -> Result<mpdrs::Client, mpdrs::error::Error> { pub(crate) fn connect() -> Result<mpdrs::Client, mpdrs::error::Error> {
mpdrs::Client::connect(host()) let mut client = mpdrs::Client::connect(host())?;
let password = std::env::var("MPD_PASSWORD").unwrap_or(String::new());
if !password.is_empty() {
client.login(&password)?;
}
Ok(client)
} }
pub(crate) fn ls(path: &str) -> anyhow::Result<Vec<Entry>> { pub(crate) fn ls(path: &str) -> anyhow::Result<Vec<Entry>> {
@ -91,31 +98,58 @@ pub(crate) enum Entry {
}, },
} }
pub(crate) async fn idle(systems: &[&str]) -> anyhow::Result<Vec<String>> { pub(crate) struct Mpd {
let mut stream = TcpStream::connect(host()).await?; stream: TcpStream,
let mut reader = BufReader::new(stream.clone()); reader: BufReader<TcpStream>,
}
// skip OK MPD line impl Mpd {
// TODO check if it is indeed OK fn escape_str(s: &str) -> String {
let mut buffer = String::new(); s.replace("\"", "\\\"").replace("'", "\\'")
reader.read_line(&mut buffer).await?; }
let systems = systems.join(" "); pub async fn connect() -> anyhow::Result<Self> {
let command = format!("idle {systems}\n"); let mut stream = TcpStream::connect(host()).await?;
stream.write_all(command.as_bytes()).await?; let mut reader = BufReader::new(stream.clone());
let mut updated = vec![]; // skip OK MPD line
loop { // TODO check if it is indeed OK
buffer.clear(); let mut buffer = String::new();
reader.read_line(&mut buffer).await?; reader.read_line(&mut buffer).await?;
if buffer == "OK\n" {
break Ok(updated); let password = std::env::var("MPD_PASSWORD").unwrap_or(String::new());
if !password.is_empty() {
let password = Self::escape_str(&password);
let command = format!("password \"{password}\"\n");
stream.write_all(command.as_bytes()).await?;
buffer.clear();
reader.read_line(&mut buffer).await?;
} }
let (_, changed) = buffer Ok(Self { stream, reader })
.trim_end() }
.split_once(": ")
.ok_or(anyhow!("unexpected response from MPD"))?; pub(crate) async fn idle(&mut self, systems: &[&str]) -> anyhow::Result<Vec<String>> {
updated.push(changed.to_string()); let mut buffer = String::new();
let systems = systems.join(" ");
let command = format!("idle {systems}\n");
self.stream.write_all(command.as_bytes()).await?;
let mut updated = vec![];
loop {
buffer.clear();
self.reader.read_line(&mut buffer).await?;
if buffer == "OK\n" {
break Ok(updated);
}
let (_, changed) = buffer
.trim_end()
.split_once(": ")
.ok_or(anyhow!("unexpected response from MPD"))?;
updated.push(changed.to_string());
}
} }
} }