<feed xmlns='http://www.w3.org/2005/Atom'>
<title>9line.git/pim/cmd/caldavfs/rsvp.go, branch master</title>
<subtitle>random plan9 experiements
</subtitle>
<id>https://git.ceux.org/9line.git/atom?h=master</id>
<link rel='self' href='https://git.ceux.org/9line.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.ceux.org/9line.git/'/>
<updated>2026-08-22T20:48:07+00:00</updated>
<entry>
<title>pim: invite, and a way to say what you mean</title>
<updated>2026-08-22T20:48:07+00:00</updated>
<author>
<name>Calvin Morrison</name>
<email>calvin@pobox.com</email>
</author>
<published>2026-08-22T20:48:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ceux.org/9line.git/commit/?id=a071bf9a56241aa743e1be21bccbb4cb72b189f2'/>
<id>urn:sha1:a071bf9a56241aa743e1be21bccbb4cb72b189f2</id>
<content type='text'>
pim/invite makes an event and, when it names attendees, sends the
invitation -- which on a caldav server with auto-schedule is the same
act. -p writes the object to standard output instead, so it can go to
upas/marshal as iMIP, into a directory an ical/fs is serving, or
nowhere in particular. There is no separate verb for inviting because
to a calendar there is no separate thing.

It writes the tree's own key: value form rather than icalendar. The
first version spelled SUMMARY: by hand and got "lunch, then a walk"
wrong: a comma is a separator there and wants escaping. Parsing with
go-ical and generating by hand is the wrong asymmetry, so calfs grew
Compose, and now the same shape the tree emits is the shape it accepts.
The one UID we ever mint -- as organiser we own the event -- is minted
there too.

pim/invites lists what is waiting for an answer, which is what makes
pim/rsvp usable: it walks the date tree rather than every event, since
an invitation you never answered last March is not news.

agenda and show take -d date now, via seconds(1), which parses a human
date where date(1) only formats one.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>pim: answer an invitation by writing to a file</title>
<updated>2026-08-22T18:14:59+00:00</updated>
<author>
<name>Calvin Morrison</name>
<email>calvin@pobox.com</email>
</author>
<published>2026-08-22T18:14:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ceux.org/9line.git/commit/?id=ebfe721eb065be1d33a13e03e40426c4b3adfad0'/>
<id>urn:sha1:ebfe721eb065be1d33a13e03e40426c4b3adfad0</id>
<content type='text'>
echo ACCEPTED &gt;events/uuid/&lt;uid&gt;/partstat now does it, on a backend
that can. caldav/fs fetches the object, rewrites only our own ATTENDEE
line and PUTs it back with If-Match; fastmail advertises
calendar-auto-schedule, so that single PUT both updates the copy and
sends the iMIP to the organiser. caps says read rsvp schedule and means
all three.

Two things that cost an hour between them. go-webdav strips the quotes
off an ETag when it parses the header, but If-Match wants an
entity-tag: a bare hex string gets 412, which reads exactly like losing
a race to another client. And the tree kept serving the old answer
right after a successful write, because RSVP resynced the backend
without rebuilding anything; a file that lies immediately after you
wrote it is worse than one that is slow.

-R uid:PARTSTAT answers one invitation without serving, which is what a
pim/rsvp wrapper wants to call.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
