Implement get_user_best and get_user_recent in peppyapi

This commit is contained in:
Howl 2016-05-28 20:24:39 +02:00
parent db323908ac
commit 6a374a4f9d
8 changed files with 129 additions and 5 deletions

View File

@ -7,6 +7,8 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var defaultResponse = []struct{}{}
func genmode(m string) string { func genmode(m string) string {
switch m { switch m {
case "1": case "1":
@ -20,6 +22,13 @@ func genmode(m string) string {
} }
return m 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) { func genUser(c *gin.Context, db *sql.DB) (string, string) {
var whereClause string var whereClause string

View File

@ -9,5 +9,5 @@ import (
// GetMatch retrieves general match information. // GetMatch retrieves general match information.
func GetMatch(c *gin.Context, db *sql.DB) { func GetMatch(c *gin.Context, db *sql.DB) {
c.JSON(200, []struct{}{}) c.JSON(200, defaultResponse)
} }

View File

@ -13,7 +13,7 @@ import (
// GetUser retrieves general user information. // GetUser retrieves general user information.
func GetUser(c *gin.Context, db *sql.DB) { func GetUser(c *gin.Context, db *sql.DB) {
if c.Query("u") == "" { if c.Query("u") == "" {
c.JSON(200, []struct{}{}) c.JSON(200, defaultResponse)
return return
} }
var user osuapi.User var user osuapi.User
@ -42,7 +42,8 @@ func GetUser(c *gin.Context, db *sql.DB) {
&user.Country, &display, &user.Country, &display,
) )
if err != nil { if err != nil {
c.JSON(200, []struct{}{}) c.JSON(200, defaultResponse)
c.Error(err)
return return
} }
if !display { if !display {

96
app/peppy/user_x.go Normal file
View File

@ -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)
}

View File

@ -70,6 +70,8 @@ func Start(conf common.Conf, dbO *sql.DB) *gin.Engine {
// peppyapi // peppyapi
api.GET("/get_user", PeppyMethod(peppy.GetUser)) api.GET("/get_user", PeppyMethod(peppy.GetUser))
api.GET("/get_match", PeppyMethod(peppy.GetMatch)) 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) r.NoRoute(v1.Handle404)

View File

@ -150,7 +150,7 @@ func scoresPuts(md common.MethodData, whereClause string, params ...interface{})
return Err500 return Err500
} }
// puck feppy // puck feppy
us.Time, err = time.Parse("060102150405", t) us.Time, err = time.Parse(common.OsuTimeFormat, t)
if err != nil { if err != nil {
md.Err(err) md.Err(err)
return Err500 return Err500

View File

@ -1,8 +1,10 @@
package common package common
import "strconv"
// In picks x if y < x, picks z if y > z, or if none of the previous // In picks x if y < x, picks z if y > z, or if none of the previous
// conditions is satisfies, it simply picks y. // conditions is satisfies, it simply picks y.
func In(x, y, z int) { func In(x, y, z int) int {
switch { switch {
case y < x: case y < x:
return x return x
@ -11,3 +13,13 @@ func In(x, y, z int) {
} }
return y 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)
}

View File

@ -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"