hivedav

A curlable free/busy scheduler with CalDAV integration
git clone https://git.in0rdr.ch/hivedav.git
Log | Files | Refs | Pull requests | README | LICENSE

commit 1825735a721a9fbb8cfb22bc712953291c2befee
parent 51f4dd3e94a609ef6751fc34945bac848322c897
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Tue, 12 Sep 2023 01:03:39 +0200

feat: add caldav module

Diffstat:
Acaldav/caldav.go | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgo.mod | 4+++-
Mgo.sum | 23++++-------------------
Mmain.go | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mserver.go | 68+-------------------------------------------------------------------
Mserver_test.go | 46----------------------------------------------
6 files changed, 274 insertions(+), 169 deletions(-)

diff --git a/caldav/caldav.go b/caldav/caldav.go @@ -0,0 +1,192 @@ +package caldav + +// Functions to read VEVENTs from the CalDav server: +// https://sabre.io/dav/building-a-caldav-client + +import ( + "bytes" + "encoding/xml" + "fmt" + "net/http" +) + +type XMLUserPrincipalResponse struct { + XMLName xml.Name `xml:multistatus` + UserPrincipal string `xml:"response>propstat>prop>current-user-principal>href"` +} +type XMLHomeSetResponse struct { + XMLName xml.Name `xml:multistatus` + HomeSet string `xml:"response>propstat>prop>calendar-home-set>href"` +} +type XMLHomeSetCalendarResponse struct { + XMLName xml.Name `xml:multistatus` + Response []Response `xml:"response"` +} +type Response struct { + XMLName xml.Name `xml:response` + Href string `xml:"href"` +} +type XMLCalendarResponse struct { + XMLName xml.Name `xml:multistatus` + CalData []CalData `xml:"response"` +} +type CalData struct { + XMLName xml.Name `xml:response` + Href string `xml:"href"` + Data string `xml:"propstat>prop>calendar-data"` +} + +func UserPrincipal(caldavUri string, user string, pass string) (string, error) { + payload := []byte(`<d:propfind xmlns:d="DAV:"> + <d:prop> + <d:current-user-principal /> + </d:prop> + </d:propfind>`) + reader := bytes.NewReader(payload) + req, err := http.NewRequest("PROPFIND", caldavUri, reader) + if err != nil { + return "", err + } + req.Header.Set("Depth", "0") + req.SetBasicAuth(user, pass) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + + if res.StatusCode != 207 { + return "", err + } + + decoder := xml.NewDecoder(res.Body) + var xmlResponse XMLUserPrincipalResponse + err = decoder.Decode(&xmlResponse) + if err != nil { + return "", err + } + + return xmlResponse.UserPrincipal, nil +} + +func CalendarHome(caldavUri string, user string, pass string, userPrincipal string, calendar int) (string, error) { + payload := []byte(`<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"> + <d:prop> + <c:calendar-home-set /> + </d:prop> + </d:propfind>`) + reader := bytes.NewReader(payload) + principalUri := fmt.Sprintf("%s%s", caldavUri, userPrincipal) + + req, err := http.NewRequest("PROPFIND", principalUri, reader) + if err != nil { + return "", err + } + req.Header.Set("Depth", "0") + req.SetBasicAuth(user, pass) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + + if res.StatusCode != 207 { + return "", err + } + + decoder := xml.NewDecoder(res.Body) + var xmlResponse XMLHomeSetResponse + err = decoder.Decode(&xmlResponse) + if err != nil { + return "", err + } + + return xmlResponse.HomeSet, nil +} + +func CalendarFromHomeSet(caldavUri string, user string, pass string, homeSetUri string, calendar int) (calendarUri string, err error) { + payload := []byte(`<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:caldav"> + <d:prop> + <d:resourcetype /> + <d:displayname /> + <cs:getctag /> + <c:supported-calendar-component-set /> + </d:prop> + </d:propfind>`) + reader := bytes.NewReader(payload) + homeSetUrl := fmt.Sprintf("%s%s", caldavUri, homeSetUri) + + req, err := http.NewRequest("PROPFIND", homeSetUrl, reader) + if err != nil { + return "", err + } + req.Header.Set("Depth", "1") + req.SetBasicAuth(user, pass) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + + if res.StatusCode != 207 { + return "", err + } + + decoder := xml.NewDecoder(res.Body) + var xmlResponse XMLHomeSetCalendarResponse + err = decoder.Decode(&xmlResponse) + if err != nil { + return "", err + } + + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("Calendar '%d' not found in homeset: %v", calendar, r) + } + }() + + calendarUri = xmlResponse.Response[calendar].Href + return calendarUri, nil +} + +func GetAvailability(caldavUri string, user string, pass string, calendarUri string) (data []CalData, err error) { + payload := []byte(`<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"> + <d:prop> + <d:getetag /> + <c:calendar-data /> + </d:prop> + <c:filter> + <c:comp-filter name="VCALENDAR"> + <c:comp-filter name="VEVENT" /> + </c:comp-filter> + </c:filter> + </c:calendar-query>`) + reader := bytes.NewReader(payload) + calendarUrl := fmt.Sprintf("%s%s", caldavUri, calendarUri) + + req, err := http.NewRequest("REPORT", calendarUrl, reader) + if err != nil { + return data, err + } + req.Header.Set("Depth", "1") + req.SetBasicAuth(user, pass) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return data, err + } + + if res.StatusCode != 207 { + return data, err + } + + decoder := xml.NewDecoder(res.Body) + var xmlResponse XMLCalendarResponse + err = decoder.Decode(&xmlResponse) + if err != nil { + return data, err + } + + data = xmlResponse.CalData + return data, nil +} diff --git a/go.mod b/go.mod @@ -5,6 +5,7 @@ go 1.21.0 require ( github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f github.com/in0rdr/go-webdav v0.0.0-20230903141941-cde95745290e + github.com/mattn/go-sqlite3 v1.14.17 github.com/pquerna/termchalk v0.0.0-20140809212720-8cc5932700ba github.com/spf13/viper v1.16.0 ) @@ -14,8 +15,8 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect @@ -25,6 +26,7 @@ require ( github.com/teambition/rrule-go v1.7.2 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum @@ -129,24 +129,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/in0rdr/go-webdav v0.0.0-20230903141941-cde95745290e h1:iXhjrrNT+r6E6HrXsUfFcYGWkG3rnOdqPHDxcvbt/9g= github.com/in0rdr/go-webdav v0.0.0-20230903141941-cde95745290e/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907184338-c9d031ee4108 h1:oH2KREpv+PJ0jaIO8qwOgtptbS94A9y7Zb/vcN51tWg= -github.com/in0rdr/go-webdav v0.0.0-20230907184338-c9d031ee4108/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907184518-8ea5e35c2230 h1:Mwlc6zZVlECl4F6gAHsb3qopMtVrnbRdXawH9k3iV40= -github.com/in0rdr/go-webdav v0.0.0-20230907184518-8ea5e35c2230/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907185437-21041d087162 h1:UMTv18vb+4zhJot7Qm3GzlFU2wLJUi5nyAF1kahAdLM= -github.com/in0rdr/go-webdav v0.0.0-20230907185437-21041d087162/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907185552-590e54c8b195 h1:Jv29fw3DauDkffs+ouwxUMBgponxcJyOCPFdnUVOw4I= -github.com/in0rdr/go-webdav v0.0.0-20230907185552-590e54c8b195/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907190333-09317bc4417c h1:bwoY0dHzZm8HkfbnKNPJcQP1WJSl+hdyxZG7g7MRUE0= -github.com/in0rdr/go-webdav v0.0.0-20230907190333-09317bc4417c/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907190540-fd765a40b791 h1:xkkot19u4rwQYPkZl0j67Rw+kA0S53GBo1TtQV0ruKA= -github.com/in0rdr/go-webdav v0.0.0-20230907190540-fd765a40b791/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907190810-50744af0029a h1:fzxAKhzvrSuJQvJAKbLCRo1Wlzfqs1c0kfF4RIgmmfM= -github.com/in0rdr/go-webdav v0.0.0-20230907190810-50744af0029a/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907191408-68a41f149545 h1:WGxZgctEFv4wv+H5PwEk6xBlLsbqK4gitmNDRgk7WL8= -github.com/in0rdr/go-webdav v0.0.0-20230907191408-68a41f149545/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= -github.com/in0rdr/go-webdav v0.0.0-20230907191719-cda7ffd8e779 h1:zeLsQw6oUcYAn5h4X1ROMjGdUloH8PRxpoQnWxL6GNk= -github.com/in0rdr/go-webdav v0.0.0-20230907191719-cda7ffd8e779/go.mod h1:u8ZQQE8aW8NvpP101ttUsXcbtRKiedaHAPtsKAFpPnY= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -164,6 +146,8 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -494,8 +478,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/main.go b/main.go @@ -3,9 +3,13 @@ package main import ( "fmt" "log" + //"time" + "strings" "net/http" "hivedav/config" + "hivedav/caldav" "github.com/emersion/go-ical" + //"github.com/arran4/golang-ical" ) func main() { @@ -27,51 +31,85 @@ func main() { log.Println("Reading availability from:", conf.CaldavUri) log.Println("Reading as user:", conf.CaldavUser) - userPrincipal, _ := server.caldavClient.FindCurrentUserPrincipal() - log.Println("User principal: ", userPrincipal) - homeSet, _ := server.caldavClient.FindCalendarHomeSet(userPrincipal) - log.Println("Calendar homeset: ", homeSet) + // Find current user principal + userPrincipal, err := caldav.UserPrincipal(conf.CaldavUri, conf.CaldavUser, conf.CaldavPassword) + if err != nil { + log.Fatal("Error reading current user principal: ", err) + } + log.Println("User principal:", userPrincipal) + + // Find home set of current user principal + homeSetUri, err := caldav.CalendarHome(conf.CaldavUri, conf.CaldavUser, conf.CaldavPassword, userPrincipal, conf.Calendar) + if err != nil { + log.Fatal("Error reading home set URI: ", err) + } + log.Println("Calendar homeset:", homeSetUri) - // Find all calendars in homeset - calendars, err := server.findCalendars(homeSet) + // Find calendar URI for the calendar specified in the config + calendarUri, err := caldav.CalendarFromHomeSet(conf.CaldavUri, conf.CaldavUser, conf.CaldavPassword, homeSetUri, conf.Calendar) if err != nil { - log.Fatal(err) + log.Fatal("Error reading calendar URI: ", err) } - server.calendars = calendars - log.Printf("Calendars in homeset: %d", len(calendars)) - log.Println("Using nth calendar in homeset:", conf.Calendar) + log.Printf("Using calendar %d in homeset with URI '%s'\n", conf.Calendar, calendarUri) + log.Println("⏳ Fetching availability from CalDAV server, please wait..") - log.Println("Fetching availability from CalDAV server, please wait..") - objects, err := server.getAvailability(server.calendars[conf.Calendar].Path) + // Get availability data for the calendar specified in the config + calData, err := caldav.GetAvailability(conf.CaldavUri, conf.CaldavUser, conf.CaldavPassword, calendarUri) if err != nil { - log.Println("Unable to fetch availability") + log.Fatal("Error reading calendar URI: ", err) } - server.objects = objects - - for _, obj := range server.objects { - // Get ics DTSTART and DTEND - // https://github.com/emersion/go-ical/blob/master/example_test.go - for _, event := range obj.Data.Events() { - // https://github.com/emersion/go-ical/blob/master/enums.go - //summary, err := event.Props.Text(ical.PropSummary) - - //localTimezone, err := time.LoadLocation("Europe/Zurich") - - // Uses UTC when location is nil - // https://github.com/emersion/go-ical/blob/master/ical.go - // https://github.com/emersion/go-ical/issues/10 - //dtstart, err := event.DateTimeStart(localTimezone) - dtstart, err := event.DateTimeStart(nil) - if err != nil { - //log.Println("TZID not in tzdb form") - // https://github.com/emersion/go-ical/blob/master/example_test.go - event.Props.SetText(ical.PropTimezoneID, "") - dtstart, err = event.DateTimeStart(nil) + + // Walk through events and store start/end time in the database + for _, event := range calData { + // arran4 library has issues with parsing the VEVENT DTEND timezones below + // cal, err := ics.ParseCalendar(strings.NewReader(event.Data)) + // if err != nil { + // log.Fatalf("Error parsing VEVENT ics: %v", err) + // } + + // for _, e := range cal.Events() { + // dtend, err := e.GetEndAt() + // if err != nil { + // log.Println("Error parsing VEVENT DTEND: ", err) + // } + // log.Printf("%d: %v\n", dtend) + // } + + // use emersion library + dec := ical.NewDecoder(strings.NewReader(event.Data)) + cal, err := dec.Decode() + if err != nil { + log.Fatalf("Error decoding VEVENT ics: %v", err) + } + + for _, e := range cal.Events() { + + + start := e.Props.Get(ical.PropDateTimeStart).Value + end := e.Props.Get(ical.PropDateTimeEnd).Value + var tz string + if tzProp := e.Props.Get(ical.PropTimezoneID); tzProp != nil { + tz = tzProp.Value + } else { + tz = "" } - dtend, err := event.DateTimeEnd(nil) + // //localTimezone, err := time.LoadLocation("Europe/Zurich") + + // // Uses UTC when location is nil + // // https://github.com/emersion/go-ical/blob/master/ical.go + // // https://github.com/emersion/go-ical/issues/10 + // //dtstart, err := event.DateTimeStart(localTimezone) + // dtstart, err := e.DateTimeStart(nil) + // if err != nil { + // log.Println("TZID not in tzdb form") + // // https://github.com/emersion/go-ical/blob/master/example_test.go + // e.Props.SetText(ical.PropTimezoneID, "Europe/Zurich") + // dtstart, err = e.DateTimeStart(nil) + // } - if _, err = server.db.Exec("INSERT INTO availability VALUES(NULL, ?, ?, ?);", dtstart, dtend, obj.Path); err != nil { + // dtend, err := e.DateTimeEnd(nil) + if _, err = server.db.Exec("INSERT INTO availability VALUES(NULL, ?, ?, ?);", start, end, tz); err != nil { log.Fatal("Error saving events to database", err) } } diff --git a/server.go b/server.go @@ -3,8 +3,6 @@ package main import ( "hivedav/config" "fmt" - "github.com/in0rdr/go-webdav" - "github.com/in0rdr/go-webdav/caldav" "github.com/pquerna/termchalk/ansistyle" "github.com/pquerna/termchalk/prettytable" _ "github.com/mattn/go-sqlite3" @@ -13,28 +11,15 @@ import ( "log" "net/http" "strings" - "time" ) type Server struct { config *config.Config - caldavClient *caldav.Client - calendars []caldav.Calendar - objects []caldav.CalendarObject db *sql.DB } func (s *Server) NewServer(c *config.Config) (*Server, error) { - // with nil, http.DefaultClient is used - // https://godocs.io/github.com/emersion/go-webdav#HTTPClientWithBasicAuth - webdavClient := webdav.HTTPClientWithBasicAuth(nil, c.CaldavUser, c.CaldavPassword) - caldavClient, err := caldav.NewClient(webdavClient, c.CaldavUri) - - if err != nil { - log.Fatal("Error creating caldav client:", err) - } s = new(Server) - s.caldavClient = caldavClient s.config = c // prepare the sqlite database @@ -50,7 +35,7 @@ func (s *Server) NewServer(c *config.Config) (*Server, error) { id INTEGER NOT NULL PRIMARY KEY, start DATETIME NOT NULL, end DATETIME NOT NULL, - path TEXT NOT NULL + tz TEXT NOT NULL );` if _, err := db.Exec(drop); err != nil { @@ -80,57 +65,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { } } -func (s *Server) findCalendars(homeSet string) ([]caldav.Calendar, error) { - calendars, err := s.caldavClient.FindCalendars(homeSet) - if err != nil { - log.Printf("No calendars in homeset: %v", err) - return nil, err - } - return calendars, nil -} - -// fetch availabiliy for a calendar -func (s *Server) getAvailability(calendarPath string) ([]caldav.CalendarObject, error) { - compReq := caldav.CalendarCompRequest{ - Name: "VCALENDAR", - Props: []string{"VERSION"}, - Comps: []caldav.CalendarCompRequest{{ - Name: "VEVENT", - Props: []string{ - "SUMMARY", - "UID", - "DTSTART", - "DTEND", - "DURATION", - }, - }}, - } - start := time.Now().Add(-24 * time.Hour) - end := time.Now().Add(24 * time.Hour) - compFilter := caldav.CompFilter{ - Name: "VCALENDAR", - Comps: []caldav.CompFilter{ - caldav.CompFilter{ - Name: "VEVENT", - Start: start, - End: end, - }, - }, - } - query := &caldav.CalendarQuery{ - CompRequest: compReq, - CompFilter: compFilter, - } - - // Get the calendar objects - objects, err := s.caldavClient.QueryCalendar(calendarPath, query) - if err != nil { - log.Printf("No calendar objects found: %v", err) - return nil, err - } - return objects, nil -} - func (s *Server) showCubicles() { } diff --git a/server_test.go b/server_test.go @@ -70,49 +70,3 @@ func TestServer(t *testing.T) { } } -func TestFindCalendars(t *testing.T) { - // TODO: test the http calls - //config := config.Config { - // ListenAddress: "[::]", - // ListenPort: 3737, - // CaldavUri: "/", - // Calendar: 0, - // CaldavUser: "gandalf", - // CaldavPassword: "ring", - //} - //server, err := server.NewServer(&config) - //if err != nil { - // t.Fatal("Could not create hivedav server") - //} - - //homeSet := "/caldav/test@example.com/" - //_, err = server.findCalendars(homeSet) - //if err != nil { - // t.Fatal("Error fetching calendars for homeset", err) - //} -} - -func TestGetAvailability(t *testing.T) { - config := config.Config { - ListenAddress: "[::]", - ListenPort: 3737, - CaldavUri: "/", - Calendar: 0, - CaldavUser: "gandalf", - CaldavPassword: "ring", - } - server, err := server.NewServer(&config) - if err != nil { - t.Fatal("Could not create hivedav server") - } - // TODO: Mock the server calender events with - // https://github.com/emersion/go-webdav/blob/master/caldav/server_test.go - webdavClient := webdav.HTTPClientWithBasicAuth(nil, - config.CaldavUser, config.CaldavPassword) - server.caldavClient, _ = caldav.NewClient(webdavClient, config.CaldavUri) - server.calendars = make([]caldav.Calendar, 1) - server.calendars[0].Path = "/" - server.objects = make([]caldav.CalendarObject, 1) - - server.getAvailability(server.calendars[0].Path) -}