go-webdav/caldav/caldav.go

128 lines
3.2 KiB
Go
Raw Permalink Normal View History

2020-01-30 12:18:05 +00:00
// Package caldav provides a client and server CalDAV implementation.
//
// CalDAV is defined in RFC 4791.
package caldav
2020-01-30 12:51:02 +00:00
2020-02-03 16:26:55 +00:00
import (
"fmt"
2020-02-03 16:26:55 +00:00
"time"
2020-02-05 17:05:48 +00:00
2020-02-24 16:52:25 +00:00
"github.com/emersion/go-ical"
2022-03-21 08:16:50 +00:00
"github.com/emersion/go-webdav"
"github.com/emersion/go-webdav/internal"
2020-02-03 16:26:55 +00:00
)
var CapabilityCalendar = webdav.Capability("calendar-access")
2022-03-21 08:16:50 +00:00
func NewCalendarHomeSet(path string) webdav.BackendSuppliedHomeSet {
return &calendarHomeSet{Href: internal.Href{Path: path}}
}
// ValidateCalendarObject checks the validity of a calendar object according to
// the contraints layed out in RFC 4791 section 4.1 and returns the only event
// type and UID occuring in this calendar, or an error if the calendar could
// not be validated.
func ValidateCalendarObject(cal *ical.Calendar) (eventType string, uid string, err error) {
// Calendar object resources contained in calendar collections
// MUST NOT specify the iCalendar METHOD property.
if prop := cal.Props.Get(ical.PropMethod); prop != nil {
return "", "", fmt.Errorf("calendar resource must not specify METHOD property")
}
for _, comp := range cal.Children {
// Calendar object resources contained in calendar collections
// MUST NOT contain more than one type of calendar component
// (e.g., VEVENT, VTODO, VJOURNAL, VFREEBUSY, etc.) with the
// exception of VTIMEZONE components, which MUST be specified
// for each unique TZID parameter value specified in the
// iCalendar object.
if comp.Name != ical.CompTimezone {
if eventType == "" {
eventType = comp.Name
}
if eventType != comp.Name {
return "", "", fmt.Errorf("conflicting event types in calendar: %s, %s", eventType, comp.Name)
}
// TODO check VTIMEZONE for each TZID?
}
// Calendar components in a calendar collection that have
// different UID property values MUST be stored in separate
// calendar object resources.
compUID, err := comp.Props.Text(ical.PropUID)
if err != nil {
return "", "", fmt.Errorf("error checking component UID: %v", err)
}
if uid == "" {
uid = compUID
}
if compUID != "" && uid != compUID {
return "", "", fmt.Errorf("conflicting UID values in calendar: %s, %s", uid, compUID)
}
}
return eventType, uid, nil
}
2020-01-30 12:51:02 +00:00
type Calendar struct {
Path string
Name string
Description string
MaxResourceSize int64
SupportedComponentSet []string
2020-01-30 12:51:02 +00:00
}
2020-02-03 16:26:55 +00:00
type CalendarCompRequest struct {
Name string
AllProps bool
Props []string
AllComps bool
Comps []CalendarCompRequest
}
type CompFilter struct {
Name string
IsNotDefined bool
Start, End time.Time
Props []PropFilter
Comps []CompFilter
}
type ParamFilter struct {
Name string
IsNotDefined bool
TextMatch *TextMatch
}
type PropFilter struct {
Name string
IsNotDefined bool
Start, End time.Time
TextMatch *TextMatch
ParamFilter []ParamFilter
}
type TextMatch struct {
Text string
NegateCondition bool
}
2020-02-03 16:26:55 +00:00
type CalendarQuery struct {
CompRequest CalendarCompRequest
CompFilter CompFilter
2020-02-03 16:26:55 +00:00
}
2020-05-13 15:45:10 +01:00
type CalendarMultiGet struct {
Paths []string
CompRequest CalendarCompRequest
}
2020-02-03 16:26:55 +00:00
type CalendarObject struct {
Path string
ModTime time.Time
ContentLength int64
ETag string
Data *ical.Calendar
2020-02-03 16:26:55 +00:00
}