]> Sergey Matveev's repositories - sgblog.git/blob - README.texi
Proper URL path escaping
[sgblog.git] / README.texi
1 \input texinfo
2 @documentencoding UTF-8
3 @settitle SGBlog
4
5 @copying
6 Copyright @copyright{} 2020 @email{stargrave@@stargrave.org, Sergey Matveev}
7 @end copying
8
9 @node Top
10 @top
11
12 SGBlog is minimalistic and simple Git-backed CGI/inetd
13 @url{https://en.wikipedia.org/wiki/Blog, blogging} and
14 @url{https://en.wikipedia.org/wiki/Phlog, phlogging} engine
15 with email-backed comments support, written on @url{https://golang.org/, Go}.
16
17 Its main competitive features:
18
19 @itemize
20 @item Single binary, responsible for both blog and phlog
21 @item @url{https://git-scm.com/, Git} DVCS as a storage for posts and comments
22 @item Single small @url{https://hjson.github.io/, Hjson} configuration file
23 @item Uses @url{https://en.wikipedia.org/wiki/Common_Gateway_Interface, CGI}
24     interface (simplicity, remember?) for dealing with HTTP-server
25 @item Uses @url{https://en.wikipedia.org/wiki/Inetd, inetd} interface
26     for working as @url{https://en.wikipedia.org/wiki/Gopher_(protocol), Gopher}
27     server
28 @item Topics (tags/categories) support
29 @item Supports on the fly generation of
30     @url{https://en.wikipedia.org/wiki/Atom_(feed), Atom} feeds
31     for posts, comments and per-post comments
32 @item Single binary for email-backed comments posting
33 @item If access is granted, then everyone can easily create an offline
34     copy of your blog/phlog!
35 @end itemize
36
37 All of that, except for comments, topics and phlog, could be achieved
38 with some Git viewer like @url{https://git.zx2c4.com/cgit/about/, cgit}.
39 But SGBlog also is able to:
40
41 @itemize
42 @item Convert URLs to clickable links
43 @item Convert SHA1-like hashes to blog links itself
44 @item Include relative @code{<link rel>} links for ease of navigation in
45     some browsers
46 @item @url{https://en.wikipedia.org/wiki/Gzip, gzip} compress both HTML
47     pages and Atom feeds
48 @item Respect @url{https://en.wikipedia.org/wiki/HTTP_ETag, ETag}
49     caching for both of them above
50 @end itemize
51
52 @url{http://blog.stargrave.org/example/, Here} is an example blog.
53
54 SGBlog is free software, licenced under
55 @url{https://www.gnu.org/licenses/agpl-3.0.html, GNU AGPLv3}:
56 see the file COPYING for copying conditions.
57
58 @menu
59 * Comments::
60 * Topics::
61 * Installation::
62 * Configuration::
63 @end menu
64
65 @node Comments
66 @unnumbered Comments
67
68 Comments are posted through the email interface, just by sending the
69 message to special address. For example:
70
71 @example
72 $ mutt "mailto:comment@@blog.example.com?subject=BlaBlaBla%20(576540a5b98517b46d0efc791bb90b9121bf147e)" <<EOF
73 This is the comments contents.
74 Could be multilined of course.
75 EOF
76 @end example
77
78 Comments are stored in Git as a @url{https://git-scm.com/docs/git-notes, note}.
79 Those objects could be updated without touching the base commit itself.
80
81 Each comment is just a plaintext with @code{From} and @code{Date}
82 headers. @code{From} is a name of email sender (with email address
83 stripped off).
84
85 Only @code{text/plain} or @code{multipart/signed+text/plain} email
86 messages are accepted and only with UTF-8, US-ASCII, ISO-8859-1
87 character sets. Sane people won't send HTML email anyway, but this is
88 just a precaution.
89
90 Comments are stored in @dfn{recfiles} --
91 @url{https://www.gnu.org/software/recutils/, GNU recutils}
92 human-editable plaintext database format. But they do not contain
93 records description:
94
95 @verbatim
96 %rec: Comment
97 %doc: SGBlog's comment
98 %mandatory: From Date Body
99 %type: Date date
100 @end verbatim
101
102 @node Topics
103 @unnumbered Topics
104
105 Each post can have any number of attached topics (also known as tags or
106 categories). They are whitespace separated single words kept in separate
107 @url{https://git-scm.com/docs/git-notes, note} namespace. You can
108 add/change comments with commands like:
109
110 @example
111 $ git notes --ref=topics add -m "linux hate" @@
112 @end example
113
114 @node Installation
115 @unnumbered Installation
116
117 SGBlog's is written on Go and uses its modules. Hopefully you can
118 install it just by running:
119
120 @example
121 $ go get go.stargrave.org/sgblog/cmd/sgblog
122 $ go get go.stargrave.org/sgblog/cmd/sgblog-comment-add # if you need commenting
123 @end example
124
125 Unfortunately by default it uses HTTPS and Go's third party servers
126 (@code{sum.golang.org}, @code{proxy.golang.org}) that trust neither
127 @code{CACert.org}'s CA (used previously) nor @code{ca.cypherpunks.ru}
128 CA. So either disable their usage and trust that certificate:
129 @code{GOPRIVATE=go.stargrave.org/sgblog}, or clone its source code
130 manually and build in place:
131 @url{git://git.stargrave.org/sgblog.git},
132 @url{https://git.stargrave.org/git/sgblog.git}.
133
134 For enabling blog availability you have to use HTTP server with CGI
135 interface. Example part of @url{http://www.lighttpd.net/, lighttpd}'s
136 configuration:
137
138 @example
139 $HTTP["host"] == "blog.example.com" @{
140   server.document-root = www_dir + "/blog.example.com"
141   $HTTP["url"] =~ "^/example" @{
142     alias.url += ("/example" => "/path/to/sgblog")
143     cgi.assign = ("sgblog" => "/path/to/sgblog")
144     setenv.add-environment = (
145       "SGBLOG_CFG" => "/path/to/example.hjson",
146     )
147   @}
148 @}
149 @end example
150
151 And be sure that you have read access to the Git repository, for example
152 by placing @code{lighttpd} user into @code{git} group.
153
154 Example @command{inetd} configuration (for phlog):
155
156 @example
157 gopher stream tcp  nowait lighttpd /path/to/sgblog sgblog -gopher /path/to/gopher.hjson
158 gopher stream tcp6 nowait lighttpd /path/to/sgblog sgblog -gopher /path/to/gopher.hjson
159 @end example
160
161 For comments workability you have to configure your SMTP server to feed
162 incoming messages to @command{sgblog-comment-add} utility. For example,
163 Postfix'es @file{/etc/aliases} can contain:
164
165 @example
166 comment: "| /path/to/sgblog-comment-add -git-dir /path/to/blog.git -committer-email comment@@blog.example.com"
167 @end example
168
169 to run that utility for all @code{comment@@} address messages.
170 You must have enough permission to be able to write to Git repository,
171 but Postfix by default runs all that commands from a @code{nobody} user.
172 So possibly you will need to @code{setuid} that executable give
173 permission for @code{nobody} running:
174
175 @example
176 -rwsr-x--- git:nobody sgblog-comment-add
177 @end example
178
179 And also do not forget about @code{lighttpd} user's (possibly in
180 @code{git} group) read permission permissions. Make sure
181 @command{sgblog-comment-add} runs with correctly set @code{-umask} (027
182 by default) for newly created Git objects/files.
183
184 @node Configuration
185 @unnumbered Configuration
186
187 SGBlog is configured via Hjson configuration file. More or less
188 self-describing blog configuration looks like that and contains many
189 optional fields:
190
191 @example
192 @{
193   GitPath: /home/sgblog/blog.git
194   Branch: refs/heads/example
195   Title: "Example blog"
196
197   BaseURL: http://blog.example.com
198   URLPrefix: /example
199
200   AtomId: "urn:uuid:54e6e53f-c615-48f1-812c-6f6b094ebbdd"
201   AtomAuthor: John Doe
202
203   # URL to CSS file, optional
204   CSS: /style.css
205   # Email address of the webmaster, optional
206   Webmaster: "webmaster@@example.com"
207   # URL to about page, optional
208   AboutURL: /
209   # Optional list of optional Git URLs for corresponding <link rel="vcs-git">
210   GitURLs: [
211     git://git.example.com/blog.git
212     https://git.example.com/git/blog.git
213   ]
214
215   # If that ref is set, then comments will be loaded from it
216   CommentsNotesRef: refs/notes/comments
217   # Display link for comment writing, if email is set
218   CommentsEmail: something@@example.com
219
220   # If that ref is set, then topics will be loaded from it
221   TopicsNotesRef: refs/notes/topics
222   # Optional file for topics state caching
223   TopicsCachePath: /path/to/sgblog-topics-cache.gob
224 @}
225 @end example
226
227 Gopher configuration can use the same file, but it requires much less
228 options:
229
230 @example
231 @{
232   GitPath: /home/sgblog/blog.git
233   Branch: refs/heads/example
234   Title: "Example blog"
235
236   GopherDomain: phlog.example.com
237
238   AboutURL: http://blog.example.com/
239
240   # Both are optional
241   CommentsNotesRef: refs/notes/comments
242   CommentsEmail: something@@example.com
243
244   # Both are optional too
245   TopicsNotesRef: refs/notes/topics
246   TopicsCachePath: /path/to/sgblog-topics-cache.gob
247 @}
248 @end example
249
250 @bye