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
|
package cal
import (
"time"
"github.com/emersion/go-ical"
)
// A Backend supplies a calendar's events and, where the protocol allows
// it, accepts changes back.
//
// Everything above this line -- the tree, recurrence expansion, ctl,
// query, alarm, changed, the 9p service -- is the same whether the
// events arrived as a published .ics, over CalDAV or over JMAP. Only
// fetching and writing differ, so only fetching and writing live here.
type Backend interface {
// Name of the calendar, as it appears in ctl.
Name() string
// Caps says what this backend can do, so that a tool can report
// "read only" rather than trying and failing. The vocabulary is
// read, write, rsvp, schedule; see pim/doc/design.md.
Caps() string
// Refresh is how often to poll. Zero means never.
Refresh() time.Duration
// Status reports when the backend last synced and the error, if
// any, from that attempt.
Status() (time.Time, string)
// Sync brings the backend up to date and reports whether anything
// actually changed. A backend that cannot tell should say true --
// the cost is a needless rebuild, not a wrong answer.
Sync() (bool, error)
// Events returns the calendar as it now stands.
Events() ([]*Event, error)
}
// Describer is implemented by backends with more to say in ctl: the
// source directory, the url, whatever identifies where events came from.
type Describer interface {
Describe() string
}
// Identity is implemented by a backend that knows whose calendar this
// is. In iTIP your identity is the mailto: in your own ATTENDEE line --
// there is no separate field for it -- so without this nothing can tell
// which of an event's attendees is you. Aliases are listed because you
// may be invited at one address and reply from another.
type Identity interface {
Me() []string
}
// Creator is implemented by a backend that can add an event.
//
// It takes a whole object rather than fields, because that is what the
// protocols underneath take: CalDAV PUTs an entire icalendar object and
// JMAP patches a whole JSCalendar one. Building an event field by field
// and hoping the server knows when you have finished is a shape that
// fits neither.
type Creator interface {
Create(c *ical.Calendar) error
}
// RSVPer is implemented by a backend that can answer an invitation.
//
// Accepting is two writes: update your own copy, and tell the organiser.
// A CalDAV server advertising calendar-auto-schedule does both from one
// PUT. A backend that cannot do both should not implement this at all,
// so that writing to partstat fails honestly rather than doing half of
// it and looking like it worked.
//
// recurID is the zero time to answer a whole series, or the start of
// one occurrence to answer only that.
type RSVPer interface {
RSVP(uid string, recurID time.Time, partstat string) error
}
|