carddav: implement AddressObject.Stat
This commit is contained in:
parent
3086fc8297
commit
0ed7542d17
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/emersion/hydroxide/protonmail"
|
"github.com/emersion/hydroxide/protonmail"
|
||||||
"github.com/emersion/go-vcard"
|
"github.com/emersion/go-vcard"
|
||||||
|
@ -14,9 +15,37 @@ type contextKey string
|
||||||
|
|
||||||
const ClientContextKey = contextKey("client")
|
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 {
|
type addressObject struct {
|
||||||
c *protonmail.Client
|
c *protonmail.Client
|
||||||
contact *protonmail.ContactExport
|
contact *protonmail.Contact
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ao *addressObject) ID() string {
|
func (ao *addressObject) ID() string {
|
||||||
|
@ -51,12 +80,12 @@ func (ao *addressObject) Card() (vcard.Card, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ao *addressObject) Stat() (os.FileInfo, error) {
|
func (ao *addressObject) Stat() (os.FileInfo, error) {
|
||||||
return nil, nil
|
return &addressFileInfo{ao.contact}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type addressBook struct {
|
type addressBook struct {
|
||||||
c *protonmail.Client
|
c *protonmail.Client
|
||||||
cache map[string]carddav.AddressObject
|
cache map[string]*addressObject
|
||||||
total int
|
total int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +102,24 @@ func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) {
|
||||||
return aos, nil
|
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
|
var aos []carddav.AddressObject
|
||||||
page := 0
|
page := 0
|
||||||
for {
|
for {
|
||||||
|
@ -87,8 +134,16 @@ func (ab *addressBook) ListAddressObjects() ([]carddav.AddressObject, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, contact := range contacts {
|
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
|
ab.cache[contact.ID] = ao
|
||||||
|
}
|
||||||
|
|
||||||
|
ao.contact.Cards = contact.Cards
|
||||||
aos = append(aos, ao)
|
aos = append(aos, ao)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +170,7 @@ func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error
|
||||||
|
|
||||||
ao := &addressObject{
|
ao := &addressObject{
|
||||||
c: ab.c,
|
c: ab.c,
|
||||||
contact: &protonmail.ContactExport{
|
contact: contact,
|
||||||
ID: contact.ID,
|
|
||||||
Cards: contact.Cards,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
ab.cache[id] = ao
|
ab.cache[id] = ao
|
||||||
return ao, nil
|
return ao, nil
|
||||||
|
@ -127,7 +179,7 @@ func (ab *addressBook) GetAddressObject(id string) (carddav.AddressObject, error
|
||||||
func NewHandler(c *protonmail.Client) http.Handler {
|
func NewHandler(c *protonmail.Client) http.Handler {
|
||||||
return carddav.NewHandler(&addressBook{
|
return carddav.NewHandler(&addressBook{
|
||||||
c: c,
|
c: c,
|
||||||
cache: make(map[string]carddav.AddressObject),
|
cache: make(map[string]*addressObject),
|
||||||
total: -1,
|
total: -1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ type Contact struct {
|
||||||
Name string
|
Name string
|
||||||
UID string
|
UID string
|
||||||
Size int
|
Size int
|
||||||
CreateTime int
|
CreateTime int64
|
||||||
ModifyTime int
|
ModifyTime int64
|
||||||
LabelIDs []string
|
LabelIDs []string
|
||||||
|
|
||||||
// Not when using ListContacts
|
// Not when using ListContacts
|
||||||
|
@ -73,21 +73,28 @@ type ContactExport struct {
|
||||||
Cards []*ContactCard
|
Cards []*ContactCard
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ListContacts() ([]*Contact, error) {
|
func (c *Client) ListContacts(page, pageSize int) (total int, contacts []*Contact, err error) {
|
||||||
req, err := c.newRequest(http.MethodGet, "/contacts", nil)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var respData struct {
|
var respData struct {
|
||||||
resp
|
resp
|
||||||
Contacts []*Contact
|
Contacts []*Contact
|
||||||
|
Total int
|
||||||
}
|
}
|
||||||
if err := c.doJSON(req, &respData); err != nil {
|
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) {
|
func (c *Client) ListContactsEmails(page, pageSize int) (total int, emails []*ContactEmail, err error) {
|
||||||
|
|
Loading…
Reference in New Issue