package medias import ( "backend/pkg/consts" "backend/pkg/errorx" "backend/pkg/pg" "backend/providers/jwt" "github.com/gofiber/fiber/v3" log "github.com/sirupsen/logrus" "github.com/speps/go-hashids/v2" ) // @provider type Controller struct { hashIds *hashids.HashID svc *Service } // List func (c *Controller) List(ctx fiber.Ctx) error { filter := ListFilter{} if err := ctx.Bind().Body(&filter); err != nil { log.WithError(err).Error("parse body failed") return err } claim := ctx.Locals(consts.CtxKeyClaim).(*jwt.Claims) if filter.Offset != "" { model, err := c.svc.GetMediaByHash(ctx.Context(), claim.TenantID, filter.Offset) if err != nil { log.WithField("action", "medias.Show").WithError(err).Error("GetMediaByHash") return err } filter.OffsetID = model.ID } items, err := c.svc.List(ctx.Context(), claim.TenantID, claim.UserID, &filter) if err != nil { return err } return ctx.JSON(items) } // Show func (c *Controller) Show(ctx fiber.Ctx) error { hash := ctx.Params("hash") claim := fiber.Locals[*jwt.Claims](ctx, consts.CtxKeyClaim) log.Debug(claim) if claim == nil { return errorx.RequestUnAuthorized } model, err := c.svc.GetMediaByHash(ctx.Context(), claim.TenantID, hash) if err != nil { log.WithField("action", "medias.Show").WithError(err).Error("GetMediaByHash") return err } resource := c.svc.ModelToListItem(ctx.Context(), model) resource.Bought, err = c.svc.HasUserBought(ctx.Context(), claim.TenantID, claim.UserID, model.ID) if err != nil { log.WithField("action", "medias.Show").WithError(err).Error("HasUserBought") return err } return ctx.JSON(resource) } // Audio func (c *Controller) MediaIndex(ctx fiber.Ctx) error { mediaType, err := pg.ParseMediaType(ctx.Params("type")) if err != nil { return err } hash := ctx.Params("hash") claim := fiber.Locals[*jwt.Claims](ctx, consts.CtxKeyClaim) log.Debug(claim) if claim == nil { return errorx.RequestUnAuthorized } // c.Locals(consts.CtxKeyJwt, token) token := fiber.Locals[string](ctx, consts.CtxKeyJwt) model, err := c.svc.GetMediaByHash(ctx.Context(), claim.TenantID, hash) if err != nil { log.WithField("action", "medias.MediaIndex").WithError(err).Error("GetMediaByHash") return err } bought, err := c.svc.HasUserBought(ctx.Context(), claim.TenantID, claim.UserID, model.ID) if err != nil { log.WithField("action", "medias.MediaIndex").WithError(err).Error("HasUserBought") return err } playlist, err := c.svc.GetM3U8(ctx.Context(), claim.TenantID, mediaType, model.Hash, bought, token) if err != nil { log.WithField("action", "medias.MediaIndex").WithError(err).Error("GetMediaPlaylist") return err } ctx.Set("Content-Type", "application/vnd.apple.mpegurl") return ctx.SendString(playlist.String()) } func (c *Controller) MediaSegment(ctx fiber.Ctx) error { mediaType, err := pg.ParseMediaType(ctx.Params("type")) if err != nil { return err } segment := ctx.Params("segment") segments, err := c.hashIds.DecodeInt64WithError(segment) if err != nil { log.WithField("action", "medias.MediaSegment").WithError(err).Error("DecodeInt64WithError") return err } hash := ctx.Params("hash") claim := fiber.Locals[*jwt.Claims](ctx, consts.CtxKeyClaim) log.Debug(claim) if claim == nil { return errorx.RequestUnAuthorized } model, err := c.svc.GetMediaByHash(ctx.Context(), claim.TenantID, hash) if err != nil { log.WithField("action", "medias.MediaSegment").WithError(err).Error("GetMediaByHash") return err } filepath := c.svc.GetSegmentPath(ctx.Context(), mediaType, model.TenantID, model.Hash, segments[0]) ctx.Set("Content-Type", "video/mp2t") return ctx.SendFile(filepath) } // Checkout func (c *Controller) Checkout(ctx fiber.Ctx) error { hash := ctx.Params("hash") claim := fiber.Locals[*jwt.Claims](ctx, consts.CtxKeyClaim) log.Debug(claim) if claim == nil { return errorx.RequestUnAuthorized } model, err := c.svc.GetMediaByHash(ctx.Context(), claim.TenantID, hash) if err != nil { log.WithField("action", "medias.MediaSegment").WithError(err).Error("GetMediaByHash") return err } if err := c.svc.Checkout(ctx.Context(), claim.TenantID, claim.UserID, model.ID); err != nil { log.WithField("action", "medias.MediaSegment").WithError(err).Error("Checkout") return err } return ctx.JSON(nil) }