-
Notifications
You must be signed in to change notification settings - Fork 1
/
gs.clj
67 lines (59 loc) · 2.21 KB
/
gs.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
(ns tools.io.gs
(:require [clojure.string :as str]
[clj-gcloud.storage :as gs]
[clj-gcloud.coerce :refer [->clj]]
[tools.io.core :refer [register-file-pred!
mk-input-stream
mk-output-stream
list-files
list-dirs]])
(:import (java.io FileNotFoundException)))
(defn- gs-file?
[path]
(str/starts-with? (str/lower-case (str path)) "gs://"))
(defn mk-client
"Make storage client from option map"
[{:keys [storage] :as options}]
(or storage (gs/init options)))
(register-file-pred! :gs gs-file?)
(defn- ->gs-blob-id
[uri]
(try
(gs/->blob-id uri)
(catch NullPointerException _ nil)))
(defmethod mk-input-stream :gs
[filename & [options]]
(let [stream (some->> filename
->gs-blob-id
(gs/get-blob (mk-client options))
gs/read-channel
gs/->input-stream)]
(if stream
{:stream stream}
(throw (FileNotFoundException. filename)))))
(defmethod mk-output-stream :gs
[filename & [options]]
(let [{:keys [encoding
mime-type]
:or {encoding "UTF-8"
mime-type "text/plain"}} options]
{:stream (-> (gs/create-blob-writer
(mk-client options)
(gs/blob-info (gs/->blob-id filename) {:content-encoding encoding
:content-type mime-type}))
gs/->output-stream)}))
(defmethod list-files :gs
[path & [options]]
(->> (gs/ls (mk-client options) path (or options {}))
(map (fn [blob]
(let [{:keys [blob-id]} (->clj blob)]
(str "gs://" (:bucket blob-id) "/" (:name blob-id)))))))
(defmethod list-dirs :gs
[path & [options]]
(let [directory (if (= (-> path seq last) \/) path
(str path "/"))]
(->> (gs/ls (mk-client options) directory
(or options {:current-directory "/"}))
(map (fn [blob]
(let [{:keys [blob-id]} (->clj blob)]
(str "gs://" (:bucket blob-id) "/" (:name blob-id))))))))