aboutsummaryrefslogtreecommitdiff
path: root/plugins/carddav/routes.go
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2020-02-05 14:58:56 +0100
committerSimon Ser <contact@emersion.fr>2020-02-05 14:58:56 +0100
commit1bd930f0438ebce5fd0e27aca0f5d5e1c5bcc750 (patch)
tree2ed420695bf816e34adf38c02d06998a154be918 /plugins/carddav/routes.go
parent3263a89185e27031dbde7007eb4b71db4cd3c54f (diff)
downloadalps-1bd930f0438ebce5fd0e27aca0f5d5e1c5bcc750.tar.gz
alps-1bd930f0438ebce5fd0e27aca0f5d5e1c5bcc750.zip
plugins/carddav: add basic contacts view
Diffstat (limited to 'plugins/carddav/routes.go')
-rw-r--r--plugins/carddav/routes.go108
1 files changed, 108 insertions, 0 deletions
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,
+ })
+ })
+}