aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmdline.rs3
-rw-r--r--src/main.rs67
2 files changed, 58 insertions, 12 deletions
diff --git a/src/cmdline.rs b/src/cmdline.rs
index 43adbec..9d3bc29 100644
--- a/src/cmdline.rs
+++ b/src/cmdline.rs
@@ -7,10 +7,11 @@ pub struct Args {
/// Path to browser executable
#[arg(short, long)]
pub browser: PathBuf,
+ /// Path to dmenu executable
#[arg(short = 'm', long)]
pub dmenu: PathBuf,
/// Location history sqlite database
- #[arg(short = 'p', long, default_value = PathBuf::from("~/.mozilla/firefox/11ybm96o.default").into_os_string())]
+ #[arg(short = 'p', long, default_value = PathBuf::from("~/.mozilla/firefox/000000.default").into_os_string())]
pub profile: PathBuf,
/// Limit of location history entries to seek
#[arg(short = 'l', long, default_value_t = 100)]
diff --git a/src/main.rs b/src/main.rs
index d3c927d..3a34912 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,14 @@
mod cmdline;
use clap::Parser;
use cmdline::Args;
-use rusqlite::{params, Connection, Result};
+use rusqlite::{Connection, Result};
+use std::io::Write;
use std::{
collections::HashSet,
fmt::Display,
fs,
- path::{Path, PathBuf},
+ path::PathBuf,
+ process::{Command, Stdio},
};
use url;
#[derive(Debug)]
@@ -30,7 +32,7 @@ fn copy_db(root_path: Option<&PathBuf>) -> Option<PathBuf> {
if let Ok(found_profile_path) = match_firefox_profile() {
found_profile_path
} else {
- panic!("thing");
+ panic!("[Profile] Cannot find any profiles!");
}
};
root.push("places.sqlite");
@@ -38,14 +40,14 @@ fn copy_db(root_path: Option<&PathBuf>) -> Option<PathBuf> {
match fs::exists(&root) {
Ok(existence) => {
if !existence {
- panic!("[FS] DB does not exist")
+ panic!("[Filesystem] Database does not exist!")
} else {
- fs::copy(root, &tmp_path);
+ let _ = fs::copy(root, &tmp_path);
return Some(tmp_path);
}
}
Err(_) => {
- panic!("[FS] something wrong...")
+ panic!("[Filesystem] Nondescript error.")
}
};
}
@@ -54,10 +56,13 @@ fn main() -> Result<()> {
let path = if let Some(p) = copy_db(Some(&args.profile)) {
p
} else {
- panic!("baddddd")
+ panic!("[main] Database copying failed.")
};
let conn = Connection::open(&path).unwrap();
- let query = format!("SELECT id, url FROM moz_places ORDER BY last_visit_date DESC LIMIT {}", args.limit);
+ let query = format!(
+ "SELECT id, url FROM moz_places ORDER BY last_visit_date DESC LIMIT {}",
+ args.limit
+ );
let mut stmt = conn.prepare(&query).unwrap();
let urls_iter = stmt.query_map([], |row| {
Ok(FirefoxPlace {
@@ -65,7 +70,7 @@ fn main() -> Result<()> {
url: row.get(1)?,
})
})?;
- let mut hosts = HashSet::new();
+ let mut hosts: HashSet<String> = HashSet::new();
for place in urls_iter {
if let Ok(p) = place {
let url = url::Url::parse(&p.url);
@@ -76,9 +81,49 @@ fn main() -> Result<()> {
}
}
}
- for h in hosts {
+ for h in &hosts {
println!("{}", h);
}
- fs::remove_file(&path);
+ let tmp_urls_path = PathBuf::from("/tmp/firefox-dmenu-urls.tmp");
+ let _ = fs::remove_file(&path);
+ let dmenu_opts = hosts.into_iter().collect::<Vec<String>>().join("\n");
+ println!(
+ "cat {} | {}",
+ tmp_urls_path.to_str().unwrap(),
+ args.dmenu.to_str().unwrap()
+ );
+ let _ = fs::write(&tmp_urls_path, &dmenu_opts);
+ let source_command = Command::new("cat")
+ .arg(&tmp_urls_path)
+ .stdout(Stdio::piped())
+ .output()
+ .expect("[cat] Failed to cat source file. Is it readable?");
+ let mut dmenu_command = Command::new(args.dmenu)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn()
+ .expect("[dmenu] Failed to launch dmenu. Is it executable?");
+ let mut dmenu_stdin = dmenu_command
+ .stdin
+ .take()
+ .expect("[dmenu] Failed to take standard input from dmenu.");
+ std::thread::spawn(move || {
+ dmenu_stdin
+ .write_all(&source_command.stdout)
+ .expect("[dmenu] Failed to write to stdin of dmenu.");
+ });
+ let dmenu_out = dmenu_command
+ .wait_with_output()
+ .expect("[dmenu] Expected dmenu to successfully execute.");
+ let dmenu_sel = String::from_utf8_lossy(&dmenu_out.stdout);
+ println!("Captured selection: {}", dmenu_sel);
+ println!("{}", dmenu_sel);
+ if dmenu_sel.to_string() == String::from("") {
+ println!("dmenu did not produce any output.");
+ return Ok(());
+ }
+ let _ = Command::new(args.browser)
+ .arg(dmenu_sel.to_string())
+ .spawn();
Ok(())
}