|
3 | 3 | [aleph.netty :as netty] |
4 | 4 | [clojure.core.cache :as cache] |
5 | 5 | [clojure.java.io :as io] |
| 6 | + [hiccup2.core :as h] |
6 | 7 | [clojure.string :as str] |
7 | 8 | [jj.sql.async-boa :as async-boa] |
8 | 9 | [jj.sql.boa.query.vertx-pg :as vertx-adapter] |
|
23 | 24 |
|
24 | 25 | (def ^:private ^:const ct-json "application/json") |
25 | 26 | (def ^:private ^:const ct-text "text/plain") |
| 27 | +(def ^:private ^:const ct-html "text/html; charset=utf-8") |
26 | 28 | (def ^:private ^:const ct-octet "application/octet-stream") |
27 | 29 | (def ^:private ^:const hdr-ct "Content-Type") |
28 | 30 | (def ^:private ^:const hdr-server "Server") |
29 | 31 | (def ^:private ^:const server-name "aleph") |
30 | 32 | (def ^:private ^:const dot ".") |
31 | 33 | (def ^:private ^:const not-found-body "Not found") |
32 | 34 | (def ^:private ^:const empty-db-body "{\"items\":[],\"count\":0}") |
| 35 | +(def ^:private ^:const fortunes-error-body |
| 36 | + "<!DOCTYPE html><html><body>db error</body></html>") |
33 | 37 | (def ^:private ^:const dataset-path "/data/dataset.json") |
34 | 38 | (def ^:private ^:const dataset-large-path "/data/dataset-large.json") |
35 | 39 | (def ^:private ^:const param-min "min") |
|
45 | 49 |
|
46 | 50 | (def ^:private json-headers {hdr-ct ct-json hdr-server server-name}) |
47 | 51 | (def ^:private text-headers {hdr-ct ct-text hdr-server server-name}) |
| 52 | +(def ^:private html-headers {hdr-ct ct-html hdr-server server-name}) |
48 | 53 | (def ^:private crud-hit-headers {hdr-ct ct-json hdr-server server-name "X-Cache" "HIT"}) |
49 | 54 | (def ^:private crud-miss-headers {hdr-ct ct-json hdr-server server-name "X-Cache" "MISS"}) |
50 | 55 | (def ^:private empty-db-response {:status 200 :headers json-headers :body empty-db-body}) |
51 | 56 |
|
| 57 | +(def ^:private runtime-fortune |
| 58 | + {:id 0 :message "Additional fortune added at request time."}) |
| 59 | + |
| 60 | +(defn render-fortunes |
| 61 | + ^String [fortunes] (str |
| 62 | + (h/html {:mode :html} |
| 63 | + (h/raw "<!DOCTYPE html>") |
| 64 | + [:html |
| 65 | + [:head [:title "Fortunes"]] |
| 66 | + [:body |
| 67 | + [:table |
| 68 | + [:tr [:th "id"] [:th "message"]] |
| 69 | + (for [f fortunes] |
| 70 | + [:tr |
| 71 | + [:td (:id f)] |
| 72 | + [:td (:message f)]])]]]))) |
| 73 | + |
52 | 74 | (def ^:private ^:const extension-map |
53 | 75 | {".css" "text/css" ".js" "application/javascript" ".html" "text/html" |
54 | 76 | ".woff2" "font/woff2" ".svg" "image/svg+xml" ".webp" "image/webp" ".json" ct-json}) |
|
150 | 172 | (def ^:private crud-read-q (async-boa/build-async-query adapter "sql/crud-read")) |
151 | 173 | (def ^:private crud-create-q (async-boa/build-async-query adapter "sql/crud-create")) |
152 | 174 | (def ^:private crud-update-q (async-boa/build-async-query adapter "sql/crud-update")) |
| 175 | +(def ^:private fortunes-q (async-boa/build-async-query adapter "sql/fortunes")) |
153 | 176 |
|
154 | 177 | (defn- build-ssl-context [] |
155 | 178 | (let [cert-path (or (System/getenv "TLS_CERT") tls-cert-default) |
|
294 | 317 | (fn [_] (d/success! dfd {:status 404 :headers json-headers :body not-found-body}))) |
295 | 318 | dfd)))))) |
296 | 319 |
|
| 320 | +(defn- handle-fortunes [pg-pool _req] |
| 321 | + (let [dfd (d/deferred)] |
| 322 | + (fortunes-q |
| 323 | + pg-pool {} |
| 324 | + (fn [rows] |
| 325 | + (let [base (mapv (fn [r] {:id (:id r) :message (:message r)}) rows) |
| 326 | + all (conj base runtime-fortune) |
| 327 | + sorted (sort-by :message all) |
| 328 | + body (render-fortunes sorted)] |
| 329 | + (d/success! dfd {:status 200 |
| 330 | + :headers html-headers |
| 331 | + :body body}))) |
| 332 | + (fn [_] |
| 333 | + (d/success! dfd {:status 500 |
| 334 | + :headers html-headers |
| 335 | + :body fortunes-error-body}))) |
| 336 | + dfd)) |
| 337 | + |
297 | 338 | (defn- handle-static [req] |
298 | 339 | (let [name (get-in req [:params :filename]) |
299 | 340 | path (str "/data" (:uri req)) |
|
315 | 356 | (POST (fn [req] (handle-crud-create pg-pool req)))] |
316 | 357 | "/crud/items/:id" [(GET (fn [req] (handle-crud-read pg-pool req))) |
317 | 358 | (PUT (fn [req] (handle-crud-update pg-pool req)))] |
| 359 | + "/fortunes" [(GET (fn [req] (handle-fortunes pg-pool req)))] |
318 | 360 | "/static/:filename" [(GET handle-static)] |
319 | 361 | "/" [(GET (fn [_] (text-response server-name)))]})) |
320 | 362 |
|
|
0 commit comments