Replace de-utm binary with ,clean-url cargo-script
Custom handle-urls.fnl module removed; URL cleaning now handled
via URLDispatcher url_redir_decoders calling ,clean-url directly.

Assisted-by: Claude Opus 4.6 via pi
change nynnpuqorllqkpwqvuskwuknktutqmpv
commit c420b61b21e66889b0bf6dbcab51919953b10c16
author Alpha Chen <alpha@kejadlen.dev>
date
parent yopyyoys
diff --git a/.hammerspoon/handle-urls.fnl b/.hammerspoon/handle-urls.fnl
deleted file mode 100644
index bca99c28..00000000
--- a/.hammerspoon/handle-urls.fnl
+++ /dev/null
@@ -1,64 +0,0 @@
-;; https://stackoverflow.com/questions/39464668/how-to-get-bundle-id-of-mac-application
-;;   osascript -e 'id of app "SomeApp"'
-;;   mdls -name kMDItemCFBundleIdentifier -r SomeApp.app
-;; (. (hs.application.infoForBundlePath "/path/to/app") :CFBundleIdentifier)
-
-(local bundle-ids {:firefox-dev :org.mozilla.firefoxdeveloperedition
-                   :firefox :org.mozilla.firefox
-                   :safari :com.apple.Safari
-                   :zoom :us.zoom.xos})
-
-(var handlers [])
-
-(fn run [bin url]
-  (let [prog (.. bin " '" url "'")
-        handle (io.popen prog)]
-    (handle:read :*a)))
-
-(fn de-utm [url]
-  (run "~/.dotfiles/bin/de-utm" url))
-
-(fn follow-redirects [url]
-  (run "curl --location --silent -o /dev/null -w %{url_effective}" url))
-
-(fn open-url [app url]
-  (let [bundle-id (. bundle-ids app)]
-    (hs.urlevent.openURLWithBundle url bundle-id)))
-
-(fn open-with [app]
-  (partial open-url app))
-
-;; fnlfmt: skip
-(local default-handlers
-       [["^https://.*%.?zoom.us/j/%d+" (open-with :zoom)]])
-
-(fn url->handler [url]
-  (accumulate [acc nil _ [pat handler] (ipairs handlers) &until acc]
-    (if (url:find pat) #(handler url) nil)))
-
-(fn handle-url [url]
-  (let [handler (or (url->handler url) #(open-url :default url))]
-    (handler)))
-
-(fn setup [{:bundle-ids extra-bundle-ids :handlers extra-handlers}]
-  (each [k v (pairs (or extra-bundle-ids {}))]
-    (tset bundle-ids k v))
-  (set handlers (hs.fnutils.concat extra-handlers default-handlers)))
-
-(fn start []
-  (set hs.urlevent.httpCallback
-       (fn [scheme host params url]
-         (let [clean-url (de-utm url)]
-           (handle-url clean-url)))))
-
-;; example usage
-;;
-;; (let [{: setup : start : open-with} (require :handle-urls)]
-;;   (setup {:bundle-ids {:default :org.mozilla.firefoxdeveloperedition}
-;;           :handlers [["^https://.*%.?discnw.org/" (open-with :safari)]
-;;                      ["^https://squareup.com/" (open-with :safari)]
-;;                      ["^https://.*%.?bulletin.com/" (open-with :safari)]]})
-;;   (start))
-
-{: setup : start : open-url : open-with}
-
diff --git a/.hammerspoon/init.fnl b/.hammerspoon/init.fnl
index e81bd109..4f9e4b5b 100644
--- a/.hammerspoon/init.fnl
+++ b/.hammerspoon/init.fnl
@@ -112,9 +112,8 @@
                             "/?"))
       url-patterns [["^https://(.*%.?)zoom.us/j/%d+" handlers.zoom]
                     [safari-patterns handlers.safari]]
-      url-redir-decoders [[:sci-hub
-                           "^https://doi.org/(.*)"
-                           "https://sci-hub.st/%1"]]]
+      ; url-redir-decoders [[:clean-url #(execute (.. "/Users/alpha/.dotfiles/bin/,clean-url" $4))]]
+      ]
   (Install:andUse :URLDispatcher {:config {:url_patterns url-patterns
                                            :url_redir_decoders url-redir-decoders
                                            :default_handler little-ff.open
diff --git a/bin/,clean-url b/bin/,clean-url
new file mode 100755
index 00000000..ec6423d4
--- /dev/null
+++ b/bin/,clean-url
@@ -0,0 +1,44 @@
+#!/usr/bin/env -S cargo +nightly -Zscript
+---cargo
+[dependencies]
+color-eyre = "*"
+url = "*"
+---
+
+use std::env;
+
+use color_eyre::eyre::{OptionExt, Result, WrapErr};
+use url::Url;
+
+const TRACKING_PREFIXES: &[&str] = &["utm_"];
+const TRACKING_PARAMS: &[&str] = &["fbclid", "gclid"];
+
+fn is_tracking_param(key: &str) -> bool {
+    TRACKING_PREFIXES
+        .iter()
+        .any(|prefix| key.starts_with(prefix))
+        || TRACKING_PARAMS.contains(&key)
+}
+
+fn main() -> Result<()> {
+    color_eyre::install()?;
+
+    let arg = env::args().nth(1).ok_or_eyre("usage: ,clean-url <url>")?;
+    let mut url = Url::parse(&arg).wrap_err_with(|| format!("failed to parse URL: {arg}"))?;
+
+    let kept: Vec<(String, String)> = url
+        .query_pairs()
+        .filter(|(key, _)| !is_tracking_param(key))
+        .map(|(k, v)| (k.into_owned(), v.into_owned()))
+        .collect();
+
+    url.query_pairs_mut().clear().extend_pairs(&kept);
+
+    if url.query() == Some("") {
+        url.set_query(None);
+    }
+
+    println!("{url}");
+
+    Ok(())
+}
diff --git a/bin/de-utm b/bin/de-utm
deleted file mode 100755
index eac03789..00000000
Binary files a/bin/de-utm and /dev/null differ