summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-09-11 21:30:39 +0800
committereltrac <hi@eltr.ac>2026-09-11 21:30:39 +0800
commit3f1c95723efe837bdbf30cfa3a89cb057cd1a851 (patch)
tree472bcbc2cd58c7385da2ef8608fd1a7bc5a4d8c9 /scripts
parent22c52332f586b5e743ad191b4cae763551bf83ea (diff)
scripts: add recalculate-hashes.clj
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/migrate-from-webmentionio.clj41
-rw-r--r--scripts/recalculate-hashes.clj60
2 files changed, 101 insertions, 0 deletions
diff --git a/scripts/migrate-from-webmentionio.clj b/scripts/migrate-from-webmentionio.clj
new file mode 100755
index 0000000..48191b8
--- /dev/null
+++ b/scripts/migrate-from-webmentionio.clj
@@ -0,0 +1,41 @@
+#!/usr/bin/env bb
+
+(require '[babashka.http-client :as http])
+(require '[cheshire.core :as json])
+
+(def api-base-url "https://webmention.io/api/mentions.jf2")
+
+(let [[token new_endpoint] *command-line-args*]
+ ;; check args
+ (when (or (empty? token) (empty? new_endpoint))
+ (println "Usage: migrate-from-webmentionio.clj <token> <new_endpoint>")
+ (System/exit 1))
+ ;; page through webmention.io API
+ ;; get all data and resend webmentions
+ (let [api-url (str api-base-url "?token=" token)
+ fetch-page (fn [page]
+ (println (str "Fetching page " page "..."))
+ (-> (http/get (str api-url "&page=" page))
+ :body
+ (json/decode true)
+ :children))
+ all-data (->> (range)
+ (map fetch-page)
+ (take-while seq)
+ (apply concat))
+ resend (fn [item]
+ (let [{:keys [wm-source wm-target]} item]
+ (printf "Resending: %s -> %s ... " wm-source wm-target)
+ (flush)
+ (try
+ (let [resp (http/post new_endpoint
+ {:form-params {:source wm-source
+ :target wm-target}})]
+ (println (str "Done (" (:status resp) ")")))
+ (catch Exception e
+ (println (str "Failed: " (.getMessage e)))))))]
+ (println "Starting migration...")
+ (doseq [item all-data]
+ (resend item)
+ (Thread/sleep 500))
+ (println "Migration complete!")))
diff --git a/scripts/recalculate-hashes.clj b/scripts/recalculate-hashes.clj
new file mode 100644
index 0000000..b42a0d1
--- /dev/null
+++ b/scripts/recalculate-hashes.clj
@@ -0,0 +1,60 @@
+#!/usr/bin/env bb
+
+;; This is a Babashka script that recalculates
+;; all :webmention :id in a edn data file
+;;
+;; this is meant to be used in these scenarios:
+;; 1. migarting from before v4.1.0, where :id used to be
+;; MD5 hashes instead of sha-256 and needs to be
+;; recalculated to SHA-256
+;; 2. migrating from before v0.2.0, where :id was not
+;; introduced yet
+
+(require '[clojure.edn :as edn])
+(require '[clojure.string :refer [upper-case join]])
+(require '[clojure.java.io :as io])
+(import java.security.MessageDigest)
+
+;; copied from production code
+;; version: commit e00891a5e7
+(defn with-webmentions
+ "Opens the data file and applies function f to a lazy sequence of parsed Webmentions."
+ [datasource f]
+ (with-open [r (io/reader datasource)]
+ (->> (line-seq r)
+ (map edn/read-string)
+ f)))
+(defn- java-digest [^String s algo]
+ (let [algorithm (MessageDigest/getInstance algo)
+ raw-bytes (.digest algorithm (.getBytes s "UTF-8"))]
+ (apply str (map #(format "%02x" %) raw-bytes))))
+(defn digest
+ ([s]
+ (digest s :sha-256 32))
+ ([s algo]
+ (digest s algo 32))
+ ([s algo length]
+ (->> (java-digest s (upper-case (name algo)))
+ (take length)
+ (apply str))))
+(defn unload-data
+ "Write to data file, replacing everything."
+ [datasource data]
+ (when-let [data-with-string (map pr-str data)]
+ (spit datasource (join "\n" data-with-string))))
+;; end
+
+(let [[datafile] *command-line-args*]
+ (with-webmentions datafile
+ (fn [wms]
+ (println "starting reading, total count:" (count wms))
+ (->> wms
+ (map (fn [wm]
+ (let [webmention (:webmention wm)
+ source (:source webmention)
+ target (:target webmention)
+ new-id (digest (str source target))]
+ (println new-id)
+ (assoc wm :webmention (assoc webmention :id new-id)))))
+ (unload-data datafile))
+ (println "complete!"))))