Skip to content

Commit

Permalink
Fix: handler, config merging, in memory serving.
Browse files Browse the repository at this point in the history
  • Loading branch information
teesloane committed May 4, 2020
1 parent dbc63b4 commit 87713a9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 46 deletions.
59 changes: 39 additions & 20 deletions clojure/src/firn/build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@
(io/make-parents (:out-name f))
(spit (:out-name f) (:contents f)))))))

(defn copy-static-files
[config]
(when-not (fs/exists? (config :dir-site-attach))
(fs/copy-dir (config :dir-attach) (config :dir-site-attach)))
(when-not (fs/exists? (config :dir-site-static))
(fs/copy-dir (config :dir-static) (config :dir-site-static))))

(defn setup
"Creates folders for output, slurps in layouts and partials.
NOTE: should slurp/mkdir/copy-dir be wrapped in try-catches? if-err handling?"
Expand All @@ -58,7 +65,7 @@

(fs/mkdir (config :dir-site)) ;; make _site

;; copy attachments and static files too final _site dir.
;; copy attachments and static files to final _site dir.
(when-not (fs/exists? (config :dir-site-attach))
(fs/copy-dir (config :dir-attach) (config :dir-site-attach)))
(when-not (fs/exists? (config :dir-site-static))
Expand Down Expand Up @@ -87,41 +94,53 @@

;; -- Server --

(defn file-server-middleware
[{:keys [dir-site dir-files] :as config}]

(defn handler
"Handles web requests for the development server.
FIXME: Needs a file watcher for determining when to copy files into dir-site"
[{:keys [dir-firn dir-site] :as config}]
(fn [request]
;; This is naive; everytime we visit a page it runs the build step.
(let [res-file-system ((r-file/wrap-file request dir-site) request)
req-uri-file (s/join "" (-> request :uri rest)) ;; we have to trim the requested uri because it comes in as "/my-link"; but they are in memory as "my-link"
file-html (get-in config [:processed-files req-uri-file :as-html])
(let [; first we try and get the request to load from the files system
res-file-system ((r-file/wrap-file request dir-site) request)
;; then we pull the uri out of req and format it: `/this-is/my-req` -> `this-is/my-req`
req-uri-file (s/join "" (-> request :uri rest))
;; use the uri to pull values out of memory in config
memory-file (get-in config [:processed-files req-uri-file])
;; a ring response for when nothing is found.
four-oh-four {:status 404 :body "File not found."}]
;; TODO: - re-process single file when hit by route.
;; TODO: - all links with .html in them need to be stripped?
;; TODO: - make sure index is rendering from memory?
(cond
(some? file-html) (response file-html)
(some? res-file-system) res-file-system
:else four-oh-four))))
;; If the request was found to match in the config...
(some? memory-file)
;; let's re-slurp the file in case it's changed
;; someday this will be handled by a file watcher.
(let [reloaded-file (file/reload-requested-file memory-file config)]
;; then we can respones with the reloaded-files's html.
(response (reloaded-file :as-html)))

;; If the file isn't found in memory, let's try using a file in the _firn/_site fs.
(some? res-file-system)
res-file-system

:else
four-oh-four))))

(defstate server
:start (let [args (mount/args)
dir-files (get args :-path (u/get-cwd))
path-to-site (str dir-files "_firn/_site")
;; config (setup (config/prepare dir-files))
config (-> (config/prepare dir-files) setup file/process-all) ;; basically doing `all-files`
path-to-site (str dir-files "/_firn/_site")
;; build all files and prepare a config.
config (-> dir-files config/prepare setup file/process-all)
port 3333]
(println "Building site...")
;; (all-files {:dir-files dir-files}) ;; we don't need this; we hold files in memory rn
(if-not (fs/exists? path-to-site)
(println "Couldn't find a _firn/ folder. Have you run `Firn new` and created a site yet?")
(do (println "🏔 Starting Firn development server on:" port)
(http/run-server (file-server-middleware config) {:port port}))))
(http/run-server (handler config) {:port port}))))
:stop (when server (server :timeout 100)))

(defn serve
[opts]
;; TODO: build the whole site before running the server.
(mount/start-with-args opts))

;; (serve {:-path "/Users/tees/Dropbox/wiki/"})
;; cider won't boot if this is uncommented at jack-in:
(serve {:-path "/Users/tees/Projects/firn/firn/clojure/test/firn/demo_org"})
41 changes: 26 additions & 15 deletions clojure/src/firn/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,23 @@

(defn default
"Assume that files-dir does NOT end in a `/`ex: /Users/tees/Dropbox/wiki"
[dir-files]
(merge starting-config
{:dir-firn (make-dir-firn dir-files)
:dir-attach (str dir-files "/" (starting-config :dir-attach))
:dir-files dir-files
:dir-layouts (str dir-files "/_firn/layouts/")
:dir-partials (str dir-files "/_firn/partials/")
:dir-site (str dir-files "/_firn/_site/")
:dir-site-attach (str dir-files "/_firn/_site/" (starting-config :dir-attach))
:dir-site-static (str dir-files "/_firn/_site/static/")
:dir-static (str dir-files "/_firn/static/")
:dirname-files (-> dir-files (s/split #"/") last)})) ;; the name of the dir where files are.
([dir-files]
(default dir-files {}))

([dir-files external-config]
(let [base-config (merge starting-config external-config)]
(merge starting-config
{:dir-firn (make-dir-firn dir-files)
:dir-attach (str dir-files "/" (base-config :dir-attach))
:dir-files dir-files
:dir-layouts (str dir-files "/_firn/layouts/")
:dir-partials (str dir-files "/_firn/partials/")
;; all outputted _site directories.
:dir-site (str dir-files "/_firn/_site/")
:dir-site-attach (str dir-files "/_firn/_site/" (base-config :dir-attach))
:dir-site-static (str dir-files "/_firn/_site/static/")
:dir-static (str dir-files "/_firn/static/")
:dirname-files (-> dir-files (s/split #"/") last)})))) ;; the name of the dir where files are.

(defn clean-config
"Takes the user config and strips any keys from it that shouldn't be changed
Expand All @@ -64,13 +69,19 @@
;; No config found
(do
(println "Didn't find a _firn site. Have you run `firn new` yet?")
(System/exit 0)) ;; TODO: good place for a "if DEV..." so the repl doesn't close.
#_(System/exit 0)) ;; TODO: good place for a "if DEV..." so the repl doesn't close.
;; try and read the config
(try
(let [read-config (sci/eval-string (slurp (str (default-config :dir-firn) "/config.edn")))
cleaned-config (clean-config read-config)
merged-config (merge default-config cleaned-config)]
merged-config)
final-config (default wiki-path cleaned-config)]
final-config)
;; merged-with-sample-config (merge base-config cleaned-config)
;; final-config (default merged-with-sample-config)]

;; merged-config (merge default-config cleaned-config)]
;; (prn "merged config is " final-config)
;; final-config)
(catch Exception ex
(println
"Failed to read 'config.edn' file - is it properly formatted?"))))))
34 changes: 23 additions & 11 deletions clojure/src/firn/file.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
[cheshire.core :as json]
[firn.util :as u]
[firn.org :as org]
[firn.layout :as layout]))
[firn.layout :as layout]
[clojure.java.io :as io]))

(defn strip-file-ext
"Removes a file extension from a file path string.
Expand Down Expand Up @@ -156,8 +157,8 @@
(let [layout (keyword (get-keyword f "FIRN_LAYOUT"))
as-html (when-not (is-private? config f)
(layout/apply-layout config f layout))]
as-html
#_(change f {:as-html as-html})))
;; as-html
(change f {:as-html as-html})))

(defn process-one
"Munge the 'file' datastructure; slowly filling it up, using let-shadowing.
Expand All @@ -172,8 +173,8 @@
:org-title (get-keyword new-file "TITLE")
:links (file-metadata :links)
:logbook (file-metadata :logbook)})
new-file (change new-file {:as-html (htmlify config new-file)})]
new-file))
final-file (htmlify config new-file)]
final-file))

(defn process-all
"Receives config, processes all files and builds up site-data
Expand All @@ -187,11 +188,12 @@
(loop [org-files (config :org-files)
output {}]
(if (empty? org-files)
(assoc config
:processed-files output
:site-map @site-map
:site-links @site-links
:site-logs @site-logs)
;; LOOP/RECUR: BREAK run one more loop on all files, and create their
;; html, now ;; that we have processed everything.
(let [config-with-data (assoc config :processed-files output :site-map @site-map :site-links @site-links :site-logs @site-logs)
with-html (into {} (for [[k pf] output] [k (htmlify config-with-data pf)]))
final (assoc config :processed-files with-html)]
final)

(let [next-file (first org-files)
processed-file (process-one config next-file)
Expand All @@ -201,11 +203,21 @@
new-site-map (merge keyword-map {:path (processed-file :path-web)})
file-metadata (extract-metadata processed-file)] ;; FIXME: why are we calling this once when we can pull the results out from `processed-file / via procssed one`?!


;; add to sitemap when file is not private.
(when-not (is-private? config processed-file)
;; (swap! site-map concat @site-map new-site-map)
(swap! site-map conj new-site-map)
(swap! site-links concat @site-links (:links file-metadata))
(swap! site-logs concat @site-logs (:logbook file-metadata)))
;; add links and logs to site wide data.
(recur org-files output))))))



(defn reload-requested-file
"Take a request to a file, pulls the file out of memory
grabs the path of the original file, reslurps it and reprocesses"
[file config]
(let [re-slurped (-> file :path io/file)
re-processed (process-one config re-slurped)]
re-processed))

0 comments on commit 87713a9

Please sign in to comment.