summaryrefslogtreecommitdiff
path: root/pim/rc/rsvp
blob: 0e21f0488ee2bb06fea7a81e803341ea4516a6b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/bin/rc
# pim/rsvp -- answer an invitation.
#
#	pim/rsvp accepted 'meet with ben'
#	pim/rsvp declined /mnt/pim/calendars/work/events/date/2026/08/24/1000-API-WG
#
# Takes an occurrence path, as pim/agenda -p prints and cal9 plumbs, or a
# pattern to search for. The answer goes to the event's partstat, and
# what happens next is the backend's business: a caldav server with
# calendar-auto-schedule updates your copy and mails the organiser, and
# a published .ics refuses outright, which is the honest answer there.
rfork e

mtpt=/mnt/pim
days=90
only=()

while(~ $1 -*){
	switch($1){
	case -m
		mtpt=$2; shift
	case -c
		only=($only $2); shift
	case -n
		days=$2; shift
	case *
		echo 'usage: rsvp [-m mtpt] [-c cal] [-n days] accepted|declined|tentative path|pattern' >[1=2]
		exit usage
	}
	shift
}
if(test $#* -lt 2){
	echo 'usage: rsvp [-m mtpt] [-c cal] [-n days] accepted|declined|tentative path|pattern' >[1=2]
	exit usage
}

want=`{echo $1 | tr a-z A-Z}
shift
switch($want){
case ACCEPTED DECLINED TENTATIVE
	;
case *
	echo 'pim/rsvp: want accepted, declined or tentative' >[1=2]
	exit usage
}
pat=$"*

# an occurrence path names one outright; anything else is a search
occ=()
if(test -f $"pat)
	occ=$"pat
if(~ $#occ 0){
	hits=`{pim/show -m $mtpt -n $days $only -a $"pat >[2]/dev/null | sed -n 's/^at *//p'}
	if(~ $#hits 0){
		echo 'pim/rsvp: nothing matching '^$"pat >[1=2]
		exit notfound
	}
	# A recurring event matches once per occurrence, and the answer
	# applies to the series, so count distinct events rather than hits.
	evs=()
	for(h in $hits){
		hd=`{basename -d $h}
		he=`{sed -n 's/^event: //p' $h}
		if(! ~ $#he 0)
			evs=($evs `{cleanname $hd/$"he})
	}
	evs=`{echo $evs | tr ' ' '\n' | sort -u}
	if(! ~ $#evs 1){
		echo 'pim/rsvp: '^$#evs^' events match; be more specific:' >[1=2]
		for(x in $evs)
			echo '	'^$x >[1=2]
		exit ambiguous
	}
	occ=$hits(1)
}

# the occurrence points at its event; 9P has no symlinks, so it is a path
d=`{basename -d $"occ}
ev=`{sed -n 's/^event: //p' $"occ}
if(~ $#ev 0){
	echo 'pim/rsvp: '^$"occ^' has no event: line' >[1=2]
	exit noevent
}
e=`{cleanname $d/$"ev}

if(! test -f $e/partstat){
	echo 'pim/rsvp: '^$"e^' has no partstat' >[1=2]
	exit nopartstat
}

# Say why before the write fails. A published .ics has nowhere to put a
# reply and no invitation to reply to, and "permission denied" does not
# explain that.
c=`{echo $"e | sed 's|(/.*/calendars/[^/]+)/.*|\1|'}
caps=`{sed -n 's/^caps //p' $"c/ctl >[2]/dev/null}
# ~ takes its first argument as the subject, so `~ $caps rsvp` asks
# whether "read" is "rsvp". Walk the list instead.
can=()
for(x in $caps)
	if(~ $x rsvp)
		can=1
if(! ~ $#caps 0)
	if(~ $#can 0){
		echo 'pim/rsvp: '^`{basename $"c}^' is '^$"caps^', it cannot answer invitations' >[1=2]
		exit readonly
	}

echo $want >$e/partstat
sum=`{sed -n 's/^summary: //p' $"occ}
echo $"sum^': '^$want
exit 0