Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions db/playlists.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,44 @@ func GetPlaylist(id int) (*Playlist, error) {

// GetPlaylistFull Gets an individual playlist with mapsets/maps included
func GetPlaylistFull(id int) (*Playlist, error) {
return getPlaylistWithMapsets(id, nil)
}

// GetPlaylistPage Gets an individual playlist with a page of mapsets/maps included
func GetPlaylistPage(id int, page int, limit int) (*Playlist, error) {
return getPlaylistWithMapsets(id, playlistMapsetPageScope(page, limit))
}

func playlistMapsetPageScope(page int, limit int) func(*gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.
Order("playlists_mapsets.id ASC").
Limit(limit).
Offset(page * limit)
}
}

func playlistMapsetOrderScope(db *gorm.DB) *gorm.DB {
return db.Order("playlists_mapsets.id ASC")
}

func playlistMapOrderScope(db *gorm.DB) *gorm.DB {
return db.Order("playlists_maps.id ASC")
}

func getPlaylistWithMapsets(id int, mapsetScope func(*gorm.DB) *gorm.DB) (*Playlist, error) {
var playlist *Playlist

result := SQL.
Preload("Mapsets").
query := SQL

if mapsetScope == nil {
mapsetScope = playlistMapsetOrderScope
}

result := query.
Preload("Mapsets", mapsetScope).
Preload("Mapsets.Mapset").
Preload("Mapsets.Maps").
Preload("Mapsets.Maps", playlistMapOrderScope).
Preload("Mapsets.Maps.Map").
Joins("User").
Where("playlists.id = ? AND playlists.visible = 1", id).
Expand Down
12 changes: 12 additions & 0 deletions db/playlists_maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ func DoesPlaylistContainMap(playlistId int, mapId int) (bool, error) {
return true, nil
}

// CountPlaylistMapsForMapset Counts the maps in a playlist mapset
func CountPlaylistMapsForMapset(playlistId int, playlistMapsetId int) (int64, error) {
var count int64

result := SQL.
Model(&PlaylistMap{}).
Where("playlist_id = ? AND playlists_mapsets_id = ?", playlistId, playlistMapsetId).
Count(&count)

return count, result.Error
}

// Insert Inserts a playlist map into the db
func (pm *PlaylistMap) Insert() error {
if err := SQL.Create(&pm).Error; err != nil {
Expand Down
2 changes: 1 addition & 1 deletion db/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ func SearchUsersByName(searchQuery string) ([]*User, error) {
Joins("StatsKeys7").
Where("username LIKE ? AND allowed = 1", fmt.Sprintf("%v%%", searchQuery)).
Limit(50).
Order("id ASC").
Order("username ASC, id ASC").
Find(&users)

if result.Error != nil {
Expand Down
1 change: 1 addition & 0 deletions enums/usergroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
UserGroupTrialRankingSupervisor
UserGroupGraphicsDesigner
UserGroupHeadRankingSupervisor
CommunityManager
)

// HasUserGroup Returns if a combination of user groups contains a single group
Expand Down
22 changes: 17 additions & 5 deletions handlers/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
)

const (
defaultUserScoreLimit = 50
defaultClanScoreLimit = 50
defaultMostPlayedLimit = 10
defaultUserActivityLimit = 50
defaultUserPlaylistLimit = 50
defaultUserScoreLimit = 50
defaultClanScoreLimit = 50
defaultMostPlayedLimit = 10
defaultUserActivityLimit = 50
defaultUserPlaylistLimit = 50
defaultPlaylistMapsetLimit = 25
)

// getQueryLimit returns a requested limit bounded by the endpoint's default limit.
Expand All @@ -29,3 +30,14 @@ func getQueryLimit(c *gin.Context, defaultLimit int) int {

return limit
}

// getQueryPage returns a requested zero-based page. Invalid and negative values use page zero.
func getQueryPage(c *gin.Context) int {
page, err := strconv.Atoi(c.Query("page"))

if err != nil || page < 0 {
return 0
}

return page
}
80 changes: 53 additions & 27 deletions handlers/playlists.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ func GetPlaylist(c *gin.Context) *APIError {
return APIErrorBadRequest("Invalid id")
}

playlist, err := db.GetPlaylistFull(id)
page := getQueryPage(c)
limit := getQueryLimit(c, defaultPlaylistMapsetLimit)

playlist, err := db.GetPlaylistPage(id, page, limit)

if err != nil && err != gorm.ErrRecordNotFound {
return APIErrorServerError("Error retrieving playlist from db", err)
Expand All @@ -74,7 +77,13 @@ func GetPlaylist(c *gin.Context) *APIError {
return APIErrorNotFound("Playlist")
}

c.JSON(http.StatusOK, gin.H{"playlist": playlist})
mapsets := playlist.Mapsets

if mapsets == nil {
mapsets = make([]*db.PlaylistMapset, 0)
}

c.JSON(http.StatusOK, gin.H{"playlist": playlistPageResponse{Playlist: playlist, Mapsets: mapsets}})
return nil
}

Expand Down Expand Up @@ -263,6 +272,11 @@ type addRemoveMapPlaylistData struct {
Map *db.MapQua
}

type playlistPageResponse struct {
*db.Playlist
Mapsets []*db.PlaylistMapset `json:"mapsets"`
}

// Parses any ids, performs validation and returns data to be used when adding/removing maps from playlists
func validateAddRemoveMapFromPlaylist(c *gin.Context) (*addRemoveMapPlaylistData, *APIError) {
playlistId, err := strconv.Atoi(c.Param("id"))
Expand All @@ -283,7 +297,7 @@ func validateAddRemoveMapFromPlaylist(c *gin.Context) (*addRemoveMapPlaylistData
return nil, APIErrorUnauthorized("User not authenticated")
}

playlist, err := db.GetPlaylistFull(playlistId)
playlist, err := db.GetPlaylist(playlistId)

if err != nil && err != gorm.ErrRecordNotFound {
return nil, APIErrorServerError("Error retrieving playlist from database", err)
Expand Down Expand Up @@ -327,19 +341,24 @@ func AddMapToPlaylist(c *gin.Context) *APIError {
return apiErr
}

var existingMapset *db.PlaylistMapset
containsMap, err := db.DoesPlaylistContainMap(data.Playlist.Id, data.Map.Id)

for _, mapset := range data.Playlist.Mapsets {
for _, playlistMap := range mapset.Maps {
if playlistMap.MapId == data.Map.Id {
return APIErrorBadRequest("This map already exists in the playlist.")
}
}
if err != nil {
return APIErrorServerError("Error checking if map exists in playlist", err)
}

// Set existing mapset
if mapset.MapsetId == data.Map.MapsetId {
existingMapset = mapset
}
if containsMap {
return APIErrorBadRequest("This map already exists in the playlist.")
}

existingMapset, err := db.GetPlaylistMapsetByIds(data.Playlist.Id, data.Map.MapsetId)

if err != nil && err != gorm.ErrRecordNotFound {
return APIErrorServerError("Error retrieving playlist mapset from database", err)
}

if err == gorm.ErrRecordNotFound {
existingMapset = nil
}

// Create new playlist mapset
Expand Down Expand Up @@ -381,30 +400,37 @@ func RemoveMapFromPlaylist(c *gin.Context) *APIError {
return apiErr
}

var deleteMap bool
var deleteMapset bool
containsMap, err := db.DoesPlaylistContainMap(data.Playlist.Id, data.Map.Id)

if err != nil {
return APIErrorServerError("Error checking if map exists in playlist", err)
}

if !containsMap {
return APIErrorBadRequest("This map is not in your playlist.")
}

for _, playlistMapset := range data.Playlist.Mapsets {
for _, playlistMap := range playlistMapset.Maps {
if playlistMap.MapId == data.Map.Id {
deleteMap = true
}
playlistMapset, err := db.GetPlaylistMapsetByIds(data.Playlist.Id, data.Map.MapsetId)

if len(playlistMapset.Maps) == 1 {
deleteMapset = true
}
if err != nil {
if err == gorm.ErrRecordNotFound {
return APIErrorBadRequest("This map is not in your playlist.")
}

return APIErrorServerError("Error retrieving playlist mapset from database", err)
}

if !deleteMap {
return APIErrorBadRequest("This map is not in your playlist.")
mapCount, err := db.CountPlaylistMapsForMapset(data.Playlist.Id, playlistMapset.Id)

if err != nil {
return APIErrorServerError("Error counting maps in playlist mapset", err)
}

if err := db.DeletePlaylistMap(data.Playlist.Id, data.Map.Id); err != nil {
return APIErrorServerError("Error removing playlist map from db", err)
}

if deleteMapset {
if mapCount == 1 {
if err := db.DeletePlaylistMapset(data.Playlist.Id, data.Map.MapsetId); err != nil {
return APIErrorServerError("Error removing playlist mapset from db", err)
}
Expand Down
Loading