Compare commits

4 Commits

Author SHA1 Message Date
c6d10b9776
All checks were successful
build / build (push) Successful in 1m47s
2026-03-25 15:50:30 -06:00
06e6b8ebaf 2026-03-25 15:05:12 -06:00
147c98ab61 2026-03-25 14:21:45 -06:00
97b83f3516 wip: feat: html 캐시
All checks were successful
build / build (push) Successful in 35s
2026-03-24 17:52:39 -06:00
12 changed files with 143 additions and 65 deletions

View File

@@ -4,10 +4,8 @@
:latex "xelatex"
:dvisvgm "dvisvgm"
:doerg-temml-worker
#profile {:dev-publisher "../doerg/doerg-temml-worker/index.js"
:dev-doerg "./doerg-temml-worker/index.js"
#profile {:dev #file "../../../../doerg-temml-worker/index.js"
:default "doerg-temml-worker"}
:doerg-parser
#profile {:dev-publisher "../doerg/doerg-parser/index.js"
:dev-doerg "./doerg-parser/index.js"
#profile {:dev #file "../../../../doerg-parser/index.js"
:default "doerg-parser"}}

View File

@@ -45,29 +45,35 @@
(and (fs/exists? x) x))
(fs/split-paths (System/getenv "XDG_DATA_DIRS"))))
(defn make-read-config [spec]
(fn [& files]
(let [r (->> files
(filter identity)
(map aero/read-config)
(apply merge))
conformed (s/conform spec r)]
(if-not (s/invalid? conformed)
conformed
(throw (IllegalArgumentException.
"bad config"
(ex-info "couldn't conform"
(s/explain-data spec r))))))))
(defmethod aero/reader 'file
[{:keys [source]} tag value]
"Aero tag to reference a `java.io.File` relative to the config
file."
(-> (aero/relative-resolver source value)
fs/file))
(def read-config (make-read-config ::d/config))
(defn read-config [spec files & {:as opts}]
(let [r (->> files
(filter identity)
(map #(aero/read-config % opts))
(apply merge))
conformed (s/conform spec r)]
(if-not (s/invalid? conformed)
conformed
(throw (ex-info "Failed to conform config"
(s/explain-data spec r))))))
(def default
(read-config
;; Default config.
(defn load-config! [var spec files & {:as opts}]
(alter-var-root var (constantly (read-config spec files opts))))
(def sources
[;; Default config.
(io/resource "net/deertopia/doerg/default-config.edn")
;; Defaults set at build time, if any.
(io/resource "net/deertopia/doerg/extra-config.edn")
;; Config set at runtime.
(System/getenv "DOERG_CONFIG")))
(System/getenv "DOERG_CONFIG")])
(def default (read-config ::d/config sources))
(def ^:dynamic *cfg* default)

View File

@@ -1,11 +1,12 @@
((nil
. ((cider-clojure-cli-aliases . ":dev")
(eval
. (progn
(defun start-deertopia-server ()
(let ((n (cider-format-connection-params "%j" cider-launch-params)))
(when (equal n "net-deertopia")
(cider-interactive-eval
"(do (require '[net.deertopia.publisher.server :as server])
(server/start!))"))))
(add-hook 'cider-connected-hook #'start-deertopia-server))))))
. ((cider-clojure-cli-aliases . ":dev:test")
;; (eval
;; . (progn
;; (defun start-deertopia-server ()
;; (let ((n (cider-format-connection-params "%j" cider-launch-params)))
;; (when (equal n "net-deertopia")
;; (cider-interactive-eval
;; "(do (require '[net.deertopia.publisher.server :as server])
;; (server/start!))"))))
;; (add-hook 'cider-connected-hook #'start-deertopia-server)))
)))

View File

@@ -17,4 +17,5 @@
:aliases
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}}}
:main-opts ["-m" "kaocha.runner"]}
:dev {:extra-paths ["dev"]}}}

20
publisher/dev/user.clj Normal file
View File

@@ -0,0 +1,20 @@
(ns user
(:require [net.deertopia.publisher.server :as server]
[net.deertopia.doerg :as-alias doerg]
[net.deertopia.publisher :as-alias publisher]
[net.deertopia.doerg.config :as doerg-config]
[net.deertopia.publisher.config :as publisher-config]
[babashka.fs :as fs]))
(doerg-config/load-config! #'doerg-config/*cfg*
::doerg/config
doerg-config/sources
:profile :dev)
(doerg-config/load-config! #'publisher-config/*cfg*
::publisher/config
publisher-config/sources
:profile :dev)
(when (nil? (server/status))
(server/start!))

View File

@@ -3,4 +3,4 @@
#envf ["%s/.local/share" HOME]]
"/doerg-publisher"]
:org-roam-db-path #join [#env HOME "/.cache/emacs/org-roam.db"]
:port 8080}
:port #profile {:default 8080}}

View File

@@ -20,5 +20,6 @@
(when (or (not *use-cache?*) stale?)
(let [r (compute)]
(assert (string? r))
(fs/create-dirs (fs/parent file))
(spit file r)))
file)

View File

@@ -14,15 +14,15 @@
(s/def ::p/state-directory ::doerg/file)
(s/def ::p/org-roam-db-path ::doerg/file)
(def read-config (doerg-config/make-read-config ::p/config))
(def default
(read-config
;; Default config.
(def sources
[;; Default config.
(io/resource "net/deertopia/publisher/default-config.edn")
;; Defaults set at build time, if any.
(io/resource "net/deertopia/publisher/extra-config.edn")
;; Config set at runtime.
(System/getenv "DOERG_PUBLISHER_CONFIG")))
(System/getenv "DOERG_PUBLISHER_CONFIG")])
(def default
(doerg-config/read-config ::p/config sources))
(def ^:dynamic *cfg* default)

View File

@@ -42,11 +42,35 @@
response/response
(response/content-type "text/html")))
(defn node-by-slug [{{{:keys [slug]} :path} :parameters}]
(let [html (-> slug slug/from-string roam/get-node
roam/org-file doerg-render/to-html)]
(-> html response/response
(response/content-type "text/html"))))
(defn- html-dir []
(-> cfg/*cfg* ::publisher/state-directory (fs/file "html")))
(defn not-found [req]
(response/not-found "not found"))
(defn org-file->html-file [org-file]
(fs/file (html-dir)
(-> org-file
fs/file-name
(fs/strip-ext {:ext "org"})
(str ".html"))))
(defn node-by-slug [{{:keys [slug]} :path-params :as req}]
(if-some [node (some-> slug slug/from-string roam/get-node)]
(let [org-file (roam/org-file node)
html-file (org-file->html-file org-file)]
(cached-file/cached-file
:file html-file
:stale? (cached-file/newer-than? org-file html-file)
:compute #(doerg-render/to-html org-file))
(-> (str html-file)
response/file-response
(response/content-type "text/html")))
(not-found req))
#_(let [html (-> slug slug/from-string roam/get-node
roam/org-file doerg-render/to-html)]
(-> html response/response
(response/content-type "text/html"))))
(defn node-by-id [req]
(hello req))
@@ -64,9 +88,7 @@
(reitit.ring/router
#{["/" {:get hello}]
["/n/:slug"
{:get {:handler #'node-by-slug
:parameters
{:path {:slug ::slug/slug}}}}]
{:get {:handler #'node-by-slug}}]
["/id/:id" {:get #'node-by-id}]}
{:validate reitit.spec/validate
:exception reitit.dev.pretty/exception

Binary file not shown.

View File

@@ -0,0 +1,7 @@
:PROPERTIES:
:ID: 23ee464d-b13e-4649-826f-622d0edef24e
:DeertopiaVisibility: public
:END:
#+title: awesome file
wow!

View File

@@ -2,23 +2,45 @@
(:require [net.deertopia.publisher.server :as sut]
[reitit.ring]
[clojure.test :as t]
[clojure.set :as set]
[net.deertopia.publisher.server :as server]
[net.deertopia.publisher.config :as cfg]
[net.deertopia.publisher :as-alias publisher]))
[net.deertopia.publisher.config :as publisher-cfg]
[net.deertopia.doerg.config :as doerg-cfg]
[net.deertopia.publisher :as-alias publisher]
[net.deertopia.doerg :as-alias doerg]))
(t/use-fixtures
:once (fn [f]
(binding [doerg-cfg/*cfg*
(doerg-cfg/read-config
::doerg/config doerg-cfg/sources
:profile :test)
publisher-cfg/*cfg*
(doerg-cfg/read-config
::publisher/config publisher-cfg/sources
:profile :test)]
(f))))
(defn with-server [f]
(let [was-already-running? (= :running (sut/status))]
(when-not was-already-running?
(sut/start!))
(f)
(when-not was-already-running?
(sut/stop!))))
(t/deftest server-is-running
;; 서버 벌써 시작한 다음에 이 테스트 하면 잘못됩니다.
(assert (not= :running (server/status)))
(server/start!)
(t/is (= :running (server/status)))
(server/stop!))
;; 서버 벌써 시작한 다음에 이 테스트 하면 잘못됩니다.
;; (assert (not= :running (sut/status)))
(with-server
(fn []
(t/is (= :running (sut/status)))
(t/is (->> (format "http://localhost:%d"
(::publisher/port publisher-cfg/*cfg*))
slurp
string?)))))
(t/deftest can-get-real-server-root
;; 서버가 벌써 시작한 다음에 이 테스트 하면 잘못됩니다.
(assert (not= :running (server/status)))
(server/start!)
(t/is (->> (format "http://localhost:%d" (::publisher/port cfg/*cfg*))
slurp
string?))
(server/stop!))
#_
(t/deftest get-nonexistent-node
(t/is (= 404
(-> {:request-method :get
:uri "/n/68XqhHerTWCbE--RYLEdHw"}
sut/app :status))))