Skip to content

Commit

Permalink
feat: API recordingInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
jibon57 committed Nov 20, 2023
1 parent 25b58d5 commit 5a67d9c
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 29 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/jordic/lti v0.0.0-20160211051708-2c756eacbab9
github.com/livekit/protocol v1.9.1
github.com/livekit/server-sdk-go v1.1.1
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120104949-40a993b31052
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120144725-8b2fcffff319
github.com/redis/go-redis/v9 v9.3.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120104949-40a993b31052 h1:aLYiRlXh1RQdR9RhDW951BGZVqHFzzhTB++164PqaZ8=
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120104949-40a993b31052/go.mod h1:KXtBamxckRtrcWtmY5BIboDkhM5elHg23hZxbA9lw8Y=
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120144725-8b2fcffff319 h1:lEnpVW75RJQTh2a6ZJRJjuyYuftBft0S8xYmA2DETis=
github.com/mynaparrot/plugnmeet-protocol v0.0.0-20231120144725-8b2fcffff319/go.mod h1:KXtBamxckRtrcWtmY5BIboDkhM5elHg23hZxbA9lw8Y=
github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E=
github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8=
github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY=
Expand Down
19 changes: 16 additions & 3 deletions pkg/controllers/analytics_auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controllers

import (
"github.com/bufbuild/protovalidate-go"
"github.com/gofiber/fiber/v2"
"github.com/mynaparrot/plugnmeet-protocol/plugnmeet"
"github.com/mynaparrot/plugnmeet-protocol/utils"
Expand All @@ -18,8 +19,12 @@ func HandleFetchAnalytics(c *fiber.Ctx) error {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand Down Expand Up @@ -50,8 +55,12 @@ func HandleDeleteAnalytics(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand All @@ -73,8 +82,12 @@ func HandleGetAnalyticsDownloadToken(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand Down
47 changes: 44 additions & 3 deletions pkg/controllers/recording_auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controllers

import (
"github.com/bufbuild/protovalidate-go"
"github.com/gofiber/fiber/v2"
"github.com/mynaparrot/plugnmeet-protocol/plugnmeet"
"github.com/mynaparrot/plugnmeet-protocol/utils"
Expand All @@ -17,8 +18,12 @@ func HandleFetchRecordings(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand All @@ -40,6 +45,34 @@ func HandleFetchRecordings(c *fiber.Ctx) error {
return utils.SendProtoJsonResponse(c, r)
}

func HandleRecordingInfo(c *fiber.Ctx) error {
req := new(plugnmeet.RecordingInfoReq)
op := protojson.UnmarshalOptions{
DiscardUnknown: true,
}
err := op.Unmarshal(c.Body(), req)
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

m := models.NewRecordingAuth()
result, err := m.RecordingInfo(req)
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

return utils.SendProtoJsonResponse(c, result)
}

func HandleDeleteRecording(c *fiber.Ctx) error {
req := new(plugnmeet.DeleteRecordingReq)
op := protojson.UnmarshalOptions{
Expand All @@ -49,8 +82,12 @@ func HandleDeleteRecording(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand All @@ -72,8 +109,12 @@ func HandleGetDownloadToken(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand Down
37 changes: 27 additions & 10 deletions pkg/controllers/room_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,14 @@ func HandleIsRoomActive(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
if req.RoomId == "" {
return utils.SendCommonProtoJsonResponse(c, false, "room_id required")

v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

m := models.NewRoomAuthModel()
Expand All @@ -71,11 +77,13 @@ func HandleGetActiveRoomInfo(c *fiber.Ctx) error {
"msg": err.Error(),
})
}
if req.RoomId == "" {
return c.JSON(fiber.Map{
"status": false,
"msg": "room_id required",
})
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
m := models.NewRoomAuthModel()
status, msg, res := m.GetActiveRoomInfo(req)
Expand Down Expand Up @@ -111,8 +119,13 @@ func HandleEndRoom(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
if req.RoomId == "" {
return utils.SendCommonProtoJsonResponse(c, false, "room_id required")
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

m := models.NewRoomAuthModel()
Expand All @@ -130,8 +143,12 @@ func HandleFetchPastRooms(c *fiber.Ctx) error {
if err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}
err = req.Validate()
v, err := protovalidate.New()
if err != nil {
utils.SendCommonProtoJsonResponse(c, false, "failed to initialize validator: "+err.Error())
}

if err = v.Validate(req); err != nil {
return utils.SendCommonProtoJsonResponse(c, false, err.Error())
}

Expand Down
1 change: 1 addition & 0 deletions pkg/handler/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func Router() *fiber.App {
// for recording
recording := auth.Group("/recording")
recording.Post("/fetch", controllers.HandleFetchRecordings)
recording.Post("/recordingInfo", controllers.HandleRecordingInfo)
recording.Post("/delete", controllers.HandleDeleteRecording)
recording.Post("/getDownloadToken", controllers.HandleGetDownloadToken)

Expand Down
28 changes: 26 additions & 2 deletions pkg/models/analytics_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,31 @@ func (m *AnalyticsAuthModel) fetchAnalytic(fileId string) (*plugnmeet.AnalyticsI
err := row.Scan(&analytic.RoomId, &analytic.FileId, &analytic.FileName, &analytic.FileSize, &analytic.RoomCreationTime, &analytic.CreationTime)

switch {
case err == sql.ErrNoRows:
case errors.Is(err, sql.ErrNoRows):
err = errors.New("no info found")
case err != nil:
err = errors.New(fmt.Sprintf("query error: %s", err.Error()))
}

if err != nil {
return nil, err
}

return analytic, nil
}

func (m *AnalyticsAuthModel) getAnalyticByRoomTableId(roomTableId int64) (*plugnmeet.AnalyticsInfo, error) {
db := m.db
ctx, cancel := context.WithTimeout(m.ctx, 3*time.Second)
defer cancel()

row := db.QueryRowContext(ctx, "SELECT room_id, file_id, file_name, file_size, room_creation_time, creation_time FROM "+m.app.FormatDBTable("room_analytics")+" WHERE room_table_id = ?", roomTableId)

analytic := new(plugnmeet.AnalyticsInfo)
err := row.Scan(&analytic.RoomId, &analytic.FileId, &analytic.FileName, &analytic.FileSize, &analytic.RoomCreationTime, &analytic.CreationTime)

switch {
case errors.Is(err, sql.ErrNoRows):
err = errors.New("no info found")
case err != nil:
err = errors.New(fmt.Sprintf("query error: %s", err.Error()))
Expand Down Expand Up @@ -186,7 +210,7 @@ func (m *AnalyticsAuthModel) DeleteAnalytics(r *plugnmeet.DeleteAnalyticsReq) er
return nil
}

// GetAnalyticsDownloadToken will use same JWT token generator as Livekit is using
// GetAnalyticsDownloadToken will use the same JWT token generator as plugNmeet is using
func (m *AnalyticsAuthModel) GetAnalyticsDownloadToken(r *plugnmeet.GetAnalyticsDownloadTokenReq) (string, error) {
analytic, err := m.fetchAnalytic(r.FileId)
if err != nil {
Expand Down
46 changes: 38 additions & 8 deletions pkg/models/recording_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (a *AuthRecording) FetchRecording(recordId string) (*plugnmeet.RecordingInf
recording.RoomSid = rSid.String

switch {
case err == sql.ErrNoRows:
case errors.Is(err, sql.ErrNoRows):
err = errors.New("no info found")
case err != nil:
err = errors.New(fmt.Sprintf("query error: %s", err.Error()))
Expand All @@ -143,8 +143,42 @@ func (a *AuthRecording) FetchRecording(recordId string) (*plugnmeet.RecordingInf
return recording, nil
}

type DeleteRecordingReq struct {
RecordId string `json:"record_id" validate:"required"`
func (a *AuthRecording) RecordingInfo(req *plugnmeet.RecordingInfoReq) (*plugnmeet.RecordingInfoRes, error) {
recording, err := a.FetchRecording(req.RecordId)
if err != nil {
return nil, err
}

pastRoomInfo := new(plugnmeet.PastRoomInfo)
// SID can't be null, so we'll check before
if recording.GetRoomSid() != "" {
rm := NewRoomModel()
roomInfo, _ := rm.GetRoomInfo("", recording.GetRoomSid(), 0)
if roomInfo != nil {
pastRoomInfo = &plugnmeet.PastRoomInfo{
RoomTitle: roomInfo.RoomTitle,
RoomId: roomInfo.RoomId,
RoomSid: roomInfo.Sid,
JoinedParticipants: roomInfo.JoinedParticipants,
WebhookUrl: roomInfo.WebhookUrl,
Ended: roomInfo.Ended,
}
pastRoomInfo.Created = time.Unix(roomInfo.CreationTime, 0).UTC().Format("2006-01-02 15:04:05")

am := NewAnalyticsAuthModel()
an, err := am.getAnalyticByRoomTableId(roomInfo.Id)
if err == nil {
pastRoomInfo.AnalyticsFileId = an.GetFileId()
}
}
}

return &plugnmeet.RecordingInfoRes{
Status: true,
Msg: "success",
RecordingInfo: recording,
RoomInfo: pastRoomInfo,
}, nil
}

func (a *AuthRecording) DeleteRecording(r *plugnmeet.DeleteRecordingReq) error {
Expand Down Expand Up @@ -203,11 +237,7 @@ func (a *AuthRecording) DeleteRecording(r *plugnmeet.DeleteRecordingReq) error {
return nil
}

type GetDownloadTokenReq struct {
RecordId string `json:"record_id" validate:"required"`
}

// GetDownloadToken will use same JWT token generator as Livekit is using
// GetDownloadToken will use the same JWT token generator as plugNmeet is using
func (a *AuthRecording) GetDownloadToken(r *plugnmeet.GetDownloadTokenReq) (string, error) {
recording, err := a.FetchRecording(r.RecordId)
if err != nil {
Expand Down

0 comments on commit 5a67d9c

Please sign in to comment.