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 51f4dd3e94a609ef6751fc34945bac848322c897
parent df1e43f379bceeb7b137656e950a0884a171a96d
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Mon, 11 Sep 2023 20:21:13 +0200

feat: write availability to db

Diffstat:
MMakefile | 2+-
Mgo.mod | 1+
Mgo.sum | 20++++++++++++++++++++
Mmain.go | 24++++++++++--------------
Mserver.go | 42++++++++++++++++++++++++++++++++++++------
5 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,7 +4,7 @@ GOCOVER=$(GO) tool cover GOFMT=gofmt hivedav: - $(GO) build + CGO_ENABLED=1 $(GO) build .PHONY: all all: hivedav diff --git a/go.mod b/go.mod @@ -14,6 +14,7 @@ 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/pelletier/go-toml/v2 v2.0.8 // indirect github.com/spf13/afero v1.9.5 // indirect diff --git a/go.sum b/go.sum @@ -129,6 +129,24 @@ 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= @@ -142,6 +160,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +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/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= diff --git a/main.go b/main.go @@ -26,7 +26,6 @@ func main() { log.Println("Reading availability from:", conf.CaldavUri) log.Println("Reading as user:", conf.CaldavUser) - log.Println("Using nth calendar in homeset:", conf.Calendar) userPrincipal, _ := server.caldavClient.FindCurrentUserPrincipal() log.Println("User principal: ", userPrincipal) @@ -39,26 +38,22 @@ func main() { log.Fatal(err) } server.calendars = calendars + log.Printf("Calendars in homeset: %d", len(calendars)) + log.Println("Using nth calendar in homeset:", conf.Calendar) + log.Println("Fetching availability from CalDAV server, please wait..") objects, err := server.getAvailability(server.calendars[conf.Calendar].Path) if err != nil { log.Println("Unable to fetch availability") } server.objects = objects - log.Printf("Using calendar objects: %+v", objects) - - for i, obj := range server.objects { - //log.Printf("%d %s\n", i, obj.Path) - log.Printf("%d - ", i) - + 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) - log.Printf("Found event: %v\n", summary) - //log.Printf("Found event: %+v\n", event.Props) + //summary, err := event.Props.Text(ical.PropSummary) //localTimezone, err := time.LoadLocation("Europe/Zurich") @@ -68,7 +63,7 @@ func main() { //dtstart, err := event.DateTimeStart(localTimezone) dtstart, err := event.DateTimeStart(nil) if err != nil { - log.Println("TZID not in tzdb form") + //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) @@ -76,11 +71,12 @@ func main() { dtend, err := event.DateTimeEnd(nil) - log.Printf("Event DTSTART: %+v\n", dtstart) - log.Printf("Event DTEND: %+v\n", dtend) + if _, err = server.db.Exec("INSERT INTO availability VALUES(NULL, ?, ?, ?);", dtstart, dtend, obj.Path); err != nil { + log.Fatal("Error saving events to database", err) + } } } - http.ListenAndServe(fmt.Sprintf("%s:%d", conf.ListenAddress, conf.ListenPort), server) log.Printf("Ready, listening on %s:%d\n", conf.ListenAddress, conf.ListenPort) + http.ListenAndServe(fmt.Sprintf("%s:%d", conf.ListenAddress, conf.ListenPort), server) } diff --git a/server.go b/server.go @@ -7,6 +7,8 @@ import ( "github.com/in0rdr/go-webdav/caldav" "github.com/pquerna/termchalk/ansistyle" "github.com/pquerna/termchalk/prettytable" + _ "github.com/mattn/go-sqlite3" + "database/sql" "io" "log" "net/http" @@ -19,6 +21,7 @@ type Server struct { caldavClient *caldav.Client calendars []caldav.Calendar objects []caldav.CalendarObject + db *sql.DB } func (s *Server) NewServer(c *config.Config) (*Server, error) { @@ -33,6 +36,30 @@ func (s *Server) NewServer(c *config.Config) (*Server, error) { s = new(Server) s.caldavClient = caldavClient s.config = c + + // prepare the sqlite database + db, err := sql.Open("sqlite3", "app.db") + if err != nil { + log.Fatal("Error opening sqlite3 database 'app.db'", err) + } + s.db = db + + drop := "DROP TABLE IF EXISTS availability;" + create := ` + CREATE TABLE availability ( + id INTEGER NOT NULL PRIMARY KEY, + start DATETIME NOT NULL, + end DATETIME NOT NULL, + path TEXT NOT NULL + );` + + if _, err := db.Exec(drop); err != nil { + return nil, err + } + if _, err := db.Exec(create); err != nil { + return nil, err + } + return s, nil } @@ -59,7 +86,6 @@ func (s *Server) findCalendars(homeSet string) ([]caldav.Calendar, error) { log.Printf("No calendars in homeset: %v", err) return nil, err } - log.Printf("Calendars in homeset: %+v", calendars) return calendars, nil } @@ -79,13 +105,17 @@ func (s *Server) getAvailability(calendarPath string) ([]caldav.CalendarObject, }, }}, } + start := time.Now().Add(-24 * time.Hour) + end := time.Now().Add(24 * time.Hour) compFilter := caldav.CompFilter{ Name: "VCALENDAR", - Comps: []caldav.CompFilter{{ - Name: "VEVENT", - Start: time.Now().Add(-24 * time.Hour), - End: time.Now().Add(24 * time.Hour), - }}, + Comps: []caldav.CompFilter{ + caldav.CompFilter{ + Name: "VEVENT", + Start: start, + End: end, + }, + }, } query := &caldav.CalendarQuery{ CompRequest: compReq,