Skip to content

Commit bdf52b8

Browse files
committed
fix: remove unnecessary functions in query class Keep feature parity
with aw-client
1 parent b705f04 commit bdf52b8

File tree

3 files changed

+91
-112
lines changed

3 files changed

+91
-112
lines changed

aw-client-rust/src/classes.rs

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@
22
//!
33
//! Taken from default classes in aw-webui
44
5-
use log::warn;
6-
use rand::Rng;
75
use serde::{Deserialize, Serialize};
86
use serde_json;
97

10-
use super::blocking::AwClient as ActivityWatchClient;
11-
128
pub type CategoryId = Vec<String>;
139

1410
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -146,61 +142,3 @@ pub fn default_classes() -> Vec<(CategoryId, CategorySpec)> {
146142
),
147143
]
148144
}
149-
150-
/// Get classes from server-side settings using default localhost:5600.
151-
/// Might throw an error if not set yet, in which case we use the default classes as a fallback.
152-
pub fn get_classes() -> Vec<(CategoryId, CategorySpec)> {
153-
get_classes_from_server("localhost", 5600)
154-
}
155-
156-
/// Get classes from server-side settings with custom host and port.
157-
/// Might throw an error if not set yet, in which case we use the default classes as a fallback.
158-
pub fn get_classes_from_server(host: &str, port: u16) -> Vec<(CategoryId, CategorySpec)> {
159-
let mut rng = rand::rng();
160-
let random_int = rng.random_range(0..10001);
161-
let client_id = format!("get-setting-{}", random_int);
162-
163-
// Create a client with a random ID, similar to the Python implementation
164-
let awc = match ActivityWatchClient::new(host, port, &client_id) {
165-
Ok(client) => client,
166-
Err(_) => {
167-
warn!(
168-
"Failed to create ActivityWatch client for {}:{}, using default classes",
169-
host, port
170-
);
171-
return default_classes();
172-
}
173-
};
174-
175-
awc.get_setting("classes")
176-
.map(|setting_value| {
177-
// Try to deserialize the setting into Vec<ClassSetting>
178-
if setting_value.is_null() {
179-
return default_classes();
180-
}
181-
182-
let class_settings: Vec<ClassSetting> = match serde_json::from_value(setting_value) {
183-
Ok(classes) => classes,
184-
Err(e) => {
185-
warn!(
186-
"Failed to deserialize classes setting: {}, using default classes",
187-
e
188-
);
189-
return default_classes();
190-
}
191-
};
192-
193-
// Convert ClassSetting to (CategoryId, CategorySpec) format
194-
class_settings
195-
.into_iter()
196-
.map(|class| (class.name, class.rule))
197-
.collect()
198-
})
199-
.unwrap_or_else(|_| {
200-
warn!(
201-
"Failed to get classes from server {}:{}, using default classes as fallback",
202-
host, port
203-
);
204-
default_classes()
205-
})
206-
}

aw-client-rust/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl std::fmt::Debug for AwClient {
3636
}
3737

3838
fn get_hostname() -> String {
39-
return gethostname::gethostname().to_string_lossy().to_string();
39+
gethostname::gethostname().to_string_lossy().to_string()
4040
}
4141

4242
impl AwClient {
@@ -123,8 +123,6 @@ impl AwClient {
123123
.map(|(start, stop)| format!("{}/{}", start, stop))
124124
.collect();
125125

126-
let query_lines: Vec<&str> = query.split('\n').collect();
127-
128126
// Result is a sequence, one element per timeperiod
129127
self.client
130128
.post(url)

aw-client-rust/src/queries.rs

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ pub static BROWSER_APPNAMES: phf::Map<&'static str, &'static [&'static str]> = p
7878
"vivaldi" => &["Vivaldi-stable", "Vivaldi-snapshot", "vivaldi.exe"],
7979
};
8080

81-
pub const DEFAULT_LIMIT: u32 = 100;
8281

8382
/// Type alias for categorization classes
8483
pub type ClassRule = (CategoryId, CategorySpec);
@@ -135,33 +134,6 @@ impl QueryParams {
135134
QueryParams::Android(params) => build_android_canonical_events(params),
136135
}
137136
}
138-
139-
/// Build canonical events query string with automatic class fetching if not provided
140-
pub fn canonical_events_with_classes(&self) -> String {
141-
self.canonical_events_with_classes_from_server("localhost", 5600)
142-
}
143-
144-
/// Build canonical events query string with automatic class fetching from custom server
145-
pub fn canonical_events_with_classes_from_server(&self, host: &str, port: u16) -> String {
146-
match self {
147-
QueryParams::Desktop(params) => {
148-
let mut params_with_classes = params.clone();
149-
if params_with_classes.base.classes.is_empty() {
150-
params_with_classes.base.classes =
151-
crate::classes::get_classes_from_server(host, port);
152-
}
153-
build_desktop_canonical_events(&params_with_classes)
154-
}
155-
QueryParams::Android(params) => {
156-
let mut params_with_classes = params.clone();
157-
if params_with_classes.base.classes.is_empty() {
158-
params_with_classes.base.classes =
159-
crate::classes::get_classes_from_server(host, port);
160-
}
161-
build_android_canonical_events(&params_with_classes)
162-
}
163-
}
164-
}
165137
}
166138

167139
/// Helper function to serialize classes in the format expected by the categorize function
@@ -201,7 +173,7 @@ fn serialize_classes(classes: &[ClassRule]) -> String {
201173
format!("[{}]", parts.join(", "))
202174
}
203175

204-
fn build_desktop_canonical_events(params: &DesktopQueryParams) -> String {
176+
pub fn build_desktop_canonical_events(params: &DesktopQueryParams) -> String {
205177
let mut query = Vec::new();
206178

207179
// Fetch window events
@@ -256,7 +228,7 @@ not_afk = period_union(not_afk, audible_events)"
256228
query.join(";\n")
257229
}
258230

259-
fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
231+
pub fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
260232
let mut query = Vec::new();
261233

262234
// Fetch app events
@@ -287,7 +259,7 @@ fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
287259
query.join(";\n")
288260
}
289261

290-
fn build_browser_events(params: &DesktopQueryParams) -> String {
262+
pub fn build_browser_events(params: &DesktopQueryParams) -> String {
291263
let mut query = String::from("browser_events = [];");
292264

293265
for browser_bucket in &params.base.bid_browsers {
@@ -311,38 +283,28 @@ browser_events = sort_by_timestamp(browser_events)",
311283
query
312284
}
313285

314-
/// Build a full desktop query
286+
/// Build a full desktop query using default localhost:5600 configuration
315287
pub fn full_desktop_query(params: &DesktopQueryParams) -> String {
316-
let mut query = QueryParams::Desktop(params.clone()).canonical_events_with_classes();
288+
let mut query = QueryParams::Desktop(params.clone()).canonical_events();
317289

318290
// Add basic event aggregations
319-
query.push_str(&format!(
320-
"
291+
query.push_str(&"
321292
title_events = sort_by_duration(merge_events_by_keys(events, [\"app\", \"title\"]));
322293
app_events = sort_by_duration(merge_events_by_keys(title_events, [\"app\"]));
323294
cat_events = sort_by_duration(merge_events_by_keys(events, [\"$category\"]));
324-
app_events = limit_events(app_events, {});
325-
title_events = limit_events(title_events, {});
326295
duration = sum_durations(events);
327-
",
328-
DEFAULT_LIMIT, DEFAULT_LIMIT
329-
));
296+
".to_string());
330297

331298
// Add browser-specific query parts if browser buckets exist
332299
if !params.base.bid_browsers.is_empty() {
333-
query.push_str(&format!(
334-
"
300+
query.push_str(&"
335301
browser_events = split_url_events(browser_events);
336302
browser_urls = merge_events_by_keys(browser_events, [\"url\"]);
337303
browser_urls = sort_by_duration(browser_urls);
338-
browser_urls = limit_events(browser_urls, {});
339304
browser_domains = merge_events_by_keys(browser_events, [\"$domain\"]);
340305
browser_domains = sort_by_duration(browser_domains);
341-
browser_domains = limit_events(browser_domains, {});
342306
browser_duration = sum_durations(browser_events);
343-
",
344-
DEFAULT_LIMIT, DEFAULT_LIMIT
345-
));
307+
".to_string());
346308
} else {
347309
query.push_str(
348310
"
@@ -490,4 +452,85 @@ mod tests {
490452
assert!(query.contains("events = categorize"));
491453
assert!(query.contains("test"));
492454
}
455+
456+
#[test]
457+
fn test_canonical_events_with_client_config() {
458+
use crate::AwClient;
459+
460+
let params = DesktopQueryParams {
461+
base: QueryParamsBase {
462+
bid_browsers: vec![],
463+
classes: vec![], // Empty - would fetch from server if available
464+
filter_classes: vec![],
465+
filter_afk: true,
466+
include_audible: true,
467+
},
468+
bid_window: "test-window".to_string(),
469+
bid_afk: "test-afk".to_string(),
470+
};
471+
472+
// Test with custom port client
473+
if let Ok(client) = AwClient::new("localhost", 8080, "test-client") {
474+
let query_params = QueryParams::Desktop(params.clone());
475+
let query = query_params.canonical_events_with_classes_from_client(&client);
476+
477+
// Should contain basic query structure
478+
assert!(query.contains("events = flood"));
479+
assert!(query.contains("test-window"));
480+
}
481+
482+
// Test with blocking client
483+
use crate::blocking::AwClient as BlockingClient;
484+
if let Ok(blocking_client) = BlockingClient::new("localhost", 9090, "test-blocking-client")
485+
{
486+
let query_params = QueryParams::Desktop(params);
487+
let query =
488+
query_params.canonical_events_with_classes_from_blocking_client(&blocking_client);
489+
490+
// Should contain basic query structure
491+
assert!(query.contains("events = flood"));
492+
assert!(query.contains("test-window"));
493+
}
494+
}
495+
496+
#[test]
497+
fn test_full_desktop_query_from_client() {
498+
use crate::AwClient;
499+
500+
let params = DesktopQueryParams {
501+
base: QueryParamsBase {
502+
bid_browsers: vec!["aw-watcher-web-chrome".to_string()],
503+
classes: vec![],
504+
filter_classes: vec![],
505+
filter_afk: true,
506+
include_audible: true,
507+
},
508+
bid_window: "test-window".to_string(),
509+
bid_afk: "test-afk".to_string(),
510+
};
511+
512+
// Test the client-aware full desktop query
513+
if let Ok(client) = AwClient::new("localhost", 8080, "test-client") {
514+
let query = full_desktop_query_from_client(&params, &client);
515+
516+
// Should contain all expected parts
517+
assert!(query.contains("events = flood"));
518+
assert!(query.contains("title_events = sort_by_duration"));
519+
assert!(query.contains("browser_events"));
520+
assert!(query.contains("RETURN"));
521+
}
522+
523+
// Test the blocking client version
524+
use crate::blocking::AwClient as BlockingClient;
525+
if let Ok(blocking_client) = BlockingClient::new("localhost", 9090, "test-blocking-client")
526+
{
527+
let query = full_desktop_query_from_blocking_client(&params, &blocking_client);
528+
529+
// Should contain all expected parts
530+
assert!(query.contains("events = flood"));
531+
assert!(query.contains("title_events = sort_by_duration"));
532+
assert!(query.contains("browser_events"));
533+
assert!(query.contains("RETURN"));
534+
}
535+
}
493536
}

0 commit comments

Comments
 (0)