Blame


1 83c817b4 2021-10-13 op # gemini.core
2 1d126b15 2021-10-13 op
3 2957b0a4 2021-10-13 op [![Clojars Project](https://img.shields.io/clojars/v/com.omarpolo/gemini.svg)](https://clojars.org/com.omarpolo/gemini)
4 2957b0a4 2021-10-13 op
5 a7994c56 2021-10-13 op A Clojure library to make Gemini requests that exposes some low-level
6 a7994c56 2021-10-13 op API to handle network requests.
7 1d126b15 2021-10-13 op
8 1d126b15 2021-10-13 op
9 1d126b15 2021-10-13 op ## Usage
10 1d126b15 2021-10-13 op
11 83c817b4 2021-10-13 op Import the library for e.g. with:
12 83c817b4 2021-10-13 op
13 1d126b15 2021-10-13 op ```clojure
14 1d126b15 2021-10-13 op user=> (require '[gemini.core :as gemini])
15 1d126b15 2021-10-13 op ```
16 1d126b15 2021-10-13 op
17 83c817b4 2021-10-13 op ### Documentation
18 1d126b15 2021-10-13 op
19 1d126b15 2021-10-13 op `fetch` makes a Gemini request and returns a map with `:request`,
20 1d126b15 2021-10-13 op `:meta`, `:code` and `:body` as keys, or `:error` if an error occur.
21 1d126b15 2021-10-13 op
22 83c817b4 2021-10-13 op The request needs to be closed afterwards using `close`.
23 1d126b15 2021-10-13 op
24 1d126b15 2021-10-13 op ```clojure
25 1d126b15 2021-10-13 op user=> (gemini/fetch "gemini://gemini.circumlunar.space/")
26 1d126b15 2021-10-13 op {:request
27 1d126b15 2021-10-13 op #object[com.omarpolo.gemini.Request 0x3b270767 "com.omarpolo.gemini.Request@3b270767"],
28 1d126b15 2021-10-13 op :meta "gemini://gemini.circumlunar.space/",
29 1d126b15 2021-10-13 op :code 31,
30 1d126b15 2021-10-13 op :body
31 1d126b15 2021-10-13 op #object[java.io.BufferedReader 0x49358b66 "java.io.BufferedReader@49358b66"]}
32 1d126b15 2021-10-13 op ```
33 1d126b15 2021-10-13 op
34 83c817b4 2021-10-13 op `body-as-string!` reads all the response into a string and returns it.
35 83c817b4 2021-10-13 op It also closes the request automatically.
36 1d126b15 2021-10-13 op
37 1d126b15 2021-10-13 op ```clojure
38 1d126b15 2021-10-13 op user=> (-> (gemini/fetch "gemini://gemini.circumlunar.space/")
39 1d126b15 2021-10-13 op gemini/body-as-string!)
40 1d126b15 2021-10-13 op "# Project Gemini\n\n## Overview\n\nGemini is a new internet protocol which..."
41 1d126b15 2021-10-13 op ```
42 1d126b15 2021-10-13 op
43 83c817b4 2021-10-13 op `close` closes a request. It needs to be called after every
44 83c817b4 2021-10-13 op (successful) request.
45 1d126b15 2021-10-13 op
46 83c817b4 2021-10-13 op ```clojure
47 83c817b4 2021-10-13 op user=> (let [req (gemini/fetch "...")]
48 83c817b4 2021-10-13 op (when-not (:error req)
49 e4f66724 2021-10-13 op ;; do something with req
50 e4f66724 2021-10-13 op ,,,
51 e4f66724 2021-10-13 op (gemini/close req)))
52 83c817b4 2021-10-13 op ```
53 1d126b15 2021-10-13 op
54 83c817b4 2021-10-13 op `with-request` is a macro like `with-open` to making connection
55 83c817b4 2021-10-13 op easily. It automatically closes the request and evaluates the body
56 83c817b4 2021-10-13 op only when the request is successful, otherwise throws an exception.
57 1d126b15 2021-10-13 op
58 1d126b15 2021-10-13 op ```clojure
59 958b98ff 2021-10-13 op user=> (gemini/with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
60 1d126b15 2021-10-13 op ,,,)
61 1d126b15 2021-10-13 op ```
62 83c817b4 2021-10-13 op
63 83c817b4 2021-10-13 op
64 83c817b4 2021-10-13 op ## Streaming content
65 83c817b4 2021-10-13 op
66 83c817b4 2021-10-13 op The `:body` keyword in the returned map is an instance of a Java
67 83c817b4 2021-10-13 op BufferedReader, so streaming content is easy.
68 83c817b4 2021-10-13 op
69 83c817b4 2021-10-13 op However, `body-as-string!` needs to materialise the full reply, so in
70 83c817b4 2021-10-13 op case of a streaming request it will never return!
71 83c817b4 2021-10-13 op
72 83c817b4 2021-10-13 op
73 83c817b4 2021-10-13 op ## text/gemini
74 83c817b4 2021-10-13 op
75 83c817b4 2021-10-13 op This library only implements the network part of Gemini, it doesn't
76 83c817b4 2021-10-13 op try to handle any kind of content. To handle text/gemini you can use
77 83c817b4 2021-10-13 op e.g. the [gemtext][gemtext] library:
78 83c817b4 2021-10-13 op
79 83c817b4 2021-10-13 op ```clojure
80 83c817b4 2021-10-13 op user=> (require '[gemtext.core :as gemtext])
81 83c817b4 2021-10-13 op nil
82 83c817b4 2021-10-13 op user=> (gemini/with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
83 83c817b4 2021-10-13 op (gemtext/parse (:body req)))
84 83c817b4 2021-10-13 op [[:header-1 "Project Gemini"]
85 83c817b4 2021-10-13 op [:text ""]
86 83c817b4 2021-10-13 op [:header-2 "Overview"]
87 83c817b4 2021-10-13 op [:text ""]
88 83c817b4 2021-10-13 op [:text "Gemini is a new internet protocol which:"]
89 83c817b4 2021-10-13 op ,,,]
90 83c817b4 2021-10-13 op ```
91 83c817b4 2021-10-13 op
92 0ccdb5e9 2021-10-13 op The [gemtext][gemtext] library supports streaming via the
93 0ccdb5e9 2021-10-13 op `gemtext.core/parse` transducer:
94 83c817b4 2021-10-13 op
95 0ccdb5e9 2021-10-13 op ```clojure
96 0ccdb5e9 2021-10-13 op user=> (gemini/with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
97 0ccdb5e9 2021-10-13 op (transduce gemtext/parser conj [] (line-seq (:body req))))
98 0ccdb5e9 2021-10-13 op ,,,
99 0ccdb5e9 2021-10-13 op ```
100 0ccdb5e9 2021-10-13 op
101 0ccdb5e9 2021-10-13 op
102 83c817b4 2021-10-13 op [gemtext]: https://github.com/omar-polo/gemtext