Add keyed ratings
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details

This commit is contained in:
Tyler 2020-06-14 02:12:26 -04:00
parent 20366ed3e4
commit 8b80a73452
3 changed files with 81 additions and 11 deletions

View File

@ -12,7 +12,7 @@ import (
)
func stats(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
data, err := statsResponse(w, ps, nil)
data, err := statsResponse(w, r, ps, nil)
if err != nil {
writeError(w, err)
@ -25,7 +25,7 @@ func stats(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
}
func profile(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
cacheKey := generateCacheKey(ps) + "-profile"
cacheKey := generateCacheKey(r, ps) + "-profile"
res, err := cacheProvider.Get(cacheKey)
@ -36,7 +36,7 @@ func profile(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
}
// Cache result for profile specifically
data, err := statsResponse(w, ps, profilePatch)
data, err := statsResponse(w, r, ps, profilePatch)
if err != nil {
writeError(w, err)
@ -63,7 +63,7 @@ func heroes(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
sort.Strings(names)
cacheKey := generateCacheKey(ps) + "-heroes-" + hex.EncodeToString(md5.New().Sum([]byte(strings.Join(names, ","))))
cacheKey := generateCacheKey(r, ps) + "-heroes-" + hex.EncodeToString(md5.New().Sum([]byte(strings.Join(names, ","))))
res, err := cacheProvider.Get(cacheKey)
@ -108,7 +108,7 @@ func heroes(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
}
// Create a patch to remove all but specified heroes
data, err := statsResponse(w, ps, patch)
data, err := statsResponse(w, r, ps, patch)
if err != nil {
writeError(w, err)

1
go.mod
View File

@ -10,5 +10,6 @@ require (
github.com/julienschmidt/httprouter v1.3.0
github.com/miekg/dns v1.1.26
github.com/rs/cors v1.7.0
golang.org/x/net v0.0.0-20190923162816-aa69164e4478
s32x.com/ovrstat v0.0.0-20200131231416-4cb42edd331d
)

81
main.go
View File

@ -4,10 +4,12 @@ import (
"encoding/json"
"errors"
"flag"
"fmt"
"git.meow.tf/ow-api/ow-api/cache"
"git.meow.tf/ow-api/ow-api/json-patch"
"github.com/julienschmidt/httprouter"
"github.com/rs/cors"
"golang.org/x/net/context"
"log"
"net/http"
"regexp"
@ -17,12 +19,19 @@ import (
)
const (
Version = "2.3.4"
Version = "2.3.5"
OpAdd = "add"
OpRemove = "remove"
)
type ApiVersion int
const (
VersionOne ApiVersion = iota
VersionTwo
)
type gamesStats struct {
Played int64 `json:"played"`
Won int64 `json:"won"`
@ -145,11 +154,30 @@ func loadHeroNames() {
}
}
var (
versionRegexp = regexp.MustCompile("^/(v\\d+)/")
)
func injectPlatform(platform string, handler httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
ps = append(ps, httprouter.Param{Key: "platform", Value: platform})
handler(w, r, ps)
ctx := context.Background()
m := versionRegexp.FindStringSubmatch(r.RequestURI)
if m != nil {
version := VersionOne
switch m[1] {
case "v2":
version = VersionTwo
}
ctx = context.WithValue(ctx, "version", version)
}
handler(w, r.WithContext(ctx), ps)
}
}
@ -157,15 +185,21 @@ var (
tagRegexp = regexp.MustCompile("-(\\d+)$")
)
func statsResponse(w http.ResponseWriter, ps httprouter.Params, patch *jsonpatch.Patch) ([]byte, error) {
func statsResponse(w http.ResponseWriter, r *http.Request, ps httprouter.Params, patch *jsonpatch.Patch) ([]byte, error) {
var stats *ovrstat.PlayerStats
var err error
version := VersionOne
if v := r.Context().Value("version"); v != nil {
version = v.(ApiVersion)
}
tag := ps.ByName("tag")
tag = strings.Replace(tag, "#", "-", -1)
cacheKey := generateCacheKey(ps)
cacheKey := generateCacheKey(r, ps)
platform := ps.ByName("platform")
@ -267,6 +301,31 @@ func statsResponse(w http.ResponseWriter, ps httprouter.Params, patch *jsonpatch
urlBase := iconUrl[0 : strings.Index(iconUrl, "rank-icons/")+11]
ratingIcon = urlBase + iconFor(rating)
if version == VersionTwo {
m := make(map[string]ovrstat.Rating)
ratingsPatches := make([]patchOperation, len(stats.Ratings))
for i, rating := range stats.Ratings {
m[rating.Role] = rating
ratingsPatches[i] = patchOperation{
Op: OpRemove,
Path: "/ratings/" + rating.Role + "/role",
}
}
extra = append(extra, patchOperation{
Op: OpRemove,
Path: "/ratings",
}, patchOperation{
Op: OpAdd,
Path: "/ratings",
Value: m,
})
extra = append(extra, ratingsPatches...)
}
}
extra = append(extra, patchOperation{
@ -330,6 +389,16 @@ func iconFor(rating int) string {
return "rank-BronzeTier.png"
}
func generateCacheKey(ps httprouter.Params) string {
return ps.ByName("platform") + "-" + ps.ByName("tag")
func generateCacheKey(r *http.Request, ps httprouter.Params) string {
version := VersionOne
if v := r.Context().Value("version"); v != nil {
version = v.(ApiVersion)
}
return versionToString(version) + "-" + ps.ByName("platform") + "-" + ps.ByName("tag")
}
func versionToString(version ApiVersion) string {
return fmt.Sprintf("v%d", version)
}