From 6a374a4f9d40e0d4e83f800eee421fad5353a5cb Mon Sep 17 00:00:00 2001 From: Howl Date: Sat, 28 May 2016 20:24:39 +0200 Subject: [PATCH] Implement get_user_best and get_user_recent in peppyapi --- app/peppy/common.go | 9 ++++ app/peppy/match.go | 2 +- app/peppy/user.go | 5 +- app/peppy/user_x.go | 96 +++++++++++++++++++++++++++++++++++++++ app/start.go | 2 + app/v1/user_scores.go | 2 +- common/in.go | 14 +++++- common/osu_time_format.go | 4 ++ 8 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 app/peppy/user_x.go create mode 100644 common/osu_time_format.go diff --git a/app/peppy/common.go b/app/peppy/common.go index 223f24d..02e7701 100644 --- a/app/peppy/common.go +++ b/app/peppy/common.go @@ -7,6 +7,8 @@ import ( "github.com/gin-gonic/gin" ) +var defaultResponse = []struct{}{} + func genmode(m string) string { switch m { case "1": @@ -20,6 +22,13 @@ func genmode(m string) string { } return m } +func genmodei(m string) int { + v, _ := strconv.Atoi(m) + if v > 3 || v < 0 { + v = 0 + } + return v +} func genUser(c *gin.Context, db *sql.DB) (string, string) { var whereClause string diff --git a/app/peppy/match.go b/app/peppy/match.go index b6fae96..318b834 100644 --- a/app/peppy/match.go +++ b/app/peppy/match.go @@ -9,5 +9,5 @@ import ( // GetMatch retrieves general match information. func GetMatch(c *gin.Context, db *sql.DB) { - c.JSON(200, []struct{}{}) + c.JSON(200, defaultResponse) } diff --git a/app/peppy/user.go b/app/peppy/user.go index aa644fa..0b297a1 100644 --- a/app/peppy/user.go +++ b/app/peppy/user.go @@ -13,7 +13,7 @@ import ( // GetUser retrieves general user information. func GetUser(c *gin.Context, db *sql.DB) { if c.Query("u") == "" { - c.JSON(200, []struct{}{}) + c.JSON(200, defaultResponse) return } var user osuapi.User @@ -42,7 +42,8 @@ func GetUser(c *gin.Context, db *sql.DB) { &user.Country, &display, ) if err != nil { - c.JSON(200, []struct{}{}) + c.JSON(200, defaultResponse) + c.Error(err) return } if !display { diff --git a/app/peppy/user_x.go b/app/peppy/user_x.go new file mode 100644 index 0000000..229b6ad --- /dev/null +++ b/app/peppy/user_x.go @@ -0,0 +1,96 @@ +package peppy + +import ( + "database/sql" + "fmt" + "strings" + "time" + + "git.zxq.co/ripple/rippleapi/common" + "git.zxq.co/x/getrank" + "github.com/gin-gonic/gin" + "gopkg.in/thehowl/go-osuapi.v1" +) + +// GetUserRecent retrieves an user's recent scores. +func GetUserRecent(c *gin.Context, db *sql.DB) { + getUserX(c, db, "ORDER BY scores.time DESC", common.InString(1, c.Query("limit"), 50, 10)) +} + +// GetUserBest retrieves an user's best scores. +func GetUserBest(c *gin.Context, db *sql.DB) { + var sb string + if genmodei(c.Query("m")) == 0 { + sb = "scores.pp" + } else { + sb = "scores.score" + } + getUserX(c, db, "ORDER BY "+sb+" DESC", common.InString(1, c.Query("limit"), 100, 10)) +} + +func getUserX(c *gin.Context, db *sql.DB, orderBy string, limit int) { + whereClause, p := genUser(c, db) + query := fmt.Sprintf( + `SELECT + beatmaps.beatmap_id, scores.score, scores.max_combo, + scores.300_count, scores.100_count, scores.50_count, + scores.gekis_count, scores.katus_count, scores.misses_count, + scores.full_combo, scores.mods, users.id, scores.time, + scores.pp, scores.accuracy + FROM scores + LEFT JOIN beatmaps ON beatmaps.beatmap_md5 = scores.beatmap_md5 + LEFT JOIN users ON scores.username = users.username + WHERE %s AND scores.play_mode = ? + %s + LIMIT %d`, whereClause, orderBy, limit, + ) + scores := make([]osuapi.GUSScore, 0, limit) + m := genmodei(c.Query("m")) + rows, err := db.Query(query, p, m) + if err != nil { + c.JSON(200, defaultResponse) + c.Error(err) + return + } + for rows.Next() { + var ( + curscore osuapi.GUSScore + rawTime string + acc float64 + fc bool + mods int + ) + err := rows.Scan( + &curscore.BeatmapID, &curscore.Score.Score, &curscore.MaxCombo, + &curscore.Count300, &curscore.Count100, &curscore.Count50, + &curscore.CountGeki, &curscore.CountKatu, &curscore.CountMiss, + &fc, &mods, &curscore.UserID, &rawTime, + &curscore.PP, &acc, + ) + if err != nil { + c.JSON(200, defaultResponse) + c.Error(err) + return + } + curscore.FullCombo = osuapi.OsuBool(fc) + curscore.Mods = osuapi.Mods(mods) + t, err := time.Parse(common.OsuTimeFormat, rawTime) + if err != nil { + c.JSON(200, defaultResponse) + c.Error(err) + return + } + curscore.Date = osuapi.MySQLDate(t) + curscore.Rank = strings.ToUpper(getrank.GetRank( + osuapi.Mode(m), + curscore.Mods, + acc, + curscore.Count300, + curscore.Count100, + curscore.Count50, + curscore.CountMiss, + )) + scores = append(scores, curscore) + } + c.JSON(200, scores) +} diff --git a/app/start.go b/app/start.go index a2f83f5..63eeef3 100644 --- a/app/start.go +++ b/app/start.go @@ -70,6 +70,8 @@ func Start(conf common.Conf, dbO *sql.DB) *gin.Engine { // peppyapi api.GET("/get_user", PeppyMethod(peppy.GetUser)) api.GET("/get_match", PeppyMethod(peppy.GetMatch)) + api.GET("/get_user_recent", PeppyMethod(peppy.GetUserRecent)) + api.GET("/get_user_best", PeppyMethod(peppy.GetUserBest)) } r.NoRoute(v1.Handle404) diff --git a/app/v1/user_scores.go b/app/v1/user_scores.go index 0cef5c7..5ad4e5b 100644 --- a/app/v1/user_scores.go +++ b/app/v1/user_scores.go @@ -150,7 +150,7 @@ func scoresPuts(md common.MethodData, whereClause string, params ...interface{}) return Err500 } // puck feppy - us.Time, err = time.Parse("060102150405", t) + us.Time, err = time.Parse(common.OsuTimeFormat, t) if err != nil { md.Err(err) return Err500 diff --git a/common/in.go b/common/in.go index 1ff46a7..280b724 100644 --- a/common/in.go +++ b/common/in.go @@ -1,8 +1,10 @@ package common +import "strconv" + // In picks x if y < x, picks z if y > z, or if none of the previous // conditions is satisfies, it simply picks y. -func In(x, y, z int) { +func In(x, y, z int) int { switch { case y < x: return x @@ -11,3 +13,13 @@ func In(x, y, z int) { } return y } + +// InString takes y as a string, also allows for a default value should y be +// invalid as a number. +func InString(x int, y string, z, def int) int { + num, err := strconv.Atoi(y) + if err != nil { + return def + } + return In(x, num, z) +} diff --git a/common/osu_time_format.go b/common/osu_time_format.go new file mode 100644 index 0000000..006e509 --- /dev/null +++ b/common/osu_time_format.go @@ -0,0 +1,4 @@ +package common + +// OsuTimeFormat is the time format for scores in the DB. Can be used with time.Parse etc. +const OsuTimeFormat = "060102150405"