diff --git a/app/peppy/beatmap.go b/app/peppy/beatmap.go index 7fec6ab..9b57b82 100644 --- a/app/peppy/beatmap.go +++ b/app/peppy/beatmap.go @@ -1,14 +1,19 @@ package peppy import ( + "strconv" + "strings" + + "git.zxq.co/ripple/rippleapi/common" "github.com/gin-gonic/gin" "github.com/jmoiron/sqlx" + "github.com/thehowl/go-osuapi" ) // GetBeatmap retrieves general beatmap information. func GetBeatmap(c *gin.Context, db *sqlx.DB) { var whereClauses []string - var params []string + var params []interface{} // since value is not stored, silently ignore if c.Query("s") != "" { @@ -19,19 +24,105 @@ func GetBeatmap(c *gin.Context, db *sqlx.DB) { whereClauses = append(whereClauses, "beatmaps.beatmap_id = ?") params = append(params, c.Query("b")) } - if c.Query("u") != "" { - wc, p := genUser(c, db) - whereClauses = append(whereClauses, wc) - params = append(params, p) + // creator is not stored, silently ignore u and type + if c.Query("m") != "" { + m := genmode(c.Query("m")) + if m == "std" { + whereClauses = append(whereClauses, "beatmaps.difficulty_std != 0") + for _, i := range modes[1:] { + whereClauses = append(whereClauses, "beatmaps.difficulty_"+i+" == 0") + } + } else { + whereClauses = append(whereClauses, "beatmaps.difficulty_"+m+" != 0") + if c.Query("a") == "1" { + whereClauses = append(whereClauses, "beatmaps.difficulty_std = 0") + } + } } - // silently ignore m - // silently ignore a if c.Query("h") != "" { whereClauses = append(whereClauses, "beatmaps.beatmap_md5 = ?") params = append(params, c.Query("h")) } - //bm := osuapi.Beatmap{} + where := strings.Join(whereClauses, " AND ") + if where != "" { + where = "WHERE " + where + } - //db.Query("SELECT beatmaps.beatmapset_id, beatmaps.beatmap FROM ") + rows, err := db.Query(`SELECT + beatmapset_id, beatmap_id, ranked, hit_length, + song_name, beatmap_md5, ar, od, bpm, playcount, + passcount, max_combo, difficulty_std, difficulty_taiko, difficulty_ctb, difficulty_mania, + latest_update + +FROM beatmaps `+where+" ORDER BY id DESC LIMIT "+strconv.Itoa(common.InString(1, c.Query("limit"), 500, 500)), + params...) + if err != nil { + c.Error(err) + c.JSON(200, defaultResponse) + return + } + + var bms []osuapi.Beatmap + for rows.Next() { + var ( + bm osuapi.Beatmap + rawRankedStatus int + rawName string + rawLastUpdate common.UnixTimestamp + diffs [4]float64 + ) + err := rows.Scan( + &bm.BeatmapSetID, &bm.BeatmapID, &rawRankedStatus, &bm.HitLength, + &rawName, &bm.FileMD5, &bm.ApproachRate, &bm.OverallDifficulty, &bm.BPM, &bm.Playcount, + &bm.Passcount, &bm.MaxCombo, &diffs[0], &diffs[1], &diffs[2], &diffs[3], + &rawLastUpdate, + ) + if err != nil { + c.Error(err) + continue + } + bm.TotalLength = bm.HitLength + bm.LastUpdate = osuapi.MySQLDate(rawLastUpdate) + if rawRankedStatus >= 2 { + bm.ApprovedDate = osuapi.MySQLDate(rawLastUpdate) + } + // zero value of ApprovedStatus == osuapi.StatusPending, so /shrug + bm.Approved = rippleToOsuRankedStatus[rawRankedStatus] + bm.Artist, bm.Title, bm.DiffName = parseDiffName(rawName) + for i, diffVal := range diffs { + if diffVal != 0 { + bm.Mode = osuapi.Mode(i) + bm.DifficultyRating = diffVal + } + } + bms = append(bms, bm) + } + + c.JSON(200, bms) +} + +var rippleToOsuRankedStatus = map[int]osuapi.ApprovedStatus{ + 0: osuapi.StatusPending, + 1: osuapi.StatusWIP, // it means "needs updating", as the one in the db needs to be updated, but whatever + 2: osuapi.StatusRanked, + 3: osuapi.StatusApproved, + 4: osuapi.StatusQualified, +} + +// buggy diffname parser +func parseDiffName(name string) (author string, title string, diffName string) { + parts := strings.SplitN(name, "-", 2) + author = parts[0] + if len(parts) > 1 { + title = parts[1] + if s := strings.Index(title, " ["); s != -1 { + diffName = title[s+2:] + if len(diffName) != 0 && diffName[len(diffName)-1] == ']' { + diffName = diffName[:len(diffName)-1] + } + title = title[:s] + } + } + return } diff --git a/app/peppy/common.go b/app/peppy/common.go index b8b95e3..b9c0ff0 100644 --- a/app/peppy/common.go +++ b/app/peppy/common.go @@ -10,20 +10,13 @@ import ( "github.com/jmoiron/sqlx" ) +var modes = []string{"std", "taiko", "ctb", "mania"} + var defaultResponse = []struct{}{} func genmode(m string) string { - switch m { - case "1": - m = "taiko" - case "2": - m = "ctb" - case "3": - m = "mania" - default: - m = "std" - } - return m + i := genmodei(m) + return modes[i] } func genmodei(m string) int { v := common.Int(m) diff --git a/app/start.go b/app/start.go index 999d13b..93d02fb 100644 --- a/app/start.go +++ b/app/start.go @@ -120,6 +120,7 @@ func Start(conf common.Conf, dbO *sqlx.DB) *gin.Engine { api.GET("/get_user_recent", PeppyMethod(peppy.GetUserRecent)) api.GET("/get_user_best", PeppyMethod(peppy.GetUserBest)) api.GET("/get_scores", PeppyMethod(peppy.GetScores)) + api.GET("/get_beatmaps", PeppyMethod(peppy.GetBeatmap)) } r.NoRoute(v1.Handle404)