add API endpoint to retrieve user achievements

This commit is contained in:
Morgan Bazalgette 2018-01-21 21:21:46 +01:00
parent 39078d00a3
commit a1eb970382
3 changed files with 93 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package app
import (
"fmt"
"time"
"github.com/DataDog/datadog-go/statsd"
fhr "github.com/buaazp/fasthttprouter"
@ -67,6 +68,9 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
// start websocket
websockets.Start(red, db)
// start load achievements
go v1.LoadAchievementsEvery(db, time.Minute*10)
// peppyapi
{
r.Peppy("/api/get_user", peppy.GetUser)
@ -87,6 +91,7 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
r.Method("/api/v1/users", v1.UsersGET)
r.Method("/api/v1/users/whatid", v1.UserWhatsTheIDGET)
r.Method("/api/v1/users/full", v1.UserFullGET)
r.Method("/api/v1/users/achievements", v1.UserAchievementsGET)
r.Method("/api/v1/users/userpage", v1.UserUserpageGET)
r.Method("/api/v1/users/lookup", v1.UserLookupGET)
r.Method("/api/v1/users/scores/best", v1.UserScoresBestGET)

View File

@ -0,0 +1,83 @@
package v1
import (
"database/sql"
"fmt"
"time"
"github.com/jmoiron/sqlx"
"zxq.co/ripple/rippleapi/common"
)
// Achievement represents an achievement in the database.
type Achievement struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Icon string `json:"icon"`
}
// LoadAchievementsEvery reloads the achievements in the database every given
// amount of time.
func LoadAchievementsEvery(db *sqlx.DB, d time.Duration) {
for {
err := db.Select(&achievs,
"SELECT id, name, description, icon FROM achievements ORDER BY id ASC")
if err != nil {
fmt.Println("LoadAchievements error", err)
common.GenericError(err)
}
time.Sleep(d)
}
}
var achievs []Achievement
type userAchievement struct {
Achievement
Achieved bool `json:"achieved"`
}
type userAchievementsResponse struct {
common.ResponseBase
Achievements []userAchievement `json:"achievements"`
}
// UserAchievementsGET handles requests for retrieving the achievements of a
// given user.
func UserAchievementsGET(md common.MethodData) common.CodeMessager {
shouldRet, whereClause, param := whereClauseUser(md, "users")
if shouldRet != nil {
return *shouldRet
}
var ids []int
err := md.DB.Select(&ids, `SELECT ua.achievement_id FROM users_achievements ua
INNER JOIN users ON users.id = ua.user_id
WHERE `+whereClause, param)
switch {
case err == sql.ErrNoRows:
return common.SimpleResponse(404, "No such user!")
case err != nil:
md.Err(err)
return Err500
}
all := md.HasQuery("all")
resp := userAchievementsResponse{Achievements: make([]userAchievement, 0, len(achievs))}
for _, ach := range achievs {
achieved := inInt(ach.ID, ids)
if all || achieved {
resp.Achievements = append(resp.Achievements, userAchievement{ach, achieved})
}
}
resp.Code = 200
return resp
}
func inInt(i int, js []int) bool {
for _, j := range js {
if i == j {
return true
}
}
return false
}

View File

@ -77,6 +77,11 @@ func WSErr(err error) {
}, nil, nil)
}
// GenericError is just an error. Can't make a good description.
func GenericError(err error) {
_err(err, nil, nil, nil)
}
func _err(err error, tags map[string]string, user *raven.User, c *fasthttp.RequestCtx) {
if RavenClient == nil {
fmt.Println("ERROR!!!!")