cabytcini/src/main.rs

144 lines
3.3 KiB
Rust

mod config;
mod xsetroot;
use chrono::prelude::*;
use log::*;
use std::{
fmt,
io::{prelude::*, BufReader},
net::Shutdown,
os::unix::net::{UnixListener, UnixStream},
sync::{Arc, Mutex},
thread, time,
};
use xsetroot::XSetRoot;
pub type MTState = Arc<Mutex<State>>;
fn handle_client(stream: UnixStream, st: MTState) {
let mut rdr = BufReader::new(&stream);
let mut msg = String::new();
let _ = rdr.read_line(&mut msg);
let _ = write!(&stream, "OK");
let mut data = st.lock().unwrap();
data.msg = msg.trim().to_string();
info!("new message: {}", data.msg);
stream.shutdown(Shutdown::Both).expect("socket to close");
}
const UPDATE_FREQUENCY: u64 = 250;
fn update_every_so_often(st: MTState) {
loop {
let so_often = time::Duration::from_millis(UPDATE_FREQUENCY);
thread::sleep(so_often);
{
let data = st.lock().unwrap();
data.show();
}
}
}
const FIVE_MINUTES: u64 = 60 * 5;
fn front_update(st: MTState, cfg: config::Config) {
loop {
match reqwest::blocking::get(&cfg.front_url) {
Ok(who) => {
let mut data = st.lock().unwrap();
let who = who.text().unwrap().trim().to_string();
if who != data.front {
data.front = who;
info!("new front: {}", data.front);
}
}
Err(why) => {
error!("front error: {:?}", why);
}
}
let dur = time::Duration::new(FIVE_MINUTES, 0);
thread::sleep(dur);
}
}
fn main() -> std::io::Result<()> {
let st: State = State::init();
st.show();
let mtst = Arc::new(Mutex::new(st));
env_logger::init();
let cfg = config::load()?;
// start update thread
{
let mtst = mtst.clone();
thread::spawn(move || update_every_so_often(mtst));
}
// start front thread
{
let mtst = mtst.clone();
let cfg = cfg.clone();
thread::spawn(move || front_update(mtst, cfg));
}
let _ = std::fs::remove_file("/home/cadey/tmp/cabytcini.sock")?;
let listener = UnixListener::bind("/home/cadey/tmp/cabytcini.sock")?;
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let mtst = mtst.clone();
thread::spawn(move || handle_client(stream, mtst));
}
Err(err) => {
error!("unix listener error: {:?}", err);
break;
}
}
}
Ok(())
}
pub struct State {
msg: String,
front: String,
}
impl fmt::Display for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.msg)
}
}
impl State {
fn init() -> State {
State {
msg: "".to_string(),
front: "".to_string(),
}
}
fn show(&self) {
let now = Local::now().format("%H:%M M%m %-d %a");
let xsr = XSetRoot::init();
let mut msg = String::new();
if self.msg != "" {
msg.push_str(format!("{} | ", msg).as_str());
}
if self.front != "" {
msg.push_str(format!("{} | ", self.front).as_str());
}
msg.push_str(format!("{}", now).as_str());
xsr.render(msg);
}
}