From e45d411450dd9d8edbd591bc10beba119495b80b Mon Sep 17 00:00:00 2001 From: eltrac Date: Tue, 12 May 2026 11:04:16 +0800 Subject: refactor(storage): make storage vtable in its ns --- src/weepinbell/core.clj | 9 +--- src/weepinbell/storage.clj | 82 ------------------------------- src/weepinbell/storage/edn_storage.clj | 90 ++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 89 deletions(-) delete mode 100644 src/weepinbell/storage.clj create mode 100644 src/weepinbell/storage/edn_storage.clj (limited to 'src') diff --git a/src/weepinbell/core.clj b/src/weepinbell/core.clj index c88f704..dab73ae 100644 --- a/src/weepinbell/core.clj +++ b/src/weepinbell/core.clj @@ -6,15 +6,10 @@ [weepinbell.config :refer [get-config load-config]] [weepinbell.webhook :as webhook] [taoensso.timbre :as timbre] - [weepinbell.storage :as storage]) + [weepinbell.storage.edn-storage :as edn]) (:gen-class)) ;; Essential for "lein uberjar" -(def datasource (get-config :data-path)) -(def store {:append (partial storage/append-wm datasource) - :update (partial storage/update-wm datasource) - :delete (partial storage/delete-wm datasource) - :get (partial storage/get-wm datasource) - :get-by-domain (partial storage/get-wms-by-domain datasource)}) +(def store (edn/use-store (get-config :data-path))) (defn -main [& _] ;; Start webmention processor diff --git a/src/weepinbell/storage.clj b/src/weepinbell/storage.clj deleted file mode 100644 index 8fa634d..0000000 --- a/src/weepinbell/storage.clj +++ /dev/null @@ -1,82 +0,0 @@ -(ns weepinbell.storage - (:require [clojure.edn :as edn] - [weepinbell.utils :refer [get-domain get-target get-path]] - [clojure.java.io :as io] - [clojure.string :refer [join]])) - -(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)))) - -;; predicates used for filtering webmention -(defn- st-pair-equal-pred [source target wm] - (and (= source (get-in wm [:webmention :source])) - (= target (get-in wm [:webmention :target])))) -(defn- id-equal-pred [id wm] - (= id (get-in wm [:webmention :id]))) -(defn- get-predicate [source target] - (if target - #(st-pair-equal-pred source target %) - #(id-equal-pred source %))) -(defn- domain-equal [domain wm] - (= domain - (-> wm get-target get-domain))) -(defn- path-equal [path wm] - (= path - (-> wm get-target get-path))) -;; end predicates - -(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 get-wm - ([datasource id] (get-wm datasource id nil)) - ([datasource source target] - (let [pred (get-predicate source target)] - (with-webmentions datasource - #(first (filter pred %)))))) - -(defn delete-wm - ([datasource id] (delete-wm datasource id nil)) - ([datasource source target] - (let [pred (get-predicate source target)] - (with-webmentions datasource - #(->> % - (remove pred) - (unload-data datasource)))))) - -(defn get-wms-by-domain - ([datasource domain] - (get-wms-by-domain datasource domain nil)) - ([datasource domain path] - (with-webmentions datasource - #(cond->> % - true (filter (partial domain-equal domain)) - (some? path) (filter (partial path-equal path)) - true vec)))) - -(defn first-line-empty? [path] - (with-open [rdr (io/reader path)] - (let [line (line-seq rdr)] - (empty? line)))) - -(defn append-wm - "Append an accepted webmention to .edn data file." - [datasource data] - (let [newline? (if (first-line-empty? datasource) "" "\n") - line (str newline? (pr-str data))] - (spit datasource line :append true))) - -(defn update-wm - "Update an existing webmention" - [datasource source target new-data] - (delete-wm datasource source target) - (append-wm datasource new-data)) - diff --git a/src/weepinbell/storage/edn_storage.clj b/src/weepinbell/storage/edn_storage.clj new file mode 100644 index 0000000..436d2be --- /dev/null +++ b/src/weepinbell/storage/edn_storage.clj @@ -0,0 +1,90 @@ +(ns weepinbell.storage.edn-storage + (:require [clojure.edn :as edn] + [weepinbell.utils :refer [get-domain get-target get-path]] + [clojure.java.io :as io] + [clojure.string :refer [join]])) + +(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)))) + +;; predicates used for filtering webmention +(defn- st-pair-equal-pred [source target wm] + (and (= source (get-in wm [:webmention :source])) + (= target (get-in wm [:webmention :target])))) +(defn- id-equal-pred [id wm] + (= id (get-in wm [:webmention :id]))) +(defn- get-predicate [source target] + (if target + #(st-pair-equal-pred source target %) + #(id-equal-pred source %))) +(defn- domain-equal [domain wm] + (= domain + (-> wm get-target get-domain))) +(defn- path-equal [path wm] + (= path + (-> wm get-target get-path))) +;; end predicates + +(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 get-wm + ([datasource id] (get-wm datasource id nil)) + ([datasource source target] + (let [pred (get-predicate source target)] + (with-webmentions datasource + #(first (filter pred %)))))) + +(defn delete-wm + ([datasource id] (delete-wm datasource id nil)) + ([datasource source target] + (let [pred (get-predicate source target)] + (with-webmentions datasource + #(->> % + (remove pred) + (unload-data datasource)))))) + +(defn get-wms-by-domain + ([datasource domain] + (get-wms-by-domain datasource domain nil)) + ([datasource domain path] + (with-webmentions datasource + #(cond->> % + true (filter (partial domain-equal domain)) + (some? path) (filter (partial path-equal path)) + true vec)))) + +(defn first-line-empty? [path] + (with-open [rdr (io/reader path)] + (let [line (line-seq rdr)] + (empty? line)))) + +(defn append-wm + "Append an accepted webmention to .edn data file." + [datasource data] + (let [newline? (if (first-line-empty? datasource) "" "\n") + line (str newline? (pr-str data))] + (spit datasource line :append true))) + +(defn update-wm + "Update an existing webmention" + [datasource source target new-data] + (delete-wm datasource source target) + (append-wm datasource new-data)) + +;; make storage vtable +(defn use-store [datasource] + {:append (partial append-wm datasource) + :update (partial update-wm datasource) + :delete (partial delete-wm datasource) + :get (partial get-wm datasource) + :get-by-domain (partial get-wms-by-domain datasource)}) + -- cgit v1.2.3