carddav: add AddressObject.{ModTime,ETag}

This commit is contained in:
Simon Ser 2020-01-22 15:35:36 +01:00
parent 2eb6e89979
commit 0a251a8dfb
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 56 additions and 15 deletions

View File

@ -4,6 +4,8 @@
package carddav
import (
"time"
"github.com/emersion/go-vcard"
)
@ -24,6 +26,8 @@ type AddressBookMultiGet struct {
}
type AddressObject struct {
Path string
Card vcard.Card
Path string
ModTime time.Time
ETag string
Card vcard.Card
}

View File

@ -6,7 +6,9 @@ import (
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/emersion/go-vcard"
"github.com/emersion/go-webdav"
@ -140,6 +142,17 @@ func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, err
return l, nil
}
func encodeAddressPropReq(props []string) (*internal.Prop, error) {
var addrDataReq addressDataReq
for _, name := range props {
addrDataReq.Props = append(addrDataReq.Props, prop{Name: name})
}
getLastModReq := internal.NewRawXMLElement(internal.GetLastModifiedName, nil, nil)
getETagReq := internal.NewRawXMLElement(internal.GetETagName, nil, nil)
return internal.EncodeProp(&addrDataReq, getLastModReq, getETagReq)
}
func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
addrs := make([]AddressObject, 0, len(ms.Responses))
for _, resp := range ms.Responses {
@ -153,6 +166,20 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
return nil, err
}
var getLastMod internal.GetLastModified
if err := resp.DecodeProp(&getLastMod); err != nil && !internal.IsNotFound(err) {
return nil, err
}
var getETag internal.GetETag
if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) {
return nil, err
}
etag, err := strconv.Unquote(getETag.ETag)
if err != nil {
return nil, fmt.Errorf("carddav: failed to unquote ETag: %v", err)
}
r := bytes.NewReader(addrData.Data)
card, err := vcard.NewDecoder(r).Decode()
if err != nil {
@ -160,8 +187,10 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
}
addrs = append(addrs, AddressObject{
Path: path,
Card: card,
Path: path,
ModTime: time.Time(getLastMod.LastModified),
ETag: etag,
Card: card,
})
}
@ -169,14 +198,12 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
}
func (c *Client) QueryAddressBook(addressBook string, query *AddressBookQuery) ([]AddressObject, error) {
var addrDataReq addressDataReq
var props []string
if query != nil {
for _, name := range query.Props {
addrDataReq.Props = append(addrDataReq.Props, prop{Name: name})
}
props = query.Props
}
propReq, err := internal.EncodeProp(&addrDataReq)
propReq, err := encodeAddressPropReq(props)
if err != nil {
return nil, err
}
@ -199,14 +226,12 @@ func (c *Client) QueryAddressBook(addressBook string, query *AddressBookQuery) (
}
func (c *Client) MultiGetAddressBook(path string, multiGet *AddressBookMultiGet) ([]AddressObject, error) {
var addrDataReq addressDataReq
var props []string
if multiGet != nil {
for _, name := range multiGet.Props {
addrDataReq.Props = append(addrDataReq.Props, prop{Name: name})
}
props = multiGet.Props
}
propReq, err := internal.EncodeProp(&addrDataReq)
propReq, err := encodeAddressPropReq(props)
if err != nil {
return nil, err
}

View File

@ -3,6 +3,7 @@ package carddav
import (
"bytes"
"encoding/xml"
"fmt"
"mime"
"net/http"
@ -259,7 +260,18 @@ func (b *backend) propfindAddressObject(propfind *internal.Propfind, ao *Address
return &addressDataResp{Data: buf.Bytes()}, nil
},
// TODO: getlastmodified, getetag
}
if !ao.ModTime.IsZero() {
props[internal.GetLastModifiedName] = func(*internal.RawXMLValue) (interface{}, error) {
return &internal.GetLastModified{LastModified: internal.Time(ao.ModTime)}, nil
}
}
if ao.ETag != "" {
props[internal.GetETagName] = func(*internal.RawXMLValue) (interface{}, error) {
return &internal.GetETag{ETag: fmt.Sprintf("%q", ao.ETag)}, nil
}
}
return internal.NewPropfindResponse(ao.Path, propfind, props)