From c1580917a0832a1789d4348ed364a6a4b2b97d88 Mon Sep 17 00:00:00 2001 From: Sudo Dios Date: Tue, 15 Oct 2024 13:22:20 +0330 Subject: [PATCH] Added support for result image themes --- README.md | 4 +++ configs.toml | 4 +++ src/cmd.rs | 9 ++++++ src/config/mod.rs | 3 ++ src/results/telemetry.rs | 62 ++++++++++++++++++++++++++++------------ 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 8523aa2..bb7e023 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,10 @@ Compatible with all librespeed clients : # redact IP addresses redact_ip_addresses=false + + # set telemetry result image theme : light, dark + # default is light + result_image_theme="light" # database config for : mysql, postgres, sqlite, memory, or disable by write none # after restarting the service, the in-memory database is reset diff --git a/configs.toml b/configs.toml index 32e2acd..57dfdaa 100644 --- a/configs.toml +++ b/configs.toml @@ -23,6 +23,10 @@ stats_password="" # redact IP addresses redact_ip_addresses=false +# set telemetry result image theme : light, dark +# default is light +result_image_theme="light" + # database config for : mysql, postgres, sqlite, memory, or disable by write none # after restarting the service, the in-memory database is reset # if none is specified, no telemetry/stats will be recorded, and no result JPG will be generated diff --git a/src/cmd.rs b/src/cmd.rs index 2b51b4b..488c124 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -11,6 +11,7 @@ pub struct Cmd { pub assets_path : Option, pub stats_password : Option, pub redact_ip_addresses : Option, + pub result_image_theme : Option, pub database_type : Option, pub database_hostname : Option, pub database_name : Option, @@ -89,6 +90,12 @@ impl Cmd { .help("Redact IP addresses") .value_parser(value_parser!(bool)) ) + .arg( + Arg::new("result-image-theme") + .long("result-image-theme") + .help("Specify telemetry result image theme : light, dark") + .value_parser(value_parser!(String)) + ) .arg( Arg::new("database-type") .long("database-type") @@ -153,6 +160,7 @@ impl Cmd { let assets_path : Option = args.get_one::("assets-path").map(|s| s.to_owned()); let stats_password : Option = args.get_one::("stats-password").map(|s| s.to_owned()); let redact_ip_addresses : Option = args.get_one::("redact-ips").map(|s| s.to_owned()); + let result_image_theme : Option = args.get_one::("result-image-theme").map(|s| s.to_owned()); let database_type : Option = args.get_one::("database-type").map(|s| s.to_owned()); let database_hostname : Option = args.get_one::("database-hostname").map(|s| s.to_owned()); let database_name : Option = args.get_one::("database-name").map(|s| s.to_owned()); @@ -172,6 +180,7 @@ impl Cmd { assets_path, stats_password, redact_ip_addresses, + result_image_theme, database_type, database_hostname, database_name, diff --git a/src/config/mod.rs b/src/config/mod.rs index a1e9429..b832cb0 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -44,6 +44,7 @@ pub struct ServerConfig { pub ipinfo_api_key : String, pub stats_password : String, pub redact_ip_addresses : bool, + pub result_image_theme : String, pub assets_path : String, pub database_type : String, pub database_hostname : Option, @@ -66,6 +67,7 @@ impl Default for ServerConfig { ipinfo_api_key: "".to_string(), stats_password: "".to_string(), redact_ip_addresses: false, + result_image_theme: "light".to_string(), assets_path: "".to_string(), database_type: "none".to_string(), database_hostname: None, @@ -194,6 +196,7 @@ fn initialize (mut config: ServerConfig,cmd : Cmd) -> std::io::Result<()> { config.assets_path.set_if_some(cmd.assets_path); config.stats_password.set_if_some(cmd.stats_password); config.redact_ip_addresses.set_if_some(cmd.redact_ip_addresses); + config.result_image_theme.set_if_some(cmd.result_image_theme); config.database_type.set_if_some(cmd.database_type); config.database_hostname.set_if_some(cmd.database_hostname); config.database_name.set_if_some(cmd.database_name); diff --git a/src/results/telemetry.rs b/src/results/telemetry.rs index fd9c785..5fa0f67 100644 --- a/src/results/telemetry.rs +++ b/src/results/telemetry.rs @@ -65,10 +65,33 @@ pub async fn record_result (request : &Request, database : &mut Arc, + text_head : Rgb, + text_value : Rgb, + text_unit : Rgb, +} +fn get_theme(is_dark : bool) -> ImageTheme { + if is_dark { + ImageTheme { + background: Rgb([42,42,42]), + text_head: Rgb([255,255,255]), + text_value: Rgb([120,166,240]), + text_unit: Rgb([174,174,174]), + } + } else { + ImageTheme { + background: Rgb([255,255,255]), + text_head: Rgb([0,0,0]), + text_value: Rgb([96,96,170]), + text_unit: Rgb([110,110,110]), + } + } +} pub fn draw_result (data : &TelemetryData) -> Vec { fn cal_text_size (font : &FontRef,text : &str,scale : f32) -> (u32,u32) { - text_size(PxScale::from(scale),&font,text) + text_size(PxScale::from(scale),font,text) } //scales @@ -113,7 +136,10 @@ pub fn draw_result (data : &TelemetryData) -> Vec { //drawing .... //background - draw_filled_rect_mut(&mut img,Rect::at(0,0).of_size(500,286),Rgb([255,255,255])); + let config = SERVER_CONFIG.get().unwrap(); + let theme = get_theme(config.result_image_theme == "dark"); + + draw_filled_rect_mut(&mut img,Rect::at(0,0).of_size(500,286),theme.background); let width_quarter = img.width() / 4; let width_3_quarter = width_quarter * 3; @@ -121,76 +147,76 @@ pub fn draw_result (data : &TelemetryData) -> Vec { //ping let mut x = width_quarter - (ping_text_size.0 / 2) + h_padding; // ping label let mut y = v_padding; // ping label - draw_text_mut(&mut img, Rgb([0, 0, 0]), x as i32, y as i32, PxScale::from(ping_jitter_name_scale), font, l_ping); // ping label + draw_text_mut(&mut img, theme.text_head, x as i32, y as i32, PxScale::from(ping_jitter_name_scale), font, l_ping); // ping label x = width_quarter - (ping_value_text_size.0 / 2) + h_padding - (ms_text_size.0 / 2); // ping value y = ping_text_size.1 + (v_padding * 2); // ping value - draw_text_mut(&mut img, Rgb([96, 96, 170]), x as i32, y as i32, PxScale::from(ping_jitter_value_scale), font, &data.ping); // ping value + draw_text_mut(&mut img, theme.text_value, x as i32, y as i32, PxScale::from(ping_jitter_value_scale), font, &data.ping); // ping value x = width_quarter + (ping_value_text_size.0 / 2) + unit_padding + h_padding - (ms_text_size.0 / 2); // ping unit y = ping_text_size.1 + (v_padding * 2) + ping_value_text_size.1 - ms_text_size.1; // ping unit - draw_text_mut(&mut img, Rgb([110,110,110]), x as i32, y as i32, PxScale::from(unit_scale), font, l_ms); // ping unit + draw_text_mut(&mut img, theme.text_unit, x as i32, y as i32, PxScale::from(unit_scale), font, l_ms); // ping unit //jitter x = width_3_quarter - (jitter_text_size.0 / 2) - h_padding; // jitter label y = v_padding; // jitter value - draw_text_mut(&mut img, Rgb([0, 0, 0]), x as i32, y as i32, PxScale::from(ping_jitter_name_scale), font, l_jitter); // jitter value + draw_text_mut(&mut img, theme.text_head, x as i32, y as i32, PxScale::from(ping_jitter_name_scale), font, l_jitter); // jitter value x = width_3_quarter - (jitter_value_text_size.0 / 2) - h_padding - (ms_text_size.0 / 2); // jitter value y = jitter_text_size.1 + (v_padding * 2); // jitter value - draw_text_mut(&mut img, Rgb([96, 96, 170]), x as i32, y as i32, PxScale::from(ping_jitter_value_scale), font, &data.jitter); // jitter value + draw_text_mut(&mut img, theme.text_value, x as i32, y as i32, PxScale::from(ping_jitter_value_scale), font, &data.jitter); // jitter value x = width_3_quarter + (jitter_value_text_size.0 / 2) + unit_padding - h_padding - (ms_text_size.0 / 2);// jitter unit y = jitter_text_size.1 + (v_padding * 2) + jitter_value_text_size.1 - ms_text_size.1;// jitter unit - draw_text_mut(&mut img, Rgb([110,110,110]), x as i32, y as i32, PxScale::from(unit_scale), font, l_ms);// jitter unit + draw_text_mut(&mut img, theme.text_unit, x as i32, y as i32, PxScale::from(unit_scale), font, l_ms);// jitter unit //download x = width_quarter - (download_text_size.0 / 2) + h_padding; // download label y = ping_text_size.1 + ping_value_text_size.1 + (v_padding * 6); // download label - draw_text_mut(&mut img, Rgb([0, 0, 0]), x as i32, y as i32, PxScale::from(d_u_name_scale), font, l_dl); // download label + draw_text_mut(&mut img, theme.text_head, x as i32, y as i32, PxScale::from(d_u_name_scale), font, l_dl); // download label x = width_quarter - (download_value_text_size.0 / 2) + h_padding;// download value y = ping_text_size.1 + ping_value_text_size.1 + download_text_size.1 + (v_padding * 7);// download value - draw_text_mut(&mut img, Rgb([96, 96, 170]), x as i32, y as i32, PxScale::from(d_u_value_scale), font, &data.download);// download value + draw_text_mut(&mut img, theme.text_value, x as i32, y as i32, PxScale::from(d_u_value_scale), font, &data.download);// download value x = width_quarter - (mbps_text_size.0 / 2) + h_padding;//download unit y = ping_text_size.1 + (unit_padding * 2) + ping_value_text_size.1 + download_text_size.1 + download_value_text_size.1 + (v_padding * 8);//download unit - draw_text_mut(&mut img, Rgb([110,110,110]), x as i32, y as i32, PxScale::from(unit_scale), font, l_mbps);//download unit + draw_text_mut(&mut img, theme.text_unit, x as i32, y as i32, PxScale::from(unit_scale), font, l_mbps);//download unit //upload x = width_3_quarter - (upload_text_size.0 / 2) - h_padding; // upload label y = jitter_text_size.1 + jitter_value_text_size.1 + (v_padding * 6); // upload label - draw_text_mut(&mut img, Rgb([0, 0, 0]), x as i32, y as i32, PxScale::from(d_u_name_scale), font, l_ul); // upload label + draw_text_mut(&mut img, theme.text_head, x as i32, y as i32, PxScale::from(d_u_name_scale), font, l_ul); // upload label x = width_3_quarter - (upload_value_text_size.0 / 2) - h_padding;// upload value y = jitter_text_size.1 + jitter_value_text_size.1 + upload_text_size.1 + (v_padding * 7);// upload value - draw_text_mut(&mut img, Rgb([96, 96, 170]), x as i32, y as i32, PxScale::from(d_u_value_scale), font, &data.upload);// upload value + draw_text_mut(&mut img, theme.text_value, x as i32, y as i32, PxScale::from(d_u_value_scale), font, &data.upload);// upload value x = width_3_quarter - (mbps_text_size.0 / 2) - h_padding;//upload unit y = jitter_text_size.1 + (unit_padding * 2) + jitter_value_text_size.1 + upload_text_size.1 + upload_value_text_size.1 + (v_padding * 8);//upload unit - draw_text_mut(&mut img, Rgb([110,110,110]), x as i32, y as i32, PxScale::from(unit_scale), font, l_mbps);//upload unit + draw_text_mut(&mut img, theme.text_unit, x as i32, y as i32, PxScale::from(unit_scale), font, l_mbps);//upload unit //isp_info x = unit_padding; y = img.height() - (watermark_text_size.1 * 2) - (unit_padding * 5); let isp_info : IPInfo = serde_json::from_str(&data.isp_info).unwrap(); - draw_text_mut(&mut img,Rgb([40,40,40]),x as i32,y as i32,PxScale::from(footer_scale),font,&isp_info.processedString); + draw_text_mut(&mut img,theme.text_head,x as i32,y as i32,PxScale::from(footer_scale),font,&isp_info.processedString); drop(isp_info); //footer divider let divider_y = (img.height() - watermark_text_size.1 - (unit_padding * 3)) as f32; - draw_line_segment_mut(&mut img, (0.0, divider_y), (500f32, divider_y), Rgb([110,110,110])); + draw_line_segment_mut(&mut img, (0.0, divider_y), (500f32, divider_y), theme.text_unit); //watermark x = img.width() - watermark_text_size.0 - unit_padding; y = img.height() - watermark_text_size.1 - (unit_padding * 2); - draw_text_mut(&mut img,Rgb([110,110,110]),x as i32,y as i32,PxScale::from(footer_scale),font,l_watermark); + draw_text_mut(&mut img,theme.text_unit,x as i32,y as i32,PxScale::from(footer_scale),font,l_watermark); //time x = unit_padding; y = img.height() - watermark_text_size.1 - (unit_padding * 2); let time = convert_time_local(data.timestamp); - draw_text_mut(&mut img,Rgb([110,110,110]),x as i32,y as i32,PxScale::from(footer_scale),font,&time); + draw_text_mut(&mut img,theme.text_unit,x as i32,y as i32,PxScale::from(footer_scale),font,&time); let mut buffer: Cursor> = Cursor::new(Vec::new()); if let Err(e) = img.write_to(&mut buffer, ImageFormat::Jpeg) {