carddav: implement AddressObject.Stat

This commit is contained in:
emersion 2017-09-09 16:37:14 +02:00
parent 3086fc8297
commit 0ed7542d17
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 76 additions and 17 deletions

View File

@ -4,6 +4,7 @@ import (
"net/http"
"os"
"strings"
"time"
"github.com/emersion/hydroxide/protonmail"
"github.com/emersion/go-vcard"
@ -14,9 +15,37 @@ type contextKey string
const ClientContextKey = contextKey("client")
type addressFileInfo struct {
contact *protonmail.Contact
}
func (fi *addressFileInfo) Name() string {
return fi.contact.ID + ".vcf"
}
func (fi *addressFileInfo) Size() int64 {
return int64(fi.contact.Size)
}
func (fi *addressFileInfo) Mode() os.FileMode {
return os.ModePerm
}
func (fi *addressFileInfo) ModTime() time.Time {
return time.Unix(fi.contact.ModifyTime, 0)
}
func (fi *addressFileInfo) IsDir() bool {
return false
}
func (fi *addressFileInfo) Sys() interface{} {
return nil
}
type addressObject struct {
c *protonmail.Client
contact *protonmail.ContactExport
contact *protonmail.Contact
}
func (ao *addressObject) ID() string {
@ -51,12 +80,12 @@ func (ao *addressObject) Card() (vcard.Card, error) {
}
func (ao *addressObject) Stat() (os.FileInfo, error) {
return nil, nil
return &addressFileInfo{ao.contact}, nil
}
type addressBook struct {
c *protonmail.Client
cache map[string]carddav.AddressObject
cache map[string]*addressObject
total int
}
@ -73,6 +102,24 @@ func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) {
return aos, nil
}
// Get a list of all contacts
// TODO: paging support
total, contacts, err := ab.c.ListContacts(0, 0)
if err != nil {
return nil, err
}
ab.total = total
for _, contact := range contacts {
if _, ok := ab.cache[contact.ID]; !ok {
ab.cache[contact.ID] = &addressObject{
c: ab.c,
contact: contact,
}
}
}
// Get all contacts cards
var aos []carddav.AddressObject
page := 0
for {
@ -87,8 +134,16 @@ func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) {
}
for _, contact := range contacts {
ao := &addressObject{c: ab.c, contact: contact}
ab.cache[contact.ID] = ao
ao, ok := ab.cache[contact.ID]
if !ok {
ao = &addressObject{
c: ab.c,
contact: &protonmail.Contact{ID: contact.ID},
}
ab.cache[contact.ID] = ao
}
ao.contact.Cards = contact.Cards
aos = append(aos, ao)
}
@ -115,10 +170,7 @@ func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error
ao := &addressObject{
c: ab.c,
contact: &protonmail.ContactExport{
ID: contact.ID,
Cards: contact.Cards,
},
contact: contact,
}
ab.cache[id] = ao
return ao, nil
@ -127,7 +179,7 @@ func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error
func NewHandler(c *protonmail.Client) http.Handler {
return carddav.NewHandler(&addressBook{
c: c,
cache: make(map[string]carddav.AddressObject),
cache: make(map[string]*addressObject),
total: -1,
})
}

View File

@ -11,8 +11,8 @@ type Contact struct {
Name string
UID string
Size int
CreateTime int
ModifyTime int
CreateTime int64
ModifyTime int64
LabelIDs []string
// Not when using ListContacts
@ -73,21 +73,28 @@ type ContactExport struct {
Cards []*ContactCard
}
func (c *Client) ListContacts() ([]*Contact, error) {
req, err := c.newRequest(http.MethodGet, "/contacts", nil)
func (c *Client) ListContacts(page, pageSize int) (total int, contacts []*Contact, err error) {
v := url.Values{}
v.Set("Page", strconv.Itoa(page))
if pageSize > 0 {
v.Set("PageSize", strconv.Itoa(pageSize))
}
req, err := c.newRequest(http.MethodGet, "/contacts?"+v.Encode(), nil)
if err != nil {
return nil, err
return 0, nil, err
}
var respData struct {
resp
Contacts []*Contact
Total int
}
if err := c.doJSON(req, &respData); err != nil {
return nil, err
return 0, nil, err
}
return respData.Contacts, nil
return respData.Total, respData.Contacts, nil
}
func (c *Client) ListContactsEmails(page, pageSize int) (total int, emails []*ContactEmail, err error) {