~pepe/pan.earth

pan.earth/panearth/app.janet -rw-r--r-- 2.8 KiB
45a69985 — Josef Pospíšil Added xbows article 4 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
(import chidi :prefix "")
(import shawn/cocoon)

(use ./utils)

(defn supervisor
  [chan handling]
  (var last-connection nil)
  (forever
    (forever
      (match (ev/take chan)
        [:emergence act] (cocoon/emerge act)
        [:close connection] (:close connection)
        [:error fiber]
        (let [err (fiber/last-value fiber)]
          (unless (or (= err "Connection reset by peer")
                      (= err "stream is closed"))
            (debug/stacktrace fiber err)
            (def conn ((fiber/getenv fiber) :conn))
            (:write conn (internal-server-error err))
            (:close conn)))
        [:conn connection]
        (ev/go
          (fiber/new
            (fn []
              (setdyn :conn connection)
              (handling connection)) :tp) nil chan)))))

(defn layout [args]
  (page app args))

(defn dashboard [envelope]
  (fn [&]
    (def {:site-title st :css css :files fs} envelope)
    (layout @{:title "Dashboard"
              :site-title st
              :css (process-css envelope)
              :content (page dash @{:files fs})})))

(defn render [render-content-file render-all]
  (fn [{:body {"file" file}}]
    (if (= file "all")
      (cocoon/emerge render-all)
      (cocoon/emerge (render-content-file file)))
    (response 303 "" {"Location" (vf file) "Content-Length" 0})))

(defn edit [envelope]
  (fn [{:query-params {"file" file}}]
    (def {:site-title st :css css :files fs} envelope)
    (layout @{:title (string "Editing " file)
              :site-title st
              :css (process-css envelope)
              :content (page edit @{:file-content
                                    (if (= :file (os/stat file :mode))
                                      (slurp file)
                                      `{:author ""
                                        :title ""
                                        :template "/templates/"}
                                      ---`)
                                    :file-name file})})))

(defn save [list-content]
  (fn [{:body {"file-name" fnm "file-content" fc}}]
    (spit fnm (string/replace-all "\r\n" "\n" fc))
    (cocoon/emerge list-content)
    (response 303 "" {"Location" (vf fnm) "Content-Length" 0})))

(defn handler [envelope useful-acts]
  (drive
    {"/__dashboard"
     {"" (-> (dashboard envelope)
             (guard-methods "GET")
             html-success)
      "/render" (-> (render (useful-acts :render-content-file)
                            (useful-acts :render-all))
                    (guard-methods "POST")
                    urlencoded)
      "/edit" (-> (edit envelope)
                  query-params
                  (guard-methods "GET")
                  html-success)
      "/save" (-> (save (useful-acts :list-content))
                  (guard-methods "POST")
                  urlencoded)}
     :not-found (stoic "public")}
    journal))