summaryrefslogtreecommitdiff
path: root/pim/cmd/caldavfs/rsvp.go
diff options
context:
space:
mode:
Diffstat (limited to 'pim/cmd/caldavfs/rsvp.go')
-rw-r--r--pim/cmd/caldavfs/rsvp.go44
1 files changed, 44 insertions, 0 deletions
diff --git a/pim/cmd/caldavfs/rsvp.go b/pim/cmd/caldavfs/rsvp.go
index 47d7425..25015a7 100644
--- a/pim/cmd/caldavfs/rsvp.go
+++ b/pim/cmd/caldavfs/rsvp.go
@@ -149,3 +149,47 @@ func quoteETag(s string) string {
}
return `"` + s + `"`
}
+
+// Create adds an event to the collection.
+//
+// The path is ours to choose, so it is derived from the UID: a server
+// that already has that object will replace it, which is what a second
+// PUT of the same event should do. With calendar-auto-schedule the
+// server mails every ATTENDEE for us, so creating an event with
+// attendees is the whole of sending an invitation.
+func (b *backend) Create(c *ical.Calendar) error {
+ var uid string
+ for _, e := range c.Events() {
+ if u, err := e.Props.Text(ical.PropUID); err == nil && u != "" {
+ uid = u
+ break
+ }
+ }
+ if uid == "" {
+ return fmt.Errorf("create: the event has no UID")
+ }
+
+ name := slugUID(uid) + ".ics"
+ path := strings.TrimSuffix(b.path, "/") + "/" + name
+ // no etag: this is a create, and If-Match on nothing is meaningless
+ return b.put(objref{path: path}, c)
+}
+
+// slugUID makes a UID safe as one path element.
+func slugUID(s string) string {
+ var out []rune
+ for _, r := range s {
+ switch {
+ case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9':
+ out = append(out, r)
+ case r == '-', r == '.', r == '_':
+ out = append(out, r)
+ default:
+ out = append(out, '-')
+ }
+ }
+ if len(out) > 100 {
+ out = out[:100]
+ }
+ return string(out)
+}