Skip to content

Commit

Permalink
Merge pull request #86
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
TheRustyPickle authored Nov 30, 2024
2 parents 7af71b2 + 54df428 commit 89e9721
Show file tree
Hide file tree
Showing 9 changed files with 723 additions and 696 deletions.
1,192 changes: 632 additions & 560 deletions Cargo.lock

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,34 @@ path = "src/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
grammers-client = "=0.5.0"
grammers-session = "=0.5.1"
grammers-mtproto = "=0.5.0"
grammers-crypto = "=0.5.1"
grammers-tl-gen = "=0.5.1"
grammers-tl-types = "=0.5.1"
grammers-mtsender = "=0.5.0"
tokio = { version = "1.39.1", features = ["rt-multi-thread"] }
grammers-client = "=0.7.0"
grammers-session = "=0.7.0"
grammers-mtproto = "=0.7.0"
grammers-crypto = "=0.7.0"
grammers-tl-gen = "=0.7.0"
grammers-tl-types = "=0.7.0"
grammers-mtsender = "=0.7.0"
tokio = { version = "1.41.1", features = ["rt-multi-thread"] }
log = "0.4.22"
pretty_env_logger = "0.5.0"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
dirs = "5.0.1"
open = "5.3.0"
reqwest = { version = "0.12.8", features = ["json"] }
open = "5.3.1"
reqwest = { version = "0.12.9", features = ["json"] }
eframe = "0.29.1"
egui_extras = { version = "0.29.1", features = ["datepicker"] }
egui_plot = "0.29.0"
egui-dropdown = "0.11.0"
egui-modal = "0.5.0"
egui-theme-lerp = "0.1.2"
egui-theme-lerp = "0.1.3"
chrono = { version = "0.4.38", features = ["serde"] }
semver = "1.0.23"
rayon = "1.10.0"
csv = "1.3.0"
csv = "1.3.1"
strum = "0.26.3"
strum_macros = "0.26.4"
egui-selectable-table = "0.1.0"
egui-selectable-table = "0.1.1"

# The profile that 'cargo dist' will build with
[profile.dist]
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.81.0
stable
13 changes: 11 additions & 2 deletions src/tg_handler/new_session.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use eframe::egui::Context;
use grammers_client::types::{LoginToken, PasswordToken};
use grammers_client::{Client, Config, SignInError};
use grammers_client::{Client, Config, FixedReconnect, InitParams, SignInError};
use grammers_session::Session;
use log::{error, info};
use std::fs;
Expand Down Expand Up @@ -43,11 +43,20 @@ pub async fn send_login_code(
Session::load_file_or_create(target_path).unwrap()
};

let reconnection = Box::leak(Box::new(FixedReconnect {
attempts: 10,
delay: std::time::Duration::from_secs(1),
}));

let client = Client::connect(Config {
session,
api_id,
api_hash,
params: Default::default(),
params: InitParams {
reconnection_policy: reconnection,
update_queue_limit: Some(1),
..Default::default()
},
})
.await
.map_err(|_| ProcessError::AuthorizationError)?;
Expand Down
25 changes: 19 additions & 6 deletions src/ui_components/initializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ use crate::ui_components::tab_ui::{
use crate::ui_components::widgets::AnimatedLabel;
use crate::ui_components::TGKeys;
use crate::utils::{
find_session_files, get_api_keys, get_font_data, get_runtime, theme_hover_text,
find_session_files, get_api_keys, get_font_data, get_runtime, last_theme, save_theme,
theme_hover_text,
};

pub struct MainWindow {
Expand Down Expand Up @@ -58,8 +59,18 @@ pub struct MainWindow {

impl MainWindow {
pub fn new(cc: &CreationContext) -> Self {
cc.egui_ctx
.options_mut(|a| a.theme_preference = ThemePreference::Light);
let last_theme_light = last_theme().unwrap_or_default();
let mut animator = ThemeAnimator::new(Visuals::light(), Visuals::dark());

if last_theme_light {
cc.egui_ctx
.options_mut(|a| a.theme_preference = ThemePreference::Light);
animator.theme_1_to_2 = true;
} else {
cc.egui_ctx
.options_mut(|a| a.theme_preference = ThemePreference::Dark);
animator.theme_1_to_2 = false;
};
let (sender, receiver) = channel();

Self {
Expand All @@ -79,15 +90,15 @@ impl MainWindow {
tg_clients: BTreeMap::new(),
incomplete_tg_client: None,
existing_sessions_checked: false,
is_light_theme: true,
is_light_theme: last_theme_light,
is_processing: false,
new_version_body: Arc::new(Mutex::new(None)),
counter_chat_index: 0,
table_chat_index: 0,
chart_chat_index: 0,
initial_chart_reset: false,
cancel_count: Arc::new(AtomicBool::new(false)),
theme_animator: ThemeAnimator::new(Visuals::light(), Visuals::dark()),
theme_animator: animator,
runtime: get_runtime(),
}
}
Expand Down Expand Up @@ -160,7 +171,9 @@ impl App for MainWindow {
.on_hover_text(hover_text)
.clicked()
{
self.theme_animator.start()
self.theme_animator.start();
self.is_light_theme = !self.is_light_theme;
save_theme(self.is_light_theme);
};

let hover_position = ui.make_persistent_id("tab_hover");
Expand Down
4 changes: 3 additions & 1 deletion src/ui_components/processor/tg_comms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ impl MainWindow {
// Also recreate table data after counting session ends for a chat
if self.counter.session_remaining() <= 1 {
self.t_table().create_rows();
let total_user = self.t_table().get_total_users_full();
self.t_count().set_total_user(total_user as i32);
self.go_next_or_stop();
} else {
self.counter.reduce_session();
Expand Down Expand Up @@ -110,7 +112,7 @@ impl MainWindow {
self.t_table().set_as_whitelisted(&[user_id]);
}

let total_user = self.t_table().get_total_user();
let total_user = self.t_table().get_total_users_full();
self.t_count().set_total_user(total_user as i32);

let total_to_iter = start_from - end_at;
Expand Down
105 changes: 2 additions & 103 deletions src/ui_components/tab_ui/charts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ use egui_dropdown::DropDownBox;
use egui_extras::DatePickerButton;
use egui_plot::{Bar, BarChart, Legend, Plot, PlotPoint};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::env::current_dir;
use strum::IntoEnumIterator;

use crate::ui_components::processor::{
ChartTiming, ChartType, DateNavigator, NavigationType, ProcessState,
};
use crate::ui_components::processor::{ChartTiming, ChartType, DateNavigator, NavigationType};
use crate::ui_components::widgets::AnimatedLabel;
use crate::ui_components::MainWindow;
use crate::utils::{create_export_file, time_to_string, weekday_num_to_string};
use crate::utils::{time_to_string, weekday_num_to_string};

#[derive(Default)]
pub struct ChartsData {
Expand Down Expand Up @@ -237,88 +234,6 @@ impl ChartsData {
self.date_nav.handler().update_dates(date);
}

/// Used to export chart data points to a text file
fn export_chart_data(&self) {
let timing_data = match self.chart_type {
ChartType::Message | ChartType::ActiveUser => match self.chart_timing {
ChartTiming::Hourly => Some(&self.hourly_message),
ChartTiming::Daily => Some(&self.daily_message),
ChartTiming::Weekly => Some(&self.weekly_message),
ChartTiming::Monthly => Some(&self.monthly_message),
},
_ => None,
};

let weekday_data = if timing_data.is_none() {
Some(&self.weekday_message)
} else {
None
};

let export_file_name = if timing_data.is_some() {
format!("export_{}_{}.txt", self.chart_type, self.chart_timing)
} else {
format!("export_{}_txt", self.chart_type)
};

let mut export_data = String::new();

if timing_data.is_some() {
// Date of chart points + {username or Full Name or user ID : total message sent}
let data = timing_data.unwrap();

for (timing, message_data) in data {
export_data += &format!("Timing: {timing}\n");
let (user_data, total_message, total_user) = self.chart_data_to_text(message_data);
export_data += &format!("Total Message: {total_message}\n");
export_data += &format!("Total User: {total_user}\n");
export_data += &format!("User Data and Message Sent:\n{user_data}");
export_data += "\n\n";
}
} else {
// Day of the week in u8 + {username or Full Name or user ID : total message sent}
let data = weekday_data.unwrap();

for (timing, message_data) in data {
let weekday_name = weekday_num_to_string(*timing);

export_data += &format!("Weekday: {weekday_name}\n");
let (user_data, total_message, total_user) = self.chart_data_to_text(message_data);
export_data += &format!("Total Message: {total_message}\n");
export_data += &format!("Total User: {total_user}\n");
export_data += &format!("User Data and Message Sent:\n{user_data}");
export_data += "\n\n";
}
}

create_export_file(&export_data, export_file_name);
}

/// Converts chart data points into textual representation
fn chart_data_to_text(&self, message_data: &HashMap<String, u64>) -> (String, u64, u64) {
let total_length = message_data.len();
let mut user_added = 0;
let mut total_message = 0;
let mut total_user = 0;
let mut user_data = String::new();
let mut index = 0;

for (user_id, message_num) in message_data {
total_message += message_num;
total_user += 1;
user_added += 1;
index += 1;

user_data += &format!("{user_id}: {message_num} ");
// Prevent adding extra space if is the last value
if user_added == 6 && index != total_length - 1 {
user_added = 0;
user_data += "\n";
}
}
(user_data, total_message, total_user)
}

/// Clears all pre-saved bars
pub fn reset_saved_bars(&mut self) {
self.hourly_bars = None;
Expand Down Expand Up @@ -634,22 +549,6 @@ impl MainWindow {
}

ui.horizontal(|ui| {
let button_text = if [ChartType::ActiveUserWeekDay, ChartType::MessageWeekDay].contains(&self.chart().chart_type) {
format!("Export {} Chart Data", self.chart().chart_type)
} else {
format!(
"Export {} {} Chart Data",
self.chart_i().chart_type, self.chart_i().chart_timing
)
};

let enable_export = !self.is_processing && !self.chart().available_users.is_empty();
if ui.add_enabled(enable_export, Button::new(button_text)).on_hover_text("Export Chart data in text file").clicked()
{
self.chart().export_chart_data();
self.process_state = ProcessState::DataExported(current_dir().unwrap().to_string_lossy().into());
};
ui.add_space(2.0);
ui.label("Use CTRL + scroll to zoom, drag mouse or scroll to move and double click to fit/reset the chart");
});

Expand Down
7 changes: 6 additions & 1 deletion src/ui_components/tab_ui/user_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ impl Default for UserTableData {
fn default() -> Self {
let table = SelectableTable::new(ColumnName::iter().collect())
.auto_scroll()
.serial_column();
.serial_column()
.horizontal_scroll();
Self {
user_data: HashMap::new(),
table,
Expand Down Expand Up @@ -405,6 +406,10 @@ impl UserTableData {
self.table.total_displayed_rows()
}

pub fn get_total_users_full(&self) -> usize {
self.table.total_rows()
}

/// Recreate the rows that will be shown in the UI. Used only when date picker date is updated
pub fn create_rows(&mut self) {
let mut id_map = HashMap::new();
Expand Down
41 changes: 34 additions & 7 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use chrono::{Local, NaiveDate, NaiveDateTime};
use egui_selectable_table::SelectableRow;
use log::{error, info};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::error::Error;
use std::fs::{self, File};
Expand All @@ -14,6 +15,11 @@ use crate::ui_components::processor::{
use crate::ui_components::tab_ui::UserRowData;
use crate::ui_components::TGKeys;

#[derive(Serialize, Deserialize)]
pub struct IsLightTheme {
is_light: bool,
}

/// Finds all the saved session files
pub fn find_session_files() -> Vec<String> {
let mut sessions = Vec::new();
Expand Down Expand Up @@ -359,13 +365,6 @@ pub fn weekday_num_to_string(weekday: u8) -> String {
}
}

pub fn create_export_file(export_data: &str, file_name: String) {
let mut export_file_location = PathBuf::from(".");
export_file_location.push(file_name);
let mut file = File::create(export_file_location).unwrap();
file.write_all(export_data.as_bytes()).unwrap();
}

pub fn export_table_data(rows: &Vec<SelectableRow<UserRowData, ColumnName>>, name: &str) {
let mut export_file_location = PathBuf::from(".");
let current_time = Local::now();
Expand Down Expand Up @@ -432,3 +431,31 @@ pub fn to_chart_name(user_name: String, full_name: &str, user_id: i64) -> String
format!("{full_name} {user_id}")
}
}

pub fn last_theme() -> Result<bool, Box<dyn Error>> {
let mut theme_json = PathBuf::from(".");
theme_json.push("theme.json");

if let Ok(mut file) = File::open(theme_json) {
let mut contents = String::new();
file.read_to_string(&mut contents)?;

let existing_data: IsLightTheme = serde_json::from_str(&contents)?;
Ok(existing_data.is_light)
} else {
Ok(true)
}
}

pub fn save_theme(status: bool) {
let new_data = IsLightTheme { is_light: status };

let data = serde_json::to_string(&new_data);

if let Ok(data) = data {
let mut theme_path = PathBuf::from(".");
theme_path.push("theme.json");
let mut file = File::create(theme_path).unwrap();
file.write_all(data.as_bytes()).unwrap();
};
}

0 comments on commit 89e9721

Please sign in to comment.