diff options
author | June McEnroe <june@causal.agency> | 2020-04-13 15:21:32 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-04-13 15:21:32 -0400 |
commit | cdd739f0a31f08ff9dbb0bfa7796e271bc9fb58d (patch) | |
tree | a031262d3e705a1df92ec5912e4e09f8ed363d42 | |
parent | Use <content type="text"> in Atom (diff) | |
download | bubger-cdd739f0a31f08ff9dbb0bfa7796e271bc9fb58d.tar.gz bubger-cdd739f0a31f08ff9dbb0bfa7796e271bc9fb58d.zip |
Add <link> elements in Atom
-rw-r--r-- | atom.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/atom.c b/atom.c index d3463ce..0572cab 100644 --- a/atom.c +++ b/atom.c @@ -22,6 +22,8 @@ #include "archive.h" +const char *atomBaseURL; + static char *atomID(const struct Envelope *envelope) { struct Variable vars[] = { { "messageID", envelope->messageID }, @@ -47,27 +49,39 @@ static int atomAuthor(FILE *file, struct Address addr) { return templateRender(file, template, vars, escapeXML); } +static char *atomEntryURL(const struct Envelope *envelope) { + struct Variable vars[] = { + { "name", pathMangle(envelope->messageID) }, + {0}, + }; + return templateURL("/message/[name].mbox", vars); +} + int atomEntryOpen(FILE *file, const struct Envelope *envelope) { - // TODO: <link> to corresponding mbox, needs base URL. const char *template = TEMPLATE( <entry> <id>[id]</id> <title>[title]</title> <updated>[updated]</updated> + <link rel="alternate" type="application/mbox" href="[base][url]"/> ); char *id = atomID(envelope); char updated[sizeof("0000-00-00T00:00:00Z")]; strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&envelope->time)); + char *url = atomEntryURL(envelope); struct Variable vars[] = { { "id", id }, { "title", envelope->subject }, { "updated", updated }, + { "base", (atomBaseURL ? atomBaseURL : "") }, + { "url", url }, {0}, }; int error = 0 || templateRender(file, template, vars, escapeXML) || atomAuthor(file, envelope->from); free(id); + free(url); return error; } @@ -83,30 +97,51 @@ int atomEntryClose(FILE *file) { return templateRender(file, TEMPLATE(</entry>), NULL, NULL); } +static char *atomFeedURL(const struct Envelope *envelope, const char *type) { + struct Variable vars[] = { + { "name", pathMangle(envelope->messageID) }, + { "type", type }, + {0}, + }; + return templateURL("/thread/[name].[type]", vars); +} + int atomFeedOpen(FILE *file, const struct Envelope *envelope) { - // TODO: <link> to the corresponding HTML, mbox. const char *template = TEMPLATE( <[q]xml version="1.0" encoding="utf-8"[q]> <feed xmlns="http://www.w3.org/2005/Atom"> <id>[id]</id> <title>[title]</title> <updated>[updated]</updated> + <link rel="self" href="[base][atom]"/> + <link rel="alternate" type="text/html" href="[base][html]"/> + <link rel="alternate" type="application/mbox" href="[base][mbox]"/> ); char *id = atomID(envelope); time_t now = time(NULL); char updated[sizeof("0000-00-00T00:00:00Z")]; strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&now)); + char *atom = atomFeedURL(envelope, "atom"); + char *html = atomFeedURL(envelope, "html"); + char *mbox = atomFeedURL(envelope, "mbox"); struct Variable vars[] = { { "q", "?" }, { "id", id }, { "title", envelope->subject }, { "updated", updated }, + { "base", (atomBaseURL ? atomBaseURL : "") }, + { "atom", atom }, + { "html", html }, + { "mbox", mbox }, {0}, }; int error = 0 || templateRender(file, template, vars, escapeXML) || atomAuthor(file, envelope->from); free(id); + free(atom); + free(html); + free(mbox); return error; } |