sway-launchpad

A small rust script to switch sway workspaces using a Launchpad S
git clone git://archive.git.mtrnord.blog/MTRNord/sway-launchpad.git
Log | Files | Refs | LICENSE

main.rs (4830B)


      1 use crate::config::Config;
      2 use color_eyre::Result;
      3 use futures_util::StreamExt;
      4 use matrix_sdk::{
      5     events::{
      6         room::message::{MessageEventContent, NoticeMessageEventContent},
      7         AnyMessageEventContent,
      8     },
      9     identifiers::RoomId,
     10     SyncSettings,
     11 };
     12 use matrix_sdk::{Client, ClientConfig};
     13 use once_cell::sync::{Lazy, OnceCell};
     14 use std::convert::TryFrom;
     15 use std::path::Path;
     16 use std::{env, fs};
     17 use tokio::io::{AsyncBufReadExt, BufStream};
     18 use tokio::net::UnixListener;
     19 use tokio::sync::Mutex;
     20 use tracing::*;
     21 use url::Url;
     22 use users::get_current_uid;
     23 
     24 mod config;
     25 
     26 static ROOM_ID: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::new()));
     27 static CLIENT: OnceCell<Mutex<Client>> = OnceCell::new();
     28 static PRESETS: Lazy<Vec<AnyMessageEventContent>> = Lazy::new(|| {
     29     vec![AnyMessageEventContent::RoomMessage(
     30         MessageEventContent::Notice(NoticeMessageEventContent {
     31             body: String::from("This is the first macro message sent using a midi controller"),
     32             formatted: None,
     33             relates_to: None,
     34         }),
     35     )]
     36 });
     37 
     38 async fn setup_matrix() -> Result<()> {
     39     info!("Beginning Matrix Setup");
     40     let config = Config::load().unwrap();
     41     let store_path_string = config.store_path.to_string();
     42     let store_path = Path::new(&store_path_string);
     43     if !store_path.exists() {
     44         fs::create_dir_all(store_path)?;
     45     }
     46     let client_config = ClientConfig::new().store_path(fs::canonicalize(&store_path)?);
     47 
     48     let homeserver_url =
     49         Url::parse(&config.homeserver_url).expect("Couldn't parse the homeserver URL");
     50 
     51     let client = Client::new_with_config(homeserver_url, client_config).unwrap();
     52 
     53     client
     54         .login(
     55             &config.mxid,
     56             &config.password,
     57             None,
     58             Some(&"macro-bot".to_string()),
     59         )
     60         .await?;
     61     info!("logged in as {}", config.mxid);
     62 
     63     let mutexed_client = Mutex::new(client.clone());
     64     CLIENT.set(mutexed_client);
     65 
     66     tokio::spawn(async move {
     67         info!("Starting full Sync...");
     68         client.sync(SyncSettings::default()).await;
     69     });
     70     Ok(())
     71 }
     72 
     73 #[tokio::main]
     74 async fn main() -> Result<()> {
     75     // Enable the logging crates
     76     color_eyre::install()?;
     77     if env::var("RUST_LOG").is_err() {
     78         env::set_var("RUST_LOG", "INFO");
     79     }
     80     tracing_subscriber::fmt::init();
     81     setup_matrix().await?;
     82 
     83     let user_id = get_current_uid();
     84     let path_string = format!("/run/user/{}/lsc_matrix_presets.sock", user_id);
     85     let socket_path = Path::new(&path_string);
     86     if socket_path.exists() {
     87         fs::remove_file(socket_path)?;
     88     }
     89 
     90     // First we create a unix socket. This is required to be a) The same as the crate name and b) to be in /run
     91     let mut listener = UnixListener::bind(socket_path).unwrap();
     92 
     93     //let mut perms = fs::metadata(socket_path)?.permissions();
     94     //perms.set_mode(0o666);
     95     //fs::set_permissions(socket_path, perms)?;
     96     // This listens for new connections
     97     while let Some(stream) = listener.next().await {
     98         match stream {
     99             Ok(stream) => {
    100                 tokio::spawn(async move {
    101                     println!("new client!");
    102                     let buffer = BufStream::new(stream);
    103                     let mut lines = buffer.lines();
    104                     while let Ok(line) = lines.next_line().await {
    105                         if let Some(line) = line {
    106                             info!("{}", line);
    107                             let split: Vec<&str> = line.split_whitespace().collect();
    108                             if split[0] == "select" {
    109                                 let mut state = ROOM_ID.lock().await;
    110                                 *state = String::from(split[1]);
    111                             }
    112                             if split[0] == "do" {
    113                                 let preset = PRESETS[split[1].parse::<usize>().unwrap()].clone();
    114                                 info!("preset: {:?}", preset);
    115                                 let room_id = ROOM_ID.lock().await;
    116                                 let cloned_id = (*room_id).clone();
    117                                 let client = CLIENT.get().unwrap().lock().await;
    118                                 client
    119                                     .room_send(&RoomId::try_from(cloned_id).unwrap(), preset, None)
    120                                     .await
    121                                     .unwrap();
    122                                 info!("executed preset");
    123                             }
    124                             let room_id = ROOM_ID.lock().await;
    125                             info!("room_id: {}", room_id);
    126                         }
    127                     }
    128                 });
    129             }
    130             Err(e) => {
    131                 error!("Unix socket connection failed: {}", e);
    132             }
    133         }
    134     }
    135     Ok(())
    136 }