about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--atom.c120
1 files changed, 76 insertions, 44 deletions
diff --git a/atom.c b/atom.c
index 98f5866..80639a3 100644
--- a/atom.c
+++ b/atom.c
@@ -22,78 +22,110 @@
 
 #include "archive.h"
 
-static char *atomID(const char *messageID) {
+static char *atomID(const struct Envelope *envelope) {
 	struct Variable vars[] = {
-		{ "messageID", messageID },
+		{ "messageID", envelope->messageID },
 		{0},
 	};
 	return templateURL("mailto:?Message-Id=[messageID]", vars);
 }
 
-int atomEntryOpen(FILE *file, const struct Envelope *envelope) {
-	char *id = atomID(envelope->messageID);
-	char date[sizeof("0000-00-00T00:00:00Z")];
-	strftime(date, sizeof(date), "%FT%TZ", gmtime(&envelope->time));
+static int atomAuthor(FILE *file, struct Address addr) {
+	// TODO: Conditionally include <email>.
+	const char *template = TEMPLATE(
+		<author>
+			<name>[name]</name>
+			<email>[mailbox]@[host]</email>
+		</author>
+	);
 	struct Variable vars[] = {
-		{ "subject", envelope->subject },
-		{ "from.name", addressName(envelope->from) },
-		{ "from.mailbox", envelope->from.mailbox },
-		{ "from.host", envelope->from.host },
-		{ "date", date },
-		{ "id", id },
+		{ "name", addressName(addr) },
+		{ "mailbox", addr.mailbox },
+		{ "host", addr.host },
 		{0},
 	};
-	const char *Entry = TEMPLATE(
+	return templateRender(file, template, vars, escapeXML);
+}
+
+int atomEntryOpen(FILE *file, const struct Envelope *envelope) {
+	// TODO: <link> to corresponding mbox, needs base URL.
+	const char *template = TEMPLATE(
 		<entry>
-		<title>[subject]</title>
-		<author>
-			<name>[from.name]</name>
-			<email>[from.mailbox]@[from.host]</email>
-		</author>
-		<updated>[date]</updated>
 		<id>[id]</id>
+		<title>[title]</title>
+		<updated>[updated]</updated>
 	);
-	int error = templateRender(file, Entry, vars, escapeXML);
+	char *id = atomID(envelope);
+	char updated[sizeof("0000-00-00T00:00:00Z")];
+	strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&envelope->time));
+	struct Variable vars[] = {
+		{ "id", id },
+		{ "title", envelope->subject },
+		{ "updated", updated },
+		{0},
+	};
+	int error = 0
+		|| templateRender(file, template, vars, escapeXML)
+		|| atomAuthor(file, envelope->from);
 	free(id);
 	return error;
 }
 
-int atomEntryClose(FILE *file) {
-	int n = fprintf(file, "</entry>\n");
-	return (n < 0 ? n : 0);
+int atomContentOpen(FILE *file) {
+	const char *template = TEMPLATE(
+		<content type="html">
+		[<pre>]
+	);
+	struct Variable vars[] = {
+		{ "<pre>", "<pre>" },
+		{0},
+	};
+	return templateRender(file, template, vars, escapeXML);
 }
 
-int atomFeedOpen(FILE *file, const struct Envelope *envelope) {
-	char *id = atomID(envelope->messageID);
-	char date[sizeof("0000-00-00T00:00:00Z")];
-	strftime(date, sizeof(date), "%FT%TZ", gmtime(&(time_t) { time(NULL) }));
+int atomContentClose(FILE *file) {
+	const char *template = TEMPLATE(
+		[</pre>]
+		</content>
+	);
 	struct Variable vars[] = {
-		{ "subject", envelope->subject },
-		{ "from.name", addressName(envelope->from) },
-		{ "from.mailbox", envelope->from.mailbox },
-		{ "from.host", envelope->from.host },
-		{ "date", date },
-		{ "id", id },
-		{ "q", "?" },
+		{ "</pre>", "</pre>" },
 		{0},
 	};
-	const char *Feed = TEMPLATE(
+	return templateRender(file, template, vars, escapeXML);
+}
+
+int atomEntryClose(FILE *file) {
+	return templateRender(file, TEMPLATE(</entry>), NULL, NULL);
+}
+
+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">
-		<title>[subject]</title>
-		<author>
-			<name>[from.name]</name>
-			<email>[from.mailbox]@[from.host]</email>
-		</author>
-		<updated>[date]</updated>
 		<id>[id]</id>
+		<title>[title]</title>
+		<updated>[updated]</updated>
 	);
-	int error = templateRender(file, Feed, vars, escapeXML);
+	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));
+	struct Variable vars[] = {
+		{ "q", "?" },
+		{ "id", id },
+		{ "title", envelope->subject },
+		{ "updated", updated },
+		{0},
+	};
+	int error = 0
+		|| templateRender(file, template, vars, escapeXML)
+		|| atomAuthor(file, envelope->from);
 	free(id);
 	return error;
 }
 
 int atomFeedClose(FILE *file) {
-	int n = fprintf(file, "</feed>\n");
-	return (n < 0 ? n : 0);
+	return templateRender(file, TEMPLATE(</feed>), NULL, NULL);
 }