Add /api/v1/beatmaps
This commit is contained in:
parent
155fbabbbc
commit
9b821e3230
|
@ -40,6 +40,7 @@ func Start(conf common.Conf, dbO *sql.DB) *gin.Engine {
|
||||||
gv1.GET("/users/scores/best", Method(v1.UserScoresBestGET, common.PrivilegeRead))
|
gv1.GET("/users/scores/best", Method(v1.UserScoresBestGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/scores/recent", Method(v1.UserScoresRecentGET, common.PrivilegeRead))
|
gv1.GET("/users/scores/recent", Method(v1.UserScoresRecentGET, common.PrivilegeRead))
|
||||||
gv1.GET("/badges", Method(v1.BadgesGET, common.PrivilegeRead))
|
gv1.GET("/badges", Method(v1.BadgesGET, common.PrivilegeRead))
|
||||||
|
gv1.GET("/beatmaps", Method(v1.BeatmapGET, common.PrivilegeRead))
|
||||||
|
|
||||||
// ReadConfidential privilege required
|
// ReadConfidential privilege required
|
||||||
gv1.GET("/friends", Method(v1.FriendsGET, common.PrivilegeReadConfidential))
|
gv1.GET("/friends", Method(v1.FriendsGET, common.PrivilegeReadConfidential))
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import "git.zxq.co/ripple/rippleapi/common"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.zxq.co/ripple/rippleapi/common"
|
||||||
|
)
|
||||||
|
|
||||||
type beatmap struct {
|
type beatmap struct {
|
||||||
BeatmapID int `json:"beatmap_id"`
|
BeatmapID int `json:"beatmap_id"`
|
||||||
|
@ -14,7 +20,7 @@ type beatmap struct {
|
||||||
HitLength int `json:"hit_length"`
|
HitLength int `json:"hit_length"`
|
||||||
Ranked int `json:"ranked"`
|
Ranked int `json:"ranked"`
|
||||||
RankedStatusFrozen int `json:"ranked_status_frozen"`
|
RankedStatusFrozen int `json:"ranked_status_frozen"`
|
||||||
LatestUpdate int `json:"latest_update"`
|
LatestUpdate time.Time `json:"latest_update"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type beatmapMayOrMayNotExist struct {
|
type beatmapMayOrMayNotExist struct {
|
||||||
|
@ -29,11 +35,11 @@ type beatmapMayOrMayNotExist struct {
|
||||||
HitLength *int
|
HitLength *int
|
||||||
Ranked *int
|
Ranked *int
|
||||||
RankedStatusFrozen *int
|
RankedStatusFrozen *int
|
||||||
LatestUpdate *int
|
LatestUpdate *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *beatmapMayOrMayNotExist) toBeatmap() *beatmap {
|
func (b *beatmapMayOrMayNotExist) toBeatmap() *beatmap {
|
||||||
if b.BeatmapID == nil {
|
if b == nil || b.BeatmapID == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &beatmap{
|
return &beatmap{
|
||||||
|
@ -62,7 +68,7 @@ type beatmapSetResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type beatmapSetStatusData struct {
|
type beatmapSetStatusData struct {
|
||||||
BeatmapSetID int `json:"beatmapset_id"`
|
BeatmapsetID int `json:"beatmapset_id"`
|
||||||
BeatmapID int `json:"beatmap_id"`
|
BeatmapID int `json:"beatmap_id"`
|
||||||
RankedStatus int `json:"ranked_status"`
|
RankedStatus int `json:"ranked_status"`
|
||||||
Frozen int `json:"frozen"`
|
Frozen int `json:"frozen"`
|
||||||
|
@ -75,7 +81,7 @@ func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
||||||
md.RequestData.Unmarshal(&req)
|
md.RequestData.Unmarshal(&req)
|
||||||
|
|
||||||
var miss []string
|
var miss []string
|
||||||
if req.BeatmapSetID == 0 && req.BeatmapID == 0 {
|
if req.BeatmapsetID == 0 && req.BeatmapID == 0 {
|
||||||
miss = append(miss, "beatmapset_id or beatmap_id")
|
miss = append(miss, "beatmapset_id or beatmap_id")
|
||||||
}
|
}
|
||||||
if len(miss) != 0 {
|
if len(miss) != 0 {
|
||||||
|
@ -91,7 +97,7 @@ func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
whereClause = "beatmapset_id"
|
whereClause = "beatmapset_id"
|
||||||
param = req.BeatmapSetID
|
param = req.BeatmapsetID
|
||||||
)
|
)
|
||||||
if req.BeatmapID != 0 {
|
if req.BeatmapID != 0 {
|
||||||
whereClause = "beatmap_id"
|
whereClause = "beatmap_id"
|
||||||
|
@ -102,8 +108,87 @@ func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
||||||
SET ranked = ?, ranked_status_freezed = ?
|
SET ranked = ?, ranked_status_freezed = ?
|
||||||
WHERE `+whereClause+` = ?`, req.RankedStatus, req.Frozen, param)
|
WHERE `+whereClause+` = ?`, req.RankedStatus, req.Frozen, param)
|
||||||
|
|
||||||
// TODO: replace with beatmapSetResponse when implemented
|
if whereClause == "beatmapset_id" {
|
||||||
return common.ResponseBase{
|
return getSet(md, param)
|
||||||
Code: 200,
|
|
||||||
}
|
}
|
||||||
|
return getBeatmap(md, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeatmapGET retrieves a beatmap.
|
||||||
|
func BeatmapGET(md common.MethodData) common.CodeMessager {
|
||||||
|
if md.C.Query("s") == "" && md.C.Query("b") == "" {
|
||||||
|
return common.SimpleResponse(400, "Must pass either querystring param 'b' or 's'")
|
||||||
|
}
|
||||||
|
setID, _ := strconv.Atoi(md.C.Query("s"))
|
||||||
|
if setID != 0 {
|
||||||
|
return getSet(md, setID)
|
||||||
|
}
|
||||||
|
beatmapID, _ := strconv.Atoi(md.C.Query("b"))
|
||||||
|
if beatmapID != 0 {
|
||||||
|
return getBeatmap(md, beatmapID)
|
||||||
|
}
|
||||||
|
return common.SimpleResponse(400, "Please pass either a valid beatmapset ID or a valid beatmap ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseBeatmapSelect = `
|
||||||
|
SELECT
|
||||||
|
beatmap_id, beatmapset_id, beatmap_md5,
|
||||||
|
song_name, ar, od, difficulty, max_combo,
|
||||||
|
hit_length, ranked, ranked_status_freezed,
|
||||||
|
latest_update
|
||||||
|
FROM beatmaps
|
||||||
|
`
|
||||||
|
|
||||||
|
func getSet(md common.MethodData, setID int) common.CodeMessager {
|
||||||
|
rows, err := md.DB.Query(baseBeatmapSelect+"WHERE beatmapset_id = ?", setID)
|
||||||
|
if err != nil {
|
||||||
|
md.Err(err)
|
||||||
|
return Err500
|
||||||
|
}
|
||||||
|
var r beatmapSetResponse
|
||||||
|
for rows.Next() {
|
||||||
|
var (
|
||||||
|
b beatmap
|
||||||
|
rawLatestUpdate int64
|
||||||
|
)
|
||||||
|
err = rows.Scan(
|
||||||
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
||||||
|
&b.SongName, &b.AR, &b.OD, &b.Difficulty, &b.MaxCombo,
|
||||||
|
&b.HitLength, &b.Ranked, &b.RankedStatusFrozen,
|
||||||
|
&rawLatestUpdate,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
md.Err(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.LatestUpdate = time.Unix(rawLatestUpdate, 0)
|
||||||
|
r.Beatmaps = append(r.Beatmaps, b)
|
||||||
|
}
|
||||||
|
r.Code = 200
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBeatmap(md common.MethodData, beatmapID int) common.CodeMessager {
|
||||||
|
var (
|
||||||
|
b beatmap
|
||||||
|
rawLatestUpdate int64
|
||||||
|
)
|
||||||
|
err := md.DB.QueryRow(baseBeatmapSelect+"WHERE beatmap_id = ? LIMIT 1", beatmapID).Scan(
|
||||||
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
||||||
|
&b.SongName, &b.AR, &b.OD, &b.Difficulty, &b.MaxCombo,
|
||||||
|
&b.HitLength, &b.Ranked, &b.RankedStatusFrozen,
|
||||||
|
&rawLatestUpdate,
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case err == sql.ErrNoRows:
|
||||||
|
return common.SimpleResponse(404, "That beatmap could not be found!")
|
||||||
|
case err != nil:
|
||||||
|
md.Err(err)
|
||||||
|
return Err500
|
||||||
|
}
|
||||||
|
b.LatestUpdate = time.Unix(rawLatestUpdate, 0)
|
||||||
|
var r beatmapResponse
|
||||||
|
r.Code = 200
|
||||||
|
r.beatmap = b
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ func scoresPuts(md common.MethodData, whereClause string, params ...interface{})
|
||||||
us userScore
|
us userScore
|
||||||
t string
|
t string
|
||||||
b beatmapMayOrMayNotExist
|
b beatmapMayOrMayNotExist
|
||||||
|
rawLatestUpdate *int64
|
||||||
)
|
)
|
||||||
err = rows.Scan(
|
err = rows.Scan(
|
||||||
&us.ID, &us.BeatmapMD5, &us.Score,
|
&us.ID, &us.BeatmapMD5, &us.Score,
|
||||||
|
@ -143,7 +144,7 @@ func scoresPuts(md common.MethodData, whereClause string, params ...interface{})
|
||||||
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
||||||
&b.SongName, &b.AR, &b.OD, &b.Difficulty,
|
&b.SongName, &b.AR, &b.OD, &b.Difficulty,
|
||||||
&b.MaxCombo, &b.HitLength, &b.Ranked,
|
&b.MaxCombo, &b.HitLength, &b.Ranked,
|
||||||
&b.RankedStatusFrozen, &b.LatestUpdate,
|
&b.RankedStatusFrozen, &rawLatestUpdate,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
md.Err(err)
|
md.Err(err)
|
||||||
|
@ -155,6 +156,11 @@ func scoresPuts(md common.MethodData, whereClause string, params ...interface{})
|
||||||
md.Err(err)
|
md.Err(err)
|
||||||
return Err500
|
return Err500
|
||||||
}
|
}
|
||||||
|
if rawLatestUpdate != nil {
|
||||||
|
// fml i should have used an inner join
|
||||||
|
xd := time.Unix(*rawLatestUpdate, 0)
|
||||||
|
b.LatestUpdate = &xd
|
||||||
|
}
|
||||||
us.Beatmap = b.toBeatmap()
|
us.Beatmap = b.toBeatmap()
|
||||||
scores = append(scores, us)
|
scores = append(scores, us)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user