@settitle SGBlog
@copying
-Copyright @copyright{} 2020 @email{stargrave@@stargrave.org, Sergey Matveev}
+Copyright @copyright{} 2020-2024 @email{stargrave@@stargrave.org, Sergey Matveev}
@end copying
@node Top
-@top
+@top SGBlog
-SGBlog is minimalistic and simple Git-backed CGI/inetd
-@url{https://en.wikipedia.org/wiki/Blog, blogging} and
-@url{https://en.wikipedia.org/wiki/Phlog, phlogging} engine
-with email-backed comments support, written on @url{https://golang.org/, Go}.
+SGBlog is minimalistic and simple Git-backed CGI/UCSPI
+@url{https://en.wikipedia.org/wiki/Blog, blogging} (@code{http://}/@code{https://}),
+@url{https://en.wikipedia.org/wiki/Phlog, phlogging} (@code{gopher://}),
+@url{https://twtxt.readthedocs.io/en/latest/index.html, twtxting}, and
+@url{https://en.wikipedia.org/wiki/Gemini_(protocol), gemlogging} (@code{gemini://})
+engine with email-backed comments support,
+written on @url{https://go.dev/, Go}.
Its main competitive features:
@itemize
-@item Single binary, responsible for both blog and phlog
+@item Single binary, responsible for both blog, phlog and gemlog
@item @url{https://git-scm.com/, Git} DVCS as a storage for posts and comments
@item Single small @url{https://hjson.github.io/, Hjson} configuration file
@item Uses @url{https://en.wikipedia.org/wiki/Common_Gateway_Interface, CGI}
interface (simplicity, remember?) for dealing with HTTP-server
-@item Uses @url{https://en.wikipedia.org/wiki/Inetd, inetd} interface
- for working as @url{https://en.wikipedia.org/wiki/Gopher_(protocol), Gopher}
- server
+@item Uses
+ @url{https://en.wikipedia.org/wiki/Inetd, inetd}/@url{http://cr.yp.to/ucspi-tcp.html, UCSPI-TCP}
+ interface for working as
+ @url{https://en.wikipedia.org/wiki/Gopher_(protocol), Gopher} server
+@item Topics (tags/categories) support
+@item Images linking support
@item Supports on the fly generation of
@url{https://en.wikipedia.org/wiki/Atom_(feed), Atom} feeds
for posts, comments and per-post comments
@item Single binary for email-backed comments posting
@item If access is granted, then everyone can easily create an offline
- copy of your blog/phlog!
+ copy of your blog/phlog/gemlog!
@end itemize
-All of that, except for comments and phlog, could be achieved with some
-Git viewer like @url{https://git.zx2c4.com/cgit/about/, cgit}. But
-SGBlog also is able to:
+All of that, except for comments, topics and phlog/gemlog, could be achieved
+with some Git viewer like @url{https://git.zx2c4.com/cgit/about/, cgit}.
+But SGBlog also is able to:
@itemize
@item Convert URLs to clickable links
@url{https://www.gnu.org/licenses/agpl-3.0.html, GNU AGPLv3}:
see the file COPYING for copying conditions.
-@menu
-* Comments::
-* Installation::
-* Configuration::
-@end menu
-
@node Comments
@unnumbered Comments
message to special address. For example:
@example
-mutt "mailto:comment@@blog.example.com?subject=576540a5b98517b46d0efc791bb90b9121bf147e" <<EOF
+$ mutt "mailto:comment@@blog.example.com?subject=BlaBlaBla%20(576540a5b98517b46d0efc791bb90b9121bf147e)" <<EOF
This is the comments contents.
Could be multilined of course.
EOF
headers. @code{From} is a name of email sender (with email address
stripped off).
-Technically comments are stored in concatenated
-@url{https://en.wikipedia.org/wiki/Netstring, netstring}. Only
-@code{text/plain} or @code{multipart/signed+text/plain} email messages
-are accepted and only with UTF-8, US-ASCII, ISO-8859-1 character sets.
-Sane people won't send HTML email anyway, but this is just a precaution.
+Only @code{text/plain} or @code{multipart/signed+text/plain} email
+messages are accepted and only with UTF-8, US-ASCII, ISO-8859-1
+character sets. Sane people won't send HTML email anyway, but this is
+just a precaution.
+
+Comments are stored in @dfn{recfiles} --
+@url{https://www.gnu.org/software/recutils/, GNU recutils}
+human-editable plaintext database format. But they do not contain
+records description:
+
+@verbatim
+%rec: Comment
+%doc: SGBlog's comment
+%mandatory: From Date Body
+%type: Date date
+@end verbatim
+
+@node Topics
+@unnumbered Topics
+
+Each post can have any number of attached topics (also known as tags or
+categories). They are whitespace separated single words kept in separate
+@url{https://git-scm.com/docs/git-notes, note} namespace. You can
+add/change comments with commands like:
+
+@example
+$ git notes --ref=topics add -m "linux hate" @@
+$ git push origin mybranch refs/notes/topics
+@end example
+
+To reset incorrectly added topic:
+
+@example
+$ git update-ref refs/notes/topics refs/notes/topics^
+@end example
+
+@node Images
+@unnumbered Images
+
+You can link any number of image files with your post. You need to put
+them in a directory (@code{ImgPath} configuration file's option) which
+path is equal to your post's hash, with two subdirectory levels. For
+example directory for post @code{3e12180dd2b6fb3b44c77c365d355d5a3796a43f}
+will be @code{ImgPath/3e/12/180dd2b6fb3b44c77c365d355d5a3796a43f}.
+Filenames are lexically sorted. Filename without an extension will be
+image's alternative text. Currently only @file{.jxl} and @file{.webp}
+are recognized. @code{ImgDomain} configuration file's option will be
+used to construct URL to @code{//ImgDomain/3e/12/180dd2b6fb3b44c77c365d355d5a3796a43f}.
@node Installation
@unnumbered Installation
Unfortunately by default it uses HTTPS and Go's third party servers
(@code{sum.golang.org}, @code{proxy.golang.org}) that trust neither
@code{CACert.org}'s CA (used previously) nor @code{ca.cypherpunks.ru}
-CA. So either disable their usage and trust that certificate:
+CAs. So either disable their usage and trust that certificate:
@code{GOPRIVATE=go.stargrave.org/sgblog}, or clone its source code
manually and build in place:
@url{git://git.stargrave.org/sgblog.git},
-@url{https://git.stargrave.org/git/sgblog.git}.
+@url{https://git.stargrave.org/sgblog.git}.
For enabling blog availability you have to use HTTP server with CGI
interface. Example part of @url{http://www.lighttpd.net/, lighttpd}'s
Example @command{inetd} configuration (for phlog):
@example
-gopher stream tcp nowait lighttpd /path/to/sgblog sgblog -gopher /path/to/gopher.hjson
gopher stream tcp6 nowait lighttpd /path/to/sgblog sgblog -gopher /path/to/gopher.hjson
@end example
+Example @command{UCSPI-TCP} service running under
+@url{http://cr.yp.to/daemontools.html, daemontools}:
+
+@example
+# mkdir -p /var/service/.phlog-ipv6/log
+# cd /var/service/.phlog-ipv6
+
+# cat > run <<EOF
+#!/bin/sh -e
+uid=\`id -u lighttpd\`
+gid=\`id -g git\`
+addr=2001::123
+exec tcpserver -DHR -u $uid -g $gid -l 0 $addr gopher \
+ sgblog -gopher /path/to/gopher.hjson
+EOF
+
+# cat > log/run <<EOF
+#!/bin/sh -e
+exec setuidgid whatever-user multilog t ./main
+EOF
+
+# chmod -R 755 /var/service/.phlog-ipv6
+# mv /var/service/.phlog-ipv6 /var/service/phlog-ipv6
+@end example
+
+Gemlog uses Gemini protocol that requires TLS usage, that can be
+achieved with @url{go.cypherpunks.ru/ucspi} tools:
+
+@example
+exec tcpserver -DRH -u $uid -g $gid -l 0 ::0 1965 \
+ tlss -key gemlog.key.pem -cert gemlog.pem \
+ sgblog -gemini /home/sgblog/gemlog.hjson 2>&1
+@end example
+
For comments workability you have to configure your SMTP server to feed
incoming messages to @command{sgblog-comment-add} utility. For example,
Postfix'es @file{/etc/aliases} can contain:
CommentsNotesRef: refs/notes/comments
# Display link for comment writing, if email is set
CommentsEmail: something@@example.com
+
+ # If that ref is set, then topics will be loaded from it
+ TopicsNotesRef: refs/notes/topics
+ # Optional file for topics state caching
+ TopicsCachePath: /path/to/sgblog-topics-cache.gob
+
+ # If set, then images are searched in XX/YY/ZZZ...ZZZ directory
+ ImgPath: /path/to/directory/with/images
+ ImgDomain: img.blog.example.com
@}
@end example
# Both are optional
CommentsNotesRef: refs/notes/comments
CommentsEmail: something@@example.com
+
+ # Both are optional too
+ TopicsNotesRef: refs/notes/topics
+ TopicsCachePath: /path/to/sgblog-topics-cache.gob
@}
@end example