Documentation/design_www.txt | 31 ++++++++++++++++++-------------
lib/PublicInbox/Feed.pm | 92 ++++++++++++++++++++++++++++++++++++++---------------
lib/PublicInbox/View.pm | 3 ++-
lib/PublicInbox/WWW.pm | 13 +++++++++++++
t/cgi.t | 12 ++++++++++++
diff --git a/Documentation/design_www.txt b/Documentation/design_www.txt
index 55e9268c90506135009d1212c70c1a8e3f196ae0..d25afca3f911082de6b367da8bee061ba29de18e 100644
--- a/Documentation/design_www.txt
+++ b/Documentation/design_www.txt
@@ -6,25 +6,30 @@ /$LISTNAME/?r=$GIT_COMMIT -> HTML only
/$LISTNAME/atom.xml -> Atom feed
#### Optional, relies on Search::Xapian
-/$LISTNAME/t/$MESSAGE_ID.html -> HTML content of thread
+/$LISTNAME/t/$MESSAGE_ID/ -> HTML content of thread
+/$LISTNAME/t/$MESSAGE_ID/atom -> Atom feed for thread
+/$LISTNAME/t/$MESSAGE_ID/mbox.gz -> gzipped mbox of thread
### Stable endpoints
-/$LISTNAME/m/$MESSAGE_ID.html -> HTML content (short quotes)
-/$LISTNAME/m/$MESSAGE_ID.txt -> raw mbox
-/$LISTNAME/m/$MESSAGE_ID -> 301 to .html version
-/$LISTNAME/f/$MESSAGE_ID.html -> HTML content (full quotes)
-/$LISTNAME/f/$MESSAGE_ID -> 301 to .html version
-/$LISTNAME/f/$MESSAGE_ID.txt -> 301 to ../m/$MESSAGE_ID.txt
+/$LISTNAME/m/$MESSAGE_ID/ -> HTML content (short quotes)
+/$LISTNAME/m/$MESSAGE_ID -> 301 to above
+/$LISTNAME/m/$MESSAGE_ID/raw -> raw mbox
+/$LISTNAME/f/$MESSAGE_ID/ -> HTML content (full quotes)
+/$LISTNAME/f/$MESSAGE_ID -> 301 to above
+/$LISTNAME/f/$MESSAGE_ID/raw (*) -> 301 to ../m/$MESSAGE_ID/raw
+
+### Legacy endpoints (may be ambiguous given Message-IDs with similar suffies)
+/$LISTNAME/m/$MESSAGE_ID.html -> 301 to $MESSAGE_ID/
+/$LISTNAME/m/$MESSAGE_ID.txt -> 301 to $MESSAGE_ID/raw
+/$LISTNAME/f/$MESSAGE_ID.html -> 301 to $MESSAGE_ID/
+/$LISTNAME/f/$MESSAGE_ID.txt (*) -> 301 to ../m/$MESSAGE_ID/raw
+
FIXME: we must refactor/cleanup/add tests for most of our CGI before
adding more endpoints and features.
-Maybe TODO (these might be expensive)
--------------------------------------
-/$LISTNAME/t/$MESSAGE_ID.mbox -> mbox content of thread
-
-We use file name suffixes on all of these (except /) so URLs may easily
-cached/memoized using a static file server.
+(*) These URLs were never linked, but only exist as a convenience to folks
+ who edit existing URLs
Encoding notes
--------------
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 3540e9a49e73704f1ced02d9fcedeb96c064ac17..1fef98491e35fc7d9426dca7cbab918eedd5e4b2 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -9,7 +9,7 @@ use Date::Parse qw(strptime);
use PublicInbox::Hval;
use PublicInbox::GitCatFile;
use PublicInbox::View;
-use PublicInbox::MID qw/mid_clean mid_compress/;
+use PublicInbox::MID qw/mid_clean mid_compress mid2path/;
use POSIX qw/strftime/;
use constant {
DATEFMT => '%Y-%m-%dT%H:%M:%SZ', # atom standard
@@ -25,6 +25,11 @@ my ($ctx) = @_;
sub { emit_atom($_[0], $ctx) };
}
+sub generate_thread_atom {
+ my ($ctx) = @_;
+ sub { emit_atom_thread($_[0], $ctx) };
+}
+
sub generate_html_index {
my ($ctx) = @_;
sub { emit_html_index($_[0], $ctx) };
@@ -32,15 +37,22 @@ }
# private subs
-sub atom_header {
- my ($feed_opts) = @_;
- my $title = $feed_opts->{description};
+sub title_tag {
+ my ($title) = @_;
+ # try to avoid the type attribute in title:
$title = PublicInbox::Hval->new_oneline($title)->as_html;
my $type = index($title, '&') >= 0 ? "\ntype=\"html\"" : '';
+ "