kopia lustrzana https://codeberg.org/nmkj/audon
fix instant room creation
rodzic
e4659da746
commit
d8a5b3898f
|
@ -32,5 +32,5 @@ app.use(createPinia());
|
||||||
app.use(vuetify);
|
app.use(vuetify);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
app.config.compilerOptions.delimiters = ["{%", "%}"];
|
// app.config.compilerOptions.delimiters = ["{%", "%}"];
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
|
1
error.go
1
error.go
|
@ -14,6 +14,7 @@ var (
|
||||||
ErrRoomNotFound = echo.NewHTTPError(http.StatusNotFound, "room_not_found")
|
ErrRoomNotFound = echo.NewHTTPError(http.StatusNotFound, "room_not_found")
|
||||||
ErrOperationNotPermitted = echo.NewHTTPError(http.StatusForbidden, "operation_not_permitted")
|
ErrOperationNotPermitted = echo.NewHTTPError(http.StatusForbidden, "operation_not_permitted")
|
||||||
ErrUserNotFound = echo.NewHTTPError(http.StatusNotFound, "user_not_found")
|
ErrUserNotFound = echo.NewHTTPError(http.StatusNotFound, "user_not_found")
|
||||||
|
ErrAlreadyEnded = echo.NewHTTPError(http.StatusGone, "already_ended")
|
||||||
)
|
)
|
||||||
|
|
||||||
func wrapValidationError(err error) error {
|
func wrapValidationError(err error) error {
|
||||||
|
|
64
room.go
64
room.go
|
@ -32,20 +32,56 @@ func createRoomHandler(c echo.Context) error {
|
||||||
return wrapValidationError(err)
|
return wrapValidationError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host := c.Get("user").(*AudonUser)
|
||||||
|
room.Host = host
|
||||||
|
|
||||||
|
coll := mainDB.Collection(COLLECTION_ROOM)
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
if now.After(room.ScheduledAt) {
|
||||||
|
// host is trying to create an instant room even though there is another instant room that wasn't used, assumed that host won't use such rooms
|
||||||
|
if cur, err := coll.Find(c.Request().Context(),
|
||||||
|
bson.D{
|
||||||
|
{Key: "host.audon_id", Value: host.AudonID},
|
||||||
|
{Key: "ended_at", Value: time.Time{}}, // host didn't close
|
||||||
|
{Key: "$expr", Value: bson.D{ // instant room
|
||||||
|
{Key: "$eq", Value: bson.A{"$created_at", "$scheduled_at"}},
|
||||||
|
}},
|
||||||
|
}); err == nil {
|
||||||
|
defer cur.Close(c.Request().Context())
|
||||||
|
|
||||||
|
roomIDsToBeDeleted := []string{}
|
||||||
|
for cur.Next(c.Request().Context()) {
|
||||||
|
emptyRoom := new(Room)
|
||||||
|
if err := cur.Decode(emptyRoom); err == nil {
|
||||||
|
if !emptyRoom.IsAnyomeInLivekitRoom(c.Request().Context()) {
|
||||||
|
roomIDsToBeDeleted = append(roomIDsToBeDeleted, emptyRoom.RoomID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(roomIDsToBeDeleted) > 0 {
|
||||||
|
coll.DeleteMany(c.Request().Context(), bson.D{{
|
||||||
|
Key: "room_id",
|
||||||
|
Value: bson.D{{Key: "$in", Value: roomIDsToBeDeleted}}},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
room.ScheduledAt = now
|
||||||
|
} else {
|
||||||
|
// TODO: limit the number of rooms one can schedule?
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use a job scheduler to manage rooms?
|
||||||
|
|
||||||
|
room.EndedAt = time.Time{}
|
||||||
|
|
||||||
canonic, err := nanoid.Standard(16)
|
canonic, err := nanoid.Standard(16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
room.RoomID = canonic()
|
room.RoomID = canonic()
|
||||||
|
|
||||||
host := c.Get("user").(*AudonUser)
|
|
||||||
room.Host = host
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
|
||||||
if now.After(room.ScheduledAt) {
|
|
||||||
room.ScheduledAt = now
|
|
||||||
}
|
|
||||||
|
|
||||||
// if cohosts are already registered, retrieve their data from DB
|
// if cohosts are already registered, retrieve their data from DB
|
||||||
for i, cohost := range room.CoHost {
|
for i, cohost := range room.CoHost {
|
||||||
cohostUser, err := findUserByRemote(c.Request().Context(), cohost.RemoteID, cohost.RemoteURL)
|
cohostUser, err := findUserByRemote(c.Request().Context(), cohost.RemoteID, cohost.RemoteURL)
|
||||||
|
@ -55,7 +91,6 @@ func createRoomHandler(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
room.CreatedAt = now
|
room.CreatedAt = now
|
||||||
coll := mainDB.Collection(COLLECTION_ROOM)
|
|
||||||
if _, insertErr := coll.InsertOne(c.Request().Context(), room); insertErr != nil {
|
if _, insertErr := coll.InsertOne(c.Request().Context(), room); insertErr != nil {
|
||||||
c.Logger().Error(insertErr)
|
c.Logger().Error(insertErr)
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
|
@ -65,6 +100,8 @@ func createRoomHandler(c echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func joinRoomHandler(c echo.Context) (err error) {
|
func joinRoomHandler(c echo.Context) (err error) {
|
||||||
|
// TODO: decline the request if user is already in the room
|
||||||
|
|
||||||
roomID := c.Param("id")
|
roomID := c.Param("id")
|
||||||
if err := mainValidator.Var(&roomID, "required,printascii"); err != nil {
|
if err := mainValidator.Var(&roomID, "required,printascii"); err != nil {
|
||||||
return wrapValidationError(err)
|
return wrapValidationError(err)
|
||||||
|
@ -86,7 +123,7 @@ func joinRoomHandler(c echo.Context) (err error) {
|
||||||
|
|
||||||
// check if room has already ended
|
// check if room has already ended
|
||||||
if !room.EndedAt.IsZero() && room.EndedAt.Before(now) {
|
if !room.EndedAt.IsZero() && room.EndedAt.Before(now) {
|
||||||
return echo.NewHTTPError(http.StatusGone, "already_ended")
|
return ErrAlreadyEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
// return 403 if one has been kicked
|
// return 403 if one has been kicked
|
||||||
|
@ -138,6 +175,11 @@ func closeRoomHandler(c echo.Context) error {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError)
|
return echo.NewHTTPError(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return 410 if the room has already ended
|
||||||
|
if !room.EndedAt.IsZero() {
|
||||||
|
return ErrAlreadyEnded
|
||||||
|
}
|
||||||
|
|
||||||
// only host can close the room
|
// only host can close the room
|
||||||
user := c.Get("user").(*AudonUser)
|
user := c.Get("user").(*AudonUser)
|
||||||
if !room.IsHost(user) {
|
if !room.IsHost(user) {
|
||||||
|
@ -220,7 +262,7 @@ func getRoomToken(room *Room, user *AudonUser, canTalk bool) (string, error) {
|
||||||
|
|
||||||
func getRoomInLivekit(ctx context.Context, roomID string) (*livekit.Room, bool) {
|
func getRoomInLivekit(ctx context.Context, roomID string) (*livekit.Room, bool) {
|
||||||
rooms, _ := lkRoomServiceClient.ListRooms(ctx, &livekit.ListRoomsRequest{Names: []string{roomID}})
|
rooms, _ := lkRoomServiceClient.ListRooms(ctx, &livekit.ListRoomsRequest{Names: []string{roomID}})
|
||||||
if len(rooms.GetRooms()) != 0 {
|
if len(rooms.GetRooms()) == 0 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,13 @@ func (r *Room) IsUserInLivekitRoom(ctx context.Context, userID string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Room) IsAnyomeInLivekitRoom(ctx context.Context) bool {
|
||||||
|
participantsInfo, _ := lkRoomServiceClient.ListParticipants(ctx, &livekit.ListParticipantsRequest{Room: r.RoomID})
|
||||||
|
participants := participantsInfo.GetParticipants()
|
||||||
|
|
||||||
|
return len(participants) > 0
|
||||||
|
}
|
||||||
|
|
||||||
func createIndexes(ctx context.Context) error {
|
func createIndexes(ctx context.Context) error {
|
||||||
userColl := mainDB.Collection(COLLECTION_USER)
|
userColl := mainDB.Collection(COLLECTION_USER)
|
||||||
userIndexes, err := userColl.Indexes().ListSpecifications(ctx)
|
userIndexes, err := userColl.Indexes().ListSpecifications(ctx)
|
||||||
|
|
Ładowanie…
Reference in New Issue