Implement query and property filters
The property filters are also used for other operations.
This commit is contained in:
parent
9b0d3b87ad
commit
18a9f9bf77
@ -7,7 +7,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -67,7 +66,28 @@ func etagForFile(path string) (string, error) {
|
|||||||
return base64.StdEncoding.EncodeToString(csum[:]), nil
|
return base64.StdEncoding.EncodeToString(csum[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func vcardFromFile(path string) (*vcard.Card, error) {
|
func vcardPropFilter(card *vcard.Card, props []string) *vcard.Card {
|
||||||
|
if card == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(props) == 0 {
|
||||||
|
return card
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make(vcard.Card)
|
||||||
|
result["VERSION"] = (*card)["VERSION"]
|
||||||
|
for _, prop := range props {
|
||||||
|
value, ok := (*card)[prop]
|
||||||
|
if ok {
|
||||||
|
result[prop] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
func vcardFromFile(path string, propFilter []string) (*vcard.Card, error) {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -80,7 +100,7 @@ func vcardFromFile(path string) (*vcard.Card, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &card, nil
|
return vcardPropFilter(&card, propFilter), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDefaultAddressBook(path string) error {
|
func createDefaultAddressBook(path string) error {
|
||||||
@ -144,7 +164,12 @@ func (b *filesystemBackend) GetAddressObject(ctx context.Context, path string, r
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
card, err := vcardFromFile(path)
|
propFilter := []string{}
|
||||||
|
if req != nil && !req.AllProp {
|
||||||
|
propFilter = req.Props
|
||||||
|
}
|
||||||
|
|
||||||
|
card, err := vcardFromFile(path, propFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -163,7 +188,7 @@ func (b *filesystemBackend) GetAddressObject(ctx context.Context, path string, r
|
|||||||
return &obj, nil
|
return &obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) {
|
func (b *filesystemBackend) loadAll(ctx context.Context, propFilter []string) ([]carddav.AddressObject, error) {
|
||||||
result := []carddav.AddressObject{}
|
result := []carddav.AddressObject{}
|
||||||
|
|
||||||
path, err := b.pathForContext(ctx)
|
path, err := b.pathForContext(ctx)
|
||||||
@ -172,12 +197,12 @@ func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = filepath.Walk(path, func(filename string, info os.FileInfo, err error) error {
|
err = filepath.Walk(path, func(filename string, info os.FileInfo, err error) error {
|
||||||
// TODO this heuristic will not work for all clients
|
// Skip address book meta data files
|
||||||
if filepath.Ext(filename) != ".vcf" {
|
if !info.Mode().IsRegular() || filepath.Ext(filename) == ".json" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
card, err := vcardFromFile(filename)
|
card, err := vcardFromFile(filename, propFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -196,17 +221,31 @@ func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav
|
|||||||
result = append(result, obj)
|
result = append(result, obj)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) QueryAddressObjects(ctx context.Context, query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) {
|
func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) {
|
||||||
// TODO
|
propFilter := []string{}
|
||||||
log.Println("QueryAddressObjects called, not implemented")
|
if req != nil && !req.AllProp {
|
||||||
return []carddav.AddressObject{}, nil
|
propFilter = req.Props
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.loadAll(ctx, propFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) QueryAddressObjects(ctx context.Context, query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) {
|
||||||
|
propFilter := []string{}
|
||||||
|
if query != nil && !query.DataRequest.AllProp {
|
||||||
|
propFilter = query.DataRequest.Props
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := b.loadAll(ctx, propFilter)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return carddav.Filter(query, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card) (loc string, err error) {
|
func (b *filesystemBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card) (loc string, err error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user