tenseleyflow/gump / c8d7d8a

Browse files

normalize imported scores to 1-100 range

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
c8d7d8a436e8db91886a3c5759c9665c11b2a6fd
Parents
0336f87
Tree
e581365

1 changed file

StatusFile+-
M src/cmd/import.rs 75 48
src/cmd/import.rsmodified
@@ -7,29 +7,54 @@ use crate::db::Database;
77
 
88
 use super::Result;
99
 
10
+/// Maximum score for imported entries (prevents one source from dominating).
11
+const MAX_IMPORT_SCORE: f64 = 100.0;
12
+
1013
 /// Import directories from various tools (zoxide, autojump, z, fasd).
1114
 pub fn run() -> Result<()> {
1215
     let mut db = Database::open()?;
1316
     let mut total_imported = 0;
1417
 
15
-    // Try each source
16
-    total_imported += import_zoxide(&mut db)?;
17
-    total_imported += import_autojump(&mut db)?;
18
-    total_imported += import_z(&mut db)?;
19
-    total_imported += import_fasd(&mut db)?;
18
+    // Collect entries from each source with their raw scores
19
+    let mut entries: Vec<(String, f64)> = Vec::new();
20
+
21
+    collect_zoxide(&mut entries)?;
22
+    collect_autojump(&mut entries)?;
23
+    collect_z(&mut entries)?;
24
+    collect_fasd(&mut entries)?;
25
+
26
+    if entries.is_empty() {
27
+        println!("No databases found to import from");
28
+        return Ok(());
29
+    }
30
+
31
+    // Find max score for normalization
32
+    let max_score = entries.iter().map(|(_, s)| *s).fold(0.0f64, f64::max);
33
+
34
+    // Normalize and import
35
+    for (path, score) in entries {
36
+        // Scale score to 0-MAX_IMPORT_SCORE range
37
+        let normalized = if max_score > 0.0 {
38
+            (score / max_score) * MAX_IMPORT_SCORE
39
+        } else {
40
+            1.0
41
+        };
42
+
43
+        if db.import_entry(&path, normalized.max(1.0)).is_ok() {
44
+            total_imported += 1;
45
+        }
46
+    }
2047
 
2148
     if total_imported > 0 {
2249
         db.save()?;
23
-        println!("Imported {} total entries", total_imported);
24
-    } else {
25
-        println!("No databases found to import from");
50
+        println!("Imported {} entries (scores normalized to 1-{})", total_imported, MAX_IMPORT_SCORE as u32);
2651
     }
2752
 
2853
     Ok(())
2954
 }
3055
 
31
-/// Import from zoxide using its CLI.
32
-fn import_zoxide(db: &mut Database) -> Result<usize> {
56
+/// Collect entries from zoxide using its CLI.
57
+fn collect_zoxide(entries: &mut Vec<(String, f64)>) -> Result<()> {
3358
     let output = Command::new("zoxide")
3459
         .args(["query", "--list", "--score"])
3560
         .stdout(Stdio::piped())
@@ -38,36 +63,37 @@ fn import_zoxide(db: &mut Database) -> Result<usize> {
3863
 
3964
     let output = match output {
4065
         Ok(o) if o.status.success() => o,
41
-        _ => return Ok(0),
66
+        _ => return Ok(()),
4267
     };
4368
 
44
-    let mut imported = 0;
4569
     let reader = BufReader::new(output.stdout.as_slice());
70
+    let mut count = 0;
4671
 
4772
     for line in reader.lines() {
4873
         let line = line?;
4974
         if let Some((score, path)) = parse_score_path(&line) {
50
-            if db.import_entry(path, score).is_ok() {
51
-                imported += 1;
75
+            if std::path::Path::new(path).exists() {
76
+                entries.push((path.to_string(), score));
77
+                count += 1;
5278
             }
5379
         }
5480
     }
5581
 
56
-    if imported > 0 {
57
-        println!("  zoxide: {} entries", imported);
82
+    if count > 0 {
83
+        println!("  zoxide: {} entries", count);
5884
     }
59
-    Ok(imported)
85
+    Ok(())
6086
 }
6187
 
62
-/// Import from autojump (~/.local/share/autojump/autojump.txt).
63
-fn import_autojump(db: &mut Database) -> Result<usize> {
88
+/// Collect entries from autojump (~/.local/share/autojump/autojump.txt).
89
+fn collect_autojump(entries: &mut Vec<(String, f64)>) -> Result<()> {
6490
     let path = dirs_autojump();
6591
     if !path.exists() {
66
-        return Ok(0);
92
+        return Ok(());
6793
     }
6894
 
6995
     let content = fs::read_to_string(&path)?;
70
-    let mut imported = 0;
96
+    let mut count = 0;
7197
 
7298
     // Format: "score\tpath" (tab-separated)
7399
     for line in content.lines() {
@@ -76,23 +102,24 @@ fn import_autojump(db: &mut Database) -> Result<usize> {
76102
             continue;
77103
         }
78104
 
79
-        if let Some((score_str, path)) = line.split_once('\t') {
105
+        if let Some((score_str, dir_path)) = line.split_once('\t') {
80106
             if let Ok(score) = score_str.parse::<f64>() {
81
-                if db.import_entry(path, score).is_ok() {
82
-                    imported += 1;
107
+                if std::path::Path::new(dir_path).exists() {
108
+                    entries.push((dir_path.to_string(), score));
109
+                    count += 1;
83110
                 }
84111
             }
85112
         }
86113
     }
87114
 
88
-    if imported > 0 {
89
-        println!("  autojump: {} entries", imported);
115
+    if count > 0 {
116
+        println!("  autojump: {} entries", count);
90117
     }
91
-    Ok(imported)
118
+    Ok(())
92119
 }
93120
 
94
-/// Import from z/z.lua/zsh-z (~/.z).
95
-fn import_z(db: &mut Database) -> Result<usize> {
121
+/// Collect entries from z/z.lua/zsh-z (~/.z).
122
+fn collect_z(entries: &mut Vec<(String, f64)>) -> Result<()> {
96123
     // Check both ~/.z and $Z_DATA / $_Z_DATA
97124
     let paths: Vec<PathBuf> = [
98125
         Some(dirs_z()),
@@ -104,7 +131,7 @@ fn import_z(db: &mut Database) -> Result<usize> {
104131
     .flatten()
105132
     .collect();
106133
 
107
-    let mut imported = 0;
134
+    let mut count = 0;
108135
 
109136
     for path in paths {
110137
         if !path.exists() {
@@ -125,31 +152,32 @@ fn import_z(db: &mut Database) -> Result<usize> {
125152
 
126153
             let parts: Vec<&str> = line.split('|').collect();
127154
             if parts.len() >= 2 {
128
-                let path = parts[0];
155
+                let dir_path = parts[0];
129156
                 if let Ok(score) = parts[1].parse::<f64>() {
130
-                    if db.import_entry(path, score).is_ok() {
131
-                        imported += 1;
157
+                    if std::path::Path::new(dir_path).exists() {
158
+                        entries.push((dir_path.to_string(), score));
159
+                        count += 1;
132160
                     }
133161
                 }
134162
             }
135163
         }
136164
     }
137165
 
138
-    if imported > 0 {
139
-        println!("  z/z.lua: {} entries", imported);
166
+    if count > 0 {
167
+        println!("  z/z.lua: {} entries", count);
140168
     }
141
-    Ok(imported)
169
+    Ok(())
142170
 }
143171
 
144
-/// Import from fasd (~/.fasd).
145
-fn import_fasd(db: &mut Database) -> Result<usize> {
172
+/// Collect entries from fasd (~/.fasd).
173
+fn collect_fasd(entries: &mut Vec<(String, f64)>) -> Result<()> {
146174
     let path = dirs_fasd();
147175
     if !path.exists() {
148
-        return Ok(0);
176
+        return Ok(());
149177
     }
150178
 
151179
     let content = fs::read_to_string(&path)?;
152
-    let mut imported = 0;
180
+    let mut count = 0;
153181
 
154182
     // Format: "path|score|timestamp" (similar to z)
155183
     for line in content.lines() {
@@ -160,22 +188,21 @@ fn import_fasd(db: &mut Database) -> Result<usize> {
160188
 
161189
         let parts: Vec<&str> = line.split('|').collect();
162190
         if parts.len() >= 2 {
163
-            let path = parts[0];
191
+            let dir_path = parts[0];
164192
             if let Ok(score) = parts[1].parse::<f64>() {
165193
                 // fasd tracks files too, only import directories
166
-                if std::path::Path::new(path).is_dir() {
167
-                    if db.import_entry(path, score).is_ok() {
168
-                        imported += 1;
169
-                    }
194
+                if std::path::Path::new(dir_path).is_dir() {
195
+                    entries.push((dir_path.to_string(), score));
196
+                    count += 1;
170197
                 }
171198
             }
172199
         }
173200
     }
174201
 
175
-    if imported > 0 {
176
-        println!("  fasd: {} entries", imported);
202
+    if count > 0 {
203
+        println!("  fasd: {} entries", count);
177204
     }
178
-    Ok(imported)
205
+    Ok(())
179206
 }
180207
 
181208
 /// Parse "  123.4 /path/to/dir" format (zoxide output).