shithub: atom

Download patch

ref: cbbeb61a6f8a34958c4eb9f88b9de034206fa6b7
author: Moody <j4kem00dy@gmail.com>
date: Mon Sep 21 05:40:06 EDT 2020

Initial commit

--- /dev/null
+++ b/atom.1
@@ -1,0 +1,45 @@
+.TH ATOM 1
+.SH NAME
+atom \- atom feed generator
+.SH SYNOPSIS
+.B atom
+[
+.B -n
+.I name
+] [
+.B -i
+.I id
+] title link path
+.SH DESCRIPTION
+.I Atom
+is a not quite RFC4287 compliant atom feed generator.
+.I Atom
+takes a feed title, base url, and directory path
+and creates one feed entry per file within the directory.
+The generated atom feed is printed on standard output.
+Each entry is expected to live at the concatination of
+the feed url and the last member of the files path. Entry
+titles are generated by stripping their file extension.
+The feed updated time is set to the current time, while
+each entry's udpated field is set to the files mtime.
+Each flag modifies the meta information of the feed,
+.I name
+and
+.I id
+default to glenda and '9front atom' respectively.
+.SH DIAGNOSTICS
+The ID for each entry is taken from its Qid path.
+All timestamps are reported in UTC.
+.br
+
+The lack of compliance is due to whitespace issues with how
+.IR xml(2)
+outputs, most atom implementations that use generic xml
+parsers seem to work fine.
+.SH SOURCE
+https://git.sr.ht/~moody/atom
+.SH BUGS
+You tell me.
+.SH SEE ALSO
+.IR xml(2),
+https://tools.ietf.org/html/rfc4287
--- /dev/null
+++ b/atom.c
@@ -1,0 +1,110 @@
+#include <u.h>
+#include <libc.h>
+#include <xml.h>
+
+Xml *x;
+Tzone *tz;
+Elem *feed;
+
+char*
+unix2date(vlong abs)
+{
+	Tm tm;
+
+	tmtime(&tm, abs, tz);
+	return smprint("%τ", tmfmt(&tm, "YYYY-MM-DDThh:mm:ssZ"));
+}
+
+void
+initmeta(char *title, char *link, char *author, char *id)
+{
+	Elem *e;
+
+	feed = xmlelem(x, &x->root, nil, "feed");
+	xmlattr(x, &feed->attrs, feed, "xmlns", "http://www.w3.org/2005/Atom");
+
+	e = xmlelem(x, &feed->child, feed, "title");
+	e->pcdata = title;
+
+	e = xmlelem(x, &feed->child, feed, "link");
+	xmlattr(x, &e->attrs, e, "href", link);
+
+	e = xmlelem(x, &feed->child, feed, "updated");
+	e->pcdata = unix2date(time(nil));
+
+	e = xmlelem(x, &feed->child, feed, "author");
+	e = xmlelem(x, &e->child, e, "name");
+	e->pcdata = author;
+
+	e = xmlelem(x, &feed->child, feed, "id");
+	e->pcdata = id;
+}
+
+void
+addentry(Dir *d, char *prefix)
+{
+	Elem *e, *entry;
+	char *dot;
+
+	entry = xmlelem(x, &feed->child, feed, "entry");
+
+	e = xmlelem(x, &entry->child, entry, "title");
+	e->pcdata = strdup(d->name);
+	if((dot = strrchr(e->pcdata, '.')) != nil)
+		*dot = '\0';
+
+	e = xmlelem(x, &entry->child, entry, "link");
+	xmlattr(x, &e->attrs, e, "href", smprint("%s/%s", prefix, d->name));
+
+	e = xmlelem(x, &entry->child, entry, "id");
+	e->pcdata = smprint("%ulld", d->qid.path);
+
+	e = xmlelem(x, &entry->child, entry, "updated");
+	e->pcdata = unix2date(d->mtime);
+}
+
+void
+usage(void)
+{
+	fprint(2, "Usage: %s [-n name] [-i id] title link dir\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *name, *id;
+	Dir *files;
+	long n, i;
+	int fd;
+
+	id = "9front atom";
+	name = "glenda";
+
+	ARGBEGIN {
+	case 'n':
+		name = EARGF(usage());
+		break;
+	case 'i':
+		id = EARGF(usage());
+		break;
+	} ARGEND
+
+	if(argc < 3)
+		usage();
+
+	tmfmtinstall();
+	tz = tzload(nil);
+	x = xmlnew(8192);
+
+	fd = open(argv[2], OREAD);
+	if(fd < 0)
+		sysfatal("failed to read dir: %r");
+
+	n = dirreadall(fd, &files);
+	initmeta(argv[0], argv[1], name, id);
+	for(i=0;i<n;i++)
+		addentry(files+i, argv[1]);
+
+	xmlprint(x, 1);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,7 @@
+</$objtype/mkfile
+BIN=/usr/moody/bin/amd64
+
+TARG=atom
+OFILES=atom.$O
+
+</sys/src/cmd/mkone