From 1d42abf23d59de9684c80c290c4498d81ce9977b Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Thu, 23 Dec 2021 17:41:30 +0700 Subject: Add initial commenting support --- .gitignore | 1 + _css/style.css | 11 ++++++- _layout/page_foot.html | 12 ++++---- _libs/formbox/comment.html | 7 +++++ _libs/formbox/comment.xml | 1 - _libs/formbox/format | 71 ++++++++++++++++++++++++++++++++++++++++++++++ _rss/comments.xml | 11 +++++-- _rss/head.xml | 4 +-- _rss/item.xml | 6 ++-- index.md | 2 +- utils.jl | 24 +++++++++++----- 11 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 _libs/formbox/comment.html create mode 100755 _libs/formbox/format diff --git a/.gitignore b/.gitignore index 2355507..0a3ca5a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ __site/ _css/fonts/ _css/katex.min.css _libs/fediring +_libs/formbox/mbox _libs/highlight/ _libs/katex/ _libs/openring/out.html diff --git a/_css/style.css b/_css/style.css index 790c177..af502d7 100644 --- a/_css/style.css +++ b/_css/style.css @@ -204,7 +204,7 @@ code, .hljs { padding: 0.1em 0.2em; } -.hljs { +.hljs, .comment pre > code { display: block; line-height: 1.45em; overflow-x: auto; @@ -227,6 +227,15 @@ code, .hljs { .hljs-selector-pseudo, .hljs-template-tag, .hljs-template-variable, .hljs-addition { color: var(--red) } +.comment { + background-color: #8881; + clear: both; + margin: 1ex 0; + overflow: hidden; + padding: 1ex; +} +.comment p { margin: 1ex } + .openring { display: flex; flex-wrap: wrap; diff --git a/_layout/page_foot.html b/_layout/page_foot.html index 848d42e..88d33ea 100644 --- a/_layout/page_foot.html +++ b/_layout/page_foot.html @@ -1,11 +1,11 @@ {{isnotempty tags}}Tags:{{for tag in tags}} {{tag}}{{end}} —{{isempty rss}}{{author}}, - {{else}}{{mailto_comment}}, {{end}}{{date}}
{{end}} + {{else}}{{author}}, + {{end}}{{date}}
{{end}} -{{isnotempty rss}}
-

Comments

-

To reply, follow the mailto link - in the the author's name.

-
{{end}} +{{isnotempty rss}}

Comments

+{{comments_rendered}} +

To reply, follow the mailto link + in the the author's name.

{{end}} {{insert footer.html}} diff --git a/_libs/formbox/comment.html b/_libs/formbox/comment.html new file mode 100644 index 0000000..60459d9 --- /dev/null +++ b/_libs/formbox/comment.html @@ -0,0 +1,7 @@ +
+ {body} +

—{author}, + {date}

+ {children} +
diff --git a/_libs/formbox/comment.xml b/_libs/formbox/comment.xml index 2078071..5f183a0 100644 --- a/_libs/formbox/comment.xml +++ b/_libs/formbox/comment.xml @@ -4,7 +4,6 @@ {date} {author} On {date}, {author} wrote: - {subject} {children} diff --git a/_libs/formbox/format b/_libs/formbox/format new file mode 100755 index 0000000..39e6132 --- /dev/null +++ b/_libs/formbox/format @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# Format mbox as HTML/XML +# Copyright (C) 2021 Nguyễn Gia Phong +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from argparse import ArgumentParser +from email.header import decode_header +from email.utils import parsedate_to_datetime +from functools import partial +from itertools import starmap +from mailbox import mbox +from pathlib import Path +from urllib.parse import quote + +from bleach import clean, linkify +from markdown import markdown + +sanitise = partial(clean, tags=('a', 'code', 'em', 'strong', 'sub', 'sup', + 'blockquote', 'p', 'pre', 'ul', 'ol', 'li'), + protocols=('ftp', 'gemini', 'gopher', 'http', 'https', + 'irc', 'ircs', 'mailto', 'matrix', 'xmpp')) + + +def extract(archive, parent): + for message_id, message in archive.copy().items(): + # TODO: handle multipart + if message['In-Reply-To'] != parent: continue + archive.pop(message_id) + yield message, extract(archive, message_id) + + +def decode(header): + for string, charset in decode_header(header): + encoding = 'utf-8' if charset is None else charset + yield string.decode(encoding) + + +def render(template, forest, parent): + for self, children in forest: + message_id = self['Message-Id'] + date = parsedate_to_datetime(self['Date']).date().isoformat() + author, address = decode(self['From']) + body = sanitise(linkify(markdown(self.get_payload(), + output_format='html5'))) + rendered_children = render(template, children, message_id) + yield template.format(message_id=quote(message_id), + date=date, author=author, body=body, + children='\n'.join(rendered_children)) + + +parser = ArgumentParser() +parser.add_argument('mbox') +parser.add_argument('id') +parser.add_argument('template', type=Path) +args = parser.parse_args() + +archive = {m['Message-Id']: m for m in mbox(args.mbox)} +template = args.template.read_text() +print(*render(template, extract(archive, args.id), args.id), sep='', end='') diff --git a/_rss/comments.xml b/_rss/comments.xml index be8fa6c..13d514b 100644 --- a/_rss/comments.xml +++ b/_rss/comments.xml @@ -4,7 +4,14 @@ xmlns:content="http://purl.org/rss/1.0/modules/content" xmlns:dc="http://purl.org/dc/elements/1.1"> -Comments on {{fd2rss rss_title}} +Re: {{fd2rss rss_title}} {{fd_full_url}} - + +Comments on {{fd2rss rss_title}} +en Formbox +{{comment_rss_items}} + + diff --git a/_rss/head.xml b/_rss/head.xml index 929038f..e27fe5e 100644 --- a/_rss/head.xml +++ b/_rss/head.xml @@ -6,9 +6,7 @@ {{website_title}} {{website_url}} - + {{website_description}} en diff --git a/_rss/item.xml b/_rss/item.xml index 76f892a..8a808ff 100644 --- a/_rss/item.xml +++ b/_rss/item.xml @@ -5,10 +5,8 @@ {{fd2rss rss_description}} {{for tag in tags}}{{tag}}{{end}} {{RFC822 rss_pubdate}} - - Reply]]> - + Reply via email]]> {{comment_rss}} diff --git a/index.md b/index.md index d360f1d..1c1166b 100644 --- a/index.md +++ b/index.md @@ -15,7 +15,7 @@ in the [Fediverse][]: * Matrix: [@cnx:halogen.city] [^culture]: Not necessarily mutually exclusive -[^xmpp]: Also XMPP, but mostly inactive +[^xmpp]: Or XMPP where I'm rarely active [^pgp]: PGP: [27148B2C06A2224B], also on [OpenPGP] [My name is]: https://www.youtube.com/watch?v=LDj8kkVwisY diff --git a/utils.jl b/utils.jl index 5a6e1c4..81c56fa 100644 --- a/utils.jl +++ b/utils.jl @@ -11,19 +11,32 @@ function hfun_abslink(args) end dir_url() = strip(dirname(locvar(:fd_url)), '/') -message_id() = @sprintf("<%s@cnx>", dir_url()) +message_id() = "<$(dir_url())@cnx>" hfun_comments() = @sprintf("https://lists.sr.ht/~cnx/site?search=%s:%s", "In-Reply-To", message_id()) +function render_comments(template) + prefix = joinpath(path(:libs), "formbox") + format = joinpath(prefix, "format") + mbox = joinpath(prefix, "mbox") + template_path = joinpath(prefix, template) + readchomp(`python3 $format $mbox $(message_id()) $template_path`) +end + +hfun_comments_rendered() = render_comments("comment.html") + function hfun_comment_rss() rpath = joinpath(dir_url(), "comments.xml") open(joinpath(path(:site), rpath), "w") do feed write(feed, convert_html(readchomp(joinpath(path(:rss), "comments.xml")))) - #write(feed, read(`python3 formbox.py mbox $(message_id()) $item_template`, String)) end joinpath(globvar(:website_url), rpath) end +hfun_comment_rss_feed_url() = joinpath(dirname(locvar(:fd_full_url)), + "comments.xml") +hfun_comment_rss_items() = render_comments("comment.xml") + function hfun_fediring(args) adj = readlines(joinpath(path(:libs), "fediring"))[parse(Int, args[1])] "$(args[2])" @@ -33,11 +46,8 @@ hfun_github(args) = "@$(args[1])" hfun_job_url() = get(ENV, "JOB_URL", "https://builds.sr.ht/~cnx/site") function hfun_mailto_comment() - @sprintf("%s", - "~cnx/site@lists.sr.ht", - "In-Reply-To", message_id(), - "Subject", locvar(:title), - globvar(:author)) + @sprintf("mailto:%s?%s=%s&%s=Re: %s", "~cnx/site@lists.sr.ht", + "In-Reply-To", message_id(), "Subject", locvar(:title)) end hfun_openring() = readchomp(joinpath(path(:libs), "openring", "out.html")) -- cgit 1.4.1