mirror of
https://github.com/GyulyVGC/sniffnet.git
synced 2025-12-23 22:29:01 -05:00
add bits data representation WIP (replace ChartType with DataRepr)
This commit is contained in:
@@ -310,7 +310,7 @@ fn test_chart_data_updates() {
|
||||
min_packets: -1000.0,
|
||||
max_packets: 21000.0,
|
||||
language: Language::default(),
|
||||
chart_type: ChartType::Packets,
|
||||
data_repr: ChartType::Packets,
|
||||
style: StyleType::default(),
|
||||
thumbnail: false,
|
||||
is_live_capture: true,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
use crate::Language;
|
||||
use crate::translations::translations::{bytes_translation, packets_translation};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Enum representing the possible kind of chart displayed.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ChartType {
|
||||
Packets,
|
||||
Bytes,
|
||||
}
|
||||
|
||||
impl ChartType {
|
||||
pub(crate) const ALL: [ChartType; 2] = [ChartType::Bytes, ChartType::Packets];
|
||||
|
||||
pub fn get_label(&self, language: Language) -> &str {
|
||||
match self {
|
||||
ChartType::Packets => packets_translation(language),
|
||||
ChartType::Bytes => bytes_translation(language),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::gui::styles::donut::Catalog;
|
||||
use crate::gui::styles::style_constants::{FONT_SIZE_FOOTER, FONT_SIZE_SUBTITLE};
|
||||
use crate::networking::types::byte_multiple::ByteMultiple;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use iced::alignment::{Horizontal, Vertical};
|
||||
use iced::widget::canvas::path::Arc;
|
||||
use iced::widget::canvas::{Frame, Text};
|
||||
@@ -10,7 +9,7 @@
|
||||
use std::f32::consts;
|
||||
|
||||
pub struct DonutChart {
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
incoming: u128,
|
||||
outgoing: u128,
|
||||
filtered_out: u128,
|
||||
@@ -21,7 +20,7 @@ pub struct DonutChart {
|
||||
|
||||
impl DonutChart {
|
||||
fn new(
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
incoming: u128,
|
||||
outgoing: u128,
|
||||
filtered_out: u128,
|
||||
@@ -30,7 +29,7 @@ fn new(
|
||||
thumbnail: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
chart_type,
|
||||
data_repr,
|
||||
incoming,
|
||||
outgoing,
|
||||
filtered_out,
|
||||
@@ -46,11 +45,7 @@ fn total(&self) -> u128 {
|
||||
|
||||
fn title(&self) -> String {
|
||||
let total = self.total();
|
||||
if self.chart_type.eq(&ChartType::Bytes) {
|
||||
ByteMultiple::formatted_string(total)
|
||||
} else {
|
||||
total.to_string()
|
||||
}
|
||||
self.data_repr.formatted_string(total)
|
||||
}
|
||||
|
||||
fn angles(&self) -> [(Radians, Radians); 4] {
|
||||
@@ -150,7 +145,7 @@ fn draw(
|
||||
}
|
||||
|
||||
pub fn donut_chart<Message, Theme: Catalog>(
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
incoming: u128,
|
||||
outgoing: u128,
|
||||
filtered_out: u128,
|
||||
@@ -164,7 +159,7 @@ pub fn donut_chart<Message, Theme: Catalog>(
|
||||
Length::Fixed(110.0)
|
||||
};
|
||||
iced::widget::canvas(DonutChart::new(
|
||||
chart_type,
|
||||
data_repr,
|
||||
incoming,
|
||||
outgoing,
|
||||
filtered_out,
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
pub mod chart_type;
|
||||
pub mod donut_chart;
|
||||
pub mod traffic_chart;
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
use crate::gui::styles::style_constants::CHARTS_LINE_BORDER;
|
||||
use crate::gui::styles::types::palette::to_rgb_color;
|
||||
use crate::gui::types::message::Message;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::traffic_direction::TrafficDirection;
|
||||
use crate::translations::translations::{incoming_translation, outgoing_translation};
|
||||
use crate::utils::error_logger::{ErrorLogger, Location};
|
||||
use crate::utils::formatted_strings::{get_formatted_num_seconds, get_formatted_timestamp};
|
||||
use crate::utils::types::timestamp::Timestamp;
|
||||
use crate::{ByteMultiple, ChartType, Language, StyleType, location};
|
||||
use crate::{Language, StyleType, location};
|
||||
|
||||
/// Struct defining the chart to be displayed in gui run page
|
||||
pub struct TrafficChart {
|
||||
@@ -45,7 +46,7 @@ pub struct TrafficChart {
|
||||
/// Language used for the chart legend
|
||||
pub language: Language,
|
||||
/// Packets or bytes
|
||||
pub chart_type: ChartType,
|
||||
pub data_repr: DataRepr,
|
||||
/// Style of the chart
|
||||
pub style: StyleType,
|
||||
/// Whether the chart is for the thumbnail page
|
||||
@@ -71,7 +72,7 @@ pub fn new(style: StyleType, language: Language) -> Self {
|
||||
min_packets: 0.0,
|
||||
max_packets: 0.0,
|
||||
language,
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: DataRepr::Bytes,
|
||||
style,
|
||||
thumbnail: false,
|
||||
is_live_capture: true,
|
||||
@@ -115,8 +116,8 @@ pub fn view(&self) -> Element<'_, Message, StyleType> {
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn change_kind(&mut self, kind: ChartType) {
|
||||
self.chart_type = kind;
|
||||
pub fn change_kind(&mut self, kind: DataRepr) {
|
||||
self.data_repr = kind;
|
||||
}
|
||||
|
||||
pub fn change_language(&mut self, language: Language) {
|
||||
@@ -169,7 +170,7 @@ fn x_axis_range(&self) -> Range<f32> {
|
||||
}
|
||||
|
||||
fn y_axis_range(&self) -> Range<f32> {
|
||||
let (min, max) = match self.chart_type {
|
||||
let (min, max) = match self.data_repr {
|
||||
ChartType::Packets => (self.min_packets, self.max_packets),
|
||||
ChartType::Bytes => (self.min_bytes, self.max_bytes),
|
||||
};
|
||||
@@ -186,7 +187,7 @@ fn font<'a>(&self, size: f64) -> TextStyle<'a> {
|
||||
}
|
||||
|
||||
fn spline_to_plot(&self, direction: TrafficDirection) -> &Spline<f32, f32> {
|
||||
match self.chart_type {
|
||||
match self.data_repr {
|
||||
ChartType::Packets => match direction {
|
||||
TrafficDirection::Incoming => &self.in_packets.spline,
|
||||
TrafficDirection::Outgoing => &self.out_packets.spline,
|
||||
@@ -283,12 +284,10 @@ fn build_chart<DB: DrawingBackend>(
|
||||
.max_light_lines(0)
|
||||
.label_style(self.font(12.5))
|
||||
.y_labels(min(5, y_labels))
|
||||
.y_label_formatter(if self.chart_type.eq(&ChartType::Packets) {
|
||||
&|packets| packets.abs().to_string()
|
||||
} else {
|
||||
.y_label_formatter(
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
&|bytes| ByteMultiple::formatted_string(bytes.abs() as u128)
|
||||
})
|
||||
&|amount| self.data_repr.formatted_string(amount.abs() as u128),
|
||||
)
|
||||
.x_labels(min(6, x_labels))
|
||||
.x_label_formatter(
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
};
|
||||
use iced::{Alignment, Font, Length, Padding, Pixels, alignment};
|
||||
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::gui::components::tab::get_pages_tabs;
|
||||
use crate::gui::components::types::my_modal::MyModal;
|
||||
use crate::gui::pages::overview_page::{get_bars, get_bars_length};
|
||||
@@ -23,8 +22,8 @@
|
||||
use crate::gui::styles::text_input::TextInputType;
|
||||
use crate::gui::types::message::Message;
|
||||
use crate::networking::types::address_port_pair::AddressPortPair;
|
||||
use crate::networking::types::byte_multiple::ByteMultiple;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_representation::{ByteMultiple, DataRepr};
|
||||
use crate::networking::types::host_data_states::HostStates;
|
||||
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
|
||||
use crate::networking::types::traffic_direction::TrafficDirection;
|
||||
@@ -144,7 +143,7 @@ fn report<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
||||
.push(get_agglomerates_row(
|
||||
font,
|
||||
agglomerate,
|
||||
sniffer.traffic_chart.chart_type,
|
||||
sniffer.traffic_chart.data_repr,
|
||||
))
|
||||
.push(Rule::horizontal(5))
|
||||
.push(get_change_page_row(
|
||||
@@ -550,12 +549,12 @@ fn get_button_change_page<'a>(increment: bool) -> Button<'a, Message, StyleType>
|
||||
fn get_agglomerates_row<'a>(
|
||||
font: Font,
|
||||
tot: DataInfo,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let tot_packets = tot.tot_packets();
|
||||
let tot_bytes = tot.tot_bytes();
|
||||
|
||||
let (in_length, out_length) = get_bars_length(chart_type, &tot, &tot);
|
||||
let (in_length, out_length) = get_bars_length(data_repr, &tot, &tot);
|
||||
let bars = get_bars(in_length, out_length).width(ReportCol::FILTER_COLUMNS_WIDTH);
|
||||
|
||||
let bytes_col = Column::new()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::countries::country_utils::get_computer_tooltip;
|
||||
use crate::countries::flags_pictures::FLAGS_HEIGHT_BIG;
|
||||
use crate::gui::components::header::get_button_settings;
|
||||
@@ -13,6 +12,7 @@
|
||||
use crate::gui::types::message::Message;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::service::Service;
|
||||
use crate::networking::types::traffic_type::TrafficType;
|
||||
@@ -21,13 +21,12 @@
|
||||
};
|
||||
use crate::report::types::sort_type::SortType;
|
||||
use crate::translations::translations::{
|
||||
bytes_exceeded_translation, clear_all_translation, favorite_transmitted_translation,
|
||||
no_notifications_received_translation, no_notifications_set_translation,
|
||||
only_last_30_translation, packets_exceeded_translation, per_second_translation,
|
||||
clear_all_translation, favorite_transmitted_translation, no_notifications_received_translation,
|
||||
no_notifications_set_translation, only_last_30_translation, per_second_translation,
|
||||
threshold_translation,
|
||||
};
|
||||
use crate::utils::types::icon::Icon;
|
||||
use crate::{ByteMultiple, ConfigSettings, Language, RunningPage, Sniffer, StyleType};
|
||||
use crate::{ConfigSettings, Language, RunningPage, Sniffer, StyleType};
|
||||
use iced::Length::FillPortion;
|
||||
use iced::widget::scrollable::Direction;
|
||||
use iced::widget::text::LineHeight;
|
||||
@@ -150,13 +149,9 @@ fn data_notification_log<'a>(
|
||||
language: Language,
|
||||
font: Font,
|
||||
) -> Container<'a, Message, StyleType> {
|
||||
let chart_type = logged_notification.chart_type;
|
||||
let data_string = if chart_type == ChartType::Bytes {
|
||||
ByteMultiple::formatted_string(logged_notification.threshold.into())
|
||||
} else {
|
||||
logged_notification.threshold.to_string()
|
||||
};
|
||||
let icon = if chart_type == ChartType::Packets {
|
||||
let data_repr = logged_notification.data_repr;
|
||||
let data_string = data_repr.formatted_string(logged_notification.threshold.into());
|
||||
let icon = if data_repr == DataRepr::Packets {
|
||||
Icon::PacketsThreshold
|
||||
} else {
|
||||
Icon::BytesThreshold
|
||||
@@ -184,13 +179,9 @@ fn data_notification_log<'a>(
|
||||
.push(Text::new(logged_notification.timestamp.clone()).font(font)),
|
||||
)
|
||||
.push(
|
||||
Text::new(if chart_type == ChartType::Bytes {
|
||||
bytes_exceeded_translation(language)
|
||||
} else {
|
||||
packets_exceeded_translation(language)
|
||||
})
|
||||
.class(TextType::Title)
|
||||
.font(font),
|
||||
Text::new(data_repr.data_exceeded_translation(language))
|
||||
.class(TextType::Title)
|
||||
.font(font),
|
||||
)
|
||||
.push(
|
||||
Text::new(threshold_str)
|
||||
@@ -222,14 +213,14 @@ fn data_notification_log<'a>(
|
||||
fn favorite_notification_log<'a>(
|
||||
logged_notification: &FavoriteTransmitted,
|
||||
first_entry_data_info: DataInfo,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
language: Language,
|
||||
font: Font,
|
||||
) -> Container<'a, Message, StyleType> {
|
||||
let host_bar = host_bar(
|
||||
&logged_notification.host,
|
||||
&logged_notification.data_info_host,
|
||||
chart_type,
|
||||
data_repr,
|
||||
first_entry_data_info,
|
||||
font,
|
||||
language,
|
||||
@@ -294,7 +285,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
|
||||
let ConfigSettings {
|
||||
style, language, ..
|
||||
} = sniffer.configs.settings;
|
||||
let chart_type = sniffer.traffic_chart.chart_type;
|
||||
let data_repr = sniffer.traffic_chart.data_repr;
|
||||
let font = style.get_extension().font;
|
||||
let mut ret_val = Column::new()
|
||||
.padding(Padding::ZERO.right(15))
|
||||
@@ -306,7 +297,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
|
||||
.0
|
||||
.iter()
|
||||
.map(LoggedNotification::data_info)
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
|
||||
.unwrap_or_default();
|
||||
|
||||
for logged_notification in &sniffer.logged_notifications.0 {
|
||||
@@ -323,7 +314,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
|
||||
favorite_notification_log(
|
||||
favorite_transmitted,
|
||||
first_entry_data_info,
|
||||
chart_type,
|
||||
data_repr,
|
||||
language,
|
||||
font,
|
||||
)
|
||||
@@ -339,10 +330,10 @@ fn threshold_bar<'a>(
|
||||
language: Language,
|
||||
font: Font,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let chart_type = logged_notification.chart_type;
|
||||
let data_repr = logged_notification.data_repr;
|
||||
let data_info = logged_notification.data_info;
|
||||
let (incoming_bar_len, outgoing_bar_len) =
|
||||
get_bars_length(chart_type, &first_entry_data_info, &data_info);
|
||||
get_bars_length(data_repr, &first_entry_data_info, &data_info);
|
||||
|
||||
Row::new()
|
||||
.align_y(Alignment::Center)
|
||||
@@ -358,16 +349,9 @@ fn threshold_bar<'a>(
|
||||
.push(
|
||||
Column::new()
|
||||
.spacing(1)
|
||||
.push(
|
||||
Row::new().push(horizontal_space()).push(
|
||||
Text::new(if chart_type.eq(&ChartType::Packets) {
|
||||
data_info.tot_packets().to_string()
|
||||
} else {
|
||||
ByteMultiple::formatted_string(data_info.tot_bytes())
|
||||
})
|
||||
.font(font),
|
||||
),
|
||||
)
|
||||
.push(Row::new().push(horizontal_space()).push(
|
||||
Text::new(data_repr.formatted_string_from_data_info(&data_info)).font(font),
|
||||
))
|
||||
.push(get_bars(incoming_bar_len, outgoing_bar_len)),
|
||||
)
|
||||
}
|
||||
@@ -424,7 +408,7 @@ fn data_notification_extra<'a>(
|
||||
let host_bar = host_bar(
|
||||
host,
|
||||
data_info_host,
|
||||
logged_notification.chart_type,
|
||||
logged_notification.data_repr,
|
||||
first_data_info_host,
|
||||
font,
|
||||
language,
|
||||
@@ -442,7 +426,7 @@ fn data_notification_extra<'a>(
|
||||
let service_bar = service_bar(
|
||||
service,
|
||||
data_info,
|
||||
logged_notification.chart_type,
|
||||
logged_notification.data_repr,
|
||||
first_data_info_service,
|
||||
font,
|
||||
);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use crate::networking::types::capture_context::CaptureSource;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::filters::Filters;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::service::Service;
|
||||
@@ -38,7 +39,7 @@
|
||||
use crate::translations::translations_4::{excluded_translation, reading_from_pcap_translation};
|
||||
use crate::utils::formatted_strings::get_active_filters_string;
|
||||
use crate::utils::types::icon::Icon;
|
||||
use crate::{ByteMultiple, ChartType, ConfigSettings, Language, RunningPage, StyleType};
|
||||
use crate::{ConfigSettings, Language, RunningPage, StyleType};
|
||||
use iced::Length::{Fill, FillPortion};
|
||||
use iced::alignment::{Horizontal, Vertical};
|
||||
use iced::widget::scrollable::Direction;
|
||||
@@ -245,16 +246,16 @@ fn col_host<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
||||
style, language, ..
|
||||
} = sniffer.configs.settings;
|
||||
let font = style.get_extension().font;
|
||||
let chart_type = sniffer.traffic_chart.chart_type;
|
||||
let data_repr = sniffer.traffic_chart.data_repr;
|
||||
|
||||
let mut scroll_host = Column::new()
|
||||
.padding(Padding::ZERO.right(11.0))
|
||||
.align_x(Alignment::Center);
|
||||
let entries = get_host_entries(&sniffer.info_traffic, chart_type, sniffer.host_sort_type);
|
||||
let entries = get_host_entries(&sniffer.info_traffic, data_repr, sniffer.host_sort_type);
|
||||
let first_entry_data_info = entries
|
||||
.iter()
|
||||
.map(|(_, d)| d.data_info)
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
|
||||
.unwrap_or_default();
|
||||
|
||||
for (host, data_info_host) in &entries {
|
||||
@@ -263,7 +264,7 @@ fn col_host<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
||||
let host_bar = host_bar(
|
||||
host,
|
||||
data_info_host,
|
||||
chart_type,
|
||||
data_repr,
|
||||
first_entry_data_info,
|
||||
font,
|
||||
language,
|
||||
@@ -322,20 +323,20 @@ fn col_service<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
||||
style, language, ..
|
||||
} = sniffer.configs.settings;
|
||||
let font = style.get_extension().font;
|
||||
let chart_type = sniffer.traffic_chart.chart_type;
|
||||
let data_repr = sniffer.traffic_chart.data_repr;
|
||||
|
||||
let mut scroll_service = Column::new()
|
||||
.padding(Padding::ZERO.right(11.0))
|
||||
.align_x(Alignment::Center);
|
||||
let entries = get_service_entries(&sniffer.info_traffic, chart_type, sniffer.service_sort_type);
|
||||
let entries = get_service_entries(&sniffer.info_traffic, data_repr, sniffer.service_sort_type);
|
||||
let first_entry_data_info = entries
|
||||
.iter()
|
||||
.map(|&(_, d)| d)
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
|
||||
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
|
||||
.unwrap_or_default();
|
||||
|
||||
for (service, data_info) in &entries {
|
||||
let content = service_bar(service, data_info, chart_type, first_entry_data_info, font);
|
||||
let content = service_bar(service, data_info, data_repr, first_entry_data_info, font);
|
||||
|
||||
scroll_service = scroll_service.push(
|
||||
button(content)
|
||||
@@ -384,16 +385,13 @@ fn col_service<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
|
||||
pub fn host_bar<'a>(
|
||||
host: &Host,
|
||||
data_info_host: &DataInfoHost,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
first_entry_data_info: DataInfo,
|
||||
font: Font,
|
||||
language: Language,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let (incoming_bar_len, outgoing_bar_len) = get_bars_length(
|
||||
chart_type,
|
||||
&first_entry_data_info,
|
||||
&data_info_host.data_info,
|
||||
);
|
||||
let (incoming_bar_len, outgoing_bar_len) =
|
||||
get_bars_length(data_repr, &first_entry_data_info, &data_info_host.data_info);
|
||||
|
||||
Row::new()
|
||||
.height(FLAGS_HEIGHT_BIG)
|
||||
@@ -422,11 +420,10 @@ pub fn host_bar<'a>(
|
||||
)
|
||||
.push(horizontal_space())
|
||||
.push(
|
||||
Text::new(if chart_type.eq(&ChartType::Packets) {
|
||||
data_info_host.data_info.tot_packets().to_string()
|
||||
} else {
|
||||
ByteMultiple::formatted_string(data_info_host.data_info.tot_bytes())
|
||||
})
|
||||
Text::new(
|
||||
data_repr
|
||||
.formatted_string_from_data_info(&data_info_host.data_info),
|
||||
)
|
||||
.font(font),
|
||||
),
|
||||
)
|
||||
@@ -437,12 +434,12 @@ pub fn host_bar<'a>(
|
||||
pub fn service_bar<'a>(
|
||||
service: &Service,
|
||||
data_info: &DataInfo,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
first_entry_data_info: DataInfo,
|
||||
font: Font,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let (incoming_bar_len, outgoing_bar_len) =
|
||||
get_bars_length(chart_type, &first_entry_data_info, data_info);
|
||||
get_bars_length(data_repr, &first_entry_data_info, data_info);
|
||||
|
||||
Row::new()
|
||||
.height(FLAGS_HEIGHT_BIG)
|
||||
@@ -456,12 +453,8 @@ pub fn service_bar<'a>(
|
||||
.push(Text::new(service.to_string()).font(font))
|
||||
.push(horizontal_space())
|
||||
.push(
|
||||
Text::new(if chart_type.eq(&ChartType::Packets) {
|
||||
data_info.tot_packets().to_string()
|
||||
} else {
|
||||
ByteMultiple::formatted_string(data_info.tot_bytes())
|
||||
})
|
||||
.font(font),
|
||||
Text::new(data_repr.formatted_string_from_data_info(&data_info))
|
||||
.font(font),
|
||||
),
|
||||
)
|
||||
.push(get_bars(incoming_bar_len, outgoing_bar_len)),
|
||||
@@ -477,7 +470,7 @@ fn col_info<'a>(sniffer: &Sniffer) -> Container<'a, Message, StyleType> {
|
||||
let col_device = col_device(language, font, &sniffer.capture_source);
|
||||
|
||||
let col_data_representation =
|
||||
col_data_representation(language, font, sniffer.traffic_chart.chart_type);
|
||||
col_data_representation(language, font, sniffer.traffic_chart.data_repr);
|
||||
|
||||
let donut_row = donut_row(language, font, sniffer);
|
||||
|
||||
@@ -555,7 +548,7 @@ fn col_device<'a>(
|
||||
fn col_data_representation<'a>(
|
||||
language: Language,
|
||||
font: Font,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
) -> Column<'a, Message, StyleType> {
|
||||
let mut ret_val = Column::new().spacing(5).push(
|
||||
Text::new(format!("{}:", data_representation_translation(language)))
|
||||
@@ -564,7 +557,7 @@ fn col_data_representation<'a>(
|
||||
);
|
||||
|
||||
for option in ChartType::ALL {
|
||||
let is_active = chart_type.eq(&option);
|
||||
let is_active = data_repr.eq(&option);
|
||||
ret_val = ret_val.push(
|
||||
Button::new(
|
||||
Text::new(option.get_label(language).to_owned())
|
||||
@@ -580,7 +573,7 @@ fn col_data_representation<'a>(
|
||||
} else {
|
||||
ButtonType::BorderedRound
|
||||
})
|
||||
.on_press(Message::ChartSelection(option)),
|
||||
.on_press(Message::DataReprSelection(option)),
|
||||
);
|
||||
}
|
||||
ret_val
|
||||
@@ -591,18 +584,18 @@ fn donut_row<'a>(
|
||||
font: Font,
|
||||
sniffer: &Sniffer,
|
||||
) -> Container<'a, Message, StyleType> {
|
||||
let chart_type = sniffer.traffic_chart.chart_type;
|
||||
let data_repr = sniffer.traffic_chart.data_repr;
|
||||
let filters = &sniffer.filters;
|
||||
|
||||
let (in_data, out_data, filtered_out, dropped) =
|
||||
sniffer.info_traffic.get_thumbnail_data(chart_type);
|
||||
sniffer.info_traffic.get_thumbnail_data(data_repr);
|
||||
|
||||
let legend_entry_filtered = if filters.none_active() {
|
||||
None
|
||||
} else {
|
||||
Some(donut_legend_entry(
|
||||
filtered_out,
|
||||
chart_type,
|
||||
data_repr,
|
||||
RuleType::FilteredOut,
|
||||
filters,
|
||||
font,
|
||||
@@ -614,7 +607,7 @@ fn donut_row<'a>(
|
||||
.spacing(5)
|
||||
.push(donut_legend_entry(
|
||||
in_data,
|
||||
chart_type,
|
||||
data_repr,
|
||||
RuleType::Incoming,
|
||||
filters,
|
||||
font,
|
||||
@@ -622,7 +615,7 @@ fn donut_row<'a>(
|
||||
))
|
||||
.push(donut_legend_entry(
|
||||
out_data,
|
||||
chart_type,
|
||||
data_repr,
|
||||
RuleType::Outgoing,
|
||||
filters,
|
||||
font,
|
||||
@@ -631,7 +624,7 @@ fn donut_row<'a>(
|
||||
.push_maybe(legend_entry_filtered)
|
||||
.push(donut_legend_entry(
|
||||
dropped,
|
||||
chart_type,
|
||||
data_repr,
|
||||
RuleType::Dropped,
|
||||
filters,
|
||||
font,
|
||||
@@ -642,7 +635,7 @@ fn donut_row<'a>(
|
||||
.align_y(Vertical::Center)
|
||||
.spacing(20)
|
||||
.push(donut_chart(
|
||||
chart_type,
|
||||
data_repr,
|
||||
in_data,
|
||||
out_data,
|
||||
filtered_out,
|
||||
@@ -661,17 +654,13 @@ fn donut_row<'a>(
|
||||
|
||||
fn donut_legend_entry<'a>(
|
||||
value: u128,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
rule_type: RuleType,
|
||||
filters: &Filters,
|
||||
font: Font,
|
||||
language: Language,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let value_text = if chart_type.eq(&ChartType::Bytes) {
|
||||
ByteMultiple::formatted_string(value)
|
||||
} else {
|
||||
value.to_string()
|
||||
};
|
||||
let value_text = data_repr.formatted_string(value);
|
||||
|
||||
let label = match rule_type {
|
||||
RuleType::Incoming => incoming_translation(language),
|
||||
@@ -702,11 +691,11 @@ fn donut_legend_entry<'a>(
|
||||
const MIN_BARS_LENGTH: f32 = 4.0;
|
||||
|
||||
pub fn get_bars_length(
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
first_entry: &DataInfo,
|
||||
data_info: &DataInfo,
|
||||
) -> (u16, u16) {
|
||||
let (in_val, out_val, first_entry_tot_val) = match chart_type {
|
||||
let (in_val, out_val, first_entry_tot_val) = match data_repr {
|
||||
ChartType::Packets => (
|
||||
data_info.incoming_packets(),
|
||||
data_info.outgoing_packets(),
|
||||
@@ -881,7 +870,6 @@ fn sort_arrows<'a>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::gui::pages::overview_page::{MIN_BARS_LENGTH, get_bars_length};
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
use iced::widget::{Checkbox, Column, Container, Row, Scrollable, Space, Text, TextInput};
|
||||
use iced::{Alignment, Font, Length, Padding};
|
||||
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::gui::components::button::button_hide;
|
||||
use crate::gui::components::tab::get_settings_tabs;
|
||||
use crate::gui::pages::types::settings_page::SettingsPage;
|
||||
@@ -14,6 +13,7 @@
|
||||
use crate::gui::styles::text::TextType;
|
||||
use crate::gui::styles::types::gradient_type::GradientType;
|
||||
use crate::gui::types::message::Message;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::notifications::types::notifications::{
|
||||
DataNotification, FavoriteNotification, Notification,
|
||||
};
|
||||
@@ -144,7 +144,7 @@ fn get_data_notify<'a>(
|
||||
data_notification,
|
||||
language,
|
||||
font,
|
||||
data_notification.chart_type,
|
||||
data_notification.data_repr,
|
||||
);
|
||||
let input_row = input_group_bytes(data_notification, font, language);
|
||||
let sound_row = sound_buttons(Notification::Data(data_notification), font, language);
|
||||
@@ -372,7 +372,7 @@ fn row_data_representation<'a>(
|
||||
data_notification: DataNotification,
|
||||
language: Language,
|
||||
font: Font,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
) -> Row<'a, Message, StyleType> {
|
||||
let mut ret_val = Row::new()
|
||||
.width(Length::Shrink)
|
||||
@@ -381,8 +381,8 @@ fn row_data_representation<'a>(
|
||||
.push(Space::with_width(45))
|
||||
.push(Text::new(format!("{}:", data_representation_translation(language))).font(font));
|
||||
|
||||
for option in ChartType::ALL {
|
||||
let is_active = chart_type.eq(&option);
|
||||
for option in DataRepr::ALL {
|
||||
let is_active = data_repr.eq(&option);
|
||||
ret_val = ret_val.push(
|
||||
Button::new(
|
||||
Text::new(option.get_label(language).to_owned())
|
||||
@@ -400,7 +400,7 @@ fn row_data_representation<'a>(
|
||||
})
|
||||
.on_press(Message::UpdateNotificationSettings(
|
||||
Notification::Data(DataNotification {
|
||||
chart_type: option,
|
||||
data_repr: option,
|
||||
..data_notification
|
||||
}),
|
||||
false,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use iced::widget::{Column, Container, Row, Rule, Space, Text, vertical_space};
|
||||
use iced::{Alignment, Font, Length};
|
||||
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::chart::types::donut_chart::donut_chart;
|
||||
use crate::configs::types::config_settings::ConfigSettings;
|
||||
use crate::countries::country_utils::get_flag_tooltip;
|
||||
@@ -12,6 +11,7 @@
|
||||
use crate::gui::styles::style_constants::FONT_SIZE_FOOTER;
|
||||
use crate::gui::styles::types::style_type::StyleType;
|
||||
use crate::gui::types::message::Message;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::{Host, ThumbnailHost};
|
||||
use crate::networking::types::info_traffic::InfoTraffic;
|
||||
use crate::report::get_report_entries::{get_host_entries, get_service_entries};
|
||||
@@ -41,16 +41,16 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
|
||||
}
|
||||
|
||||
let info_traffic = &sniffer.info_traffic;
|
||||
let chart_type = sniffer.traffic_chart.chart_type;
|
||||
let data_repr = sniffer.traffic_chart.data_repr;
|
||||
|
||||
let (in_data, out_data, filtered_out, dropped) = info_traffic.get_thumbnail_data(chart_type);
|
||||
let (in_data, out_data, filtered_out, dropped) = info_traffic.get_thumbnail_data(data_repr);
|
||||
|
||||
let charts = Row::new()
|
||||
.padding(5)
|
||||
.height(Length::Fill)
|
||||
.align_y(Alignment::Center)
|
||||
.push(donut_chart(
|
||||
chart_type,
|
||||
data_repr,
|
||||
in_data,
|
||||
out_data,
|
||||
filtered_out,
|
||||
@@ -71,14 +71,14 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
|
||||
.align_y(Alignment::Start)
|
||||
.push(host_col(
|
||||
info_traffic,
|
||||
chart_type,
|
||||
data_repr,
|
||||
font,
|
||||
sniffer.host_sort_type,
|
||||
))
|
||||
.push(Rule::vertical(10))
|
||||
.push(service_col(
|
||||
info_traffic,
|
||||
chart_type,
|
||||
data_repr,
|
||||
font,
|
||||
sniffer.service_sort_type,
|
||||
));
|
||||
@@ -93,7 +93,7 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
|
||||
|
||||
fn host_col<'a>(
|
||||
info_traffic: &InfoTraffic,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
font: Font,
|
||||
sort_type: SortType,
|
||||
) -> Column<'a, Message, StyleType> {
|
||||
@@ -101,7 +101,7 @@ fn host_col<'a>(
|
||||
.padding([0, 5])
|
||||
.spacing(3)
|
||||
.width(Length::FillPortion(2));
|
||||
let hosts = get_host_entries(info_traffic, chart_type, sort_type);
|
||||
let hosts = get_host_entries(info_traffic, data_repr, sort_type);
|
||||
let mut thumbnail_hosts = Vec::new();
|
||||
|
||||
for (host, data_info_host) in &hosts {
|
||||
@@ -136,12 +136,12 @@ fn host_col<'a>(
|
||||
|
||||
fn service_col<'a>(
|
||||
info_traffic: &InfoTraffic,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
font: Font,
|
||||
sort_type: SortType,
|
||||
) -> Column<'a, Message, StyleType> {
|
||||
let mut service_col = Column::new().padding([0, 5]).spacing(3).width(Length::Fill);
|
||||
let services = get_service_entries(info_traffic, chart_type, sort_type);
|
||||
let services = get_service_entries(info_traffic, data_repr, sort_type);
|
||||
let n_entry = min(services.len(), MAX_ENTRIES);
|
||||
for (service, _) in services.get(..n_entry).unwrap_or_default() {
|
||||
service_col = service_col.push(
|
||||
|
||||
@@ -304,7 +304,7 @@ pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
}
|
||||
self.filters.port_str = value;
|
||||
}
|
||||
Message::ChartSelection(unit) => self.traffic_chart.change_kind(unit),
|
||||
Message::DataReprSelection(unit) => self.traffic_chart.change_kind(unit),
|
||||
Message::ReportSortSelection(sort) => {
|
||||
self.page_number = 1;
|
||||
self.report_sort_type = sort;
|
||||
@@ -868,7 +868,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
|
||||
let notifications = self.configs.settings.notifications;
|
||||
let sound = match notification {
|
||||
Notification::Data(DataNotification {
|
||||
chart_type,
|
||||
data_repr,
|
||||
threshold,
|
||||
byte_multiple,
|
||||
sound,
|
||||
@@ -880,7 +880,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
|
||||
|| temp_threshold.previous_threshold != previous_threshold
|
||||
{
|
||||
temp_threshold = DataNotification {
|
||||
chart_type,
|
||||
data_repr,
|
||||
threshold,
|
||||
byte_multiple,
|
||||
sound,
|
||||
@@ -910,7 +910,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
|
||||
.settings
|
||||
.notifications
|
||||
.data_notification
|
||||
.chart_type = chart_type;
|
||||
.data_repr = data_repr;
|
||||
sound
|
||||
}
|
||||
Notification::Favorite(favorite_notification) => {
|
||||
@@ -1200,13 +1200,13 @@ fn test_correctly_update_protocol() {
|
||||
fn test_correctly_update_chart_kind() {
|
||||
let mut sniffer = Sniffer::new(Configs::default());
|
||||
|
||||
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Bytes);
|
||||
sniffer.update(Message::ChartSelection(ChartType::Packets));
|
||||
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Packets);
|
||||
sniffer.update(Message::ChartSelection(ChartType::Packets));
|
||||
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Packets);
|
||||
sniffer.update(Message::ChartSelection(ChartType::Bytes));
|
||||
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Bytes);
|
||||
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Bytes);
|
||||
sniffer.update(Message::DataReprSelection(ChartType::Packets));
|
||||
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Packets);
|
||||
sniffer.update(Message::DataReprSelection(ChartType::Packets));
|
||||
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Packets);
|
||||
sniffer.update(Message::DataReprSelection(ChartType::Bytes));
|
||||
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1662,7 +1662,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
|
||||
let mut sniffer = Sniffer::new(Configs::default());
|
||||
|
||||
let bytes_notification_init = DataNotification {
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: ChartType::Bytes,
|
||||
threshold: None,
|
||||
byte_multiple: ByteMultiple::KB,
|
||||
sound: Sound::Pop,
|
||||
@@ -1670,7 +1670,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
|
||||
};
|
||||
|
||||
let bytes_notification_toggled_on = DataNotification {
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: ChartType::Bytes,
|
||||
threshold: Some(800_000),
|
||||
byte_multiple: ByteMultiple::GB,
|
||||
sound: Sound::Pop,
|
||||
@@ -1678,7 +1678,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
|
||||
};
|
||||
|
||||
let bytes_notification_adjusted_threshold_sound_off = DataNotification {
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: ChartType::Bytes,
|
||||
threshold: Some(3),
|
||||
byte_multiple: ByteMultiple::KB,
|
||||
sound: Sound::None,
|
||||
@@ -1686,7 +1686,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
|
||||
};
|
||||
|
||||
let bytes_notification_sound_off_only = DataNotification {
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: ChartType::Bytes,
|
||||
threshold: Some(800_000),
|
||||
byte_multiple: ByteMultiple::GB,
|
||||
sound: Sound::None,
|
||||
@@ -1806,7 +1806,7 @@ fn test_clear_all_notifications() {
|
||||
VecDeque::from([LoggedNotification::DataThresholdExceeded(
|
||||
DataThresholdExceeded {
|
||||
id: 1,
|
||||
chart_type: ChartType::Packets,
|
||||
data_repr: ChartType::Packets,
|
||||
threshold: 0,
|
||||
data_info: DataInfo::default(),
|
||||
timestamp: "".to_string(),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
use crate::gui::pages::types::running_page::RunningPage;
|
||||
use crate::gui::pages::types::settings_page::SettingsPage;
|
||||
use crate::gui::styles::types::gradient_type::GradientType;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::{Host, HostMessage};
|
||||
use crate::networking::types::info_traffic::InfoTraffic;
|
||||
use crate::notifications::types::notifications::Notification;
|
||||
@@ -12,7 +13,7 @@
|
||||
use crate::report::types::sort_type::SortType;
|
||||
use crate::utils::types::file_info::FileInfo;
|
||||
use crate::utils::types::web_page::WebPage;
|
||||
use crate::{ChartType, IpVersion, Language, Protocol, ReportSortType, StyleType};
|
||||
use crate::{IpVersion, Language, Protocol, ReportSortType, StyleType};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// Messages types that permit reacting to application interactions/subscriptions
|
||||
@@ -31,8 +32,8 @@ pub enum Message {
|
||||
AddressFilter(String),
|
||||
/// Changed port filter
|
||||
PortFilter(String),
|
||||
/// Select chart type to be displayed
|
||||
ChartSelection(ChartType),
|
||||
/// Select data representation to use
|
||||
DataReprSelection(DataRepr),
|
||||
/// Select report sort type to be displayed (inspect page)
|
||||
ReportSortSelection(ReportSortType),
|
||||
/// Select host sort type to be displayed (overview page)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
use iced::window::settings::PlatformSpecific;
|
||||
use iced::{Font, Pixels, Settings, application, window};
|
||||
|
||||
use chart::types::chart_type::ChartType;
|
||||
use chart::types::traffic_chart::TrafficChart;
|
||||
use cli::handle_cli_args;
|
||||
use configs::types::config_device::ConfigDevice;
|
||||
@@ -18,7 +17,7 @@
|
||||
use gui::sniffer::Sniffer;
|
||||
use gui::styles::style_constants::FONT_SIZE_BODY;
|
||||
use gui::styles::types::style_type::StyleType;
|
||||
use networking::types::byte_multiple::ByteMultiple;
|
||||
use networking::types::data_representation::ByteMultiple;
|
||||
use networking::types::info_traffic::InfoTraffic;
|
||||
use networking::types::ip_version::IpVersion;
|
||||
use networking::types::protocol::Protocol;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Module defining the `DataInfo` struct, which represents incoming and outgoing packets and bytes.
|
||||
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::traffic_direction::TrafficDirection;
|
||||
use crate::report::types::sort_type::SortType;
|
||||
use std::cmp::Ordering;
|
||||
@@ -47,8 +47,8 @@ pub fn tot_bytes(&self) -> u128 {
|
||||
self.incoming_bytes + self.outgoing_bytes
|
||||
}
|
||||
|
||||
pub fn tot_data(&self, chart_type: ChartType) -> u128 {
|
||||
match chart_type {
|
||||
pub fn tot_data(&self, data_repr: DataRepr) -> u128 {
|
||||
match data_repr {
|
||||
ChartType::Packets => self.tot_packets(),
|
||||
ChartType::Bytes => self.tot_bytes(),
|
||||
}
|
||||
@@ -103,8 +103,8 @@ pub fn refresh(&mut self, rhs: Self) {
|
||||
self.final_instant = rhs.final_instant;
|
||||
}
|
||||
|
||||
pub fn compare(&self, other: &Self, sort_type: SortType, chart_type: ChartType) -> Ordering {
|
||||
match chart_type {
|
||||
pub fn compare(&self, other: &Self, sort_type: SortType, data_repr: DataRepr) -> Ordering {
|
||||
match data_repr {
|
||||
ChartType::Packets => match sort_type {
|
||||
SortType::Ascending => self.tot_packets().cmp(&other.tot_packets()),
|
||||
SortType::Descending => other.tot_packets().cmp(&self.tot_packets()),
|
||||
|
||||
@@ -1,8 +1,73 @@
|
||||
use std::fmt;
|
||||
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::translations::translations::{
|
||||
bytes_exceeded_translation, bytes_translation, packets_exceeded_translation,
|
||||
packets_translation,
|
||||
};
|
||||
use crate::translations::translations_4::{bits_exceeded_translation, bits_translation};
|
||||
use crate::translations::types::language::Language;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Enum representing the possible observed values of IP protocol version.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum DataRepr {
|
||||
Packets,
|
||||
Bytes,
|
||||
Bits,
|
||||
}
|
||||
|
||||
impl DataRepr {
|
||||
pub(crate) const ALL: [DataRepr; 3] = [DataRepr::Bits, DataRepr::Bytes, DataRepr::Packets];
|
||||
|
||||
pub fn get_label(&self, language: Language) -> &str {
|
||||
match self {
|
||||
DataRepr::Packets => packets_translation(language),
|
||||
DataRepr::Bytes => bytes_translation(language),
|
||||
DataRepr::Bits => bits_translation(language),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a String representing a quantity of traffic (packets / bytes / bits) with the proper multiple if applicable
|
||||
pub fn formatted_string(&self, amount: u128) -> String {
|
||||
if self == &DataRepr::Packets {
|
||||
return amount.to_string();
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let mut n = amount as f32;
|
||||
|
||||
let byte_multiple = ByteMultiple::from_amount(amount);
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let multiplier = byte_multiple.multiplier() as f32;
|
||||
n /= multiplier;
|
||||
if n > 999.0 && byte_multiple != ByteMultiple::PB {
|
||||
// this allows representing e.g. 999_999 as 999 KB instead of 1000 KB
|
||||
n = 999.0;
|
||||
}
|
||||
let precision = usize::from(byte_multiple != ByteMultiple::B && n <= 9.95);
|
||||
format!("{n:.precision$} {}", byte_multiple.pretty_print(*self))
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn formatted_string_from_data_info(&self, data_info: &DataInfo) -> String {
|
||||
let amount = match self {
|
||||
DataRepr::Packets => data_info.tot_packets(),
|
||||
DataRepr::Bytes => data_info.tot_bytes(),
|
||||
DataRepr::Bits => data_info.tot_bytes() * 8,
|
||||
};
|
||||
self.formatted_string(amount)
|
||||
}
|
||||
|
||||
pub fn data_exceeded_translation(&self, language: Language) -> &str {
|
||||
match self {
|
||||
DataRepr::Packets => packets_exceeded_translation(language),
|
||||
DataRepr::Bytes => bytes_exceeded_translation(language),
|
||||
DataRepr::Bits => bits_exceeded_translation(language),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a Byte or bit multiple for displaying values in a human-readable format.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ByteMultiple {
|
||||
/// A Byte
|
||||
@@ -19,12 +84,6 @@ pub enum ByteMultiple {
|
||||
PB,
|
||||
}
|
||||
|
||||
impl fmt::Display for ByteMultiple {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl ByteMultiple {
|
||||
pub fn multiplier(self) -> u64 {
|
||||
match self {
|
||||
@@ -37,7 +96,7 @@ pub fn multiplier(self) -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn from_num_bytes(bytes: u128) -> Self {
|
||||
fn from_amount(bytes: u128) -> Self {
|
||||
match bytes {
|
||||
x if (u128::MIN..u128::from(ByteMultiple::KB.multiplier())).contains(&x) => {
|
||||
ByteMultiple::B
|
||||
@@ -71,10 +130,14 @@ fn from_num_bytes(bytes: u128) -> Self {
|
||||
}
|
||||
|
||||
pub fn get_char(self) -> String {
|
||||
self.to_string()
|
||||
.strip_suffix('B')
|
||||
.unwrap_or_default()
|
||||
.to_owned()
|
||||
match self {
|
||||
Self::B => String::new(),
|
||||
Self::KB => "K".to_string(),
|
||||
Self::MB => "M".to_string(),
|
||||
Self::GB => "G".to_string(),
|
||||
Self::TB => "T".to_string(),
|
||||
Self::PB => "P".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_char(ch: char) -> Self {
|
||||
@@ -88,22 +151,12 @@ pub fn from_char(ch: char) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a String representing a quantity of bytes with its proper multiple (B, KB, MB, GB, TB)
|
||||
pub fn formatted_string(bytes: u128) -> String {
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let mut n = bytes as f32;
|
||||
|
||||
let byte_multiple = ByteMultiple::from_num_bytes(bytes);
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let multiplier = byte_multiple.multiplier() as f32;
|
||||
n /= multiplier;
|
||||
if n > 999.0 && byte_multiple != ByteMultiple::PB {
|
||||
// this allows representing e.g. 999_999 as 999 KB instead of 1000 KB
|
||||
n = 999.0;
|
||||
pub fn pretty_print(&self, repr: DataRepr) -> String {
|
||||
match repr {
|
||||
DataRepr::Packets => String::new(),
|
||||
DataRepr::Bytes => format!("{}B", self.get_char()),
|
||||
DataRepr::Bits => format!("{}b", self.get_char()),
|
||||
}
|
||||
let precision = usize::from(byte_multiple != ByteMultiple::B && n <= 9.95);
|
||||
format!("{n:.precision$} {byte_multiple}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::Service;
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::networking::types::address_port_pair::AddressPortPair;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
|
||||
use crate::utils::types::timestamp::Timestamp;
|
||||
@@ -65,8 +65,8 @@ pub fn refresh(&mut self, msg: &mut InfoTraffic) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_thumbnail_data(&self, chart_type: ChartType) -> (u128, u128, u128, u128) {
|
||||
if chart_type.eq(&ChartType::Bytes) {
|
||||
pub fn get_thumbnail_data(&self, data_repr: DataRepr) -> (u128, u128, u128, u128) {
|
||||
if data_repr.eq(&ChartType::Bytes) {
|
||||
(
|
||||
self.tot_data_info.incoming_bytes(),
|
||||
self.tot_data_info.outgoing_bytes(),
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
pub mod arp_type;
|
||||
pub mod asn;
|
||||
pub mod bogon;
|
||||
pub mod byte_multiple;
|
||||
pub mod capture_context;
|
||||
pub mod data_info;
|
||||
pub mod data_info_host;
|
||||
pub mod data_representation;
|
||||
pub mod filters;
|
||||
pub mod host;
|
||||
pub mod host_data_states;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::InfoTraffic;
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::networking::types::capture_context::CaptureSource;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::service::Service;
|
||||
use crate::notifications::types::logged_notification::{
|
||||
@@ -31,8 +31,8 @@ pub fn notify_and_log(
|
||||
let data_info = info_traffic_msg.tot_data_info;
|
||||
// data threshold
|
||||
if let Some(threshold) = notifications.data_notification.threshold {
|
||||
let chart_type = notifications.data_notification.chart_type;
|
||||
if data_info.tot_data(chart_type) > u128::from(threshold) {
|
||||
let data_repr = notifications.data_notification.data_repr;
|
||||
if data_info.tot_data(data_repr) > u128::from(threshold) {
|
||||
//log this notification
|
||||
logged_notifications.1 += 1;
|
||||
if logged_notifications.0.len() >= 30 {
|
||||
@@ -43,13 +43,13 @@ pub fn notify_and_log(
|
||||
.push_front(LoggedNotification::DataThresholdExceeded(
|
||||
DataThresholdExceeded {
|
||||
id: logged_notifications.1,
|
||||
chart_type,
|
||||
data_repr,
|
||||
threshold: notifications.data_notification.previous_threshold,
|
||||
data_info,
|
||||
timestamp: get_formatted_timestamp(timestamp),
|
||||
is_expanded: false,
|
||||
hosts: hosts_list(info_traffic_msg, chart_type),
|
||||
services: services_list(info_traffic_msg, chart_type),
|
||||
hosts: hosts_list(info_traffic_msg, data_repr),
|
||||
services: services_list(info_traffic_msg, data_repr),
|
||||
},
|
||||
));
|
||||
if sound_to_play.eq(&Sound::None) {
|
||||
@@ -98,7 +98,7 @@ pub fn notify_and_log(
|
||||
logged_notifications.1 - emitted_notifications_prev
|
||||
}
|
||||
|
||||
fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Host, DataInfoHost)> {
|
||||
fn hosts_list(info_traffic_msg: &InfoTraffic, data_repr: DataRepr) -> Vec<(Host, DataInfoHost)> {
|
||||
let mut hosts: Vec<(Host, DataInfoHost)> = info_traffic_msg
|
||||
.hosts
|
||||
.iter()
|
||||
@@ -106,7 +106,7 @@ fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Hos
|
||||
.collect();
|
||||
hosts.sort_by(|(_, a), (_, b)| {
|
||||
a.data_info
|
||||
.compare(&b.data_info, SortType::Descending, chart_type)
|
||||
.compare(&b.data_info, SortType::Descending, data_repr)
|
||||
});
|
||||
let n_entry = min(hosts.len(), 4);
|
||||
hosts
|
||||
@@ -117,17 +117,14 @@ fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Hos
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn services_list(
|
||||
info_traffic_msg: &InfoTraffic,
|
||||
chart_type: ChartType,
|
||||
) -> Vec<(Service, DataInfo)> {
|
||||
fn services_list(info_traffic_msg: &InfoTraffic, data_repr: DataRepr) -> Vec<(Service, DataInfo)> {
|
||||
let mut services: Vec<(Service, DataInfo)> = info_traffic_msg
|
||||
.services
|
||||
.iter()
|
||||
.filter(|(service, _)| service != &&Service::NotApplicable)
|
||||
.map(|(s, data)| (*s, *data))
|
||||
.collect();
|
||||
services.sort_by(|(_, a), (_, b)| a.compare(b, SortType::Descending, chart_type));
|
||||
services.sort_by(|(_, a), (_, b)| a.compare(b, SortType::Descending, data_repr));
|
||||
let n_entry = min(services.len(), 4);
|
||||
services
|
||||
.get(..n_entry)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::service::Service;
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn expand(&mut self, expand: bool) {
|
||||
#[derive(Clone)]
|
||||
pub struct DataThresholdExceeded {
|
||||
pub(crate) id: usize,
|
||||
pub(crate) chart_type: ChartType,
|
||||
pub(crate) data_repr: DataRepr,
|
||||
pub(crate) threshold: u64,
|
||||
pub(crate) data_info: DataInfo,
|
||||
pub(crate) timestamp: String,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ByteMultiple;
|
||||
use crate::chart::types::chart_type::ChartType;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::notifications::types::sound::Sound;
|
||||
|
||||
/// Used to contain the notifications configuration set by the user
|
||||
@@ -34,7 +34,7 @@ pub enum Notification {
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug, Copy)]
|
||||
pub struct DataNotification {
|
||||
/// Data representation
|
||||
pub chart_type: ChartType,
|
||||
pub data_repr: DataRepr,
|
||||
/// Threshold of received + sent bytes; if exceeded a notification is emitted
|
||||
pub threshold: Option<u64>,
|
||||
/// B, KB, MB or GB
|
||||
@@ -48,7 +48,7 @@ pub struct DataNotification {
|
||||
impl Default for DataNotification {
|
||||
fn default() -> Self {
|
||||
DataNotification {
|
||||
chart_type: ChartType::Bytes,
|
||||
data_repr: DataRepr::Bytes,
|
||||
threshold: None,
|
||||
byte_multiple: ByteMultiple::KB,
|
||||
sound: Sound::Pop,
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
use crate::networking::types::address_port_pair::AddressPortPair;
|
||||
use crate::networking::types::data_info::DataInfo;
|
||||
use crate::networking::types::data_info_host::DataInfoHost;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::host::Host;
|
||||
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
|
||||
use crate::report::types::sort_type::SortType;
|
||||
use crate::{ChartType, InfoTraffic, ReportSortType, Service, Sniffer};
|
||||
use crate::{InfoTraffic, ReportSortType, Service, Sniffer};
|
||||
|
||||
/// Return the elements that satisfy the search constraints and belong to the given page,
|
||||
/// and the total number of elements which satisfy the search constraints,
|
||||
@@ -82,12 +83,12 @@ pub fn get_searched_entries(
|
||||
|
||||
pub fn get_host_entries(
|
||||
info_traffic: &InfoTraffic,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
sort_type: SortType,
|
||||
) -> Vec<(Host, DataInfoHost)> {
|
||||
let mut sorted_vec: Vec<(&Host, &DataInfoHost)> = info_traffic.hosts.iter().collect();
|
||||
|
||||
sorted_vec.sort_by(|&(_, a), &(_, b)| a.data_info.compare(&b.data_info, sort_type, chart_type));
|
||||
sorted_vec.sort_by(|&(_, a), &(_, b)| a.data_info.compare(&b.data_info, sort_type, data_repr));
|
||||
|
||||
let n_entry = min(sorted_vec.len(), 30);
|
||||
sorted_vec[0..n_entry]
|
||||
@@ -98,7 +99,7 @@ pub fn get_host_entries(
|
||||
|
||||
pub fn get_service_entries(
|
||||
info_traffic: &InfoTraffic,
|
||||
chart_type: ChartType,
|
||||
data_repr: DataRepr,
|
||||
sort_type: SortType,
|
||||
) -> Vec<(Service, DataInfo)> {
|
||||
let mut sorted_vec: Vec<(&Service, &DataInfo)> = info_traffic
|
||||
@@ -107,7 +108,7 @@ pub fn get_service_entries(
|
||||
.filter(|(service, _)| service != &&Service::NotApplicable)
|
||||
.collect();
|
||||
|
||||
sorted_vec.sort_by(|&(_, a), &(_, b)| a.compare(b, sort_type, chart_type));
|
||||
sorted_vec.sort_by(|&(_, a), &(_, b)| a.compare(b, sort_type, data_repr));
|
||||
|
||||
let n_entry = min(sorted_vec.len(), 30);
|
||||
sorted_vec[0..n_entry]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::ByteMultiple;
|
||||
use crate::networking::types::address_port_pair::AddressPortPair;
|
||||
use crate::networking::types::data_representation::DataRepr;
|
||||
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
|
||||
use crate::report::types::search_parameters::FilterInputType;
|
||||
use crate::translations::translations::{
|
||||
@@ -25,6 +25,7 @@ pub enum ReportCol {
|
||||
DstPort,
|
||||
Proto,
|
||||
Service,
|
||||
Bits,
|
||||
Bytes,
|
||||
Packets,
|
||||
}
|
||||
@@ -92,8 +93,9 @@ pub(crate) fn get_value(&self, key: &AddressPortPair, val: &InfoAddressPortPair)
|
||||
}
|
||||
ReportCol::Proto => key.protocol.to_string(),
|
||||
ReportCol::Service => val.service.to_string(),
|
||||
ReportCol::Bytes => ByteMultiple::formatted_string(val.transmitted_bytes),
|
||||
ReportCol::Packets => val.transmitted_packets.to_string(),
|
||||
ReportCol::Bits => DataRepr::Bits.formatted_string(val.transmitted_bytes * 8),
|
||||
ReportCol::Bytes => DataRepr::Bytes.formatted_string(val.transmitted_bytes),
|
||||
ReportCol::Packets => DataRepr::Packets.formatted_string(val.transmitted_packets),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user