audon/user.go

195 wiersze
5.2 KiB
Go

package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/livekit/protocol/livekit"
mastodon "github.com/mattn/go-mastodon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MastodonAccount struct {
ID mastodon.ID `json:"id"`
Username string `json:"username"`
Acct string `json:"acct"`
DisplayName string `json:"displayName"`
Locked bool `json:"locked"`
CreatedAt time.Time `json:"createdAt"`
FollowersCount int64 `json:"followersCount"`
FollowingCount int64 `json:"followingCount"`
StatusesCount int64 `json:"statusesCount"`
Note string `json:"note"`
URL string `json:"url"`
Avatar string `json:"avatar"`
AvatarStatic string `json:"avatarStatic"`
Header string `json:"header"`
HeaderStatic string `json:"headerStatic"`
Emojis []mastodon.Emoji `json:"emojis"`
Moved *MastodonAccount `json:"moved"`
Fields []mastodon.Field `json:"fields"`
Bot bool `json:"bot"`
Discoverable bool `json:"discoverable"`
Source *mastodon.AccountSource `json:"source"`
}
func getUserHandler(c echo.Context) error {
audonID := c.Param("id")
if err := mainValidator.Var(&audonID, "required,printascii"); err != nil {
return wrapValidationError(err)
}
user, err := findUserByID(c.Request().Context(), audonID)
if err != nil {
return ErrUserNotFound
}
return c.JSON(http.StatusOK, user)
}
func getStatusHandler(c echo.Context) error {
u := c.Get("user").(*AudonUser)
status, err := u.GetCurrentRoomStatus(c.Request().Context())
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
}
return c.JSON(http.StatusOK, status)
}
func redirectUserHandler(c echo.Context) error {
input := c.Param("webfinger")
if err := mainValidator.Var(&input, "required,startswith=@,min=4"); err != nil {
return wrapValidationError(err)
}
webfinger := input[1:]
if err := mainValidator.Var(&webfinger, "email"); err != nil {
return wrapValidationError(err)
}
user, err := findUserByWebfinger(c.Request().Context(), webfinger)
if err != nil || user == nil {
return ErrUserNotFound
}
coll := mainDB.Collection(COLLECTION_ROOM)
opts := options.FindOne().SetSort(bson.D{{Key: "created_at", Value: -1}})
var room Room
searchCohost := false
if err := coll.FindOne(c.Request().Context(), bson.D{
{Key: "host.audon_id", Value: user.AudonID},
}, opts).Decode(&room); err == nil {
if room.ExistsInLivekit(c.Request().Context()) {
// redirect to the hosting room if online
return c.Redirect(http.StatusFound, fmt.Sprintf("/r/%s", room.RoomID))
} else {
searchCohost = true
}
} else {
searchCohost = true
}
if searchCohost {
// redirect to the first cohosting room if online
status, err := user.GetCurrentRoomStatus(c.Request().Context())
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
}
for _, v := range status {
if v.Role == "cohost" {
return c.Redirect(http.StatusFound, fmt.Sprintf("/r/%s", v.RoomID))
}
}
}
return c.Redirect(http.StatusFound, "/offline")
}
func (a *AudonUser) Equal(u *AudonUser) bool {
if a == nil {
return false
}
return a.AudonID == u.AudonID || a.Webfinger == u.Webfinger
}
func (a *AudonUser) InLivekit(ctx context.Context) (bool, error) {
rooms, err := a.GetCurrentLivekitRooms(ctx)
if err != nil {
return false, err
}
return len(rooms) > 0, nil
}
func (a *AudonUser) ClearUserAvatar(ctx context.Context) error {
coll := mainDB.Collection(COLLECTION_USER)
_, err := coll.UpdateOne(ctx,
bson.D{{Key: "audon_id", Value: a.AudonID}},
bson.D{
{Key: "$set", Value: bson.D{{Key: "avatar", Value: ""}}},
})
// if err == nil {
// os.Remove(a.getAvatarImagePath(a.AvatarFile))
// }
return err
}
type UserStatus struct {
RoomID string `json:"roomID"`
Role string `json:"role"`
}
func (a *AudonUser) GetCurrentRoomStatus(ctx context.Context) ([]UserStatus, error) {
rooms, err := a.GetCurrentLivekitRooms(ctx)
if err != nil {
return nil, err
}
roomList := make([]UserStatus, len(rooms))
for _, r := range rooms {
meta, _ := getRoomMetadataFromLivekitRoom(r)
role := "listener"
if meta.Room.IsHost(a) {
role = "host"
} else if meta.Room.IsCoHost(a) {
role = "cohost"
} else if meta.IsSpeaker(a) {
role = "speaker"
}
roomList = append(roomList, UserStatus{
RoomID: r.GetName(),
Role: role,
})
}
for _, s := range roomList {
if s.Role == "host" {
return roomList, nil
}
}
allRooms, err := lkRoomServiceClient.ListRooms(ctx, &livekit.ListRoomsRequest{})
if err != nil {
return nil, err
}
for _, r := range allRooms.GetRooms() {
meta, _ := getRoomMetadataFromLivekitRoom(r)
if meta.IsHost(a) {
roomList = append(roomList, UserStatus{
RoomID: r.GetName(),
Role: "host",
})
}
}
return roomList, nil
}