aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/carddav/public/address-object.html6
-rw-r--r--plugins/carddav/routes.go59
2 files changed, 54 insertions, 11 deletions
diff --git a/plugins/carddav/public/address-object.html b/plugins/carddav/public/address-object.html
index 2c96fd4..1d564ee 100644
--- a/plugins/carddav/public/address-object.html
+++ b/plugins/carddav/public/address-object.html
@@ -10,6 +10,12 @@
<h2>Contact: {{$fn}}</h2>
+<p>
+ <a href="/contacts/{{.AddressObject.Card.Value "UID" | pathescape}}/edit">
+ Edit
+ </a>
+</p>
+
<ul>
<li><strong>Name</strong>: {{$fn}}</li>
{{range .AddressObject.Card.Values "EMAIL"}}
diff --git a/plugins/carddav/routes.go b/plugins/carddav/routes.go
index e05f32d..88b471a 100644
--- a/plugins/carddav/routes.go
+++ b/plugins/carddav/routes.go
@@ -27,7 +27,7 @@ type AddressObjectRenderData struct {
type UpdateAddressObjectRenderData struct {
koushin.BaseRenderData
AddressObject *carddav.AddressObject // nil if creating a new contact
- Card vcard.Card
+ Card vcard.Card
}
func registerRoutes(p *plugin) {
@@ -117,8 +117,39 @@ func registerRoutes(p *plugin) {
})
})
- createContact := func(ctx *koushin.Context) error {
- card := make(vcard.Card)
+ updateContact := func(ctx *koushin.Context) error {
+ uid := ctx.Param("uid")
+
+ c, addressBook, err := p.clientWithAddressBook(ctx.Session)
+ if err != nil {
+ return err
+ }
+
+ var ao *carddav.AddressObject
+ var card vcard.Card
+ if uid != "" {
+ query := carddav.AddressBookQuery{
+ DataRequest: carddav.AddressDataRequest{AllProp: true},
+ PropFilters: []carddav.PropFilter{{
+ Name: vcard.FieldUID,
+ TextMatches: []carddav.TextMatch{{
+ Text: uid,
+ MatchType: carddav.MatchEquals,
+ }},
+ }},
+ }
+ aos, err := c.QueryAddressBook(addressBook.Path, &query)
+ if err != nil {
+ return fmt.Errorf("failed to query CardDAV address: %v", err)
+ }
+ if len(aos) != 1 {
+ return fmt.Errorf("expected exactly one address object with UID %q, got %v", uid, len(aos))
+ }
+ ao = &aos[0]
+ card = ao.Card
+ } else {
+ card = make(vcard.Card)
+ }
if ctx.Request().Method == "POST" {
fn := ctx.FormValue("fn")
@@ -152,12 +183,12 @@ func registerRoutes(p *plugin) {
card.SetValue(vcard.FieldUID, id.URN())
}
- c, addressBook, err := p.clientWithAddressBook(ctx.Session)
- if err != nil {
- return err
+ var p string
+ if ao != nil {
+ p = ao.Path
+ } else {
+ p = path.Join(addressBook.Path, id.String()+".vcf")
}
-
- p := path.Join(addressBook.Path, id.String() + ".vcf")
_, err = c.PutAddressObject(p, card)
if err != nil {
return fmt.Errorf("failed to put address object: %v", err)
@@ -165,13 +196,19 @@ func registerRoutes(p *plugin) {
// TODO: check if the returned AddressObject's path matches, if not
// fetch the new UID (the server may mutate it)
- return ctx.Redirect(http.StatusFound, "/contacts/" + card.Value(vcard.FieldUID))
+ return ctx.Redirect(http.StatusFound, "/contacts/"+card.Value(vcard.FieldUID))
}
return ctx.Render(http.StatusOK, "update-address-object.html", &UpdateAddressObjectRenderData{
BaseRenderData: *koushin.NewBaseRenderData(ctx),
+ AddressObject: ao,
+ Card: card,
})
}
- p.GET("/contacts/create", createContact)
- p.POST("/contacts/create", createContact)
+
+ p.GET("/contacts/create", updateContact)
+ p.POST("/contacts/create", updateContact)
+
+ p.GET("/contacts/:uid/edit", updateContact)
+ p.POST("/contacts/:uid/edit", updateContact)
}