From 1bd930f0438ebce5fd0e27aca0f5d5e1c5bcc750 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Feb 2020 14:58:56 +0100 Subject: plugins/carddav: add basic contacts view --- plugins/carddav/routes.go | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 plugins/carddav/routes.go (limited to 'plugins/carddav/routes.go') diff --git a/plugins/carddav/routes.go b/plugins/carddav/routes.go new file mode 100644 index 0000000..82b729e --- /dev/null +++ b/plugins/carddav/routes.go @@ -0,0 +1,108 @@ +package koushincarddav + +import ( + "fmt" + "net/http" + "net/url" + + "git.sr.ht/~emersion/koushin" + "github.com/emersion/go-vcard" + "github.com/emersion/go-webdav/carddav" +) + +type AddressBookRenderData struct { + koushin.BaseRenderData + AddressBook *carddav.AddressBook + AddressObjects []carddav.AddressObject + Query string +} + +type AddressObjectRenderData struct { + koushin.BaseRenderData + AddressObject *carddav.AddressObject +} + +func registerRoutes(p *koushin.GoPlugin, u *url.URL) { + p.GET("/contacts", func(ctx *koushin.Context) error { + queryText := ctx.QueryParam("query") + + c, addressBook, err := getAddressBook(u, ctx.Session) + if err != nil { + return err + } + + query := carddav.AddressBookQuery{ + DataRequest: carddav.AddressDataRequest{ + Props: []string{ + vcard.FieldFormattedName, + vcard.FieldEmail, + vcard.FieldUID, + }, + }, + } + + if queryText != "" { + query.PropFilters = []carddav.PropFilter{ + { + Name: vcard.FieldFormattedName, + TextMatches: []carddav.TextMatch{{Text: queryText}}, + }, + { + Name: vcard.FieldEmail, + TextMatches: []carddav.TextMatch{{Text: queryText}}, + }, + } + } + + addrs, err := c.QueryAddressBook(addressBook.Path, &query) + if err != nil { + return fmt.Errorf("failed to query CardDAV addresses: %v", err) + } + + return ctx.Render(http.StatusOK, "address-book.html", &AddressBookRenderData{ + BaseRenderData: *koushin.NewBaseRenderData(ctx), + AddressBook: addressBook, + AddressObjects: addrs, + Query: queryText, + }) + }) + + p.GET("/contacts/:uid", func(ctx *koushin.Context) error { + uid := ctx.Param("uid") + + c, addressBook, err := getAddressBook(u, ctx.Session) + if err != nil { + return err + } + + query := carddav.AddressBookQuery{ + DataRequest: carddav.AddressDataRequest{ + Props: []string{ + vcard.FieldFormattedName, + vcard.FieldEmail, + vcard.FieldUID, + }, + }, + PropFilters: []carddav.PropFilter{{ + Name: vcard.FieldUID, + TextMatches: []carddav.TextMatch{{ + Text: uid, + MatchType: carddav.MatchEquals, + }}, + }}, + } + addrs, err := c.QueryAddressBook(addressBook.Path, &query) + if err != nil { + return fmt.Errorf("failed to query CardDAV address: %v", err) + } + if len(addrs) != 1 { + return fmt.Errorf("expected exactly one address object with UID %q, got %v", uid, len(addrs)) + } + addr := &addrs[0] + + return ctx.Render(http.StatusOK, "address-object.html", &AddressObjectRenderData{ + BaseRenderData: *koushin.NewBaseRenderData(ctx), + AddressObject: addr, + }) + }) +} -- cgit v1.2.3