-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrefs.go
186 lines (157 loc) · 4.87 KB
/
refs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"strings"
)
var (
// Save refcodes in the local directory
refSavePath = "./refcodes.json"
)
// Refs is a struct containing referral codes associated on a per-user basis.
// User will be able to add their data by sending messages to this bot.
type Refs struct {
RefSavePath string
ReferralCodes []ReferralCode `json:"referral_codes"`
// PendingUsers is an array of pending ReferralCode
PendingUsers []ReferralCode
}
// NewRefs creates a Refs struct populated with the default save path.
// It tries to load from the default path an alread-existing referral code database.
func NewRefs() Refs {
r := Refs{
RefSavePath: refSavePath,
}
checkError(r.loadFromFile())
return r
}
// NewRefsFromPath creates a Refs struct populated with the content of the file pointed by path.defa
// It tries to load from the path an alread-existing referral code database.
func NewRefsFromPath(path string) Refs {
r := Refs{
RefSavePath: path,
}
checkError(r.loadFromFile())
return r
}
// ReferralCode is a single referral code, with data about its proprietary, the AssociatedUser
// and the Code itself.
type ReferralCode struct {
AssociatedUser string `json:"associated_user"`
Code string `json:"code"`
ChatID int64 `json:"chat_id"`
}
// SaveNewRefCode saves the newly-added referral code to the struct, and saves it to disk.
func (r *Refs) SaveNewRefCode(rf ReferralCode) {
r.ReferralCodes = append(r.ReferralCodes, rf)
// saveToFile in a goroutine, non-blocking call
go func() {
err := r.saveToFile()
if err != nil {
log.Println("error during database write:", err)
}
}()
}
// saveToFile saves its struct to file.
func (r *Refs) saveToFile() (err error) {
codesByte, err := json.Marshal(r)
if err != nil {
return
}
err = ioutil.WriteFile(r.RefSavePath, codesByte, 0644)
return
}
// loadFromFile loads its struct from file.
func (r *Refs) loadFromFile() (err error) {
fileContent, err := ioutil.ReadFile(r.RefSavePath)
if err != nil {
return
}
// unmarshal json into the file
var newR Refs
err = json.Unmarshal(fileContent, &newR)
if err != nil {
return
}
r.ReferralCodes = newR.ReferralCodes
r.RefSavePath = newR.RefSavePath
return
}
// PrettyPrintList returns a pretty-printed string containing all the current pending requests
func (r Refs) PrettyPrintList() (result string) {
if len(r.PendingUsers) <= 0 {
result = fmt.Sprintf("There are no requests currently awaiting approval!\nGood job :)\n")
return
}
result = fmt.Sprintf("There are currently %d requests awaiting approval:\n\n", len(r.PendingUsers))
for index, item := range r.PendingUsers {
result = result + fmt.Sprintf("%d) @%s\n", index+1, item.AssociatedUser)
}
result = result + fmt.Sprintf("\nUse the /deny {username} or /allow {username} commands to either deny or allow the addition to the database!")
return
}
// GetPendingUserByUsername returns a pending user by its username.
func (r Refs) GetPendingUserByUsername(username string) (pendingUser ReferralCode, err error) {
for _, puser := range r.PendingUsers {
if strings.ToUpper(puser.AssociatedUser) == strings.ToUpper(username) {
pendingUser = puser
return
}
}
err = errors.New(fmt.Sprintln(username, "not found"))
return
}
// GetPendingUserByID returns a pending user by its id.
func (r Refs) GetPendingUserByID(id int64) (pendingUser ReferralCode, err error) {
for _, puser := range r.PendingUsers {
if puser.ChatID == id {
pendingUser = puser
return
}
}
err = errors.New(fmt.Sprintln(id, "not found"))
return
}
// GetUserByUsername returns a user by its username.
func (r Refs) GetUserByUsername(username string) (user ReferralCode, err error) {
for _, ruser := range r.ReferralCodes {
if strings.ToUpper(ruser.AssociatedUser) == strings.ToUpper(username) {
user = ruser
return
}
}
err = errors.New(fmt.Sprintln(username, "not found"))
return
}
// GetUserByID returns a pending user by its id.
func (r Refs) GetUserByID(id int64) (user ReferralCode, err error) {
for _, ruser := range r.ReferralCodes {
if ruser.ChatID == id {
user = ruser
return
}
}
err = errors.New(fmt.Sprintln(id, "not found"))
return
}
// AlreadyGotUser checks if the user is already either in the pending list or on the reflist
func (r Refs) AlreadyGotUser(id int64) bool {
_, errID := r.GetUserByID(id)
_, errPendingID := r.GetPendingUserByID(id)
if errID != nil && errPendingID != nil {
return false
}
return true
}
// RemovePendingUser remove a pending request from the session.
func (r *Refs) RemovePendingUser(username string) {
for index, user := range r.PendingUsers {
if strings.ToUpper(user.AssociatedUser) == strings.ToUpper(username) {
r.PendingUsers[len(r.PendingUsers)-1], r.PendingUsers[index] = r.PendingUsers[index], r.PendingUsers[len(r.PendingUsers)-1]
r.PendingUsers = r.PendingUsers[:len(r.PendingUsers)-1]
}
}
}