groupware: add ical blob parsing endpoint

This commit is contained in:
Pascal Bleser
2025-10-28 10:45:29 +01:00
parent 585fed1a03
commit 64bf860eea
4 changed files with 85 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
package jmap
import (
"context"
"github.com/opencloud-eu/opencloud/pkg/log"
)
func (j *Client) ParseICalendarBlob(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, blobIds []string) (CalendarEventParseResponse, SessionState, Language, Error) {
logger = j.logger("ParseICalendarBlob", session, logger)
cmd, err := j.request(session, logger,
invocation(CommandCalendarEventParse, CalendarEventParseCommand{AccountId: accountId, BlobIDs: blobIds}, "0"),
)
if err != nil {
return CalendarEventParseResponse{}, "", "", err
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, acceptLanguage, func(body *Response) (CalendarEventParseResponse, Error) {
var response CalendarEventParseResponse
err = retrieveResponseMatchParameters(logger, body, CommandCalendarEventParse, "0", &response)
if err != nil {
return CalendarEventParseResponse{}, err
}
return response, nil
})
}

View File

@@ -3790,7 +3790,7 @@ type CalendarEvent struct {
//
// The id uniquely identifies a JSCalendar Event with a particular `uid` and
// `recurrenceId` within a particular account.
Id string `json:"id"`
Id string `json:"id,omitempty"`
// This is only defined if the `id` property is a synthetic id, generated by the
// server to represent a particular instance of a recurring event (immutable; server-set).
@@ -5204,6 +5204,35 @@ type ContactCardSetResponse struct {
NotDestroyed map[string]SetError `json:"notDestroyed,omitempty"`
}
type CalendarEventParseCommand struct {
// The id of the account to use.
AccountId string `json:"accountId"`
// The ids of the blobs to parse
BlobIDs []string `json:"blobIds,omitempty"`
// If supplied, only the properties listed in the array are returned for each CalendarEvent object.
//
// If omitted, defaults to all the properties.
Properties []string `json:"properties,omitempty"`
}
type CalendarEventParseResponse struct {
// The id of the account used for the call.
AccountId string `json:"accountId"`
// A map of blob ids to parsed CalendarEvent objects representations for each successfully
// parsed blob, or null if none.
Parsed map[string][]CalendarEvent `json:"parsed,omitempty"`
// A list of blob ids given that could not be found, or null if none.
NotFound []string `json:"notFound,omitempty"`
// A list of blob ids given that corresponded to blobs that could not be parsed as
// CalendarEvents, or null if none.
NotParsable []string `json:"notParsable,omitempty"`
}
type ErrorResponse struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
@@ -5234,6 +5263,7 @@ const (
CommandContactCardQuery Command = "ContactCard/query"
CommandContactCardGet Command = "ContactCard/get"
CommandContactCardSet Command = "ContactCard/set"
CommandCalendarEventParse Command = "CalendarEvent/parse"
)
var CommandResponseTypeMap = map[Command]func() any{
@@ -5260,4 +5290,5 @@ var CommandResponseTypeMap = map[Command]func() any{
CommandContactCardQuery: func() any { return ContactCardQueryResponse{} },
CommandContactCardGet: func() any { return ContactCardGetResponse{} },
CommandContactCardSet: func() any { return ContactCardSetResponse{} },
CommandCalendarEventParse: func() any { return CalendarEventParseResponse{} },
}

View File

@@ -2,9 +2,11 @@ package groupware
import (
"net/http"
"strings"
"github.com/go-chi/chi/v5"
"github.com/opencloud-eu/opencloud/pkg/jmap"
"github.com/opencloud-eu/opencloud/pkg/log"
)
// When the request succeeds.
@@ -105,3 +107,24 @@ func (g *Groupware) GetEventsInCalendar(w http.ResponseWriter, r *http.Request)
return response(events, req.session.State, "")
})
}
func (g *Groupware) ParseIcalBlob(w http.ResponseWriter, r *http.Request) {
g.respond(w, r, func(req Request) Response {
accountId, err := req.GetAccountIdForBlob()
if err != nil {
return errorResponse(err)
}
blobId := chi.URLParam(r, UriParamBlobId)
blobIds := strings.Split(blobId, ",")
l := req.logger.With().Array(UriParamBlobId, log.SafeStringArray(blobIds))
logger := log.From(l)
resp, sessionState, lang, jerr := g.jmap.ParseICalendarBlob(accountId, req.session, req.ctx, logger, req.language(), blobIds)
if jerr != nil {
return req.errorResponseFromJmap(jerr)
}
return response(resp, sessionState, lang)
})
}

View File

@@ -113,6 +113,9 @@ func (g *Groupware) Route(r chi.Router) {
r.Get("/{blobid}", g.GetBlobMeta)
r.Get("/{blobid}/{blobname}", g.DownloadBlob) // ?type=
})
r.Route("/ical", func(r chi.Router) {
r.Get("/{blobid}", g.ParseIcalBlob)
})
r.Route("/addressbooks", func(r chi.Router) {
r.Get("/", g.GetAddressbooks)
r.Get("/{addressbookid}", g.GetAddressbook)