mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-06 04:11:21 -05:00
groupware: some fixes accordingly to the latest JMAP and jscalendarbis RFCs
This commit is contained in:
@@ -17,6 +17,7 @@ type LocalDateTime struct {
|
||||
}
|
||||
*/
|
||||
type LocalDateTime string
|
||||
type UTCDateTime string
|
||||
|
||||
type TypeOfRelation string
|
||||
type TypeOfLink string
|
||||
@@ -41,7 +42,6 @@ type Relationship string
|
||||
type Display string
|
||||
type Rel string
|
||||
type LocationTypeOption string
|
||||
type LocationRelation string
|
||||
type VirtualLocationFeature string
|
||||
type Frequency string
|
||||
type Skip string
|
||||
@@ -301,9 +301,6 @@ const (
|
||||
LocationTypeOptionWaterFacility = LocationTypeOption("water-facility")
|
||||
LocationTypeOptionYouthCamp = LocationTypeOption("youth-camp")
|
||||
|
||||
LocationRelationStart = LocationRelation("start")
|
||||
LocationRelationEnd = LocationRelation("end")
|
||||
|
||||
VirtualLocationFeatureAudio = VirtualLocationFeature("audio")
|
||||
VirtualLocationFeatureChat = VirtualLocationFeature("chat")
|
||||
VirtualLocationFeatureFeed = VirtualLocationFeature("feed")
|
||||
@@ -611,11 +608,6 @@ var (
|
||||
LocationTypeOptionYouthCamp,
|
||||
}
|
||||
|
||||
LocationRelations = []LocationRelation{
|
||||
LocationRelationStart,
|
||||
LocationRelationEnd,
|
||||
}
|
||||
|
||||
Frequencies = []Frequency{
|
||||
FrequencyYearly,
|
||||
FrequencyMonthly,
|
||||
@@ -645,7 +637,6 @@ var (
|
||||
"relatedTo",
|
||||
"replyTo",
|
||||
"sentBy",
|
||||
"timeZones",
|
||||
"uid",
|
||||
}
|
||||
|
||||
@@ -836,13 +827,6 @@ type Link struct {
|
||||
// server to avoid embedding arbitrarily large data in JSCalendar object instances.
|
||||
Href string `json:"href"`
|
||||
|
||||
// This MUST be a valid content-id value according to the definition of Section 2 of [RFC2392].
|
||||
//
|
||||
// The value MUST be unique within this `Link` object but has no meaning beyond that.
|
||||
//
|
||||
// It MAY be different from the link id for this `Link` object.
|
||||
Cid string `json:"cid,omitempty"`
|
||||
|
||||
// This is the media type [RFC6838] of the resource, if known.
|
||||
ContentType string `json:"contentType,omitempty"`
|
||||
|
||||
@@ -897,21 +881,6 @@ type Location struct {
|
||||
// The value for each key in the map MUST be `true`.
|
||||
LocationTypes map[LocationTypeOption]bool `json:"locationTypes,omitempty"`
|
||||
|
||||
// This specifies the relation between this location and the time of the JSCalendar object.
|
||||
//
|
||||
// This is primarily to allow events representing travel to specify the location of departure (at the
|
||||
// start of the event) and location of arrival (at the end); this is particularly important if these
|
||||
// locations are in different time zones, as a client may wish to highlight this information for the user.
|
||||
//
|
||||
// This MUST be one of the following values; any value the client or server doesn't understand
|
||||
// should be treated the same as if this property is omitted:
|
||||
// !- `start`: The event/task described by this JSCalendar object occurs at this location at the time the event/task starts.
|
||||
// !- `end`: The event/task described by this JSCalendar object occurs at this location at the time the event/task ends.
|
||||
RelativeTo LocationRelation `json:"relativeTo,omitempty"`
|
||||
|
||||
// This is a time zone for this location.
|
||||
TimeZone string `json:"timeZone,omitempty"`
|
||||
|
||||
// This is a geo: URI [RFC5870] for the location.
|
||||
Coordinates string `json:"coordinates,omitempty"`
|
||||
|
||||
@@ -1645,15 +1614,11 @@ type CommonObject struct {
|
||||
ProdId string `json:"prodId,omitempty"`
|
||||
|
||||
// This is the date and time this object was initially created.
|
||||
//
|
||||
// TODO serialize as UTCDateTime
|
||||
Created time.Time `json:"created,omitzero"`
|
||||
Created UTCDateTime `json:"created,omitzero"`
|
||||
|
||||
// This is the date and time the data in this object was last modified (or its creation date/time
|
||||
// if not modified since).
|
||||
//
|
||||
// TODO serialize as UTCDateTime
|
||||
Updated time.Time `json:"updated,omitzero"`
|
||||
Updated UTCDateTime `json:"updated,omitzero"`
|
||||
|
||||
// This is a short summary of the object.
|
||||
Title string `json:"title,omitempty"`
|
||||
@@ -1719,35 +1684,6 @@ type CommonObject struct {
|
||||
// [Section 4.3 of CSS Color Module Level 3]: https://www.w3.org/TR/css-color-3/#svg-color
|
||||
// [Section 4.2.1 of CSS Color Module Level 3]: https://www.w3.org/TR/css-color-3/#rgb-color
|
||||
Color string `json:"color,omitempty"`
|
||||
|
||||
// This maps identifiers of custom time zones to their time zone definitions.
|
||||
//
|
||||
// The following restrictions apply for each key in the map:
|
||||
// !- To avoid conflict with names in the IANA Time Zone Database [TZDB], it MUST start with the `/` character.
|
||||
// !- It MUST be a valid `paramtext` value, as specified in Section 3.1 of [RFC5545].
|
||||
// !- At least one other property in the same JSCalendar object MUST reference a time zone using this identifier (i.e.,
|
||||
// orphaned time zones are not allowed).
|
||||
//
|
||||
// An identifier need only be unique to this JSCalendar object.
|
||||
//
|
||||
// It MAY differ from the tzId property value of the TimeZone object it maps to.
|
||||
//
|
||||
// A JSCalendar object may be part of a hierarchy of other JSCalendar objects (say, an `Event` is an entry in a `Group`).
|
||||
//
|
||||
// In this case, the set of time zones is the sum of the time zone definitions of this object and its parent objects.
|
||||
//
|
||||
// If multiple time zones with the same identifier exist, then the definition closest to the calendar object in relation
|
||||
// to its parents MUST be used.
|
||||
//
|
||||
// (In context of `Event`, a time zone definition in its `timeZones` property has precedence over a definition of the
|
||||
// same id in the `Group`).
|
||||
//
|
||||
// Time zone definitions in any children of the calendar object MUST be ignored.
|
||||
//
|
||||
// A `TimeZone` object maps a `VTIMEZONE` component from iCalendar, and the semantics are as defined in [RFC5545].
|
||||
//
|
||||
// A valid time zone MUST define at least one transition rule in the `standard` or `daylight` property.
|
||||
TimeZones map[string]TimeZone `json:"timeZones,omitempty"`
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -2128,6 +2064,14 @@ type Event struct {
|
||||
// the `Event`'s Location objects (see Section 4.2.5).
|
||||
Duration Duration `json:"duration,omitempty"`
|
||||
|
||||
// This identifies the time zone in which this event ends, for cases where the start and time zones of the event differ
|
||||
// (e.g., a transcontinental flight).
|
||||
//
|
||||
// If this property is not set, then the event starts and ends in the same time zone.
|
||||
//
|
||||
// This property MUST NOT be set if the timeZone property value is null or not set.
|
||||
EndTimeZone string `json:"endTimeZone,omitempty"`
|
||||
|
||||
// This is the scheduling status (Section 4.4) of an Event.
|
||||
//
|
||||
// If set, it MUST be one of the following values, another value registered in the IANA
|
||||
|
||||
@@ -74,7 +74,6 @@ func TestLink(t *testing.T) {
|
||||
}`, Link{
|
||||
Type: LinkType,
|
||||
Href: "https://opencloud.eu.example.com/f72ae875-40be-48a4-84ff-aea9aed3e085.png",
|
||||
Cid: "c1",
|
||||
ContentType: "image/png",
|
||||
Size: 128912,
|
||||
Rel: RelIcon,
|
||||
@@ -115,14 +114,11 @@ func TestLocation(t *testing.T) {
|
||||
LocationTypeOptionLandmarkAddress: true,
|
||||
LocationTypeOptionIndustrial: true,
|
||||
},
|
||||
RelativeTo: LocationRelationStart,
|
||||
TimeZone: "Europe/Paris",
|
||||
Coordinates: "geo:48.8559324,2.2932441",
|
||||
Links: map[string]Link{
|
||||
"l1": {
|
||||
Type: LinkType,
|
||||
Href: "https://upload.wikimedia.org/wikipedia/commons/f/fd/Eiffel_blue.PNG",
|
||||
Cid: "cl1",
|
||||
ContentType: "image/png",
|
||||
Size: 12345,
|
||||
Rel: RelIcon,
|
||||
@@ -340,7 +336,6 @@ func TestParticipant(t *testing.T) {
|
||||
"l1": {
|
||||
Type: LinkType,
|
||||
Href: "https://opa.org/opa.png",
|
||||
Cid: "c1",
|
||||
ContentType: "image/png",
|
||||
Size: 182912,
|
||||
Rel: RelIcon,
|
||||
@@ -608,11 +603,13 @@ func TestTimeZone(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEvent(t *testing.T) {
|
||||
ts1, err := time.Parse(time.RFC3339, "2025-09-25T18:26:14+02:00")
|
||||
local1 := "2025-09-25T18:26:14"
|
||||
ts1, err := time.Parse(time.RFC3339, local1+"+02:00")
|
||||
require.NoError(t, err)
|
||||
ts1 = ts1.UTC()
|
||||
|
||||
ts2, err := time.Parse(time.RFC3339, "2025-09-29T15:53:01+02:00")
|
||||
local2 := "2025-09-29T15:53:01"
|
||||
ts2, err := time.Parse(time.RFC3339, local2+"+02:00")
|
||||
require.NoError(t, err)
|
||||
ts2 = ts2.UTC()
|
||||
|
||||
@@ -692,8 +689,8 @@ func TestEvent(t *testing.T) {
|
||||
CommonObject: CommonObject{
|
||||
Uid: "b422cfec-f7b4-4e04-8ec6-b794007f63f1",
|
||||
ProdId: "OpenCloud 1.0",
|
||||
Created: ts1,
|
||||
Updated: ts2,
|
||||
Created: UTCDateTime(local1),
|
||||
Updated: UTCDateTime(local2),
|
||||
Title: "End of year party",
|
||||
Description: "It's the party at the end of the year.",
|
||||
DescriptionContentType: "text/plain",
|
||||
@@ -713,12 +710,6 @@ func TestEvent(t *testing.T) {
|
||||
"cat": true,
|
||||
},
|
||||
Color: "oil",
|
||||
TimeZones: map[string]TimeZone{
|
||||
"cest": {
|
||||
Type: TimeZoneType,
|
||||
TzId: "cest",
|
||||
},
|
||||
},
|
||||
},
|
||||
RelatedTo: map[string]Relation{
|
||||
"a": {
|
||||
@@ -738,8 +729,6 @@ func TestEvent(t *testing.T) {
|
||||
LocationTypes: map[LocationTypeOption]bool{
|
||||
LocationTypeOptionBar: true,
|
||||
},
|
||||
RelativeTo: LocationRelationStart,
|
||||
TimeZone: "cest",
|
||||
Coordinates: "geo:16.7685657,-4.8629852",
|
||||
Links: map[string]Link{
|
||||
"l1": {
|
||||
|
||||
@@ -80,8 +80,8 @@ var E1 = jmap.CalendarEvent{
|
||||
CommonObject: jscalendar.CommonObject{
|
||||
Uid: "9a7ab91a-edca-4988-886f-25e00743430d",
|
||||
ProdId: "Mock 0.0",
|
||||
Created: mustParseTime("2025-09-29T16:17:18Z"),
|
||||
Updated: mustParseTime("2025-09-29T16:17:18Z"),
|
||||
Created: "2025-09-29T16:17:18",
|
||||
Updated: "2025-09-29T16:17:18",
|
||||
Title: "Meeting of the Minds",
|
||||
Description: "Internal meeting about the grand strategy for the future",
|
||||
DescriptionContentType: "text/plain",
|
||||
@@ -103,12 +103,6 @@ var E1 = jmap.CalendarEvent{
|
||||
"internal": true,
|
||||
},
|
||||
Color: "purple",
|
||||
TimeZones: map[string]jscalendar.TimeZone{
|
||||
"airee8ai": {
|
||||
Type: jscalendar.TimeZoneType,
|
||||
TzId: "CEST",
|
||||
},
|
||||
},
|
||||
},
|
||||
RelatedTo: map[string]jscalendar.Relation{},
|
||||
Sequence: 0,
|
||||
@@ -121,8 +115,6 @@ var E1 = jmap.CalendarEvent{
|
||||
LocationTypes: map[jscalendar.LocationTypeOption]bool{
|
||||
jscalendar.LocationTypeOptionOffice: true,
|
||||
},
|
||||
RelativeTo: jscalendar.LocationRelationStart,
|
||||
TimeZone: "CEST",
|
||||
Coordinates: "geo:52.5334956,13.4079872",
|
||||
Links: map[string]jscalendar.Link{
|
||||
"eefe2pax": {
|
||||
|
||||
@@ -82,8 +82,8 @@ var T1 = jmap.Task{
|
||||
CommonObject: jscalendar.CommonObject{
|
||||
Uid: "7da0d4a2-385c-430f-9022-61db302734d9",
|
||||
ProdId: "Mock 0.0",
|
||||
Created: mustParseTime("2025-10-01T17:31:49Z"),
|
||||
Updated: mustParseTime("2025-10-01T17:35:12Z"),
|
||||
Created: "2025-10-01T17:31:49",
|
||||
Updated: "2025-10-01T17:35:12",
|
||||
Title: "Crossing the Ring",
|
||||
Description: "We need to cross the Ring the protomolecule opened.",
|
||||
DescriptionContentType: "text/plain",
|
||||
@@ -117,8 +117,6 @@ var T1 = jmap.Task{
|
||||
LocationTypes: map[jscalendar.LocationTypeOption]bool{
|
||||
jscalendar.LocationTypeOptionLandmarkAddress: true,
|
||||
},
|
||||
RelativeTo: jscalendar.LocationRelationStart,
|
||||
TimeZone: "UTC",
|
||||
Coordinates: "geo:40.4165583,-3.7063595",
|
||||
Links: map[string]jscalendar.Link{
|
||||
"jeeshei5": {
|
||||
|
||||
Reference in New Issue
Block a user