diff --git a/bb.edn b/bb.edn index 519d575..b9b06ba 100644 --- a/bb.edn +++ b/bb.edn @@ -3,6 +3,6 @@ lock {:doc "Update the clj-nix lockfile" :task (-> (p/sh {:out :inherit :err :inherit} - "nix run github:jlesquembre/clj-nix#deps-lock") + "nix run github:jlesquembre/clj-nix#deps-lock") :exit System/exit)}}} diff --git a/publisher/src/net/deertopia/publisher/cached_file.clj b/publisher/src/net/deertopia/publisher/cached_file.clj new file mode 100644 index 0000000..bce16eb --- /dev/null +++ b/publisher/src/net/deertopia/publisher/cached_file.clj @@ -0,0 +1,24 @@ +(ns net.deertopia.publisher.cached-file + (:require [babashka.fs :as fs])) + +(defn newer-than? + "Return `true` if fs `file₁` was last modified sooner or at the same + time as `file₂`, or if `file₂` does not exist." + [file₁ file₂] + (or (not (fs/exists? file₂)) + (<= 0 (compare (fs/last-modified-time file₁) + (fs/last-modified-time file₂))))) + +(def ^:dynamic *use-cache?* + "Bind to `false` to disable caching for debugging purposes." + true) + +(defn cached-content + "Return a file path after potentially regenerating the file by + calling `compute` with no arguments only if stale? is logical true." + [& {:keys [file stale? compute]}] + (when (or (not *use-cache?*) stale?) + (let [r (compute)] + (assert (string? r)) + (spit file r))) + file) diff --git a/publisher/src/net/deertopia/publisher/elisp.clj b/publisher/src/net/deertopia/publisher/elisp.clj index 2b7e672..59345e3 100644 --- a/publisher/src/net/deertopia/publisher/elisp.clj +++ b/publisher/src/net/deertopia/publisher/elisp.clj @@ -9,22 +9,23 @@ (io/resource "net/deertopia/publisher/elisp/grammar")) (defn- transform-string [s] - (letfn [(go [s acc] - (match s - ([\\ c & cs] :seq) - (recur - cs - (str acc - (condp = c - \n \newline - \f \formfeed - \\ \\ - \" \" - \newline nil - (throw (ex-info "IDK!" {:char c}))))) - ([c & cs] :seq) (recur cs (str acc c)) - ([] :seq) acc))] - [:string (apply str (go (seq s) ""))])) + (let [s* (loop [s (seq s) + acc ""] + (match s + ([\\ c & cs] :seq) + (recur + cs + (str acc + (condp = c + \n \newline + \f \formfeed + \\ \\ + \" \" + \newline nil + (throw (ex-info "IDK!" {:char c}))))) + ([c & cs] :seq) (recur cs (str acc c)) + ([] :seq) acc))] + [:string (apply str s*)])) (defn- transform-integer [s] [:integer (parse-long s)]) @@ -107,7 +108,9 @@ ;; TODO: this is really not how it should be done lol. at the ;; moment, `print` is only used in `net.deertopia.publisher.roam` ;; and only to serialise uuids, so it's not a /massive/ priority. - (cond (string? x) (str \" s \"))) + (cond (string? x) (str \" x \") + :else (throw (ex-info "`print` is unimplemented lol" + {:x x})))) (comment (do (ip/defparser parse* (io/resource "elisp-grammar")) diff --git a/publisher/src/net/deertopia/publisher/roam.clj b/publisher/src/net/deertopia/publisher/roam.clj index 2ce8805..765bb45 100644 --- a/publisher/src/net/deertopia/publisher/roam.clj +++ b/publisher/src/net/deertopia/publisher/roam.clj @@ -49,13 +49,12 @@ (defn org-file [node] (fetch-with-cache - node - :org-file + node :org-file (fn [node] (when-some [r (sql/execute-one! - ds - ["select file from nodes where id = ?" - (elisp/print (:id node))])] + ds + ["select file from nodes where id = ?" + (-> node :id str elisp/print)])] (-> r :nodes/file elisp/read-string))))) (defprotocol GetNode diff --git a/publisher/src/net/deertopia/publisher/server.clj b/publisher/src/net/deertopia/publisher/server.clj index a99121b..7bfc8ab 100644 --- a/publisher/src/net/deertopia/publisher/server.clj +++ b/publisher/src/net/deertopia/publisher/server.clj @@ -4,6 +4,7 @@ [hiccup2.core :as hiccup] [net.deertopia.doerg.html :as doerg-html] [net.deertopia.publisher.slug :as slug] + [net.deertopia.publisher.roam :as roam] [org.httpkit.server :as http] [reitit.coercion] [reitit.coercion.spec] @@ -15,7 +16,8 @@ [spec-tools.spell] [reitit.spec] [reitit.dev.pretty] - [clojure.spec.alpha :as s])) + [clojure.spec.alpha :as s] + [net.deertopia.doerg.render :as doerg-render])) ;;; Routes @@ -35,18 +37,19 @@ response/response (response/content-type "text/html"))) -(defn node-by-slug [req] +(defn node-by-slug [{{{:keys [slug]} :path} :parameters}] (-> (hiccup/html {} [:html [:head - [:title "node-by-slug"] + [:title "node by sluggg"] doerg-html/charset doerg-html/viewport] [:body [:h1 "node by slug"] [:pre (with-out-str - (pprint (:parameters req)))]]]) + (pprint (-> slug slug/from-string roam/get-node + roam/org-file)))]]]) str response/response (response/content-type "text/html"))) @@ -58,10 +61,10 @@ (reitit.ring/router #{["/" {:get hello}] ["/n/:slug" - {:get {:handler node-by-slug + {:get {:handler #'node-by-slug :parameters {:path {:slug ::slug/slug}}}}] - ["/id/:id" {:get node-by-id}]} + ["/id/:id" {:get #'node-by-id}]} {:validate reitit.spec/validate :exception reitit.dev.pretty/exception :spec (s/merge :reitit.spec/default-data)