use std::collections::BTreeSet; use parking_lot::RwLock; use regex::Regex; use tracing::info; use crate::client_manager::ClientManager; use crate::helpers::{determine_active_trackers, get_trackers}; use crate::models::{TrackerInfo, TrackerMap}; pub struct TrackerInfoManager { trackers: RwLock, active_trackers: RwLock>, included_projects: Vec, excluded_projects: Vec, inactive_minutes: u64, } impl TrackerInfoManager { pub fn new(client_mgr: &ClientManager, included_projects: Vec, excluded_projects: Vec, inactive_minutes: u64) -> color_eyre::Result { info!("Fetching projects..."); let t = get_trackers(client_mgr)?; info!("Found {} projects.", t.len()); let a = determine_active_trackers(client_mgr, &t, inactive_minutes.clone())?; info!("Found {} projects are active.", a.len()); Ok(Self { trackers: RwLock::new(t), active_trackers: RwLock::new(a), included_projects, excluded_projects, inactive_minutes, }) } pub fn refresh_trackers(&self, client_mgr: &ClientManager) -> color_eyre::Result<()> { let mut l = self.trackers.write(); *l = get_trackers(client_mgr)?; Ok(()) } pub fn refresh_active_trackers(&self, client_mgr: &ClientManager) -> color_eyre::Result<()> { let r = self.trackers.read(); let new = determine_active_trackers(client_mgr, &r, self.inactive_minutes.clone())?; let mut w = self.active_trackers.write(); *w = new; Ok(()) } pub fn get_tracker_info(&self, name: &str) -> color_eyre::Result { let l = self.trackers.read(); if let Some(v) = l.get(&name.to_string()) { Ok(v.clone()) } else { Err(color_eyre::eyre::eyre!("Tracker {} not found!", name)) } } pub fn project_is_included(&self, name: &str) -> bool { self.included_projects.iter().all(|r| r.is_match(name)) } pub fn project_is_excluded(&self, name: &str) -> bool { self.excluded_projects.iter().any(|r| r.is_match(name)) } pub fn project_is_active(&self, name: &str) -> bool { (self.inactive_minutes == 0) || self.active_trackers.read().contains(&name.to_string()) } pub fn enabled_projects(&self) -> Vec<(String, TrackerInfo)> { self.trackers.read().iter() .filter(|(name, _)| { self.project_is_included(name) && !self.project_is_excluded(name) && self.project_is_active(name) }) .map(|(a, b)| (a.clone(), b.clone())) .collect() } }