Skip to content

Commit a98fc6e

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

File tree

3 files changed

+97
-113
lines changed

3 files changed

+97
-113
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: 96 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +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;
82-
8381
/// Type alias for categorization classes
8482
pub type ClassRule = (CategoryId, CategorySpec);
8583

@@ -135,33 +133,6 @@ impl QueryParams {
135133
QueryParams::Android(params) => build_android_canonical_events(params),
136134
}
137135
}
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-
}
165136
}
166137

167138
/// Helper function to serialize classes in the format expected by the categorize function
@@ -201,7 +172,7 @@ fn serialize_classes(classes: &[ClassRule]) -> String {
201172
format!("[{}]", parts.join(", "))
202173
}
203174

204-
fn build_desktop_canonical_events(params: &DesktopQueryParams) -> String {
175+
pub fn build_desktop_canonical_events(params: &DesktopQueryParams) -> String {
205176
let mut query = Vec::new();
206177

207178
// Fetch window events
@@ -256,7 +227,7 @@ not_afk = period_union(not_afk, audible_events)"
256227
query.join(";\n")
257228
}
258229

259-
fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
230+
pub fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
260231
let mut query = Vec::new();
261232

262233
// Fetch app events
@@ -287,7 +258,7 @@ fn build_android_canonical_events(params: &AndroidQueryParams) -> String {
287258
query.join(";\n")
288259
}
289260

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

293264
for browser_bucket in &params.base.bid_browsers {
@@ -311,38 +282,34 @@ browser_events = sort_by_timestamp(browser_events)",
311282
query
312283
}
313284

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

318289
// Add basic event aggregations
319-
query.push_str(&format!(
320-
"
290+
query.push_str(
291+
&"
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+
"
297+
.to_string(),
298+
);
330299

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

0 commit comments

Comments
 (0)