diff options
author | delta <darkussdelta@gmail.com> | 2024-03-05 14:48:59 +0100 |
---|---|---|
committer | delta <darkussdelta@gmail.com> | 2024-03-05 14:48:59 +0100 |
commit | 510ef8e178929cf5e0c7fd5a5120fecf5f1b79f2 (patch) | |
tree | 3582e5cd7d000335ca94f2a009f3aed57bd86919 /.config/awesome/quarrel/native/src/mpd.rs | |
parent | 95ba8030f722a616cff06c122dcfb2f63e25cf45 (diff) |
idk anymore
Diffstat (limited to '.config/awesome/quarrel/native/src/mpd.rs')
-rw-r--r-- | .config/awesome/quarrel/native/src/mpd.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/.config/awesome/quarrel/native/src/mpd.rs b/.config/awesome/quarrel/native/src/mpd.rs new file mode 100644 index 0000000..08c9e42 --- /dev/null +++ b/.config/awesome/quarrel/native/src/mpd.rs @@ -0,0 +1,142 @@ +use std::{ + ffi::c_void, + fs::File, + net::TcpStream, + path::PathBuf, + sync::mpsc::channel, +}; + +use dirs::home_dir; +use gdk_pixbuf::{ + ffi::GdkPixbuf, + glib::translate::IntoGlibPtr, + traits::PixbufLoaderExt, + Pixbuf, + PixbufLoader, +}; +use mlua::{ + prelude::*, + LuaSerdeExt, +}; +use mpd::Client; +use once_cell::sync::Lazy; +use symphonia::{ + core::{ + formats::FormatOptions, + io::{ + MediaSourceStream, + MediaSourceStreamOptions, + }, + meta::MetadataOptions, + probe::Hint, + }, + default::get_probe, +}; + +static MPD_MUSIC_PATH: Lazy<PathBuf> = Lazy::new(|| { + [ + home_dir().expect("home directory should be set"), + "Music".into(), + ] + .iter() + .collect() +}); + +static COVER_FORMATS: [&str; 2] = ["png", "jpg"]; + +pub struct Connection(Client<TcpStream>); + +impl LuaUserData for Connection { + fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_method_mut("status", |lua, this: &mut Connection, (): ()| { + lua.to_value(&this.0.status().map_err(LuaError::external)?) + }); + + methods.add_method_mut("song", |lua, this: &mut Connection, (): ()| { + Ok( + if let Some(song) = this.0.currentsong().map_err(LuaError::external)? { + lua.to_value(&song)? + } else { + LuaNil + }, + ) + }); + + methods.add_method( + "get_cover_pixbuf", + |_, _: &Connection, file: String| { + let song_path = MPD_MUSIC_PATH.join(file); + let mut has_external_cover = false; + let mut cover_path = PathBuf::new(); + + for format in COVER_FORMATS { + let cover = song_path + .parent() + .unwrap() + .to_owned() + .join(format!("cover.{}", format)); + if cover.exists() { + has_external_cover = cover.exists(); + cover_path = cover; + break; + } + } + + let mss = MediaSourceStream::new( + Box::new(File::open(song_path)?), + MediaSourceStreamOptions::default(), + ); + + let mut probed = get_probe() + .format( + &Hint::default(), + mss, + &FormatOptions::default(), + &MetadataOptions::default(), + ) + .map_err(LuaError::external)?; + + let visuals; + + if let Some(metadata) = probed.format.metadata().skip_to_latest() { + visuals = metadata.visuals(); + if visuals.is_empty() && has_external_cover { + let pixbuf = Pixbuf::from_file(cover_path).map_err(LuaError::external)?; + + return Ok(( + Some(LuaLightUserData(unsafe { + <Pixbuf as IntoGlibPtr<*mut GdkPixbuf>>::into_glib_ptr(pixbuf) + .cast::<c_void>() + })), + Some(true), + )); + } + + let loader = PixbufLoader::new(); + loader + .write(visuals.first().unwrap().data.as_ref()) + .map_err(LuaError::external)?; + loader.close().map_err(LuaError::external)?; + + return Ok(( + Some(LuaLightUserData(unsafe { + <Pixbuf as IntoGlibPtr<*mut GdkPixbuf>>::into_glib_ptr( + loader.pixbuf().expect("Pixbuf should be initialized"), + ) + .cast::<c_void>() + })), + Some(false), + )); + } + + Ok((None, None)) + }, + ); + } +} + +pub fn init(_: &Lua, _: ()) -> LuaResult<Connection> { + Ok(Connection( + Client::connect("localhost:6600").map_err(LuaError::external)?, + )) +} |