mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-23 00:34:23 +00:00
carddav: add AddressObject.{ModTime,ETag}
This commit is contained in:
parent
2eb6e89979
commit
0a251a8dfb
@ -4,6 +4,8 @@
|
|||||||
package carddav
|
package carddav
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/emersion/go-vcard"
|
"github.com/emersion/go-vcard"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ type AddressBookMultiGet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AddressObject struct {
|
type AddressObject struct {
|
||||||
Path string
|
Path string
|
||||||
Card vcard.Card
|
ModTime time.Time
|
||||||
|
ETag string
|
||||||
|
Card vcard.Card
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/emersion/go-vcard"
|
"github.com/emersion/go-vcard"
|
||||||
"github.com/emersion/go-webdav"
|
"github.com/emersion/go-webdav"
|
||||||
@ -140,6 +142,17 @@ func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, err
|
|||||||
return l, nil
|
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) {
|
func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
|
||||||
addrs := make([]AddressObject, 0, len(ms.Responses))
|
addrs := make([]AddressObject, 0, len(ms.Responses))
|
||||||
for _, resp := range ms.Responses {
|
for _, resp := range ms.Responses {
|
||||||
@ -153,6 +166,20 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
|
|||||||
return nil, err
|
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)
|
r := bytes.NewReader(addrData.Data)
|
||||||
card, err := vcard.NewDecoder(r).Decode()
|
card, err := vcard.NewDecoder(r).Decode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -160,8 +187,10 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addrs = append(addrs, AddressObject{
|
addrs = append(addrs, AddressObject{
|
||||||
Path: path,
|
Path: path,
|
||||||
Card: card,
|
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) {
|
func (c *Client) QueryAddressBook(addressBook string, query *AddressBookQuery) ([]AddressObject, error) {
|
||||||
var addrDataReq addressDataReq
|
var props []string
|
||||||
if query != nil {
|
if query != nil {
|
||||||
for _, name := range query.Props {
|
props = query.Props
|
||||||
addrDataReq.Props = append(addrDataReq.Props, prop{Name: name})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
propReq, err := internal.EncodeProp(&addrDataReq)
|
propReq, err := encodeAddressPropReq(props)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
func (c *Client) MultiGetAddressBook(path string, multiGet *AddressBookMultiGet) ([]AddressObject, error) {
|
||||||
var addrDataReq addressDataReq
|
var props []string
|
||||||
if multiGet != nil {
|
if multiGet != nil {
|
||||||
for _, name := range multiGet.Props {
|
props = multiGet.Props
|
||||||
addrDataReq.Props = append(addrDataReq.Props, prop{Name: name})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
propReq, err := internal.EncodeProp(&addrDataReq)
|
propReq, err := encodeAddressPropReq(props)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package carddav
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -259,7 +260,18 @@ func (b *backend) propfindAddressObject(propfind *internal.Propfind, ao *Address
|
|||||||
|
|
||||||
return &addressDataResp{Data: buf.Bytes()}, nil
|
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)
|
return internal.NewPropfindResponse(ao.Path, propfind, props)
|
||||||
|
Loading…
Reference in New Issue
Block a user