came with various optimizations

This commit is contained in:
Paul 2021-09-12 20:16:11 +02:00
parent 8b22768886
commit 355643ecdd
5 changed files with 69 additions and 87 deletions

View File

@ -1,8 +1,8 @@
use clap::{App, Arg, ArgMatches};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Error; use serde_json::Error;
use std::string::String; use std::string::String;
use std::{fs::File, io::Read}; use std::{fs::File, io::Read};
use clap::{App, Arg, ArgMatches};
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct Config { pub struct Config {
@ -27,7 +27,7 @@ impl Config {
} }
pub fn load<'a>(&mut self, configfile: &'a str) { pub fn load<'a>(&mut self, configfile: &'a str) {
let fileopen: Result<File,std::io::Error>; let fileopen: Result<File, std::io::Error>;
let filemeta = std::fs::metadata(configfile); let filemeta = std::fs::metadata(configfile);
let fileexists = match filemeta { let fileexists = match filemeta {
Ok(_) => true, Ok(_) => true,
@ -43,7 +43,7 @@ impl Config {
Ok(f) => f, Ok(f) => f,
Err(e) => { Err(e) => {
panic!("{}", e); panic!("{}", e);
}, }
}; };
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents).unwrap(); file.read_to_string(&mut contents).unwrap();
@ -63,15 +63,17 @@ impl Config {
} }
pub fn argparse<'a>() -> ArgMatches<'a> { pub fn argparse<'a>() -> ArgMatches<'a> {
App::new("Zabbix Launch") App::new("Zabbix Launch")
.version("1.0") .version("1.0")
.author("PaulBSD <paul@paulbsd.com>") .author("PaulBSD <paul@paulbsd.com>")
.about("Lights up Launchpad mini using Zabbix data") .about("Lights up Launchpad mini using Zabbix data")
.arg(Arg::with_name("config") .arg(
.short("c") Arg::with_name("config")
.long("config") .short("c")
.value_name("FILE") .long("config")
.help("Sets a custom config file") .value_name("FILE")
.takes_value(true)) .help("Sets a custom config file")
.get_matches() .takes_value(true),
} )
.get_matches()
}

View File

@ -3,27 +3,23 @@ mod padcontrol;
mod zabbix; mod zabbix;
use config::Config; use config::Config;
//use std::rc::Rc;
//use std::vec::Vec;
use zabbix::problems::ZabbixLayout; use zabbix::problems::ZabbixLayout;
fn main() { fn main() {
let mut datamatrix = ZabbixLayout{layout: vec!()}; let mut datamatrix = ZabbixLayout { layout: Vec::new() };
// parse arguments // parse arguments
let matches = config::argparse(); let matches = config::argparse();
// load configuration // load configuration
let configfile = matches let configfile = matches.value_of("config").unwrap_or("config.json");
.value_of("config")
.unwrap_or("config.json");
let mut cfg = Config::new(); let mut cfg = Config::new();
cfg.load(&configfile); cfg.load(&configfile);
zabbix::api::get_zabbix_authtoken(&mut cfg); zabbix::api::get_zabbix_authtoken(&mut cfg);
cfg.save(&configfile); cfg.save(&configfile);
// init/connect to launchpad and clear it // init/connect to launchpad and clear it
let (mut canvas, mut poller) = padcontrol::initpad(); let (mut canvas, mut _poller) = padcontrol::initpad();
//padcontrol::input(&mut canvas, &mut poller); //padcontrol::input(&mut canvas, &mut _poller);
padcontrol::draw(&mut canvas, &mut poller, &mut datamatrix, &mut cfg); padcontrol::draw(&mut canvas, &mut datamatrix, &mut cfg);
} }

View File

@ -1,9 +1,8 @@
use crate::config::Config;
use crate::zabbix::api::get_zabbix_problems;
use crate::zabbix::problems::ZabbixLayout;
use launchy::Color; use launchy::Color;
use launchy::{self, Canvas, CanvasLayout, CanvasLayoutPoller, MsgPollingWrapper, Pad}; use launchy::{self, Canvas, CanvasLayout, CanvasLayoutPoller, MsgPollingWrapper, Pad};
use crate::zabbix;
use crate::zabbix::problems::{ZabbixLayout};
use crate::config::Config;
pub fn initpad() -> (CanvasLayout<'static>, CanvasLayoutPoller) { pub fn initpad() -> (CanvasLayout<'static>, CanvasLayoutPoller) {
let (mut canvas, poller) = launchy::CanvasLayout::new_polling(); let (mut canvas, poller) = launchy::CanvasLayout::new_polling();
@ -12,14 +11,14 @@ pub fn initpad() -> (CanvasLayout<'static>, CanvasLayoutPoller) {
_ => { _ => {
eprintln!("Failed to connect to device, check USB connection"); eprintln!("Failed to connect to device, check USB connection");
std::process::exit(1); std::process::exit(1);
}, }
}; };
println!("Connected to device using USB"); println!("Connected to device using USB");
clear(&mut canvas); clear(&mut canvas);
(canvas, poller) (canvas, poller)
} }
pub fn input(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) { pub fn _input(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) {
for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) { for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) {
for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) { for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) {
canvas[msg.pad()] = color; canvas[msg.pad()] = color;
@ -29,13 +28,17 @@ pub fn input(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) {
} }
} }
pub fn draw(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller, datamatrix: &mut ZabbixLayout, cfg: &mut Config) { pub fn draw(canvas: &mut CanvasLayout, datamatrix: &mut ZabbixLayout, cfg: &mut Config) {
println!("Refresh rate is {} seconds", cfg.refresh.unwrap()); println!("Refresh rate is {} seconds", cfg.refresh.unwrap());
loop { loop {
let zabbix_data = zabbix::api::get_zabbix_problems(cfg); let zabbix_data = get_zabbix_problems(cfg);
datamatrix.compute(&zabbix_data); datamatrix.compute(&zabbix_data);
for (i, j) in datamatrix.layout.iter().enumerate() { let mut y = 1i32;
let p = Pad{x: i as i32, y: 1i32}; for (x, j) in datamatrix.layout.iter().enumerate() {
if y % 8 == 0 {
y += 1;
};
let p = Pad { x: x as i32, y: y };
let c = match j.status { let c = match j.status {
4 => Color::RED, 4 => Color::RED,
3 => Color::YELLOW, 3 => Color::YELLOW,
@ -49,7 +52,6 @@ pub fn draw(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller, datamatr
} }
} }
/*
fn _effect(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) { fn _effect(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) {
for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) { for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) {
for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) { for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) {
@ -70,7 +72,7 @@ fn _effect(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) {
canvas[pad] = canvas[pad].mix(surrounding_color, 0.4); canvas[pad] = canvas[pad].mix(surrounding_color, 0.4);
}); });
} }
}*/ }
fn clear(canvas: &mut CanvasLayout) { fn clear(canvas: &mut CanvasLayout) {
for a in 0..8 { for a in 0..8 {
@ -83,4 +85,4 @@ fn clear(canvas: &mut CanvasLayout) {
} }
} }
let _res = canvas.flush(); let _res = canvas.flush();
} }

View File

@ -2,54 +2,49 @@ use crate::config::Config;
use serde_json::{json, Value}; use serde_json::{json, Value};
pub const ZABBIX_API_VERSION: &'static str = "2.0"; pub const ZABBIX_API_VERSION: &'static str = "2.0";
pub const ZABBIX_API_ID: i32 = 1;
pub fn get_zabbix_authtoken(cfg: &mut Config) { pub fn get_zabbix_authtoken(cfg: &mut Config) {
let body = query_auth_token(&cfg.username, &cfg.password); let body = query_auth_token(&cfg.username, &cfg.password);
let response = reqwest::blocking::Client::new() let resp = reqwest::blocking::Client::new()
.post(&cfg.server) .post(&cfg.server)
.json(&body) .json(&body)
.send() .send()
.unwrap(); .unwrap();
let values: Value = response.json() let values: Value = resp.json().unwrap();
.unwrap(); cfg.authtoken = Some(values["result"].as_str().unwrap().to_string());
cfg.authtoken = Some(values["result"].as_str()
.unwrap()
.to_string());
} }
pub fn get_zabbix_problems(cfg: &mut Config) -> Value { pub fn get_zabbix_problems(cfg: &mut Config) -> Value {
let body = query_problems(&cfg.authtoken.as_ref() let body = query_problems(
.unwrap_or(&String::from("")), &cfg.authtoken.as_ref().unwrap_or(&String::from("")),
cfg.limit.unwrap()); cfg.limit.unwrap(),
let response = reqwest::blocking::Client::new() );
let resp = reqwest::blocking::Client::new()
.post(&cfg.server) .post(&cfg.server)
.json(&body) .json(&body)
.send() .send()
.unwrap(); .unwrap();
response.json().unwrap() resp.json().unwrap()
} }
pub fn query_auth_token(zabbix_username: &String, pub fn query_auth_token(zabbix_username: &String, zabbix_password: &String) -> Value {
zabbix_password: &String) -> Value { let zabbix_api_function = "user.login";
let api_function = "user.login";
let api_id = 1;
json!({ json!({
"jsonrpc": ZABBIX_API_VERSION, "jsonrpc": ZABBIX_API_VERSION,
"method": api_function, "method": zabbix_api_function,
"params": { "params": {
"user": zabbix_username, "user": zabbix_username,
"password": zabbix_password "password": zabbix_password
}, },
"id": api_id "id": ZABBIX_API_ID
}) })
} }
pub fn query_problems(zabbix_token: &String, pub fn query_problems(zabbix_token: &String, zabbix_limit: i64) -> Value {
zabbix_limit: i64) -> Value {
let zabbix_api_function = "problem.get"; let zabbix_api_function = "problem.get";
let zabbix_api_id = 1;
json!({ json!({
"jsonrpc": ZABBIX_API_VERSION, "jsonrpc": ZABBIX_API_VERSION,
"method": zabbix_api_function, "method": zabbix_api_function,
@ -64,6 +59,6 @@ pub fn query_problems(zabbix_token: &String,
"limit": zabbix_limit "limit": zabbix_limit
}, },
"auth": zabbix_token, "auth": zabbix_token,
"id": zabbix_api_id "id": ZABBIX_API_ID
}) })
} }

View File

@ -1,5 +1,5 @@
use serde_json::Value; use serde_json::Value;
use std::fmt::{Display,Formatter,Result}; use std::fmt::{Display, Formatter, Result};
#[derive(Debug)] #[derive(Debug)]
pub enum ZabbixStatus { pub enum ZabbixStatus {
@ -14,42 +14,29 @@ pub struct ZabbixLayout {
} }
pub struct ZabbixProblems { pub struct ZabbixProblems {
hostname: String,
pub status: i64, pub status: i64,
} }
impl Display for ZabbixProblems { impl Display for ZabbixProblems {
fn fmt(&self, f: &mut Formatter) -> Result { fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, write!(f, "status: {:?}", self.status)
"hostname: {}, status: {:?}",
self.hostname,
self.status)
} }
} }
impl ZabbixLayout { impl ZabbixLayout {
pub fn compute(&mut self, input: &Value) { pub fn compute(&mut self, input: &Value) {
self.layout = vec!(); self.layout = Vec::new();
for j in input.as_object().unwrap()["result"].as_array().unwrap()[0..8].to_vec() { for j in input.as_object().unwrap()["result"].as_array().unwrap() {
let severity = j.as_object() let res = j.as_object().unwrap();
.unwrap()["severity"] let severity = res["severity"].as_str().unwrap().parse::<i64>().unwrap();
.as_str() let ack = res["acknowledged"]
.unwrap() .as_str()
.parse::<i64>() .unwrap()
.unwrap(); .parse::<i64>()
let acknowledged = j.as_object() .unwrap();
.unwrap()["acknowledged"] if ack == 0 {
.as_str() self.layout.push(ZabbixProblems { status: severity });
.unwrap()
.parse::<i64>()
.unwrap();
if acknowledged == 0 {
self.layout.push(
ZabbixProblems{
hostname: "test".to_string(),
status: severity
});
}; };
} }
} }
} }