Browse Source

add API endpoint to retrieve user achievements

master
Morgan Bazalgette 1 year ago
parent
commit
a1eb970382
3 changed files with 93 additions and 0 deletions
  1. 5
    0
      app/start.go
  2. 83
    0
      app/v1/user_achievements.go
  3. 5
    0
      common/method_data.go

+ 5
- 0
app/start.go View File

@@ -2,6 +2,7 @@ package app
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"time"
5 6
 
6 7
 	"github.com/DataDog/datadog-go/statsd"
7 8
 	fhr "github.com/buaazp/fasthttprouter"
@@ -67,6 +68,9 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
67 68
 	// start websocket
68 69
 	websockets.Start(red, db)
69 70
 
71
+	// start load achievements
72
+	go v1.LoadAchievementsEvery(db, time.Minute*10)
73
+
70 74
 	// peppyapi
71 75
 	{
72 76
 		r.Peppy("/api/get_user", peppy.GetUser)
@@ -87,6 +91,7 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
87 91
 		r.Method("/api/v1/users", v1.UsersGET)
88 92
 		r.Method("/api/v1/users/whatid", v1.UserWhatsTheIDGET)
89 93
 		r.Method("/api/v1/users/full", v1.UserFullGET)
94
+		r.Method("/api/v1/users/achievements", v1.UserAchievementsGET)
90 95
 		r.Method("/api/v1/users/userpage", v1.UserUserpageGET)
91 96
 		r.Method("/api/v1/users/lookup", v1.UserLookupGET)
92 97
 		r.Method("/api/v1/users/scores/best", v1.UserScoresBestGET)

+ 83
- 0
app/v1/user_achievements.go View File

@@ -0,0 +1,83 @@
1
+package v1
2
+
3
+import (
4
+	"database/sql"
5
+	"fmt"
6
+	"time"
7
+
8
+	"github.com/jmoiron/sqlx"
9
+	"zxq.co/ripple/rippleapi/common"
10
+)
11
+
12
+// Achievement represents an achievement in the database.
13
+type Achievement struct {
14
+	ID          int    `json:"id"`
15
+	Name        string `json:"name"`
16
+	Description string `json:"description"`
17
+	Icon        string `json:"icon"`
18
+}
19
+
20
+// LoadAchievementsEvery reloads the achievements in the database every given
21
+// amount of time.
22
+func LoadAchievementsEvery(db *sqlx.DB, d time.Duration) {
23
+	for {
24
+		err := db.Select(&achievs,
25
+			"SELECT id, name, description, icon FROM achievements ORDER BY id ASC")
26
+		if err != nil {
27
+			fmt.Println("LoadAchievements error", err)
28
+			common.GenericError(err)
29
+		}
30
+		time.Sleep(d)
31
+	}
32
+}
33
+
34
+var achievs []Achievement
35
+
36
+type userAchievement struct {
37
+	Achievement
38
+	Achieved bool `json:"achieved"`
39
+}
40
+
41
+type userAchievementsResponse struct {
42
+	common.ResponseBase
43
+	Achievements []userAchievement `json:"achievements"`
44
+}
45
+
46
+// UserAchievementsGET handles requests for retrieving the achievements of a
47
+// given user.
48
+func UserAchievementsGET(md common.MethodData) common.CodeMessager {
49
+	shouldRet, whereClause, param := whereClauseUser(md, "users")
50
+	if shouldRet != nil {
51
+		return *shouldRet
52
+	}
53
+	var ids []int
54
+	err := md.DB.Select(&ids, `SELECT ua.achievement_id FROM users_achievements ua
55
+INNER JOIN users ON users.id = ua.user_id
56
+WHERE `+whereClause, param)
57
+	switch {
58
+	case err == sql.ErrNoRows:
59
+		return common.SimpleResponse(404, "No such user!")
60
+	case err != nil:
61
+		md.Err(err)
62
+		return Err500
63
+	}
64
+	all := md.HasQuery("all")
65
+	resp := userAchievementsResponse{Achievements: make([]userAchievement, 0, len(achievs))}
66
+	for _, ach := range achievs {
67
+		achieved := inInt(ach.ID, ids)
68
+		if all || achieved {
69
+			resp.Achievements = append(resp.Achievements, userAchievement{ach, achieved})
70
+		}
71
+	}
72
+	resp.Code = 200
73
+	return resp
74
+}
75
+
76
+func inInt(i int, js []int) bool {
77
+	for _, j := range js {
78
+		if i == j {
79
+			return true
80
+		}
81
+	}
82
+	return false
83
+}

+ 5
- 0
common/method_data.go View File

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

Loading…
Cancel
Save