user/dev discussion of public-inbox itself
 help / color / Atom feed
* [PATCH] doc: generate NEWS, NEWS.atom, and NEWS.html
@ 2019-10-06 23:31 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2019-10-06 23:31 UTC (permalink / raw)
  To: meta

We'll use our Documentation/RelNotes directory and internal APIs
to generate these files for website use (the website should be
completely reproducible).
---
 .gitignore                |   3 +
 Documentation/include.mk  |  25 +++++--
 Documentation/mknews.perl | 146 ++++++++++++++++++++++++++++++++++++++
 MANIFEST                  |   1 +
 4 files changed, 170 insertions(+), 5 deletions(-)
 create mode 100755 Documentation/mknews.perl

diff --git a/.gitignore b/.gitignore
index 6a44471f..66f165e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,6 @@
 *.8
 *.html
 *.gz
+/NEWS.html
+/NEWS.atom
+/NEWS
diff --git a/Documentation/include.mk b/Documentation/include.mk
index 55c10b51..65ba4e17 100644
--- a/Documentation/include.mk
+++ b/Documentation/include.mk
@@ -9,6 +9,7 @@ all::
 RSYNC = rsync
 RSYNC_DEST = public-inbox.org:/srv/public-inbox/
 MAN = man
+XMLSTARLET = xmlstarlet
 
 # same as pod2text
 COLUMNS = 76
@@ -91,8 +92,9 @@ manuals += $(m8)
 mantxt = $(addprefix Documentation/, $(addsuffix .txt, $(manuals)))
 docs += $(mantxt)
 dtxt += $(mantxt)
+docs += NEWS
 
-all :: $(mantxt)
+all :: $(docs)
 
 Documentation/%.txt : Documentation/%.pod
 	$(podtext) $< $@+ && touch -r $< $@+ && mv $@+ $@
@@ -103,16 +105,29 @@ txt2pre = $(PERL) -I lib ./Documentation/txt2pre <$< >$@+ && \
 Documentation/standards.txt : Documentation/standards.perl
 	$(PERL) $< >$@+ && touch -r $< $@+ && mv $@+ $@
 
+RELEASES =
+RELEASES += v1.1.0-pre1
+RELEASES += v1.0.0
+
+NEWS NEWS.atom NEWS.html : Documentation/RelNotes
+	$(PERL) -w Documentation/mknews.perl $@ $(RELEASES)
+
+# check for internal API changes:
+check :: NEWS check-NEWS.atom NEWS.html
+
+check-NEWS.atom: NEWS.atom
+	$(XMLSTARLET) val $<; e=$$?; test $$e -eq 0 || test $$e -eq 127
+
 Documentation/%.html: Documentation/%.txt
 	$(txt2pre)
 
 %.html: %
 	$(txt2pre)
 
-docs_html := $(addsuffix .html, $(subst .txt,,$(dtxt)) $(txt))
+docs_html := $(addsuffix .html, $(subst .txt,,$(dtxt)) $(txt)) NEWS.html
 html: $(docs_html)
 gz_docs := $(addsuffix .gz, $(docs) $(docs_html))
-rsync_docs := $(gz_docs) $(docs) $(docs_html)
+rsync_docs := $(gz_docs) $(docs) $(docs_html) NEWS.atom NEWS.atom.gz
 
 # external manpages which we host ourselves, since some packages
 # (currently just Xapian) doesn't host manpages themselves.
@@ -147,7 +162,7 @@ gz-doc: $(gz_docs)
 
 gz-xdoc: $(gz_xdocs)
 
-rsync-doc:
+rsync-doc: NEWS.atom.gz
 	# /usr/share/doc/rsync/scripts/git-set-file-times{.gz} on Debian systems
 	# It is also at: https://yhbt.net/git-set-file-times
 	-git set-file-times $(docs) $(txt)
@@ -156,7 +171,7 @@ rsync-doc:
 
 clean-doc:
 	$(RM) $(man1) $(man5) $(man7) $(man8) $(gz_docs) $(docs_html) $(mantxt)
-	$(RM) $(gz_xdocs) $(xdocs_html) $(xdocs)
+	$(RM) $(gz_xdocs) $(xdocs_html) $(xdocs) NEWS NEWS.atom NEWS.html
 
 clean :: clean-doc
 
diff --git a/Documentation/mknews.perl b/Documentation/mknews.perl
new file mode 100755
index 00000000..509da3b1
--- /dev/null
+++ b/Documentation/mknews.perl
@@ -0,0 +1,146 @@
+#!/usr/bin/perl -w
+# Copyright (C) 2019 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+# Generates NEWS, NEWS.atom, and NEWS.html files using release emails
+# this uses unstable internal APIs of public-inbox, and this script
+# needs to be updated if they change.
+use strict;
+use PublicInbox::MIME;
+use PublicInbox::View;
+use Plack::Util;
+use PublicInbox::MsgTime qw(msg_datestamp);
+use PublicInbox::MID qw(mids mid_escape);
+my $dst = shift @ARGV or die "Usage: $0 <NEWS|NEWS.atom|NEWS.html>";
+
+# newest to oldest
+my @releases = @ARGV;
+my $dir = 'Documentation/RelNotes';
+my $base_url = 'https://public-inbox.org/meta';
+my $html_url = 'https://public-inbox.org/NEWS.html';
+my $atom_url = 'https://public-inbox.org/NEWS.atom';
+my $addr = 'meta@public-inbox.org';
+
+my $latest = shift(@releases) or die 'no releases?';
+my $mime_latest = release2mime($latest);
+my $mtime = msg_datestamp($mime_latest->header_obj);
+my $tmp = "$dst+";
+my $out;
+if ($dst eq 'NEWS') {
+	open $out, '>', $tmp or die;
+	mime2txt($out, $mime_latest);
+	for my $v (@releases) {
+		print $out "\n" or die;
+		mime2txt($out, release2mime($v));
+	}
+} elsif ($dst eq 'NEWS.atom' || $dst eq 'NEWS.html') {
+	open $out, '>', $tmp or die;
+	my $ibx = Plack::Util::inline_object(
+		description => sub { 'public-inbox releases' },
+		over => sub { undef },
+		search => sub { 1 }, # for WwwStream:_html_top
+		base_url => sub { "$base_url/" },
+	);
+	$ibx->{-primary_address} = $addr;
+	my $ctx = {
+		-inbox => $ibx,
+		-upfx => "$base_url/",
+		-hr => 1,
+	};
+	if ($dst eq 'NEWS.html') {
+		html_start($out, $ctx);
+		mime2html($out, $mime_latest, $ctx);
+		while (defined(my $v = shift(@releases))) {
+			mime2html($out, release2mime($v), $ctx);
+		}
+		html_end($out, $ctx);
+	} elsif ($dst eq 'NEWS.atom') {
+		my $astream = atom_start($out, $ctx, $mtime);
+		for my $v (reverse(@releases)) {
+			mime2atom($out, $astream, release2mime($v), $ctx);
+		}
+		mime2atom($out, $astream, $mime_latest, $ctx);
+		print $out '</feed>' or die;
+	} else {
+		die "BUG: Unrecognized $dst\n";
+	}
+} else {
+	die "Unrecognized $dst\n";
+}
+
+close($out) or die;
+utime($mtime, $mtime, $tmp) or die;
+rename($tmp, $dst) or die;
+exit 0;
+
+sub release2mime {
+	my $f = "$dir/$_[0].eml";
+	open(my $fh, '<', $f) or die "open($f): $!";
+	PublicInbox::MIME->new(do { local $/; <$fh> });
+}
+
+sub mime2txt {
+	my ($out, $mime) = @_;
+	my $title = $mime->header_str('Subject');
+	$title =~ s/^\s*\[\w+\]\s*//g; # [ANNOUNCE] or [ANN]
+	my $dtime = msg_datestamp($mime->header_obj);
+	$title .= ' - ' . PublicInbox::View::fmt_ts($dtime) . ' UTC';
+	print $out $title, "\n" or die;
+	my $uline = '=' x length($title);
+	print $out $uline, "\n\n" or die;
+
+	my $mid = mids($mime)->[0];
+	print $out 'Link: ', $base_url, '/', mid_escape($mid), "/\n\n" or die;
+	print $out $mime->body_str or die;
+}
+
+sub mime2html {
+	my ($out, $mime, $ctx) = @_;
+	my $smsg = bless { mime => $mime }, 'PublicInbox::SearchMsg';
+	print $out PublicInbox::View::index_entry($smsg, $ctx, 1) or die;
+}
+
+sub html_start {
+	my ($out, $ctx) = @_;
+	require PublicInbox::WwwStream;
+	$ctx->{www} = Plack::Util::inline_object(style => sub { '' });
+	my $www_stream = PublicInbox::WwwStream->new($ctx);
+	print $out $www_stream->_html_top, '<pre>' or die;
+}
+
+sub html_end {
+	print $out <<EOF or die;
+	git clone $PublicInbox::WwwStream::CODE_URL
+</pre></body></html>
+EOF
+}
+
+sub atom_start {
+	my ($out, $ctx, $mtime) = @_;
+	require PublicInbox::WwwAtomStream;
+	# WwwAtomStream stats this dir for mtime
+	my $astream = PublicInbox::WwwAtomStream->new($ctx);
+	delete $ctx->{emit_header};
+	my $ibx = $ctx->{-inbox};
+	my $title = PublicInbox::WwwAtomStream::title_tag($ibx->description);
+	my $updated = PublicInbox::WwwAtomStream::feed_updated(gmtime($mtime));
+	print $out <<EOF or die;
+<?xml version="1.0" encoding="us-ascii"?>
+<feed
+xmlns="http://www.w3.org/2005/Atom"
+xmlns:thr="http://purl.org/syndication/thread/1.0">$title<link
+rel="alternate"
+type="text/html"
+href="$html_url"/><link
+rel="self"
+href="$atom_url"/><id>$atom_url</id>$updated
+EOF
+	$astream;
+}
+
+sub mime2atom  {
+	my ($out, $astream, $mime, $ctx) = @_;
+	my $smsg = bless { mime => $mime }, 'PublicInbox::SearchMsg';
+	if (defined(my $str = $astream->feed_entry($smsg))) {
+		print $out $str or die;
+	}
+}
diff --git a/MANIFEST b/MANIFEST
index b3046cf6..20dbdc54 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -13,6 +13,7 @@ Documentation/extman.perl
 Documentation/hosted.txt
 Documentation/include.mk
 Documentation/marketing.txt
+Documentation/mknews.perl
 Documentation/public-inbox-compact.pod
 Documentation/public-inbox-config.pod
 Documentation/public-inbox-convert.pod

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-06 23:31 [PATCH] doc: generate NEWS, NEWS.atom, and NEWS.html Eric Wong

user/dev discussion of public-inbox itself

Archives are clonable:
	git clone --mirror https://public-inbox.org/meta
	git clone --mirror http://czquwvybam4bgbro.onion/meta
	git clone --mirror http://hjrcffqmbrq6wope.onion/meta
	git clone --mirror http://ou63pmih66umazou.onion/meta

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.mail.public-inbox.meta
	nntp://ou63pmih66umazou.onion/inbox.comp.mail.public-inbox.meta
	nntp://czquwvybam4bgbro.onion/inbox.comp.mail.public-inbox.meta
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.mail.public-inbox.meta
	nntp://news.gmane.org/gmane.mail.public-inbox.general

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox