Mercurial > beefweb_mpris
comparison src/beefweb.rs @ 2:594c0f9d7972
errr
| author | Paper <paper@tflc.us> |
|---|---|
| date | Sat, 04 Apr 2026 16:04:31 -0400 |
| parents | a5ee18c79a04 |
| children | 18f743c980fa |
comparison
equal
deleted
inserted
replaced
| 1:a5ee18c79a04 | 2:594c0f9d7972 |
|---|---|
| 16 * You should have received a copy of the GNU General Public License | 16 * You should have received a copy of the GNU General Public License |
| 17 * along with this program; if not, see | 17 * along with this program; if not, see |
| 18 * <https://www.gnu.org/licenses/>. | 18 * <https://www.gnu.org/licenses/>. |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 /* Fuck off, I don't care. */ | |
| 22 #![allow(nonstandard_style)] | |
| 23 | |
| 21 #[derive(serde::Serialize, serde::Deserialize, Debug)] | 24 #[derive(serde::Serialize, serde::Deserialize, Debug)] |
| 22 pub struct PlayerInfo { | 25 pub struct PlayerInfo { |
| 23 pub name: String, | 26 pub name: String, |
| 24 pub title: String, | 27 pub title: String, |
| 25 pub version: String, | 28 pub version: String, |
| 69 #[serde(rename = "changeClientConfig")] | 72 #[serde(rename = "changeClientConfig")] |
| 70 pub change_client_config: bool, | 73 pub change_client_config: bool, |
| 71 } | 74 } |
| 72 | 75 |
| 73 #[derive(serde::Serialize, serde::Deserialize, Debug)] | 76 #[derive(serde::Serialize, serde::Deserialize, Debug)] |
| 77 pub enum PlaybackState { | |
| 78 #[serde(rename = "stopped")] | |
| 79 STOPPED, | |
| 80 #[serde(rename = "playing")] | |
| 81 PLAYING, | |
| 82 #[serde(rename = "paused")] | |
| 83 PAUSED, | |
| 84 } | |
| 85 | |
| 86 /* fb2k playback order */ | |
| 87 #[derive(Debug)] | |
| 88 pub enum PlaybackOrder { | |
| 89 DEFAULT, | |
| 90 REPEAT_PLAYLIST, | |
| 91 REPEAT_TRACK, | |
| 92 RANDOM, | |
| 93 SHUFFLE_TRACKS, | |
| 94 SHUFFLE_ALBUMS, | |
| 95 SHUFFLE_FOLDERS, | |
| 96 } | |
| 97 | |
| 98 #[derive(serde::Serialize, serde::Deserialize, Debug)] | |
| 99 #[serde(tag = "type")] | |
| 100 pub enum Options { | |
| 101 #[serde(rename = "enum")] | |
| 102 Enumeration { | |
| 103 #[serde(rename = "enumNames")] | |
| 104 enum_names: Vec<String>, | |
| 105 id: String, | |
| 106 name: String, | |
| 107 value: i64, | |
| 108 }, | |
| 109 #[serde(rename = "bool")] | |
| 110 Boolean { | |
| 111 id: String, | |
| 112 name: String, | |
| 113 value: bool, | |
| 114 }, | |
| 115 } | |
| 116 | |
| 117 #[derive(serde::Serialize, serde::Deserialize, Debug)] | |
| 74 pub struct Player { | 118 pub struct Player { |
| 75 pub info: PlayerInfo, | 119 pub info: PlayerInfo, |
| 76 #[serde(rename = "activeItem")] | 120 #[serde(rename = "activeItem")] |
| 77 pub active_item: ActiveItemInfo, | 121 pub active_item: ActiveItemInfo, |
| 78 /* XXX actually an enum */ | 122 /* XXX actually an enum */ |
| 79 #[serde(rename = "playbackState")] | 123 #[serde(rename = "playbackState")] |
| 80 pub playback_state: String, | 124 pub playback_state: PlaybackState, |
| 81 pub volume: VolumeInfo, | 125 pub volume: VolumeInfo, |
| 82 pub permissions: ApiPermissions, | 126 pub permissions: ApiPermissions, |
| 127 | |
| 128 options: Option<Vec<Options>>, | |
| 129 | |
| 130 /* these two fields are deprecated, | |
| 131 * replaced with "options" array */ | |
| 132 #[serde(skip_serializing_if = "Option::is_none")] | |
| 133 playbackMode: Option<i64>, | |
| 134 | |
| 135 #[serde(skip_serializing_if = "Option::is_none")] | |
| 136 playbackModes: Option<Vec<String>>, | |
| 83 } | 137 } |
| 84 | 138 |
| 85 /* {"player": {struct Player}} */ | 139 /* {"player": {struct Player}} */ |
| 86 #[derive(serde::Serialize, serde::Deserialize, Debug)] | 140 #[derive(serde::Serialize, serde::Deserialize, Debug)] |
| 87 struct PlayerHelper { | 141 struct PlayerHelper { |
| 156 .json::<PlayerHelper>() | 210 .json::<PlayerHelper>() |
| 157 .await? | 211 .await? |
| 158 .player); | 212 .player); |
| 159 } | 213 } |
| 160 | 214 |
| 215 fn playback_order_lookup(playback_order: &str) -> Option<PlaybackOrder> | |
| 216 { | |
| 217 return match playback_order { | |
| 218 "Default" => return Some(PlaybackOrder::DEFAULT), | |
| 219 "Repeat (playlist)" => return Some(PlaybackOrder::REPEAT_PLAYLIST), | |
| 220 "Repeat (track)" => return Some(PlaybackOrder::REPEAT_TRACK), | |
| 221 "Random" => return Some(PlaybackOrder::RANDOM), | |
| 222 "Shuffle (tracks)" => return Some(PlaybackOrder::SHUFFLE_TRACKS), | |
| 223 "Shuffle (albums)" => return Some(PlaybackOrder::SHUFFLE_ALBUMS), | |
| 224 "Shuffle (folders)" => return Some(PlaybackOrder::SHUFFLE_FOLDERS), | |
| 225 _ => None, | |
| 226 }; | |
| 227 } | |
| 228 | |
| 229 fn playback_order_cruft(v: &Vec<String>, s: i64) -> Option<PlaybackOrder> | |
| 230 { | |
| 231 let x = v.get(s as usize); | |
| 232 | |
| 233 match x { | |
| 234 Some(y) => return Self::playback_order_lookup(y), | |
| 235 _ => (), | |
| 236 }; | |
| 237 | |
| 238 return None; | |
| 239 } | |
| 240 | |
| 241 pub async fn playback_order(&self) -> Result<PlaybackOrder, anyhow::Error> | |
| 242 { | |
| 243 let p = self.player().await?; | |
| 244 | |
| 245 match p.options { | |
| 246 Some(x) => { | |
| 247 for i in x { | |
| 248 match i { | |
| 249 Options::Enumeration { enum_names: e, id: id, name: _, value: v } => { | |
| 250 match id.as_str() { | |
| 251 "playbackOrder" => { | |
| 252 match Self::playback_order_cruft(&e, v) { | |
| 253 Some(z) => return Ok(z), | |
| 254 _ => (), | |
| 255 }; | |
| 256 }, | |
| 257 _ => (), | |
| 258 }; | |
| 259 }, | |
| 260 _ => (), | |
| 261 }; | |
| 262 } | |
| 263 }, | |
| 264 _ => (), | |
| 265 } | |
| 266 | |
| 267 match p.playbackModes { | |
| 268 Some(x) => { | |
| 269 match p.playbackMode { | |
| 270 Some(y) => { | |
| 271 match Self::playback_order_cruft(&x, y) { | |
| 272 Some(v) => return Ok(v), | |
| 273 _ => (), | |
| 274 } | |
| 275 }, | |
| 276 _ => (), | |
| 277 }; | |
| 278 } | |
| 279 _ => (), | |
| 280 } | |
| 281 | |
| 282 return Err(anyhow::anyhow!("Unknown or invalid playback order?")); | |
| 283 } | |
| 284 | |
| 161 pub async fn volume(&self) -> Result<VolumeInfo, anyhow::Error> | 285 pub async fn volume(&self) -> Result<VolumeInfo, anyhow::Error> |
| 162 { | 286 { |
| 163 return Ok(self.player().await?.volume); | 287 return Ok(self.player().await?.volume); |
| 164 } | 288 } |
| 165 | 289 |
| 235 | 359 |
| 236 pub async fn set_position(&self, position: f64) -> Result<(), anyhow::Error> | 360 pub async fn set_position(&self, position: f64) -> Result<(), anyhow::Error> |
| 237 { | 361 { |
| 238 return self.set_player(&SetPlayer { | 362 return self.set_player(&SetPlayer { |
| 239 volume: None, | 363 volume: None, |
| 240 relative_volume: Some(position), | 364 relative_volume: None, |
| 365 muted: None, | |
| 366 position: Some(position), | |
| 367 relative_position: None, | |
| 368 options: None, | |
| 369 }).await; | |
| 370 } | |
| 371 | |
| 372 /* TODO -- finish this; need to link between string and enum | |
| 373 | |
| 374 pub async fn set_playback_order(&self, ) -> Result<(), anyhow::Error> | |
| 375 { | |
| 376 let p = self.set_player(&SetPlayer { | |
| 377 volume: None, | |
| 378 relative_volume: None, | |
| 241 muted: None, | 379 muted: None, |
| 242 position: None, | 380 position: None, |
| 243 relative_position: None, | 381 relative_position: None, |
| 244 options: None, | 382 options: |
| 245 }).await; | 383 }) |
| 246 } | 384 } |
| 385 */ | |
| 247 | 386 |
| 248 pub async fn playlist_items(&self, playlist_id: &str, offset: i64, count: i64, columns: Vec<&str>) -> Result<PlaylistItems, anyhow::Error> | 387 pub async fn playlist_items(&self, playlist_id: &str, offset: i64, count: i64, columns: Vec<&str>) -> Result<PlaylistItems, anyhow::Error> |
| 249 { | 388 { |
| 250 return Ok(self.client | 389 return Ok(self.client |
| 251 .get(format!("{}/playlists/{}/items/{}:{}", self.base_url, playlist_id, offset, count)) | 390 .get(format!("{}/playlists/{}/items/{}:{}", self.base_url, playlist_id, offset, count)) |
