carddav: cache contacts

This commit is contained in:
emersion 2017-09-04 11:41:26 +02:00
parent 937242e3ef
commit 951bf27da0
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
1 changed files with 36 additions and 10 deletions

View File

@ -7,8 +7,6 @@ import (
"github.com/emersion/hydroxide/protonmail" "github.com/emersion/hydroxide/protonmail"
"github.com/emersion/go-vcard" "github.com/emersion/go-vcard"
"github.com/emersion/go-webdav/carddav" "github.com/emersion/go-webdav/carddav"
"log"
) )
type addressObject struct { type addressObject struct {
@ -49,40 +47,68 @@ func (ao *addressObject) Card() (vcard.Card, error) {
type addressBook struct { type addressBook struct {
c *protonmail.Client c *protonmail.Client
cache map[string]carddav.AddressObject
total int
}
func (ab *addressBook) cacheComplete() bool {
return ab.total >= 0 && len(ab.cache) == ab.total
} }
func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) { func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) {
// TODO: cache this if ab.cacheComplete() {
aos := make([]carddav.AddressObject, 0, len(ab.cache))
for _, ao := range ab.cache {
aos = append(aos, ao)
}
return aos, nil
}
// TODO: paging support // TODO: paging support
_, contacts, err := ab.c.ListContactsExport(0, 0) total, contacts, err := ab.c.ListContactsExport(0, 0)
log.Println(contacts, err)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ab.total = total
aos := make([]carddav.AddressObject, len(contacts)) aos := make([]carddav.AddressObject, len(contacts))
for i, contact := range contacts { for i, contact := range contacts {
aos[i] = &addressObject{c: ab.c, contact: contact} ao := &addressObject{c: ab.c, contact: contact}
ab.cache[contact.ID] = ao
aos[i] = ao
} }
return aos, nil return aos, nil
} }
func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error) { func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error) {
if ao, ok := ab.cache[id]; ok {
return ao, nil
} else if ab.cacheComplete() {
return nil, carddav.ErrNotFound
}
contact, err := ab.c.GetContact(id) contact, err := ab.c.GetContact(id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &addressObject{ ao := &addressObject{
c: ab.c, c: ab.c,
contact: &protonmail.ContactExport{ contact: &protonmail.ContactExport{
ID: contact.ID, ID: contact.ID,
Cards: contact.Cards, Cards: contact.Cards,
}, },
}, nil }
ab.cache[id] = ao
return ao, nil
} }
func NewHandler(c *protonmail.Client) http.Handler { func NewHandler(c *protonmail.Client) http.Handler {
return carddav.NewHandler(&addressBook{c}) return carddav.NewHandler(&addressBook{
c: c,
cache: make(map[string]carddav.AddressObject),
total: -1,
})
} }