aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmdline.rs18
-rw-r--r--src/main.rs84
2 files changed, 102 insertions, 0 deletions
diff --git a/src/cmdline.rs b/src/cmdline.rs
new file mode 100644
index 0000000..43adbec
--- /dev/null
+++ b/src/cmdline.rs
@@ -0,0 +1,18 @@
+use std::path::PathBuf;
+
+use clap::Parser;
+#[derive(Parser, Debug)]
+#[command(version, about, long_about = None)]
+pub struct Args {
+ /// Path to browser executable
+ #[arg(short, long)]
+ pub browser: PathBuf,
+ #[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())]
+ pub profile: PathBuf,
+ /// Limit of location history entries to seek
+ #[arg(short = 'l', long, default_value_t = 100)]
+ pub limit: usize,
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..d3c927d
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,84 @@
+mod cmdline;
+use clap::Parser;
+use cmdline::Args;
+use rusqlite::{params, Connection, Result};
+use std::{
+ collections::HashSet,
+ fmt::Display,
+ fs,
+ path::{Path, PathBuf},
+};
+use url;
+#[derive(Debug)]
+struct FirefoxPlace {
+ id: u64,
+ url: String,
+}
+struct NoProfileFoundError {}
+impl Display for NoProfileFoundError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "No suitable profile was found")
+ }
+}
+fn match_firefox_profile() -> Result<PathBuf, NoProfileFoundError> {
+ todo!()
+}
+fn copy_db(root_path: Option<&PathBuf>) -> Option<PathBuf> {
+ let mut root = if let Some(p) = root_path {
+ p.clone()
+ } else {
+ if let Ok(found_profile_path) = match_firefox_profile() {
+ found_profile_path
+ } else {
+ panic!("thing");
+ }
+ };
+ root.push("places.sqlite");
+ let tmp_path = PathBuf::from("/tmp/firefox-dmenu-places.db");
+ match fs::exists(&root) {
+ Ok(existence) => {
+ if !existence {
+ panic!("[FS] DB does not exist")
+ } else {
+ fs::copy(root, &tmp_path);
+ return Some(tmp_path);
+ }
+ }
+ Err(_) => {
+ panic!("[FS] something wrong...")
+ }
+ };
+}
+fn main() -> Result<()> {
+ let args = Args::parse();
+ let path = if let Some(p) = copy_db(Some(&args.profile)) {
+ p
+ } else {
+ panic!("baddddd")
+ };
+ 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 mut stmt = conn.prepare(&query).unwrap();
+ let urls_iter = stmt.query_map([], |row| {
+ Ok(FirefoxPlace {
+ id: row.get(0)?,
+ url: row.get(1)?,
+ })
+ })?;
+ let mut hosts = HashSet::new();
+ for place in urls_iter {
+ if let Ok(p) = place {
+ let url = url::Url::parse(&p.url);
+ if let Ok(u) = url {
+ if let Some(s) = u.host_str() {
+ hosts.insert(s.to_string());
+ }
+ }
+ }
+ }
+ for h in hosts {
+ println!("{}", h);
+ }
+ fs::remove_file(&path);
+ Ok(())
+}