|
1 | | -use active_win_pos_rs::get_active_window; |
| 1 | +mod get_state; |
| 2 | +mod write_csv; |
| 3 | + |
2 | 4 | use chrono::Local; |
3 | | -use device_query::{DeviceQuery, DeviceState}; |
4 | | -use std::fs::{create_dir_all, OpenOptions}; |
5 | | -use std::io::Write; |
6 | | -use std::path::Path; |
7 | 5 | use std::thread::sleep; |
8 | 6 | use std::time::Duration; |
9 | 7 |
|
10 | | -const SKIP_WRITING_TO_FILE: bool = false; |
11 | 8 | const FREQUENCY: f64 = 10.0; // seconds |
12 | 9 |
|
13 | | -/// Retrieves the current mouse cursor position. |
14 | | -/// Returns a tuple (x, y). If an error occurs, returns None. |
15 | | -fn get_mouse_cursor_position() -> Option<(i32, i32)> { |
16 | | - let device = DeviceState::new(); |
17 | | - let mouse = device.get_mouse(); |
18 | | - Some((mouse.coords.0, mouse.coords.1)) |
19 | | -} |
20 | | - |
21 | | -/// Retrieves the title of the active window. |
22 | | -/// If no active window is found or an error occurs, returns an empty String. |
23 | | -fn get_active_window_title() -> String { |
24 | | - match get_active_window() { |
25 | | - Ok(window) => format!("{}: {}", window.app_name, window.title), |
26 | | - Err(e) => { |
27 | | - eprintln!("Error getting active window: {:?}", e); |
28 | | - String::new() |
29 | | - } |
30 | | - } |
31 | | -} |
32 | | - |
33 | | -/// Appends a log line to the CSV file. |
34 | | -/// |
35 | | -/// The log line has the format: |
36 | | -/// `YYYY-MM-DD HH:MM:SS.mmm;window_title_without_semicolon;x,y` |
37 | | -fn add_to_csv( |
38 | | - csv_filename: &str, |
39 | | - current_time: &chrono::DateTime<Local>, |
40 | | - window_title: &str, |
41 | | - cursor: &str, |
42 | | -) { |
43 | | - // Format the time to include milliseconds (as in the Python code) |
44 | | - let ms = current_time.timestamp_subsec_millis(); |
45 | | - let time_str = format!("{}.{:03}", current_time.format("%Y-%m-%d %H:%M:%S"), ms); |
46 | | - |
47 | | - // Remove any semicolons from the window title |
48 | | - let title_adapted = window_title.replace(";", ""); |
49 | | - let line = format!("{};{};{}", time_str, title_adapted, cursor); |
50 | | - |
51 | | - println!("{}", line); |
52 | | - |
53 | | - if !SKIP_WRITING_TO_FILE { |
54 | | - // Ensure that the parent directory exists |
55 | | - if let Some(parent) = Path::new(csv_filename).parent() { |
56 | | - if !parent.exists() { |
57 | | - println!("creating {}", parent.display()); |
58 | | - if let Err(e) = create_dir_all(parent) { |
59 | | - eprintln!("Error creating directory {}: {}", parent.display(), e); |
60 | | - } |
61 | | - } |
62 | | - } |
63 | | - |
64 | | - // Open the file in append mode (or create it if it does not exist) |
65 | | - let file_result = OpenOptions::new() |
66 | | - .append(true) |
67 | | - .create(true) |
68 | | - .open(csv_filename); |
69 | | - match file_result { |
70 | | - Ok(mut file) => { |
71 | | - if let Err(e) = writeln!(file, "{}", line) { |
72 | | - eprintln!("Error writing to file {}: {}", csv_filename, e); |
73 | | - } |
74 | | - } |
75 | | - Err(e) => { |
76 | | - eprintln!("Error opening file {}: {}", csv_filename, e); |
77 | | - } |
78 | | - } |
79 | | - } |
80 | | -} |
81 | | - |
82 | 10 | fn main() { |
| 11 | + let mut prev_state = get_state::get_state(); |
83 | 12 | loop { |
84 | 13 | let current_time = Local::now(); |
85 | | - |
86 | | - // Get the active window title and mouse cursor position |
87 | | - let current_window_title = get_active_window_title(); |
88 | | - if let Some((x, y)) = get_mouse_cursor_position() { |
89 | | - let cursor = format!("{},{}", x, y); |
90 | | - // Build the filename: logs/activity_log_YYYY_MM_DD.csv |
| 14 | + let state = get_state::get_state(); |
| 15 | + if state != prev_state { |
| 16 | + let cursor = format!("{},{}", state.cursor.0, state.cursor.1); |
91 | 17 | let csv_filename = format!("logs/activity_log_{}.csv", current_time.format("%Y_%m_%d")); |
92 | | - add_to_csv(&csv_filename, ¤t_time, ¤t_window_title, &cursor); |
93 | | - } else { |
94 | | - println!("Error getting mouse cursor position"); |
| 18 | + write_csv::add_to_csv(&csv_filename, ¤t_time, &state.window_title, &cursor); |
| 19 | + prev_state = state; |
95 | 20 | } |
96 | 21 |
|
97 | 22 | sleep(Duration::from_secs_f64(FREQUENCY)); |
|
0 commit comments