Start implementing peppyapi; implement /api/get_user
This commit is contained in:
parent
a939d15779
commit
d6f67915c5
|
@ -1,7 +1,6 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
@ -10,13 +9,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Method wraps an API method to a HandlerFunc.
|
// Method wraps an API method to a HandlerFunc.
|
||||||
func Method(f func(md common.MethodData) common.CodeMessager, db *sql.DB, privilegesNeeded ...int) gin.HandlerFunc {
|
func Method(f func(md common.MethodData) common.CodeMessager, privilegesNeeded ...int) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
initialCaretaker(c, f, db, privilegesNeeded...)
|
initialCaretaker(c, f, privilegesNeeded...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initialCaretaker(c *gin.Context, f func(md common.MethodData) common.CodeMessager, db *sql.DB, privilegesNeeded ...int) {
|
func initialCaretaker(c *gin.Context, f func(md common.MethodData) common.CodeMessager, privilegesNeeded ...int) {
|
||||||
data, err := ioutil.ReadAll(c.Request.Body)
|
data, err := ioutil.ReadAll(c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error(err)
|
c.Error(err)
|
||||||
|
|
52
app/peppy/common.go
Normal file
52
app/peppy/common.go
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package peppy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func genmode(m string) string {
|
||||||
|
switch m {
|
||||||
|
case "1":
|
||||||
|
m = "taiko"
|
||||||
|
case "2":
|
||||||
|
m = "ctb"
|
||||||
|
case "3":
|
||||||
|
m = "mania"
|
||||||
|
default:
|
||||||
|
m = "std"
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func genUser(c *gin.Context, db *sql.DB) (string, string) {
|
||||||
|
var whereClause string
|
||||||
|
var p string
|
||||||
|
|
||||||
|
// used in second case of switch
|
||||||
|
_, err := strconv.Atoi(c.Query("u"))
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// We know for sure that it's an username.
|
||||||
|
case c.Query("type") == "string":
|
||||||
|
whereClause = "WHERE users.username = ?"
|
||||||
|
p = c.Query("u")
|
||||||
|
// It could be an user ID, so we look for an user with that username first.
|
||||||
|
case err == nil:
|
||||||
|
err = db.QueryRow("SELECT id FROM users WHERE username = ? LIMIT 1", c.Query("u")).Scan(&p)
|
||||||
|
// If there is an error, that means u is an userID.
|
||||||
|
// If there is none, p will automatically have become the user id retrieved from the database
|
||||||
|
// in the last query.
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
p = c.Query("u")
|
||||||
|
}
|
||||||
|
whereClause = "WHERE users.id = ?"
|
||||||
|
// u contains letters, so it's an username.
|
||||||
|
default:
|
||||||
|
p = c.Query("u")
|
||||||
|
whereClause = "WHERE users.username = ?"
|
||||||
|
}
|
||||||
|
return whereClause, p
|
||||||
|
}
|
|
@ -1,2 +1,53 @@
|
||||||
// Package peppy implements the osu! API as defined on the osu-api repository wiki (https://github.com/ppy/osu-api/wiki).
|
// Package peppy implements the osu! API as defined on the osu-api repository wiki (https://github.com/ppy/osu-api/wiki).
|
||||||
package peppy
|
package peppy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/thehowl/go-osuapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetUser retrieves general user information.
|
||||||
|
func GetUser(c *gin.Context, db *sql.DB) {
|
||||||
|
if c.Query("u") == "" {
|
||||||
|
c.JSON(200, []struct{}{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var user osuapi.User
|
||||||
|
whereClause, p := genUser(c, db)
|
||||||
|
|
||||||
|
mode := genmode(c.Query("m"))
|
||||||
|
|
||||||
|
fmt.Println(whereClause, p)
|
||||||
|
|
||||||
|
var display bool
|
||||||
|
err := db.QueryRow(fmt.Sprintf(
|
||||||
|
`SELECT
|
||||||
|
users.id, users.username,
|
||||||
|
users_stats.playcount_%s, users_stats.ranked_score_%s, users_stats.total_score_%s,
|
||||||
|
leaderboard_%s.position, users_stats.pp_%s, users_stats.avg_accuracy_%s,
|
||||||
|
users_stats.country, users_stats.show_country
|
||||||
|
FROM users
|
||||||
|
LEFT JOIN users_stats ON users_stats.id = users.id
|
||||||
|
LEFT JOIN leaderboard_%s ON leaderboard_%s.user = users.id
|
||||||
|
%s
|
||||||
|
LIMIT 1`,
|
||||||
|
mode, mode, mode, mode, mode, mode, mode, mode, whereClause,
|
||||||
|
), p).Scan(
|
||||||
|
&user.UserID, &user.Username,
|
||||||
|
&user.Playcount, &user.RankedScore, &user.TotalScore,
|
||||||
|
&user.Rank, &user.PP, &user.Accuracy,
|
||||||
|
&user.Country, &display,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, []struct{}{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !display {
|
||||||
|
user.Country = "XX"
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, []osuapi.User{user})
|
||||||
|
}
|
||||||
|
|
16
app/peppy_method.go
Normal file
16
app/peppy_method.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PeppyMethod generates a method for the peppyapi
|
||||||
|
func PeppyMethod(a func(c *gin.Context, db *sql.DB)) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
// I have no idea how, but I manged to accidentally string the first 4
|
||||||
|
// letters of the alphabet into a single function call.
|
||||||
|
a(c, db)
|
||||||
|
}
|
||||||
|
}
|
51
app/start.go
51
app/start.go
|
@ -4,14 +4,18 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"git.zxq.co/ripple/rippleapi/app/internals"
|
"git.zxq.co/ripple/rippleapi/app/internals"
|
||||||
|
"git.zxq.co/ripple/rippleapi/app/peppy"
|
||||||
"git.zxq.co/ripple/rippleapi/app/v1"
|
"git.zxq.co/ripple/rippleapi/app/v1"
|
||||||
"git.zxq.co/ripple/rippleapi/common"
|
"git.zxq.co/ripple/rippleapi/common"
|
||||||
"github.com/gin-gonic/contrib/gzip"
|
"github.com/gin-gonic/contrib/gzip"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var db *sql.DB
|
||||||
|
|
||||||
// Start begins taking HTTP connections.
|
// Start begins taking HTTP connections.
|
||||||
func Start(conf common.Conf, db *sql.DB) *gin.Engine {
|
func Start(conf common.Conf, dbO *sql.DB) *gin.Engine {
|
||||||
|
db = dbO
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
r.Use(gzip.Gzip(gzip.DefaultCompression), ErrorHandler())
|
r.Use(gzip.Gzip(gzip.DefaultCompression), ErrorHandler())
|
||||||
|
|
||||||
|
@ -19,47 +23,50 @@ func Start(conf common.Conf, db *sql.DB) *gin.Engine {
|
||||||
{
|
{
|
||||||
gv1 := api.Group("/v1")
|
gv1 := api.Group("/v1")
|
||||||
{
|
{
|
||||||
gv1.POST("/tokens/new", Method(v1.TokenNewPOST, db))
|
gv1.POST("/tokens/new", Method(v1.TokenNewPOST))
|
||||||
|
|
||||||
// Auth-free API endpoints
|
// Auth-free API endpoints
|
||||||
gv1.GET("/ping", Method(v1.PingGET, db))
|
gv1.GET("/ping", Method(v1.PingGET))
|
||||||
gv1.GET("/surprise_me", Method(v1.SurpriseMeGET, db))
|
gv1.GET("/surprise_me", Method(v1.SurpriseMeGET))
|
||||||
gv1.GET("/privileges", Method(v1.PrivilegesGET, db))
|
gv1.GET("/privileges", Method(v1.PrivilegesGET))
|
||||||
|
|
||||||
// Read privilege required
|
// Read privilege required
|
||||||
gv1.GET("/users", Method(v1.UsersGET, db, common.PrivilegeRead))
|
gv1.GET("/users", Method(v1.UsersGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/self", Method(v1.UserSelfGET, db, common.PrivilegeRead))
|
gv1.GET("/users/self", Method(v1.UserSelfGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/whatid", Method(v1.UserWhatsTheIDGET, db, common.PrivilegeRead))
|
gv1.GET("/users/whatid", Method(v1.UserWhatsTheIDGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/full", Method(v1.UserFullGET, db, common.PrivilegeRead))
|
gv1.GET("/users/full", Method(v1.UserFullGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/userpage", Method(v1.UserUserpageGET, db, common.PrivilegeRead))
|
gv1.GET("/users/userpage", Method(v1.UserUserpageGET, common.PrivilegeRead))
|
||||||
gv1.GET("/users/lookup", Method(v1.UserLookupGET, db, common.PrivilegeRead))
|
gv1.GET("/users/lookup", Method(v1.UserLookupGET, common.PrivilegeRead))
|
||||||
gv1.GET("/badges", Method(v1.BadgesGET, db, common.PrivilegeRead))
|
gv1.GET("/badges", Method(v1.BadgesGET, common.PrivilegeRead))
|
||||||
|
|
||||||
// ReadConfidential privilege required
|
// ReadConfidential privilege required
|
||||||
gv1.GET("/friends", Method(v1.FriendsGET, db, common.PrivilegeReadConfidential))
|
gv1.GET("/friends", Method(v1.FriendsGET, common.PrivilegeReadConfidential))
|
||||||
gv1.GET("/friends/with", Method(v1.FriendsWithGET, db, common.PrivilegeReadConfidential))
|
gv1.GET("/friends/with", Method(v1.FriendsWithGET, common.PrivilegeReadConfidential))
|
||||||
|
|
||||||
// Write privilege required
|
// Write privilege required
|
||||||
gv1.GET("/friends/add", Method(v1.FriendsAddGET, db, common.PrivilegeWrite))
|
gv1.GET("/friends/add", Method(v1.FriendsAddGET, common.PrivilegeWrite))
|
||||||
gv1.GET("/friends/del", Method(v1.FriendsDelGET, db, common.PrivilegeWrite))
|
gv1.GET("/friends/del", Method(v1.FriendsDelGET, common.PrivilegeWrite))
|
||||||
|
|
||||||
// Admin: beatmap
|
// Admin: beatmap
|
||||||
gv1.POST("/beatmaps/set_status", Method(v1.BeatmapSetStatusPOST, db, common.PrivilegeBeatmap))
|
gv1.POST("/beatmaps/set_status", Method(v1.BeatmapSetStatusPOST, common.PrivilegeBeatmap))
|
||||||
|
|
||||||
// Admin: user managing
|
// Admin: user managing
|
||||||
gv1.POST("/users/manage/set_allowed", Method(v1.UserManageSetAllowedPOST, db, common.PrivilegeManageUser))
|
gv1.POST("/users/manage/set_allowed", Method(v1.UserManageSetAllowedPOST, common.PrivilegeManageUser))
|
||||||
|
|
||||||
// M E T A
|
// M E T A
|
||||||
// E T "wow thats so meta"
|
// E T "wow thats so meta"
|
||||||
// T E -- the one who said "wow thats so meta"
|
// T E -- the one who said "wow thats so meta"
|
||||||
// A T E M
|
// A T E M
|
||||||
gv1.GET("/meta/restart", Method(v1.MetaRestartGET, db, common.PrivilegeAPIMeta))
|
gv1.GET("/meta/restart", Method(v1.MetaRestartGET, common.PrivilegeAPIMeta))
|
||||||
gv1.GET("/meta/kill", Method(v1.MetaKillGET, db, common.PrivilegeAPIMeta))
|
gv1.GET("/meta/kill", Method(v1.MetaKillGET, common.PrivilegeAPIMeta))
|
||||||
gv1.GET("/meta/up_since", Method(v1.MetaUpSinceGET, db, common.PrivilegeAPIMeta))
|
gv1.GET("/meta/up_since", Method(v1.MetaUpSinceGET, common.PrivilegeAPIMeta))
|
||||||
gv1.GET("/meta/update", Method(v1.MetaUpdateGET, db, common.PrivilegeAPIMeta))
|
gv1.GET("/meta/update", Method(v1.MetaUpdateGET, common.PrivilegeAPIMeta))
|
||||||
}
|
}
|
||||||
|
|
||||||
api.GET("/status", internals.Status)
|
api.GET("/status", internals.Status)
|
||||||
|
|
||||||
|
// peppyapi
|
||||||
|
api.GET("/get_user", PeppyMethod(peppy.GetUser))
|
||||||
}
|
}
|
||||||
|
|
||||||
r.NoRoute(v1.Handle404)
|
r.NoRoute(v1.Handle404)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user