carddav: implement AddressObject.Stat
This commit is contained in:
parent
3086fc8297
commit
0ed7542d17
|
@ -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}
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue