diff options
author | June McEnroe <june@causal.agency> | 2020-04-26 15:57:07 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-04-26 16:04:43 -0400 |
commit | 7953ea0aef6d6d7110c95f368c07c1ac8b6223b8 (patch) | |
tree | b10d55b0e940dd8a287cb5b51b732c0faef25ae5 | |
parent | Generate XHTML content in Atom entries (diff) | |
download | bubger-7953ea0aef6d6d7110c95f368c07c1ac8b6223b8.tar.gz bubger-7953ea0aef6d6d7110c95f368c07c1ac8b6223b8.zip |
Generate index.atom
Diffstat (limited to '')
-rw-r--r-- | archive.c | 9 | ||||
-rw-r--r-- | archive.h | 11 | ||||
-rw-r--r-- | atom.c | 58 | ||||
-rw-r--r-- | concat.c | 29 | ||||
-rw-r--r-- | html.c | 8 |
5 files changed, 81 insertions, 34 deletions
diff --git a/archive.c b/archive.c index af0329a..7aa6028 100644 --- a/archive.c +++ b/archive.c @@ -29,6 +29,9 @@ #define ENV_PASSWORD "BUBGER_IMAP_PASSWORD" +const char *baseURL = ""; +const char *baseTitle; + static uint32_t uidRead(const char *path) { FILE *file = fopen(path, "r"); if (!file) return 0; @@ -72,8 +75,8 @@ int main(int argc, char *argv[]) { break; case 'h': concatHead = optarg; break; case 'p': port = optarg; break; case 's': search = optarg; - break; case 't': htmlTitle = optarg; - break; case 'u': atomBaseURL = optarg; + break; case 't': baseTitle = optarg; + break; case 'u': baseURL = optarg; break; case 'v': imapVerbose = true; break; case 'w': passPath = optarg; } @@ -84,7 +87,7 @@ int main(int argc, char *argv[]) { if (!host) errx(EX_USAGE, "host required"); if (!user) errx(EX_USAGE, "user required"); - if (!htmlTitle) htmlTitle = mailbox; + if (!baseTitle) baseTitle = mailbox; char *pass = NULL; if (passPath) { diff --git a/archive.h b/archive.h index 136723b..9a0de12 100644 --- a/archive.h +++ b/archive.h @@ -188,14 +188,17 @@ int mboxFrom(FILE *file); int mboxHeader(FILE *file, const char *header); int mboxBody(FILE *file, const char *body); -extern const char *atomBaseURL; +extern const char *baseURL; +extern const char *baseTitle; + int atomEntryOpen(FILE *file, const struct Envelope *envelope); int atomContent(FILE *file, const char *content); int atomEntryClose(FILE *file); -int atomFeedOpen(FILE *file, const struct Envelope *envelope); -int atomFeedClose(FILE *file); +int atomThreadOpen(FILE *file, const struct Envelope *envelope); +int atomThreadClose(FILE *file); +int atomIndexOpen(FILE *file); +int atomIndexClose(FILE *file); -extern const char *htmlTitle; int htmlMessageOpen(FILE *file, const struct Envelope *envelope); int htmlInline(FILE *file, const struct BodyPart *part, const char *content); int htmlAttachmentOpen(FILE *file); diff --git a/atom.c b/atom.c index b0ee921..85393c9 100644 --- a/atom.c +++ b/atom.c @@ -22,8 +22,6 @@ #include "archive.h" -const char *atomBaseURL; - static char *atomID(const struct Envelope *envelope) { struct Variable vars[] = { { "messageID", envelope->messageID }, @@ -33,7 +31,6 @@ static char *atomID(const struct Envelope *envelope) { } static int atomAuthor(FILE *file, struct Address addr) { - // TODO: Conditionally include <email>. const char *template = TEMPLATE( <author> <name>[name]</name> @@ -51,11 +48,12 @@ static int atomAuthor(FILE *file, struct Address addr) { static char *atomEntryURL(const struct Envelope *envelope) { struct Variable vars[] = { + { "base", baseURL }, { "messageID", envelope->messageID }, { "type", "mbox" }, {0}, }; - return templateURL("/" PATH_MESSAGE, vars); + return templateURL("[base]/" PATH_MESSAGE, vars); } int atomEntryOpen(FILE *file, const struct Envelope *envelope) { @@ -64,7 +62,7 @@ int atomEntryOpen(FILE *file, const struct Envelope *envelope) { <id>[id]</id> <title>[title]</title> <updated>[updated]</updated> - <link rel="alternate" type="application/mbox" href="[base][url]"/> + <link rel="alternate" type="application/mbox" href="[url]"/> ); char *id = atomID(envelope); char updated[sizeof("0000-00-00T00:00:00Z")]; @@ -74,7 +72,6 @@ int atomEntryOpen(FILE *file, const struct Envelope *envelope) { { "id", id }, { "title", envelope->subject }, { "updated", updated }, - { "base", (atomBaseURL ? atomBaseURL : "") }, { "url", url }, {0}, }; @@ -105,39 +102,39 @@ int atomEntryClose(FILE *file) { return templateRender(file, TEMPLATE(</entry>), NULL, NULL); } -static char *atomFeedURL(const struct Envelope *envelope, const char *type) { +static char *atomThreadURL(const struct Envelope *envelope, const char *type) { struct Variable vars[] = { + { "base", baseURL }, { "messageID", envelope->messageID }, { "type", type }, {0}, }; - return templateURL("/" PATH_THREAD, vars); + return templateURL("[base]/" PATH_THREAD, vars); } -int atomFeedOpen(FILE *file, const struct Envelope *envelope) { +int atomThreadOpen(FILE *file, const struct Envelope *envelope) { 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]"/> + <link rel="self" href="[atom]"/> + <link rel="alternate" type="text/html" href="[html]"/> + <link rel="alternate" type="application/mbox" href="[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"); + char *atom = atomThreadURL(envelope, "atom"); + char *html = atomThreadURL(envelope, "html"); + char *mbox = atomThreadURL(envelope, "mbox"); struct Variable vars[] = { { "q", "?" }, { "id", id }, { "title", envelope->subject }, { "updated", updated }, - { "base", (atomBaseURL ? atomBaseURL : "") }, { "atom", atom }, { "html", html }, { "mbox", mbox }, @@ -153,6 +150,33 @@ int atomFeedOpen(FILE *file, const struct Envelope *envelope) { return error; } -int atomFeedClose(FILE *file) { +int atomThreadClose(FILE *file) { + return templateRender(file, TEMPLATE(</feed>), NULL, NULL); +} + +int atomIndexOpen(FILE *file) { + const char *template = TEMPLATE( + <[q]xml version="1.0" encoding="utf-8"[q]> + <feed xmlns="http://www.w3.org/2005/Atom"> + <id>[base]</id> + <title>[title]</title> + <updated>[updated]</updated> + <link rel="self" href="[base]/index.atom"/> + <link rel="alternate" type="text/html" href="[base]/index.html"/> + ); + time_t now = time(NULL); + char updated[sizeof("0000-00-00T00:00:00Z")]; + strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&now)); + struct Variable vars[] = { + { "q", "?" }, + { "base", (baseURL ? baseURL : "") }, + { "title", baseTitle }, + { "updated", updated }, + {0}, + }; + return templateRender(file, template, vars, escapeXML); +} + +int atomIndexClose(FILE *file) { return templateRender(file, TEMPLATE(</feed>), NULL, NULL); } diff --git a/concat.c b/concat.c index 8e165d2..7be35e0 100644 --- a/concat.c +++ b/concat.c @@ -169,7 +169,7 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { FILE *file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); - error = atomFeedOpen(file, envelope); + error = atomThreadOpen(file, envelope); if (error) err(EX_IOERR, "%s", path); for (size_t i = 0; i < flat.len; ++i) { @@ -178,7 +178,7 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { if (error) err(EX_IOERR, "%s", path); } - error = atomFeedClose(file) || fclose(file); + error = atomThreadClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); } @@ -230,6 +230,25 @@ static int compar(const void *_a, const void *_b) { } void concatIndex(struct List threads, const struct Envelope *envelopes) { + const char *path = "index.atom"; + FILE *file = fopen(path, "w"); + if (!file) err(EX_CANTCREAT, "%s", path); + + int error = atomIndexOpen(file); + if (error) err(EX_IOERR, "%s", path); + + struct List flat = {0}; + listFlatten(&flat, threads); + for (size_t i = flat.len - 1; i < flat.len; --i) { + uint32_t uid = dataCheck(flat.ptr[i], Number).number; + error = concatFile(file, uidPath(uid, "atom")); + if (error) err(EX_IOERR, "%s", path); + } + listFree(flat); + + error = atomIndexClose(file) || fclose(file); + if (error) err(EX_IOERR, "%s", path); + struct Sort *order = calloc(threads.len, sizeof(*order)); if (!order) err(EX_OSERR, "calloc"); @@ -245,11 +264,11 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { } qsort(order, threads.len, sizeof(*order), compar); - const char *path = "index.html"; - FILE *file = fopen(path, "w"); + path = "index.html"; + file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); - int error = htmlIndexHead(file); + error = htmlIndexHead(file); if (error) err(EX_IOERR, "%s", path); if (concatHead) { diff --git a/html.c b/html.c index 8f349e5..3bd192a 100644 --- a/html.c +++ b/html.c @@ -296,8 +296,6 @@ int htmlMessageClose(FILE *file) { return templateRender(file, TEMPLATE(</article>), NULL, NULL); } -const char *htmlTitle; - static char *htmlThreadURL(const struct Envelope *envelope, const char *type) { struct Variable vars[] = { { "messageID", envelope->messageID }, @@ -319,7 +317,7 @@ int htmlThreadHead(FILE *file, const struct Envelope *envelope) { char *mbox = htmlThreadURL(envelope, "mbox"); struct Variable vars[] = { { "subject", envelope->subject }, - { "title", htmlTitle }, + { "title", baseTitle }, { "atom", atom }, { "mbox", mbox }, {0}, @@ -421,7 +419,7 @@ int htmlIndexHead(FILE *file) { <link rel="alternate" type="application/atom+xml" href="index.atom"> ); struct Variable vars[] = { - { "title", htmlTitle }, + { "title", baseTitle }, {0}, }; return templateRender(file, template, vars, escapeXML); @@ -441,7 +439,7 @@ int htmlIndexOpen(FILE *file) { <ol> ); struct Variable vars[] = { - { "title", htmlTitle }, + { "title", baseTitle }, {0}, }; return templateRender(file, template, vars, escapeXML); |