Convert events to a client-friendly form

This commit is contained in:
Kegan Dougal 2017-04-13 10:52:13 +01:00
parent 6499b70c24
commit 38605ddf04
3 changed files with 55 additions and 29 deletions

View file

@ -1,6 +1,9 @@
package events
import "encoding/json"
import (
"encoding/json"
"github.com/matrix-org/gomatrixserverlib"
)
// ClientEvent is an event which is fit for consumption by clients, in accordance with the specification.
type ClientEvent struct {
@ -8,7 +11,28 @@ type ClientEvent struct {
Sender string `json:"sender"`
Type string `json:"type"`
StateKey *string `json:"state_key,omitempty"`
Unsigned json.RawMessage `json:"unsigned"`
Unsigned json.RawMessage `json:"unsigned,omitempty"`
OriginServerTS int64 `json:"origin_server_ts"`
EventID string `json:"event_id"`
}
// ToClientEvents converts server events to client events
func ToClientEvents(serverEvs []gomatrixserverlib.Event) []ClientEvent {
evs := make([]ClientEvent, len(serverEvs))
for i, se := range serverEvs {
evs[i] = ToClientEvent(se)
}
return evs
}
// ToClientEvent converts a single server event to a client event
func ToClientEvent(se gomatrixserverlib.Event) ClientEvent {
return ClientEvent{
Content: json.RawMessage(se.Content()),
Sender: se.Sender(),
Type: se.Type(),
StateKey: se.StateKey(),
// TODO: No unsigned / origin_server_ts fields?
EventID: se.EventID(),
}
}

View file

@ -8,6 +8,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/events"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/syncserver/storage"
@ -148,9 +149,9 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err
res.NextBatch = pos.String()
for roomID, d := range data {
jr := types.NewJoinResponse()
jr.Timeline.Events = d.RecentEvents
jr.Timeline.Events = events.ToClientEvents(d.RecentEvents)
jr.Timeline.Limited = true
jr.State.Events = d.State
jr.State.Events = events.ToClientEvents(d.State)
res.Rooms.Join[roomID] = *jr
}
return res, nil
@ -170,16 +171,16 @@ func (rp *RequestPool) currentSyncForUser(req syncRequest) (*types.Response, err
// c) Check if the user is CURRENTLY left/banned. If so, add room to 'archived' block. // Synapse has a TODO: How do we handle ban -> leave in same batch?
// 4) Add joined rooms (joined room list)
events, err := rp.db.EventsInRange(req.since, currentPos)
evs, err := rp.db.EventsInRange(req.since, currentPos)
if err != nil {
return nil, err
}
res := types.NewResponse()
// for now, dump everything as join timeline events
for _, ev := range events {
for _, ev := range evs {
roomData := res.Rooms.Join[ev.RoomID()]
roomData.Timeline.Events = append(roomData.Timeline.Events, ev)
roomData.Timeline.Events = append(roomData.Timeline.Events, events.ToClientEvent(ev))
res.Rooms.Join[ev.RoomID()] = roomData
}

View file

@ -3,6 +3,7 @@ package types
import (
"strconv"
"github.com/matrix-org/dendrite/clientapi/events"
"github.com/matrix-org/gomatrixserverlib"
)
@ -24,10 +25,10 @@ type RoomData struct {
type Response struct {
NextBatch string `json:"next_batch"`
AccountData struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"account_data"`
Presence struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"presence"`
Rooms struct {
Join map[string]JoinResponse `json:"join"`
@ -49,8 +50,8 @@ func NewResponse() *Response {
// TODO: We really shouldn't have to do all this to coerce encoding/json to Do The Right Thing. We should
// really be using our own Marshal/Unmarshal implementations otherwise this may prove to be a CPU bottleneck.
// This also applies to NewJoinResponse, NewInviteResponse and NewLeaveResponse.
res.AccountData.Events = make([]gomatrixserverlib.Event, 0)
res.Presence.Events = make([]gomatrixserverlib.Event, 0)
res.AccountData.Events = make([]events.ClientEvent, 0)
res.Presence.Events = make([]events.ClientEvent, 0)
return &res
}
@ -58,61 +59,61 @@ func NewResponse() *Response {
// JoinResponse represents a /sync response for a room which is under the 'join' key.
type JoinResponse struct {
State struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"state"`
Timeline struct {
Events []gomatrixserverlib.Event `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
Events []events.ClientEvent `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
} `json:"timeline"`
Ephemeral struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"ephemeral"`
AccountData struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"account_data"`
}
// NewJoinResponse creates an empty response with initialised arrays.
func NewJoinResponse() *JoinResponse {
res := JoinResponse{}
res.State.Events = make([]gomatrixserverlib.Event, 0)
res.Timeline.Events = make([]gomatrixserverlib.Event, 0)
res.Ephemeral.Events = make([]gomatrixserverlib.Event, 0)
res.AccountData.Events = make([]gomatrixserverlib.Event, 0)
res.State.Events = make([]events.ClientEvent, 0)
res.Timeline.Events = make([]events.ClientEvent, 0)
res.Ephemeral.Events = make([]events.ClientEvent, 0)
res.AccountData.Events = make([]events.ClientEvent, 0)
return &res
}
// InviteResponse represents a /sync response for a room which is under the 'invite' key.
type InviteResponse struct {
InviteState struct {
Events []gomatrixserverlib.Event
Events []events.ClientEvent
} `json:"invite_state"`
}
// NewInviteResponse creates an empty response with initialised arrays.
func NewInviteResponse() *InviteResponse {
res := InviteResponse{}
res.InviteState.Events = make([]gomatrixserverlib.Event, 0)
res.InviteState.Events = make([]events.ClientEvent, 0)
return &res
}
// LeaveResponse represents a /sync response for a room which is under the 'leave' key.
type LeaveResponse struct {
State struct {
Events []gomatrixserverlib.Event `json:"events"`
Events []events.ClientEvent `json:"events"`
} `json:"state"`
Timeline struct {
Events []gomatrixserverlib.Event `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
Events []events.ClientEvent `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
} `json:"timeline"`
}
// NewLeaveResponse creates an empty response with initialised arrays.
func NewLeaveResponse() *LeaveResponse {
res := LeaveResponse{}
res.State.Events = make([]gomatrixserverlib.Event, 0)
res.Timeline.Events = make([]gomatrixserverlib.Event, 0)
res.State.Events = make([]events.ClientEvent, 0)
res.Timeline.Events = make([]events.ClientEvent, 0)
return &res
}