forked from babashka/babashka
-
Notifications
You must be signed in to change notification settings - Fork 0
/
image-viewer.clj
executable file
·81 lines (72 loc) · 2.17 KB
/
image-viewer.clj
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
#!/usr/bin/env bb
(ns image-viewer
(:require [clojure.java.browse :as browse]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.tools.cli :refer [parse-opts]]
[org.httpkit.server :as server])
(:import [java.net URLDecoder URLEncoder]))
(def cli-options [["-p" "--port PORT" "Port for HTTP server" :default 8090 :parse-fn #(Integer/parseInt %)]
["-d" "--dir DIR" "Directory to scan for images" :default "."]])
(def opts (:options (parse-opts *command-line-args* cli-options)))
(def port (:port opts))
(def dir (:dir opts))
(def images
(filter #(and (.isFile %)
(let [name (.getName %)
ext (some-> (str/split name #"\.")
last
str/lower-case)]
(contains? #{"jpg" "jpeg" "png" "gif" "svg"} ext)))
(file-seq (io/file dir))))
(def image-count (count images))
(defn page [n]
(let [prev (max 0 (dec n))
next (min (inc n) (dec image-count))
file-path (.getCanonicalPath (nth images n))
encoded-file-path (URLEncoder/encode file-path)]
{:body (format "
<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\"/>
<script>
window.onkeydown=function(e) {
switch (e.key) {
case \"ArrowLeft\":
window.location.href=\"/%s\"; break;
case \"ArrowRight\":
window.location.href=\"/%s\"; break;
}
}
</script>
</head>
<body>
Navigation: use left/right arrow keys
<p>%s</p>
<div>
<img style=\"max-height: 90vh; margin: auto; display: block;\" src=\"assets/%s\"/>
</div>
<div>
</div>
</body>
</html>" prev next file-path encoded-file-path)}))
(server/run-server
(fn [{:keys [:uri]}]
(cond
;; serve the file
(str/starts-with? uri "/assets")
(let [f (io/file (-> (str/replace uri "assets" "")
(URLDecoder/decode)))]
{:body f})
;; serve html
(re-matches #"/[0-9]+" uri)
(let [n (-> (str/replace uri "/" "")
(Integer/parseInt))]
(page n))
;; favicon.ico, etc
:else
{:status 404}))
{:port port})
(browse/browse-url (format "http://localhost:%s/0" port))
@(promise)