#!/bin/rc # pim/invite -- make an event, and invite people to it. # # pim/invite -c fastmail 'catch up' '2026-08-28 15:00' 30 # pim/invite -c fastmail -a bob@example.com -l 'the wire' \ # 'design review' 'tomorrow 14:00' 60 # # What this really does is write an icalendar object. Where it goes is # somebody else's business: # # -p writes it to standard output, so you can mail it yourself # (upas/marshal -t 'text/calendar; method=REQUEST'), keep it, # or drop it in a directory some ical/fs is serving # otherwise it goes to the calendar's new file, and a backend with # calendar-auto-schedule mails every attendee for you # # So there is no separate verb for "invite": to a calendar there is no # separate thing, and to everything else it is just a file. rfork e mtpt=/mnt/pim print=() cal=() att=() loc=() desc=() while(~ $1 -*){ switch($1){ case -m mtpt=$2; shift case -c cal=$2; shift case -a att=($att $2); shift case -l loc=$2; shift case -D desc=$2; shift case -p print=1 case * echo 'usage: invite [-m mtpt] [-c cal] [-a attendee]... [-l where] [-D text] [-p] summary start [minutes]' >[1=2] exit usage } shift } if(test $#* -lt 2){ echo 'usage: invite [-m mtpt] [-c cal] [-a attendee]... [-l where] [-D text] summary start [minutes]' >[1=2] exit usage } summary=$1 when=$2 mins=30 if(! ~ $#* 2) mins=$3 # with -p the object goes to standard output and no calendar is needed if(! ~ $#print 0){ if(~ $#cal 0) cal=`{pim/calendars -m $mtpt | sed 1q} } if(~ $#print 0 && ~ $#cal 0){ for(c in `{pim/calendars -m $mtpt}){ caps=`{sed -n 's/^caps //p' $mtpt/calendars/$c/ctl >[2]/dev/null} for(x in $caps) if(~ $x write) cal=($cal $c) } if(~ $#cal 0){ echo 'pim/invite: no calendar here can create events' >[1=2] exit nowhere } if(! ~ $#cal 1){ echo 'pim/invite: which calendar? -c one of: '^$"cal >[1=2] exit ambiguous } } d=$mtpt/calendars/$"cal if(~ $#print 0) if(! test -f $d/new){ echo 'pim/invite: '^$"cal^' cannot create events' >[1=2] exit readonly } start=`{seconds $"when} if(~ $#start 0){ echo 'pim/invite: cannot read the time '^$"when >[1=2] exit baddate } # organiser is whoever this calendar says we are me=`{sed -n 's/^me //p' $d/ctl >[2]/dev/null | sed 's/,.*//'} if(~ $#att 0) me=() if(! ~ $#att 0) if(~ $#me 0){ echo 'pim/invite: '^$"cal^' has no me=; cannot say who is organising' >[1=2] exit nome } # The event is written as key: value, the same form the tree emits and # calfs composes from. A script spelling SUMMARY: by hand has to know # that a comma means something there, and will eventually forget; this # way go-ical does the spelling and the escaping. end=`{echo $"start + $"mins '*' 60 | bc} tmp=/tmp/invite.$pid fn sigexit { rm -f $tmp } { echo 'summary: '^$"summary echo 'start: '^$"start echo 'end: '^$"end if(! ~ $#loc 0) echo 'location: '^$"loc if(! ~ $#desc 0) echo 'description: '^$"desc if(! ~ $#att 0){ echo 'organizer: '^$"me for(a in $att) echo 'attendee: '^$a } } >$tmp if(! ~ $#print 0){ cat $tmp exit 0 } cat $tmp >$d/new if(! ~ $status ''){ echo 'pim/invite: '^$"status >[1=2] exit failed } w=`{date -f 'WWW DD MMM hh:mm' $"start} echo $"summary^': '^$"w^' on '^$"cal if(! ~ $#att 0) echo 'invited: '^$"att exit 0