feat: add media sources
This commit is contained in:
@@ -5,3 +5,4 @@ types:
|
|||||||
|
|
||||||
media_resources: # table name
|
media_resources: # table name
|
||||||
type: backend/pkg/pg.MediaType
|
type: backend/pkg/pg.MediaType
|
||||||
|
source: backend/pkg/pg.MediaSource
|
||||||
|
|||||||
@@ -28,3 +28,30 @@ func (c *Controller) List(ctx fiber.Ctx) error {
|
|||||||
|
|
||||||
return ctx.JSON(items)
|
return ctx.JSON(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show
|
||||||
|
func (c *Controller) Show(ctx fiber.Ctx) error {
|
||||||
|
id := ToInt64(ctx.Params("id"))
|
||||||
|
tenantId, userId := ToInt64(ctx.Locals("tenantId")), ToInt64(ctx.Locals("userId"))
|
||||||
|
|
||||||
|
item, err := c.svc.GetByID(ctx.Context(), tenantId, userId, id)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.Status(fiber.StatusInternalServerError).JSON(errorx.InternalError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.JSON(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
func (c *Controller) Video(ctx fiber.Ctx) error {
|
||||||
|
mediaId := ToInt64(ctx.Params("media"))
|
||||||
|
tenantId := ToInt64(ctx.Locals("tenantId"))
|
||||||
|
userId := ToInt64(ctx.Locals("userId"))
|
||||||
|
|
||||||
|
item, err := c.svc.GetVideo(ctx.Context(), tenantId, userId, mediaId)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.Status(fiber.StatusInternalServerError).JSON(errorx.InternalError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.JSON(item)
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func (r *Router) Register() error {
|
|||||||
group := r.http.Engine.Group("medias")
|
group := r.http.Engine.Group("medias")
|
||||||
log.Infof("register route group: %s", group.(*fiber.Group).Prefix)
|
log.Infof("register route group: %s", group.(*fiber.Group).Prefix)
|
||||||
group.Get("", r.controller.List)
|
group.Get("", r.controller.List)
|
||||||
group.Get("{id}", r.controller.List)
|
group.Get("{id}", r.controller.Show)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"backend/database/models/qvyun/public/model"
|
"backend/database/models/qvyun/public/model"
|
||||||
"backend/database/models/qvyun/public/table"
|
"backend/database/models/qvyun/public/table"
|
||||||
|
"backend/pkg/pg"
|
||||||
|
|
||||||
. "github.com/go-jet/jet/v2/postgres"
|
. "github.com/go-jet/jet/v2/postgres"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -25,11 +26,15 @@ func (svc *Service) Prepare() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetByID
|
// GetByID
|
||||||
func (svc *Service) GetByID(ctx context.Context, id, userId int64) (*ListItem, error) {
|
func (svc *Service) GetByID(ctx context.Context, tenantId, userId, id int64) (*ListItem, error) {
|
||||||
log := svc.log.WithField("method", "GetByID")
|
log := svc.log.WithField("method", "GetByID")
|
||||||
|
|
||||||
tbl := table.Medias
|
tbl := table.Medias
|
||||||
stmt := tbl.SELECT(tbl.AllColumns).WHERE(tbl.ID.EQ(Int(id)))
|
stmt := tbl.SELECT(tbl.AllColumns).WHERE(
|
||||||
|
tbl.ID.EQ(Int(id)).AND(
|
||||||
|
tbl.TenantID.EQ(Int(tenantId)),
|
||||||
|
),
|
||||||
|
)
|
||||||
log.Debug(stmt.Sql())
|
log.Debug(stmt.Sql())
|
||||||
|
|
||||||
var media ListItem
|
var media ListItem
|
||||||
@@ -59,7 +64,7 @@ func (svc *Service) GetByID(ctx context.Context, id, userId int64) (*ListItem, e
|
|||||||
media.MediaResources = resources
|
media.MediaResources = resources
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
media.Bought, err = svc.HasUserBought(ctx, media.TenantID, userId, media.ID)
|
media.Bought, err = svc.HasUserBought(ctx, tenantId, userId, media.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "check user bought")
|
return nil, errors.Wrap(err, "check user bought")
|
||||||
}
|
}
|
||||||
@@ -220,3 +225,58 @@ func (svc *Service) HasUserBought(ctx context.Context, tenantId, userId, mediaId
|
|||||||
|
|
||||||
return mediaID > 0, nil
|
return mediaID > 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetVideo
|
||||||
|
func (svc *Service) GetVideo(ctx context.Context, tenantId, userId, mediaId int64) (*pg.MediaSource, error) {
|
||||||
|
log := svc.log.WithField("method", "GetVideo")
|
||||||
|
|
||||||
|
ok, err := svc.HasUserBought(ctx, tenantId, userId, mediaId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "check user bought")
|
||||||
|
}
|
||||||
|
log.Debugf("user bought media: %d of tennatID: %d", mediaId, tenantId)
|
||||||
|
|
||||||
|
source, err := svc.GetResourceOfType(ctx, mediaId, pg.MediaTypeVideo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "get video resource")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return source, nil
|
||||||
|
}
|
||||||
|
// cut 1 min video
|
||||||
|
maxDuration := int64(60)
|
||||||
|
duration := int64(0)
|
||||||
|
|
||||||
|
for i, item := range source.Items {
|
||||||
|
duration += item.Duration
|
||||||
|
if duration >= maxDuration {
|
||||||
|
source.Items = source.Items[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return source, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceOfType
|
||||||
|
func (svc *Service) GetResourceOfType(ctx context.Context, mediaId int64, resourceType pg.MediaType) (*pg.MediaSource, error) {
|
||||||
|
log := svc.log.WithField("method", "GetResourceOfType")
|
||||||
|
|
||||||
|
tbl := table.MediaResources
|
||||||
|
stmt := tbl.
|
||||||
|
SELECT(tbl.Source).
|
||||||
|
WHERE(
|
||||||
|
tbl.MediaID.EQ(Int(mediaId)).AND(
|
||||||
|
tbl.Type.EQ(String(resourceType.String())),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
log.Debug(stmt.DebugSql())
|
||||||
|
|
||||||
|
var source pg.MediaSource
|
||||||
|
if err := stmt.QueryContext(ctx, svc.db, &source); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "query media source")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &source, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package pg
|
package pg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
// swagger:enum MediaType
|
// swagger:enum MediaType
|
||||||
// ENUM(
|
// ENUM(
|
||||||
// Video = "video",
|
// Video = "video",
|
||||||
@@ -7,3 +13,30 @@ package pg
|
|||||||
// Pdf = "pdf",
|
// Pdf = "pdf",
|
||||||
// )
|
// )
|
||||||
type MediaType string
|
type MediaType string
|
||||||
|
|
||||||
|
type MediaSource struct {
|
||||||
|
Duration int64 `json:"duration"`
|
||||||
|
Items []MediaSourceItem `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x MediaSource) Scan(value interface{}) (err error) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
return json.Unmarshal([]byte(v), &x)
|
||||||
|
case []byte:
|
||||||
|
return json.Unmarshal(v, &x)
|
||||||
|
case *string:
|
||||||
|
return json.Unmarshal([]byte(*v), &x)
|
||||||
|
}
|
||||||
|
return errors.New("Unknown type for ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x MediaSource) Value() (driver.Value, error) {
|
||||||
|
return json.Marshal(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaSourceItem struct {
|
||||||
|
Source string `json:"source"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Duration int64 `json:"duration"`
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user