2016-04-27 18:03:06 +00:00
|
|
|
package v1
|
|
|
|
|
2016-06-08 17:55:52 +00:00
|
|
|
import (
|
|
|
|
"database/sql"
|
2016-09-17 21:27:20 +00:00
|
|
|
"fmt"
|
|
|
|
"net/url"
|
2016-06-08 17:55:52 +00:00
|
|
|
|
|
|
|
"git.zxq.co/ripple/rippleapi/common"
|
|
|
|
)
|
2016-04-27 18:03:06 +00:00
|
|
|
|
2016-07-18 21:27:37 +00:00
|
|
|
type difficulty struct {
|
|
|
|
STD float64 `json:"std"`
|
|
|
|
Taiko float64 `json:"taiko"`
|
|
|
|
CTB float64 `json:"ctb"`
|
|
|
|
Mania float64 `json:"mania"`
|
|
|
|
}
|
|
|
|
|
2016-04-27 18:03:06 +00:00
|
|
|
type beatmap struct {
|
2016-07-06 20:32:30 +00:00
|
|
|
BeatmapID int `json:"beatmap_id"`
|
|
|
|
BeatmapsetID int `json:"beatmapset_id"`
|
|
|
|
BeatmapMD5 string `json:"beatmap_md5"`
|
|
|
|
SongName string `json:"song_name"`
|
|
|
|
AR float32 `json:"ar"`
|
|
|
|
OD float32 `json:"od"`
|
|
|
|
Difficulty float64 `json:"difficulty"`
|
2016-07-18 21:27:37 +00:00
|
|
|
Diff2 difficulty `json:"difficulty2"` // fuck nyo
|
2016-07-06 20:32:30 +00:00
|
|
|
MaxCombo int `json:"max_combo"`
|
|
|
|
HitLength int `json:"hit_length"`
|
|
|
|
Ranked int `json:"ranked"`
|
|
|
|
RankedStatusFrozen int `json:"ranked_status_frozen"`
|
|
|
|
LatestUpdate common.UnixTimestamp `json:"latest_update"`
|
2016-04-27 18:03:06 +00:00
|
|
|
}
|
2016-05-19 15:15:17 +00:00
|
|
|
|
2016-04-27 18:03:06 +00:00
|
|
|
type beatmapResponse struct {
|
|
|
|
common.ResponseBase
|
|
|
|
beatmap
|
|
|
|
}
|
|
|
|
type beatmapSetResponse struct {
|
|
|
|
common.ResponseBase
|
|
|
|
Beatmaps []beatmap `json:"beatmaps"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type beatmapSetStatusData struct {
|
2016-06-08 17:55:52 +00:00
|
|
|
BeatmapsetID int `json:"beatmapset_id"`
|
2016-06-08 16:30:23 +00:00
|
|
|
BeatmapID int `json:"beatmap_id"`
|
2016-04-27 18:03:06 +00:00
|
|
|
RankedStatus int `json:"ranked_status"`
|
|
|
|
Frozen int `json:"frozen"`
|
|
|
|
}
|
|
|
|
|
2016-06-08 16:30:23 +00:00
|
|
|
// BeatmapSetStatusPOST changes the ranked status of a beatmap, and whether
|
|
|
|
// the beatmap ranked status is frozen. Or freezed. Freezed best meme 2k16
|
2016-04-27 18:03:06 +00:00
|
|
|
func BeatmapSetStatusPOST(md common.MethodData) common.CodeMessager {
|
|
|
|
var req beatmapSetStatusData
|
|
|
|
md.RequestData.Unmarshal(&req)
|
|
|
|
|
|
|
|
var miss []string
|
2016-06-08 17:55:52 +00:00
|
|
|
if req.BeatmapsetID == 0 && req.BeatmapID == 0 {
|
2016-06-08 16:30:23 +00:00
|
|
|
miss = append(miss, "beatmapset_id or beatmap_id")
|
2016-04-27 18:03:06 +00:00
|
|
|
}
|
|
|
|
if len(miss) != 0 {
|
|
|
|
return ErrMissingField(miss...)
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.Frozen != 0 && req.Frozen != 1 {
|
|
|
|
return common.SimpleResponse(400, "frozen status must be either 0 or 1")
|
|
|
|
}
|
2016-04-27 19:03:16 +00:00
|
|
|
if req.RankedStatus > 4 || -1 > req.RankedStatus {
|
|
|
|
return common.SimpleResponse(400, "ranked status must be 5 < x < -2")
|
2016-04-27 18:03:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-08 22:29:00 +00:00
|
|
|
param := req.BeatmapsetID
|
2016-06-08 16:30:23 +00:00
|
|
|
if req.BeatmapID != 0 {
|
2016-06-08 22:29:00 +00:00
|
|
|
err := md.DB.QueryRow("SELECT beatmapset_id FROM beatmaps WHERE beatmap_id = ? LIMIT 1", req.BeatmapID).Scan(¶m)
|
2016-06-09 08:52:55 +00:00
|
|
|
switch {
|
|
|
|
case err == sql.ErrNoRows:
|
|
|
|
return common.SimpleResponse(404, "That beatmap could not be found!")
|
|
|
|
case err != nil:
|
2016-06-08 22:29:00 +00:00
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
|
|
|
}
|
2016-06-08 16:30:23 +00:00
|
|
|
}
|
|
|
|
|
2016-07-20 08:49:29 +00:00
|
|
|
md.DB.Exec(`UPDATE beatmaps
|
2016-06-08 16:30:23 +00:00
|
|
|
SET ranked = ?, ranked_status_freezed = ?
|
2016-06-08 22:29:00 +00:00
|
|
|
WHERE beatmapset_id = ?`, req.RankedStatus, req.Frozen, param)
|
2016-04-27 18:03:06 +00:00
|
|
|
|
2016-09-17 21:27:20 +00:00
|
|
|
var x = make(map[string]interface{}, 1)
|
|
|
|
if req.BeatmapID != 0 {
|
|
|
|
x["bb"] = req.BeatmapID
|
|
|
|
} else {
|
|
|
|
x["s"] = req.BeatmapsetID
|
|
|
|
}
|
|
|
|
md.C.Request.URL = genURL(x)
|
2016-08-23 14:27:09 +00:00
|
|
|
return getMultipleBeatmaps(md)
|
2016-06-08 17:55:52 +00:00
|
|
|
}
|
|
|
|
|
2016-09-17 21:27:20 +00:00
|
|
|
func genURL(d map[string]interface{}) *url.URL {
|
|
|
|
var s string
|
|
|
|
for k, v := range d {
|
|
|
|
if s != "" {
|
|
|
|
s += "&"
|
|
|
|
}
|
|
|
|
s += k + "=" + url.QueryEscape(fmt.Sprintf("%v", v))
|
|
|
|
}
|
|
|
|
u := new(url.URL)
|
|
|
|
if len(d) == 0 {
|
|
|
|
return u
|
|
|
|
}
|
|
|
|
u.RawQuery = s
|
|
|
|
return u
|
|
|
|
}
|
|
|
|
|
2016-06-08 17:55:52 +00:00
|
|
|
// BeatmapGET retrieves a beatmap.
|
|
|
|
func BeatmapGET(md common.MethodData) common.CodeMessager {
|
2016-08-15 17:59:46 +00:00
|
|
|
beatmapID := common.Int(md.Query("b"))
|
2016-06-08 17:55:52 +00:00
|
|
|
if beatmapID != 0 {
|
2016-08-23 14:27:09 +00:00
|
|
|
return getBeatmapSingle(md, beatmapID)
|
2016-06-08 17:55:52 +00:00
|
|
|
}
|
2016-08-23 14:27:09 +00:00
|
|
|
return getMultipleBeatmaps(md)
|
2016-06-08 17:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const baseBeatmapSelect = `
|
|
|
|
SELECT
|
|
|
|
beatmap_id, beatmapset_id, beatmap_md5,
|
2016-07-18 21:27:37 +00:00
|
|
|
song_name, ar, od, difficulty_std, difficulty_taiko,
|
|
|
|
difficulty_ctb, difficulty_mania, max_combo,
|
2016-06-08 17:55:52 +00:00
|
|
|
hit_length, ranked, ranked_status_freezed,
|
|
|
|
latest_update
|
|
|
|
FROM beatmaps
|
|
|
|
`
|
|
|
|
|
2016-08-23 14:27:09 +00:00
|
|
|
func getMultipleBeatmaps(md common.MethodData) common.CodeMessager {
|
|
|
|
sort := common.Sort(md, common.SortConfiguration{
|
|
|
|
Allowed: []string{
|
|
|
|
"beatmapset_id",
|
|
|
|
"beatmap_id",
|
|
|
|
"id",
|
|
|
|
"ar",
|
|
|
|
"od",
|
|
|
|
"difficulty_std",
|
|
|
|
"difficulty_taiko",
|
|
|
|
"difficulty_ctb",
|
|
|
|
"difficulty_mania",
|
|
|
|
"max_combo",
|
|
|
|
"latest_update",
|
|
|
|
"playcount",
|
|
|
|
"passcount",
|
|
|
|
},
|
|
|
|
Default: "id DESC",
|
|
|
|
Table: "beatmaps",
|
|
|
|
})
|
2016-09-17 21:27:20 +00:00
|
|
|
where := common.
|
|
|
|
Where("beatmap_id = ?", md.Query("bb")).
|
|
|
|
Where("beatmapset_id = ?", md.Query("s")).
|
2016-08-23 14:27:09 +00:00
|
|
|
Where("song_name = ?", md.Query("song_name")).
|
|
|
|
Where("ranked_status_freezed = ?", md.Query("ranked_status_frozen"), "0", "1")
|
|
|
|
|
|
|
|
rows, err := md.DB.Query(baseBeatmapSelect+
|
|
|
|
where.Clause+" "+sort+" "+
|
|
|
|
common.Paginate(md.Query("p"), md.Query("l"), 50), where.Params...)
|
2016-06-08 17:55:52 +00:00
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
|
|
|
}
|
|
|
|
var r beatmapSetResponse
|
|
|
|
for rows.Next() {
|
2016-07-06 20:32:30 +00:00
|
|
|
var b beatmap
|
2016-06-08 17:55:52 +00:00
|
|
|
err = rows.Scan(
|
|
|
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
2016-07-18 21:27:37 +00:00
|
|
|
&b.SongName, &b.AR, &b.OD, &b.Diff2.STD, &b.Diff2.Taiko,
|
|
|
|
&b.Diff2.CTB, &b.Diff2.Mania, &b.MaxCombo,
|
2016-06-08 17:55:52 +00:00
|
|
|
&b.HitLength, &b.Ranked, &b.RankedStatusFrozen,
|
2016-07-06 20:32:30 +00:00
|
|
|
&b.LatestUpdate,
|
2016-06-08 17:55:52 +00:00
|
|
|
)
|
2016-07-18 21:27:37 +00:00
|
|
|
b.Difficulty = b.Diff2.STD
|
2016-06-08 17:55:52 +00:00
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
r.Beatmaps = append(r.Beatmaps, b)
|
|
|
|
}
|
|
|
|
r.Code = 200
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2016-08-23 14:27:09 +00:00
|
|
|
func getBeatmapSingle(md common.MethodData, beatmapID int) common.CodeMessager {
|
2016-07-06 20:32:30 +00:00
|
|
|
var b beatmap
|
2016-06-08 17:55:52 +00:00
|
|
|
err := md.DB.QueryRow(baseBeatmapSelect+"WHERE beatmap_id = ? LIMIT 1", beatmapID).Scan(
|
|
|
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
2016-07-18 21:27:37 +00:00
|
|
|
&b.SongName, &b.AR, &b.OD, &b.Diff2.STD, &b.Diff2.Taiko,
|
|
|
|
&b.Diff2.CTB, &b.Diff2.Mania, &b.MaxCombo,
|
2016-06-08 17:55:52 +00:00
|
|
|
&b.HitLength, &b.Ranked, &b.RankedStatusFrozen,
|
2016-07-06 20:32:30 +00:00
|
|
|
&b.LatestUpdate,
|
2016-06-08 17:55:52 +00:00
|
|
|
)
|
2016-07-18 21:27:37 +00:00
|
|
|
b.Difficulty = b.Diff2.STD
|
2016-06-08 17:55:52 +00:00
|
|
|
switch {
|
|
|
|
case err == sql.ErrNoRows:
|
|
|
|
return common.SimpleResponse(404, "That beatmap could not be found!")
|
|
|
|
case err != nil:
|
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
2016-04-27 18:03:06 +00:00
|
|
|
}
|
2016-06-08 17:55:52 +00:00
|
|
|
var r beatmapResponse
|
|
|
|
r.Code = 200
|
|
|
|
r.beatmap = b
|
|
|
|
return r
|
2016-04-27 18:03:06 +00:00
|
|
|
}
|
2016-06-08 21:33:08 +00:00
|
|
|
|
|
|
|
type beatmapReduced struct {
|
|
|
|
BeatmapID int `json:"beatmap_id"`
|
|
|
|
BeatmapsetID int `json:"beatmapset_id"`
|
|
|
|
BeatmapMD5 string `json:"beatmap_md5"`
|
|
|
|
Ranked int `json:"ranked"`
|
|
|
|
RankedStatusFrozen int `json:"ranked_status_frozen"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type beatmapRankedFrozenFullResponse struct {
|
|
|
|
common.ResponseBase
|
|
|
|
Beatmaps []beatmapReduced `json:"beatmaps"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// BeatmapRankedFrozenFullGET retrieves all beatmaps with a certain
|
|
|
|
// ranked_status_freezed
|
|
|
|
func BeatmapRankedFrozenFullGET(md common.MethodData) common.CodeMessager {
|
|
|
|
rows, err := md.DB.Query(`
|
|
|
|
SELECT beatmap_id, beatmapset_id, beatmap_md5, ranked, ranked_status_freezed
|
|
|
|
FROM beatmaps
|
|
|
|
WHERE ranked_status_freezed = '1'
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
|
|
|
}
|
|
|
|
var r beatmapRankedFrozenFullResponse
|
|
|
|
for rows.Next() {
|
|
|
|
var b beatmapReduced
|
|
|
|
err = rows.Scan(&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5, &b.Ranked, &b.RankedStatusFrozen)
|
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
r.Beatmaps = append(r.Beatmaps, b)
|
|
|
|
}
|
|
|
|
r.Code = 200
|
|
|
|
return r
|
|
|
|
}
|