dendrite/syncapi/routing/threads.go

108 lines
2.8 KiB
Go
Raw Normal View History

2024-07-31 00:55:58 -05:00
package routing
import (
2024-08-09 02:24:12 -05:00
rstypes "github.com/matrix-org/dendrite/roomserver/types"
"net/http"
"strconv"
2024-07-31 00:55:58 -05:00
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/syncapi/storage"
"github.com/matrix-org/dendrite/syncapi/synctypes"
"github.com/matrix-org/dendrite/syncapi/types"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/matrix-org/util"
"github.com/sirupsen/logrus"
)
type ThreadsResponse struct {
Chunk []synctypes.ClientEvent `json:"chunk"`
NextBatch string `json:"next_batch,omitempty"`
}
func Threads(
req *http.Request,
2024-08-09 02:46:48 -05:00
device *userapi.Device,
2024-07-31 00:55:58 -05:00
syncDB storage.Database,
rsAPI api.SyncRoomserverAPI,
rawRoomID string) util.JSONResponse {
var err error
roomID, err := spec.NewRoomID(rawRoomID)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.InvalidParam("invalid room ID"),
}
}
limit, err := strconv.ParseUint(req.URL.Query().Get("limit"), 10, 64)
if err != nil {
limit = 50
}
if limit > 100 {
limit = 100
}
2024-08-09 02:24:12 -05:00
var from types.StreamPosition
if f := req.URL.Query().Get("from"); f != "" {
if from, err = types.NewStreamPositionFromString(f); err != nil {
return util.ErrorResponse(err)
}
}
2024-07-31 00:55:58 -05:00
include := req.URL.Query().Get("include")
snapshot, err := syncDB.NewDatabaseSnapshot(req.Context())
if err != nil {
logrus.WithError(err).Error("Failed to get snapshot for relations")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
var succeeded bool
defer sqlutil.EndTransactionWithCheck(snapshot, &succeeded, &err)
res := &ThreadsResponse{
Chunk: []synctypes.ClientEvent{},
}
2024-08-09 02:24:12 -05:00
var userID string
2024-07-31 00:55:58 -05:00
if include == "participated" {
2024-08-09 02:24:12 -05:00
_, err := spec.NewUserID(device.UserID, true)
2024-07-31 00:55:58 -05:00
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("device.UserID invalid")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("internal server error"),
}
}
2024-08-09 02:24:12 -05:00
userID = device.UserID
} else {
userID = ""
}
var headeredEvents []*rstypes.HeaderedEvent
headeredEvents, _, res.NextBatch, err = snapshot.ThreadsFor(
req.Context(), roomID.String(), userID, from, limit,
)
2024-08-09 06:25:26 -05:00
if err != nil {
return util.ErrorResponse(err)
}
2024-08-09 02:24:12 -05:00
for _, event := range headeredEvents {
ce, err := synctypes.ToClientEvent(event, synctypes.FormatAll, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return rsAPI.QueryUserIDForSender(req.Context(), roomID, senderID)
})
if err != nil {
return util.ErrorResponse(err)
}
res.Chunk = append(res.Chunk, *ce)
}
return util.JSONResponse{
2024-08-09 06:15:20 -05:00
Code: http.StatusOK,
2024-08-09 02:24:12 -05:00
JSON: res,
2024-07-31 00:55:58 -05:00
}
}