-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.go
More file actions
211 lines (179 loc) · 4.82 KB
/
server.go
File metadata and controls
211 lines (179 loc) · 4.82 KB
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/rojaswestall/platform/gtools"
"github.com/rojaswestall/platform/migrate"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)
func homeLink(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome home : )")
}
// Add omit empty so unmarshalling json won't require that we have things like
// id or phone number
type Person struct {
Id string `json:"id"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Email string `json:"email"`
PhoneNumber string `json:"number"`
}
type Ref struct {
Person
}
type Player struct {
Person
}
type Coach struct {
Person
}
type Team struct {
Id string `json:"id"`
Captains []Player `json:"captains"`
Players []Player `json:"players"` // have this be a list of ids
Name string `json:"name"`
Wins int `json:"wins"`
Losses int `json:"losses"`
Draws int `json:"draws:"`
Icon string `json:"icon"` // url of icon or flag to represent team
}
type GameState int
const (
unknown GameState = iota
FirstHalf
SecondHalf
NotStarted
HalfTime
ExtraTime
OverTime
Complete
sentinel
)
func (s GameState) isValid() bool {
return s > unknown && s < sentinel
}
// to get the string representations of the gameState
func (s GameState) String() string {
states := [...]string{
"First Half",
"Second Half",
"Not Started",
"Half Time",
"Extra Time",
"Overtime",
"Complete"}
if !s.isValid() {
return "Unknown"
}
return states[s]
}
type Game struct {
Id string `json:"id"`
HomeTeam Team
AwayTeam Team
HomeTeamScore string
AwayTeamScore string
Date string
Time string
Venue string
GameState GameState // could be something like first half, second half, overtime ...
// Refs []string // ids of the refs
}
// We'll need to define an Upgrader
// this will require a Read and Write buffer size
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// We'll need to check the origin of our connection
// this will allow us to make requests from our React
// development server to here.
// For now, we'll do no checking and just allow any connection
CheckOrigin: func(r *http.Request) bool { return true },
}
// define a reader which will listen for
// new messages being sent to our WebSocket
// endpoint
func reader(conn *websocket.Conn) {
for {
// read in a message
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
// print out that message for clarity
fmt.Println(string(p))
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
// define our WebSocket endpoint
func serveWs(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.Host)
// upgrade this connection to a WebSocket
// connection
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
}
// listen indefinitely for new messages coming
// through on our WebSocket connection
reader(ws)
}
type RegistrationInfo struct {
TeamName string `json:"team_name"`
Players []string `json:"players"`
}
func handleRegister(w http.ResponseWriter, r *http.Request) {
// TODO:: Use AWS secrets to set spreadsheetId for sheets
spreadsheetId := "1jDCdULFKmxmgCsJTJgqzKloCvnE85r8PyLvXDAlKLcA"
// TODO:: Use AWS secrets to get credentials/token
var info RegistrationInfo
// Try to decode the request body into the struct. If there is an error,
// respond to the client with the error message and a 400 status code.
err := json.NewDecoder(r.Body).Decode(&info)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Create new sheet
err = gtools.AddSheet(spreadsheetId, info.TeamName)
// Add logic to handle name already exists
if err != nil {
log.Fatal(err)
}
// add values to the new sheet
err = gtools.AddSheetRow(info.TeamName, spreadsheetId, info.Players)
if err != nil {
log.Fatal(err)
}
// respond back to the client that the team was registered
fmt.Fprintf(w, "Team Info: %+v", info)
fmt.Println("register endpoint was hit")
}
func main() {
// create db instance
// TODO:: Use AWS secrets to get username and password
db, err := sql.Open("postgres", "postgres://nuwcuser:password@localhost:5432/nuwc?sslmode=disable")
// Want sslmode to be enable as some point, for now disable
if err != nil {
log.Fatal(err)
}
// migrate
migrate.Migrate(db)
// Create router
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/", homeLink)
router.HandleFunc("/serveWs", serveWs)
router.HandleFunc("/register", handleRegister).Methods("POST")
//add any new endpoints here
// Start listening
fmt.Println("The server is listening at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", router))
}