Fix: movies error and first login dont init version

pull/21/head
zijiren233 1 year ago
parent 15defa6c69
commit ea14873633

@ -9,70 +9,17 @@ func CreateMovie(movie *model.Movie) error {
return db.Create(movie).Error
}
type GetMovies struct {
max int
page int
}
func DefaultGetMovies() *GetMovies {
return &GetMovies{
max: 10,
page: 1,
}
}
type GetMoviesConfig func(gm *GetMovies)
func GetMoviesMax(max int) GetMoviesConfig {
return func(gm *GetMovies) {
gm.max = max
}
}
func GetMoviesPage(page int) GetMoviesConfig {
return func(gm *GetMovies) {
gm.page = page
}
}
func GetMoviesByRoomID(roomID uint, conf ...GetMoviesConfig) ([]model.Movie, error) {
movies := []model.Movie{}
df := DefaultGetMovies()
for _, c := range conf {
c(df)
}
err := db.Where("room_id = ?", roomID).Limit(df.max).Offset((df.page - 1) * df.max).Find(&movies).Error
return movies, err
}
func GetAllMoviesByRoomID(roomID uint) ([]model.Movie, error) {
movies := []model.Movie{}
err := db.Where("room_id = ?", roomID).Find(&movies).Error
err := db.Where("room_id = ?", roomID).Order("position ASC").Find(&movies).Error
return movies, err
}
func GetMovieWithPullKey(roomID uint, pullKey string) (*model.Movie, error) {
movie := &model.Movie{}
err := db.Where("room_id = ? AND pull_key = ?", roomID, pullKey).First(movie).Error
return movie, err
}
func GetMoviesCountByRoomID(roomID uint) (int64, error) {
var count int64
err := db.Model(&model.Movie{}).Where("room_id = ?", roomID).Count(&count).Error
return count, err
}
func GetMovieByID(roomID, id uint) (*model.Movie, error) {
movie := &model.Movie{}
err := db.Where("room_id = ? AND id = ?", roomID, id).First(movie).Error
return movie, err
}
func DeleteMovieByID(roomID, id uint) error {
return db.Where("room_id = ? AND id = ?", roomID, id).Delete(&model.Movie{}).Error
}
// TODO: delete error
func LoadAndDeleteMovieByID(roomID, id uint, columns ...clause.Column) (*model.Movie, error) {
movie := &model.Movie{}
err := db.Clauses(clause.Returning{Columns: columns}).Where("room_id = ? AND id = ?", roomID, id).Delete(movie).Error
@ -93,8 +40,8 @@ func UpdateMovie(movie model.Movie) error {
return db.Model(&model.Movie{}).Where("room_id = ? AND id = ?", movie.RoomID, movie.ID).Updates(movie).Error
}
func LoadAndUpdateMovie(movie model.Movie, columns ...string) (*model.Movie, error) {
err := db.Model(&model.Movie{}).Where("room_id = ? AND id = ?", movie.RoomID, movie.ID).Updates(movie).Error
func LoadAndUpdateMovie(movie model.Movie, columns ...clause.Column) (*model.Movie, error) {
err := db.Model(&model.Movie{}).Clauses(clause.Returning{Columns: columns}).Where("room_id = ? AND id = ?", movie.RoomID, movie.ID).Updates(&movie).Error
return &movie, err
}

@ -6,23 +6,23 @@ import (
type Movie struct {
gorm.Model
Position uint `gorm:"not null"`
RoomID uint `gorm:"not null"`
MovieInfo
Position uint `gorm:"not null" json:"-"`
RoomID uint `gorm:"not null" json:"roomId"`
MovieInfo `gorm:"embedded"`
}
type MovieInfo struct {
BaseMovieInfo
PullKey string
CreatorID uint `gorm:"not null"`
BaseMovieInfo `gorm:"embedded"`
PullKey string `gorm:"varchar(16)" json:"pullKey"`
CreatorID uint `gorm:"not null" json:"creatorId"`
}
type BaseMovieInfo struct {
Url string `gorm:"varchar(4096)"`
Name string `gorm:"not null;varchar(256)"`
Live bool
Proxy bool
RtmpSource bool
Type string
Headers map[string]string `gorm:"serializer:json"`
Url string `gorm:"varchar(4096)" json:"url"`
Name string `gorm:"not null;varchar(256)" json:"name"`
Live bool `json:"live"`
Proxy bool `json:"proxy"`
RtmpSource bool `json:"rtmpSource"`
Type string `gorm:"varchar(32)" json:"type"`
Headers map[string]string `gorm:"serializer:json" json:"headers"`
}

@ -13,25 +13,48 @@ var movieCache = gcache.New(2048).
LRU().
Build()
func GetMoviesByRoomID(roomID uint) ([]model.Movie, error) {
func GetAllMoviesByRoomID(roomID uint) ([]model.Movie, error) {
i, err := movieCache.Get(roomID)
if err == nil {
return i.([]model.Movie), nil
}
m, err := db.GetMoviesByRoomID(roomID)
m, err := db.GetAllMoviesByRoomID(roomID)
if err != nil {
return nil, err
}
return m, movieCache.SetWithExpire(roomID, m, time.Hour)
}
func GetMoviesByRoomIDWithPage(roomID uint, page, pageSize int) ([]model.Movie, error) {
i, err := movieCache.Get(roomID)
if err != nil {
return nil, err
}
ms := i.([]model.Movie)
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 1
}
start := (page - 1) * pageSize
end := page * pageSize
if start > len(ms) {
start = len(ms)
}
if end > len(ms) {
end = len(ms)
}
return ms[start:end], nil
}
func GetMovieByID(roomID, id uint) (*model.Movie, error) {
var m []model.Movie
i, err := movieCache.Get(roomID)
if err == nil {
m = i.([]model.Movie)
} else {
m, err = GetMoviesByRoomID(roomID)
m, err = GetAllMoviesByRoomID(roomID)
if err != nil {
return nil, err
}
@ -43,3 +66,129 @@ func GetMovieByID(roomID, id uint) (*model.Movie, error) {
}
return nil, errors.New("movie not found")
}
func GetMoviesCountByRoomID(roomID uint) (int, error) {
ms, err := GetAllMoviesByRoomID(roomID)
return len(ms), err
}
func DeleteMovieByID(roomID, id uint) error {
err := db.DeleteMovieByID(roomID, id)
if err != nil {
return err
}
i, err := movieCache.Get(roomID)
if err != nil {
return err
}
ms := i.([]model.Movie)
for i, v := range ms {
if v.ID == id {
ms = append(ms[:i], ms[i+1:]...)
break
}
}
return nil
}
func UpdateMovie(movie model.Movie) error {
m, err := db.LoadAndUpdateMovie(movie)
if err != nil {
return err
}
i, err := movieCache.Get(movie.RoomID)
if err != nil {
return err
}
ms := i.([]model.Movie)
for i, v := range ms {
if v.ID == movie.ID {
ms[i] = *m
break
}
}
return nil
}
func DeleteMoviesByRoomID(roomID uint) error {
err := db.DeleteMoviesByRoomID(roomID)
if err != nil {
return err
}
movieCache.Remove(roomID)
return nil
}
func LoadAndDeleteMovieByID(roomID, id uint) (*model.Movie, error) {
m, err := db.LoadAndDeleteMovieByID(roomID, id)
if err != nil {
return nil, err
}
i, err := movieCache.Get(roomID)
if err != nil {
return nil, err
}
ms := i.([]model.Movie)
for i, v := range ms {
if v.ID == id {
ms = append(ms[:i], ms[i+1:]...)
break
}
}
return m, nil
}
// data race
func CreateMovie(movie *model.Movie) error {
err := db.CreateMovie(movie)
if err != nil {
return err
}
i, err := movieCache.Get(movie.RoomID)
if err != nil {
movieCache.Set(movie.RoomID, []model.Movie{*movie})
return nil
}
ms := i.([]model.Movie)
ms = append(ms, *movie)
movieCache.Set(movie.RoomID, ms)
return nil
}
func GetMovieWithPullKey(roomID uint, pullKey string) (*model.Movie, error) {
i, err := movieCache.Get(roomID)
if err != nil {
return nil, err
}
ms := i.([]model.Movie)
for _, v := range ms {
if v.PullKey == pullKey {
return &v, nil
}
}
return nil, errors.New("movie not found")
}
func SwapMoviePositions(roomID uint, movie1ID uint, movie2ID uint) error {
err := db.SwapMoviePositions(roomID, movie1ID, movie2ID)
if err != nil {
return err
}
i, err := movieCache.Get(roomID)
if err != nil {
return err
}
ms := i.([]model.Movie)
movie1I, movie2I := 0, 0
for i, v := range ms {
if v.ID == movie1ID {
movie1I = i
}
if v.ID == movie2ID {
movie2I = i
}
}
ms[movie1I].Position, ms[movie2I].Position = ms[movie2I].Position, ms[movie1I].Position
ms[movie1I], ms[movie2I] = ms[movie2I], ms[movie1I]
return nil
}

@ -36,7 +36,6 @@ type Room struct {
func (r *Room) lazyInit() {
r.initOnce.Do(func() {
atomic.CompareAndSwapUint32(&r.version, 0, 1)
r.current = newCurrent()
r.hub = newHub(r.ID)
a, err := rtmp.RtmpServer().NewApp(r.Name)
@ -85,7 +84,7 @@ func (r *Room) UpdateMovie(movieId uint, movie model.BaseMovieInfo) error {
case m.Proxy && !movie.Proxy:
m.PullKey = ""
}
return db.UpdateMovie(*m)
return UpdateMovie(*m)
}
func (r *Room) InitMovie(movie *model.Movie) error {
@ -203,7 +202,7 @@ func (r *Room) AddMovie(m model.MovieInfo) error {
return err
}
return db.CreateMovie(movie)
return CreateMovie(movie)
}
func (r *Room) HasPermission(user *model.User, permission model.Permission) bool {
@ -251,24 +250,24 @@ func (r *Room) RemoveUserPermission(userID uint, permission model.Permission) er
return db.RemoveUserPermission(r.ID, userID, permission)
}
func (r *Room) GetMovies(conf ...db.GetMoviesConfig) ([]model.Movie, error) {
return db.GetMoviesByRoomID(r.ID, conf...)
func (r *Room) GetMoviesCount() (int, error) {
return GetMoviesCountByRoomID(r.ID)
}
func (r *Room) GetMoviesCount() (int64, error) {
return db.GetMoviesCountByRoomID(r.ID)
func (r *Room) GetAllMoviesByRoomID() ([]model.Movie, error) {
return GetAllMoviesByRoomID(r.ID)
}
func (r *Room) GetAllMoviesByRoomID() ([]model.Movie, error) {
return db.GetAllMoviesByRoomID(r.ID)
func (r *Room) GetMoviesByRoomIDWithPage(page, pageSize int) ([]model.Movie, error) {
return GetMoviesByRoomIDWithPage(r.ID, page, pageSize)
}
func (r *Room) GetMovieByID(id uint) (*model.Movie, error) {
return db.GetMovieByID(r.ID, id)
return GetMovieByID(r.ID, id)
}
func (r *Room) DeleteMovieByID(id uint) error {
m, err := db.LoadAndDeleteMovieByID(r.ID, id)
m, err := LoadAndDeleteMovieByID(r.ID, id)
if err != nil {
return err
}
@ -300,7 +299,7 @@ func (r *Room) Current() *Current {
}
func (r *Room) ChangeCurrentMovie(id uint) error {
m, err := db.GetMovieByID(r.ID, id)
m, err := GetMovieByID(r.ID, id)
if err != nil {
return err
}
@ -310,11 +309,11 @@ func (r *Room) ChangeCurrentMovie(id uint) error {
}
func (r *Room) SwapMoviePositions(id1, id2 uint) error {
return db.SwapMoviePositions(r.ID, id1, id2)
return SwapMoviePositions(r.ID, id1, id2)
}
func (r *Room) GetMovieWithPullKey(pullKey string) (*model.Movie, error) {
return db.GetMovieWithPullKey(r.ID, pullKey)
return GetMovieWithPullKey(r.ID, pullKey)
}
func (r *Room) RegClient(user *User, conn *websocket.Conn) (*Client, error) {

@ -2,6 +2,7 @@ package op
import (
"errors"
"math/rand"
"sync/atomic"
"time"
@ -32,6 +33,7 @@ func initRoom(room *model.Room, conf ...RoomConf) (*Room, error) {
r := &Room{
Room: *room,
lastActive: time.Now().UnixMilli(),
version: rand.Uint32(),
}
for _, c := range conf {
c(r)

@ -13,7 +13,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
"github.com/synctv-org/synctv/internal/conf"
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
"github.com/synctv-org/synctv/internal/rtmp"
@ -56,12 +55,28 @@ func MovieList(ctx *gin.Context) {
return
}
m, err := room.GetMovies(db.GetMoviesPage(int(page)), db.GetMoviesMax(int(max)))
m, err := room.GetMoviesByRoomIDWithPage(int(page), int(max))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
mresp := make([]model.MoviesResp, len(m))
var creater string
for i, v := range m {
// get cteater
u, err := op.GetUserById(v.CreatorID)
if err == nil {
creater = u.Username
}
mresp[i] = model.MoviesResp{
Id: v.ID,
Base: m[i].BaseMovieInfo,
PullKey: v.PullKey,
Creater: creater,
}
}
i, err := room.GetMoviesCount()
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
@ -71,7 +86,7 @@ func MovieList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"current": room.Current(),
"total": i,
"movies": m,
"movies": mresp,
}))
}
@ -94,12 +109,28 @@ func Movies(ctx *gin.Context) {
return
}
m, err := room.GetMovies(db.GetMoviesPage(int(page)), db.GetMoviesMax(int(max)))
m, err := room.GetMoviesByRoomIDWithPage(int(page), int(max))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
mresp := make([]model.MoviesResp, len(m))
var creater string
for i, v := range m {
// get cteater
u, err := op.GetUserById(v.CreatorID)
if err == nil {
creater = u.Username
}
mresp[i] = model.MoviesResp{
Id: v.ID,
Base: m[i].BaseMovieInfo,
PullKey: v.PullKey,
Creater: creater,
}
}
i, err := room.GetMoviesCount()
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
@ -108,7 +139,7 @@ func Movies(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"total": i,
"movies": m,
"movies": mresp,
}))
}

@ -36,19 +36,19 @@ func CreateRoom(ctx *gin.Context) {
return
}
r, err := user.CreateRoom(req.RoomId, req.Password, db.WithSetting(req.Setting))
r, err := user.CreateRoom(req.RoomName, req.Password, db.WithSetting(req.Setting))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
_, err = op.LoadRoom(r)
room, err := op.LoadRoom(r)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
token, err := middlewares.NewAuthUserToken(user)
token, err := middlewares.NewAuthRoomToken(user, room)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return

@ -107,3 +107,10 @@ func (s *SwapMovieReq) Validate() error {
}
return nil
}
type MoviesResp struct {
Id uint `json:"id"`
Base model.BaseMovieInfo `json:"base"`
PullKey string `json:"pullKey"`
Creater string `json:"creater"`
}

@ -13,9 +13,9 @@ import (
)
var (
ErrEmptyRoomId = errors.New("empty room id")
ErrRoomIdTooLong = errors.New("room id too long")
ErrRoomIdHasInvalidChar = errors.New("room id has invalid char")
ErrEmptyRoomName = errors.New("empty room name")
ErrRoomNameTooLong = errors.New("room name too long")
ErrRoomNameHasInvalidChar = errors.New("room name has invalid char")
ErrPasswordTooLong = errors.New("password too long")
ErrPasswordHasInvalidChar = errors.New("password has invalid char")
@ -38,7 +38,7 @@ func (f FormatEmptyPasswordError) Error() string {
}
type CreateRoomReq struct {
RoomId string `json:"roomId"`
RoomName string `json:"roomName"`
Password string `json:"password"`
Setting model.Setting `json:"setting"`
}
@ -48,12 +48,12 @@ func (c *CreateRoomReq) Decode(ctx *gin.Context) error {
}
func (c *CreateRoomReq) Validate() error {
if c.RoomId == "" {
return ErrEmptyRoomId
} else if len(c.RoomId) > 32 {
return ErrRoomIdTooLong
} else if !alphaNumChineseReg.MatchString(c.RoomId) {
return ErrRoomIdHasInvalidChar
if c.RoomName == "" {
return ErrEmptyRoomName
} else if len(c.RoomName) > 32 {
return ErrRoomNameTooLong
} else if !alphaNumChineseReg.MatchString(c.RoomName) {
return ErrRoomNameHasInvalidChar
}
if c.Password != "" {
@ -89,7 +89,7 @@ func (l *LoginRoomReq) Decode(ctx *gin.Context) error {
func (l *LoginRoomReq) Validate() error {
if l.RoomId == 0 {
return ErrEmptyRoomId
return ErrEmptyRoomName
}
return nil

Loading…
Cancel
Save