Add initial beatmap reqeusts API to get current status

This commit is contained in:
Howl 2016-09-06 20:11:46 +02:00
parent 6eda6aea87
commit dd00c39075
4 changed files with 87 additions and 22 deletions

View File

@ -84,6 +84,7 @@ func Start(conf common.Conf, dbO *sqlx.DB) *gin.Engine {
gv1.GET("/users/scores/recent", Method(v1.UserScoresRecentGET)) gv1.GET("/users/scores/recent", Method(v1.UserScoresRecentGET))
gv1.GET("/badges", Method(v1.BadgesGET)) gv1.GET("/badges", Method(v1.BadgesGET))
gv1.GET("/beatmaps", Method(v1.BeatmapGET)) gv1.GET("/beatmaps", Method(v1.BeatmapGET))
gv1.GET("/beatmaps/rank_requests/status", Method(v1.BeatmapRankRequestsStatusGET))
gv1.GET("/leaderboard", Method(v1.LeaderboardGET)) gv1.GET("/leaderboard", Method(v1.LeaderboardGET))
gv1.GET("/tokens", Method(v1.TokenGET)) gv1.GET("/tokens", Method(v1.TokenGET))
gv1.GET("/users/self", Method(v1.UserSelfGET)) gv1.GET("/users/self", Method(v1.UserSelfGET))
@ -122,12 +123,12 @@ func Start(conf common.Conf, dbO *sqlx.DB) *gin.Engine {
common.PrivilegeManageUser, common.PrivilegeAPIMeta)) common.PrivilegeManageUser, common.PrivilegeAPIMeta))
// in the new osu-web, the old endpoints are also in /v1 it seems. So /shrug // in the new osu-web, the old endpoints are also in /v1 it seems. So /shrug
p.GET("/get_user", PeppyMethod(peppy.GetUser)) gv1.GET("/get_user", PeppyMethod(peppy.GetUser))
p.GET("/get_match", PeppyMethod(peppy.GetMatch)) gv1.GET("/get_match", PeppyMethod(peppy.GetMatch))
p.GET("/get_user_recent", PeppyMethod(peppy.GetUserRecent)) gv1.GET("/get_user_recent", PeppyMethod(peppy.GetUserRecent))
p.GET("/get_user_best", PeppyMethod(peppy.GetUserBest)) gv1.GET("/get_user_best", PeppyMethod(peppy.GetUserBest))
p.GET("/get_scores", PeppyMethod(peppy.GetScores)) gv1.GET("/get_scores", PeppyMethod(peppy.GetScores))
p.GET("/get_beatmaps", PeppyMethod(peppy.GetBeatmap)) gv1.GET("/get_beatmaps", PeppyMethod(peppy.GetBeatmap))
} }
api.GET("/status", internals.Status) api.GET("/status", internals.Status)

View File

@ -0,0 +1,55 @@
package v1
import (
"strconv"
"time"
"git.zxq.co/ripple/rippleapi/common"
)
type rankRequestsStatusResponse struct {
common.ResponseBase
QueueSize int `json:"queue_size"`
MaxPeruser int `json:"max_per_user"`
Submitted int `json:"submitted"`
SubmittedByUser int `json:"submitted_by_user"`
CanSubmit bool `json:"can_submit"`
NextExpiration *time.Time `json:"next_expiration"`
}
// BeatmapRankRequestsStatusGET gets the current status for beatmap ranking requests.
func BeatmapRankRequestsStatusGET(md common.MethodData) common.CodeMessager {
c := common.GetConf()
rows, err := md.DB.Query("SELECT userid, time FROM rank_requests WHERE time > ? ORDER BY id ASC LIMIT "+strconv.Itoa(c.RankQueueSize), time.Now().Add(-time.Hour*24).Unix())
if err != nil {
md.Err(err)
return Err500
}
var r rankRequestsStatusResponse
isFirst := true
for rows.Next() {
var (
user int
timestamp common.UnixTimestamp
)
err := rows.Scan(&user, &timestamp)
if err != nil {
md.Err(err)
continue
}
if user == md.ID() {
r.SubmittedByUser++
}
if isFirst {
x := time.Time(timestamp)
r.NextExpiration = &x
isFirst = false
}
r.Submitted++
}
r.QueueSize = c.RankQueueSize
r.MaxPeruser = c.BeatmapRequestsPerUser
r.CanSubmit = r.Submitted < r.QueueSize && r.SubmittedByUser < r.MaxPeruser
r.Code = 200
return r
}

View File

@ -1,5 +0,0 @@
package v1
func init() {
go removeUseless()
}

View File

@ -13,12 +13,14 @@ var Version string
// Conf is the configuration file data for the ripple API. // Conf is the configuration file data for the ripple API.
// Conf uses https://github.com/thehowl/conf // Conf uses https://github.com/thehowl/conf
type Conf struct { type Conf struct {
DatabaseType string `description:"At the moment, 'mysql' is the only supported database type."` DatabaseType string `description:"At the moment, 'mysql' is the only supported database type."`
DSN string `description:"The Data Source Name for the database. More: https://github.com/go-sql-driver/mysql#dsn-data-source-name"` DSN string `description:"The Data Source Name for the database. More: https://github.com/go-sql-driver/mysql#dsn-data-source-name"`
ListenTo string `description:"The IP/Port combination from which to take connections, e.g. :8080"` ListenTo string `description:"The IP/Port combination from which to take connections, e.g. :8080"`
Unix bool `description:"Bool indicating whether ListenTo is a UNIX socket or an address."` Unix bool `description:"Bool indicating whether ListenTo is a UNIX socket or an address."`
SentryDSN string `description:"thing for sentry whatever"` SentryDSN string `description:"thing for sentry whatever"`
HanayoKey string HanayoKey string
BeatmapRequestsPerUser int
RankQueueSize int
} }
var cachedConf *Conf var cachedConf *Conf
@ -33,14 +35,26 @@ func Load() (c Conf, halt bool) {
halt = err == conf.ErrNoFile halt = err == conf.ErrNoFile
if halt { if halt {
conf.MustExport(Conf{ conf.MustExport(Conf{
DatabaseType: "mysql", DatabaseType: "mysql",
DSN: "root@/ripple", DSN: "root@/ripple",
ListenTo: ":40001", ListenTo: ":40001",
Unix: false, Unix: false,
HanayoKey: "Potato", HanayoKey: "Potato",
BeatmapRequestsPerUser: 2,
RankQueueSize: 25,
}, "api.conf") }, "api.conf")
fmt.Println("Please compile the configuration file (api.conf).") fmt.Println("Please compile the configuration file (api.conf).")
} }
cachedConf = &c cachedConf = &c
return return
} }
// GetConf returns the cachedConf.
func GetConf() *Conf {
if cachedConf == nil {
return nil
}
// so that the cachedConf cannot actually get modified
c := *cachedConf
return &c
}