Compare commits
5 commits
26a3381a25
...
dae598e15c
Author | SHA1 | Date | |
---|---|---|---|
dae598e15c | |||
9dfa38225f | |||
62651ea80b | |||
1cf1429753 | |||
05dddfde6d |
2 changed files with 41 additions and 34 deletions
10
src/main.rs
10
src/main.rs
|
@ -53,8 +53,14 @@ async fn get_player(_req: tide::Request<()>) -> tide::Result {
|
|||
let song = mpd.command("currentsong").await?.into_hashmap();
|
||||
let status = mpd.command("status").await?.into_hashmap();
|
||||
|
||||
let elapsed = status["elapsed"].parse().unwrap_or(0.0);
|
||||
let duration = status["duration"].parse().unwrap_or(1.0);
|
||||
let elapsed = status
|
||||
.get("elapsed")
|
||||
.and_then(|e| e.parse().ok())
|
||||
.unwrap_or(0.0);
|
||||
let duration = status
|
||||
.get("duration")
|
||||
.and_then(|e| e.parse().ok())
|
||||
.unwrap_or(1.0);
|
||||
|
||||
let mut template = PlayerTemplate {
|
||||
song: if song.is_empty() { None } else { Some(&song) },
|
||||
|
|
65
src/mpd.rs
65
src/mpd.rs
|
@ -49,6 +49,20 @@ pub struct CommandResult {
|
|||
}
|
||||
|
||||
impl CommandResult {
|
||||
pub fn new(properties: Vec<(String, String)>) -> Self {
|
||||
Self {
|
||||
properties,
|
||||
binary: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_binary(properties: Vec<(String, String)>, binary: Vec<u8>) -> Self {
|
||||
Self {
|
||||
properties,
|
||||
binary: Some(binary),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_hashmap(self) -> HashMap<String, String> {
|
||||
self.properties.into_iter().collect()
|
||||
}
|
||||
|
@ -84,28 +98,24 @@ impl Mpd {
|
|||
}
|
||||
|
||||
pub async fn connect() -> anyhow::Result<Self> {
|
||||
let mut stream = TcpStream::connect(host()).await?;
|
||||
let mut reader = BufReader::new(stream.clone());
|
||||
let stream = TcpStream::connect(host()).await?;
|
||||
let reader = BufReader::new(stream.clone());
|
||||
let mut this = Self { stream, reader };
|
||||
|
||||
// skip OK MPD line
|
||||
// TODO check if it is indeed OK
|
||||
let mut buffer = String::new();
|
||||
reader.read_line(&mut buffer).await?;
|
||||
this.reader.read_line(&mut buffer).await?;
|
||||
|
||||
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?;
|
||||
|
||||
reader.read_line(&mut buffer).await?;
|
||||
this.command(&format!(r#"password "{password}""#)).await?;
|
||||
}
|
||||
|
||||
stream.write_all(b"binarylimit 1048576\n").await?;
|
||||
buffer.clear();
|
||||
reader.read_line(&mut buffer).await?;
|
||||
this.command("binarylimit 1048576").await?;
|
||||
|
||||
Ok(Self { stream, reader })
|
||||
Ok(this)
|
||||
}
|
||||
|
||||
async fn read_binary_data(&mut self, size: usize) -> anyhow::Result<Vec<u8>> {
|
||||
|
@ -142,21 +152,15 @@ impl Mpd {
|
|||
|
||||
if key == "binary" {
|
||||
let binary = self.read_binary_data(value.parse()?).await?;
|
||||
|
||||
break Ok(CommandResult {
|
||||
properties,
|
||||
binary: Some(binary),
|
||||
});
|
||||
break Ok(CommandResult::new_binary(properties, binary));
|
||||
}
|
||||
} else if buffer.starts_with("OK") {
|
||||
break Ok(CommandResult {
|
||||
properties,
|
||||
binary: None,
|
||||
});
|
||||
break Ok(CommandResult::new(properties));
|
||||
} else if buffer.starts_with("ACK") {
|
||||
break Err(anyhow!(buffer));
|
||||
} else {
|
||||
println!("Unexpected MPD response {buffer}");
|
||||
break Err(anyhow!(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,16 +176,10 @@ impl Mpd {
|
|||
if !binary.is_empty() {
|
||||
buffer.append(&mut binary);
|
||||
} else {
|
||||
return Ok(CommandResult {
|
||||
properties: result.properties,
|
||||
binary: Some(buffer),
|
||||
});
|
||||
return Ok(CommandResult::new_binary(result.properties, buffer));
|
||||
}
|
||||
} else {
|
||||
return Ok(CommandResult {
|
||||
properties: result.properties,
|
||||
binary: None,
|
||||
});
|
||||
return Ok(CommandResult::new(result.properties));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +198,7 @@ impl Mpd {
|
|||
pub async fn add_pos(&mut self, path: &str, pos: &str) -> anyhow::Result<()> {
|
||||
let path = Self::escape_str(path);
|
||||
let pos = Self::escape_str(pos);
|
||||
self.command(&format!("add \"{path}\" \"{pos}\"")).await?;
|
||||
self.command(&format!(r#"add "{path}" "{pos}""#)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -223,7 +221,9 @@ impl Mpd {
|
|||
|
||||
pub async fn albumart(&mut self, path: &str) -> anyhow::Result<Vec<u8>> {
|
||||
let path = Self::escape_str(path);
|
||||
let result = self.command_binary(&format!("albumart \"{path}\"")).await?;
|
||||
let result = self
|
||||
.command_binary(&format!(r#"albumart "{path}""#))
|
||||
.await?;
|
||||
|
||||
match result.binary {
|
||||
Some(binary) => Ok(binary),
|
||||
|
@ -234,7 +234,7 @@ impl Mpd {
|
|||
pub async fn readpicture(&mut self, path: &str) -> anyhow::Result<Vec<u8>> {
|
||||
let path = Self::escape_str(path);
|
||||
let result = self
|
||||
.command_binary(&format!("readpicture \"{path}\""))
|
||||
.command_binary(&format!(r#"readpicture "{path}""#))
|
||||
.await?;
|
||||
|
||||
match result.binary {
|
||||
|
@ -252,8 +252,9 @@ impl Mpd {
|
|||
.unwrap_or("n/a".to_string())
|
||||
}
|
||||
|
||||
let path = Self::escape_str(path);
|
||||
let result = self
|
||||
.command(&format!("lsinfo \"{}\"", Self::escape_str(path)))
|
||||
.command(&format!(r#"lsinfo "{path}""#))
|
||||
.await?
|
||||
.into_hashmaps(&["file", "directory", "playlist"]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue