1use crate::core::scanner;
7use crate::i18n;
8use crate::model::{EntryStatus, SortState, TrackedEntry, GONE_RETENTION};
9use std::time::Instant;
10
11pub struct Session {
19 pub entries: Vec<TrackedEntry>,
20 pub sort: SortState,
21 pub is_elevated: bool,
22 pub is_root: bool,
23 sudo_password: Option<String>,
24}
25
26impl Default for Session {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl Session {
33 pub fn new() -> Self {
34 Self {
35 entries: Vec::new(),
36 sort: SortState::default(),
37 is_elevated: false,
38 is_root: scanner::is_root(),
39 sudo_password: None,
40 }
41 }
42
43 pub fn refresh(&mut self) -> Result<(), String> {
45 let scan_result = if let Some(password) = &self.sudo_password {
46 scanner::scan_with_sudo(password)
47 } else {
48 scanner::scan()
49 };
50
51 match scan_result {
52 Ok(new_entries) => {
53 let now = Instant::now();
54 self.entries = scanner::diff_entries(&self.entries, new_entries, now);
55 self.entries.retain(|e| {
56 e.status != EntryStatus::Gone || now.duration_since(e.seen_at) < GONE_RETENTION
57 });
58 scanner::sort_entries(&mut self.entries, &self.sort);
59 Ok(())
60 }
61 Err(e) => {
62 let s = i18n::strings();
63 Err(s.fmt_scan_error(&e.to_string()))
64 }
65 }
66 }
67
68 pub fn filtered_indices(&self, query: &str) -> Vec<usize> {
69 scanner::filter_indices(&self.entries, query)
70 }
71
72 pub fn try_sudo(&mut self, password: &str) -> String {
74 let s = i18n::strings();
75 match scanner::scan_with_sudo(password) {
76 Ok(new_entries) => {
77 self.sudo_password = Some(password.to_string());
78 self.is_elevated = true;
79 self.is_root = true;
80 let now = Instant::now();
81 self.entries = scanner::diff_entries(&self.entries, new_entries, now);
82 scanner::sort_entries(&mut self.entries, &self.sort);
83 s.sudo_elevated.to_string()
84 }
85 Err(e) => {
86 self.sudo_password = None;
87 self.is_elevated = false;
88 let msg = e.to_string();
89 if msg.contains("incorrect password") || msg.contains("Sorry") {
90 s.sudo_wrong_password.to_string()
91 } else {
92 s.fmt_sudo_error(&msg)
93 }
94 }
95 }
96 }
97}