Make ready for production

websocket
ALI Hamza 2020-01-31 10:03:02 +07:00
parent 1fa7cfd996
commit 3a3871652e
9 changed files with 233 additions and 111 deletions

@ -19,7 +19,7 @@ func GetAllVisitors() []common.Visitor {
//GetVisitor retrieves the visitor with the specified ID in the form of `common.Visitor`. //GetVisitor retrieves the visitor with the specified ID in the form of `common.Visitor`.
func GetVisitor(email string) (common.Visitor, error) { func GetVisitor(email string) (common.Visitor, error) {
rows, _ := db.Query("SELECT * FROM clients WHERE email=?", email) rows, _ := db.Query("SELECT * FROM clients WHERE email=? COLLATE NOCASE", email)
defer rows.Close() defer rows.Close()
visitors := convertIntoVisitors(rows) visitors := convertIntoVisitors(rows)
if len(visitors) == 0 { if len(visitors) == 0 {
@ -42,7 +42,7 @@ func NewVisitor(visitor common.Visitor) (bool, common.Visitor) {
//EditVisitor updates the provided visitor with the new name associated with the email. //EditVisitor updates the provided visitor with the new name associated with the email.
func EditVisitor(visitor common.Visitor) (bool, common.Visitor) { func EditVisitor(visitor common.Visitor) (bool, common.Visitor) {
result, _ := db.Exec("UPDATE clients SET name=? WHERE email=?", visitor.Name, visitor.Email) result, _ := db.Exec("UPDATE clients SET name=? WHERE email=? COLLATE NOCASE", visitor.Name, visitor.Email)
rowsAffected, _ := result.RowsAffected() rowsAffected, _ := result.RowsAffected()
updated, _ := GetVisitor(visitor.Email) updated, _ := GetVisitor(visitor.Email)
@ -51,7 +51,7 @@ func EditVisitor(visitor common.Visitor) (bool, common.Visitor) {
//SetFirstTicket updates the first ticket column for the provided visitor //SetFirstTicket updates the first ticket column for the provided visitor
func SetFirstTicket(visitor common.Visitor) bool { func SetFirstTicket(visitor common.Visitor) bool {
result, _ := db.Exec("UPDATE clients SET first_ticket=? WHERE email=?", visitor.FirstTicket, visitor.Email) result, _ := db.Exec("UPDATE clients SET first_ticket=? WHERE email=? COLLATE NOCASE", visitor.FirstTicket, visitor.Email)
rowsAffected, _ := result.RowsAffected() rowsAffected, _ := result.RowsAffected()
return rowsAffected > 0 return rowsAffected > 0

@ -3,6 +3,8 @@ module JISQueueing
go 1.12 go 1.12
require ( require (
github.com/go-redis/redis/v7 v7.0.0-beta.5 // indirect
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.3 github.com/gorilla/mux v1.7.3
github.com/gorilla/websocket v1.4.1 github.com/gorilla/websocket v1.4.1
github.com/mattn/go-sqlite3 v1.11.0 github.com/mattn/go-sqlite3 v1.11.0

@ -1,13 +1,40 @@
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-redis/redis/v7 v7.0.0-beta.5 h1:7bdbDkv2nKZm6Tydrvmay3xOvVaxpAT4ZsNTrSDMZUE=
github.com/go-redis/redis/v7 v7.0.0-beta.5/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -1,22 +1,29 @@
package main package main
import ( import (
"JISQueueing/common"
"JISQueueing/server" "JISQueueing/server"
"flag" "flag"
"log"
"net/http" "net/http"
"strconv" "strconv"
)
var hashToStaff = make(map[string]common.Staff) "github.com/gorilla/handlers"
)
func main() { func main() {
var port int var port int
var debug bool var debug bool
flag.IntVar(&port, "port", 8080, "Specify port for socket and webserver") flag.IntVar(&port, "port", 443, "Specify port for socket and webserver")
flag.BoolVar(&debug, "debug", false, "Specify the debug mode status") flag.BoolVar(&debug, "debug", false, "Specify the debug mode status")
flag.Parse()
hostLocation := ":" + strconv.Itoa(port) hostLocation := ":" + strconv.Itoa(port)
mux := server.NewServerMux(debug) mux := server.NewServerMux(debug)
http.ListenAndServe(hostLocation, mux) cors := handlers.CORS(
handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}),
handlers.AllowedMethods([]string{"POST", "OPTIONS"}),
handlers.AllowedOrigins([]string{"*"}),
)(mux)
//log.Fatal(http.ListenAndServe(hostLocation, cors))
log.Fatal(http.ListenAndServeTLS(hostLocation, "server.crt", "server.key", cors))
} }

@ -23,10 +23,7 @@ func NewServerMux(debug bool) http.Handler {
router.PathPrefix("/api").Handler(http.HandlerFunc(NotFound)) router.PathPrefix("/api").Handler(http.HandlerFunc(NotFound))
router.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./static/"))) router.PathPrefix("/static").Handler(http.FileServer(http.Dir("./static")))
router.PathPrefix("/css").Handler(http.FileServer(http.Dir("./static/")))
router.PathPrefix("/js").Handler(http.FileServer(http.Dir("./static/")))
router.PathPrefix("/").HandlerFunc(indexHandler) router.PathPrefix("/").HandlerFunc(indexHandler)
return router return router

@ -1,6 +1,8 @@
package socket package socket
import ( import (
"fmt"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
@ -8,6 +10,13 @@ var displays = make(map[*websocket.Conn]bool)
func onNewDisplay(who *websocket.Conn) { func onNewDisplay(who *websocket.Conn) {
displays[who] = true displays[who] = true
for _, conn := range onlineStaff {
if conn.Table == -1 {
continue
}
who.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("status %d %d %d", conn.Table, conn.Status, conn.CurrentTicket)))
}
} }
func onDisplayMessage(who *websocket.Conn, msg string) { func onDisplayMessage(who *websocket.Conn, msg string) {
@ -21,4 +30,4 @@ func sendDisplayMessage(msg string) {
for display := range displays { for display := range displays {
display.WriteMessage(websocket.TextMessage, []byte(msg)) display.WriteMessage(websocket.TextMessage, []byte(msg))
} }
} }

@ -9,14 +9,18 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
var tickets = make(map[common.Ticket]bool) var queue = make([]common.Ticket, 0)
func newTicket(ticket common.Ticket, who *websocket.Conn) { func newTicket(ticket common.Ticket, who *websocket.Conn) {
tickets[ticket] = false queue = append(queue, ticket)
jsonTicket, _ := json.Marshal(ticket) jsonTicket, _ := json.Marshal(ticket)
sendStaffMessage("new " + string(jsonTicket))
who.WriteMessage(websocket.TextMessage, []byte("success new "+string(jsonTicket))) who.WriteMessage(websocket.TextMessage, []byte("success new "+string(jsonTicket)))
for _, conn := range onlineStaff {
if conn.Status == 1 {
notifyTicket(conn.Conn)
}
}
} }
func claimedTicket(ticket common.Ticket, staff common.Staff, table int, who *websocket.Conn) { func claimedTicket(ticket common.Ticket, staff common.Staff, table int, who *websocket.Conn) {
@ -24,57 +28,71 @@ func claimedTicket(ticket common.Ticket, staff common.Staff, table int, who *web
who.WriteMessage(websocket.TextMessage, []byte("error accept the ticket has already been completed or cancelled")) who.WriteMessage(websocket.TextMessage, []byte("error accept the ticket has already been completed or cancelled"))
return return
} }
delete(tickets, ticket) removeTicket(ticket.ID)
ticket.Staff = staff.Username ticket.Staff = staff.Username
tickets[ticket] = true
jsonTicket, _ := json.Marshal(ticket) jsonTicket, _ := json.Marshal(ticket)
sendDisplayMessage("claimed " + strconv.Itoa(table) + " " + strconv.Itoa(ticket.ID)) sendDisplayMessage("claimed " + strconv.Itoa(table) + " " + strconv.Itoa(ticket.ID))
who.WriteMessage(websocket.TextMessage, []byte("success claimed "+string(jsonTicket))) who.WriteMessage(websocket.TextMessage, []byte("success claimed "+string(jsonTicket)))
for conn, s := range connToStaff { for _, conn := range onlineStaff {
if s.Username != staff.Username { if conn.Status == 1 {
conn.WriteMessage(websocket.TextMessage, []byte("claimed "+string(jsonTicket))) conn.Conn.WriteMessage(websocket.TextMessage, []byte("info claimed "+string(jsonTicket)))
notifyTicket(conn.Conn)
} }
} }
} }
func finishedTicket(ticket common.Ticket, id int, table int, who *websocket.Conn) { func finishedTicket(id int, table int, who *websocket.Conn) {
delete(tickets, ticket)
if success := db.FinishTicket(id); !success { if success := db.FinishTicket(id); !success {
who.WriteMessage(websocket.TextMessage, []byte("error complete the ticket has already been completed or cancelled")) who.WriteMessage(websocket.TextMessage, []byte("error complete the ticket has already been completed or cancelled"))
return return
} }
who.WriteMessage(websocket.TextMessage, []byte("success complete "+strconv.Itoa(id))) who.WriteMessage(websocket.TextMessage, []byte("success complete "+strconv.Itoa(id)))
notifyTicket(who)
sendDisplayMessage("complete " + strconv.Itoa(table)) sendDisplayMessage("complete " + strconv.Itoa(table))
} }
func cancelTicket(ticket common.Ticket, id int, table int, who *websocket.Conn) { func cancelTicket(id int, table int, who *websocket.Conn) {
delete(tickets, ticket)
if success := db.CancelTicket(id); !success { if success := db.CancelTicket(id); !success {
who.WriteMessage(websocket.TextMessage, []byte("error cancel the ticket has already been completed or cancelled")) who.WriteMessage(websocket.TextMessage, []byte("error cancel the ticket has already been completed or cancelled"))
return return
} }
who.WriteMessage(websocket.TextMessage, []byte("success cancel "+strconv.Itoa(id))) who.WriteMessage(websocket.TextMessage, []byte("success cancel "+strconv.Itoa(id)))
notifyTicket(who)
sendDisplayMessage("cancel " + strconv.Itoa(table)) sendDisplayMessage("cancel " + strconv.Itoa(table))
} }
func newStaff(table int, who *websocket.Conn) { func newStaff(table int, who *websocket.Conn) {
who.WriteMessage(websocket.TextMessage, []byte("success pick "+strconv.Itoa(table))) who.WriteMessage(websocket.TextMessage, []byte("success pick "+strconv.Itoa(table)))
for member, num := range connToTable { for _, conn := range onlineStaff {
if num == -1 { sendTaken(conn.Conn)
sendTaken(member)
}
} }
sendDisplayMessage("pick " + strconv.Itoa(table)) sendDisplayMessage("pick " + strconv.Itoa(table))
notifyTicket(who)
} }
func leaveStaff(table int) { func leaveStaff(table int) {
sendDisplayMessage("unpick " + strconv.Itoa(table)) sendDisplayMessage("unpick " + strconv.Itoa(table))
for member, num := range connToTable { for _, conn := range onlineStaff {
if num == -1 { sendTaken(conn.Conn)
sendTaken(member) }
}
func notifyTicket(who *websocket.Conn) {
if len(queue) == 0 {
return
}
jsonTicket, _ := json.Marshal(queue[0])
who.WriteMessage(websocket.TextMessage, []byte("info new "+string(jsonTicket)))
}
func removeTicket(id int) {
for i, t := range queue {
if id == t.ID {
copy(queue[i:], queue[i+1:])
queue[len(queue)-1] = common.Ticket{}
queue = queue[:len(queue)-1]
return
} }
} }
} }

@ -3,7 +3,6 @@ package socket
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strings"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
@ -20,7 +19,8 @@ var upgrader = websocket.Upgrader{
ReadBufferSize: 1024, ReadBufferSize: 1024,
WriteBufferSize: 1024, WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool { CheckOrigin: func(r *http.Request) bool {
return strings.Contains(r.Host, "localhost") return true
//return strings.Contains(r.Host, "localhost")
}, },
} }

@ -3,131 +3,188 @@ package socket
import ( import (
"JISQueueing/common" "JISQueueing/common"
"JISQueueing/db" "JISQueueing/db"
"github.com/gorilla/websocket"
"strconv" "strconv"
"strings" "strings"
"github.com/gorilla/websocket"
) )
//Receive Commands: [status, pick, accept, complete] //Receive Commands: [status, pick, accept, complete]
//Send Commands: [new, //Send Commands: [new,
var connToTable = make(map[*websocket.Conn]int) type staffConnection struct {
var connToStaff = make(map[*websocket.Conn]common.Staff) Conn *websocket.Conn
Staff common.Staff
Table int
Status int
CurrentTicket int
}
var onlineStaff = make(map[*websocket.Conn]staffConnection)
func onNewStaff(who *websocket.Conn) { func onNewStaff(who *websocket.Conn) {
connToTable[who] = -1 onlineStaff[who] = staffConnection{
Conn: who,
Staff: common.Staff{
Username: "{}",
},
Table: -1,
Status: 0,
CurrentTicket: -1,
}
sendTaken(who) sendTaken(who)
} }
func onStaffMessage(who *websocket.Conn, msg string) { func onStaffMessage(who *websocket.Conn, msg string) {
message := strings.SplitN(strings.TrimSpace(msg), " ", 2) message := strings.SplitN(strings.TrimSpace(msg), " ", 2)
switch message[0] { switch message[0] {
case "unpick":
if table, ok := connToTable[who]; !ok || table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return
}
connToTable[who] = -1 case "accept":
delete(connToStaff, who) id, err := strconv.Atoi(strings.TrimSpace(message[1]))
who.WriteMessage(websocket.TextMessage, []byte("success unpick")) conn, ok := onlineStaff[who]
leaveStaff(connToTable[who])
case "pick": if err != nil || !ok {
args := strings.SplitN(msg, " ", 3)
if len(args) < 3 {
return return
} }
choice, err := strconv.Atoi(strings.TrimSpace(args[1])) if conn.Staff.Username == "{}" || conn.Status == 0 {
if err != nil { who.WriteMessage(websocket.TextMessage, []byte("error accept your session token was found to be invalid. please relogin"))
return return
} }
if conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error accept you do not have a table chosen"))
}
staff, err := db.GetTokenOwner(strings.TrimSpace(args[2])) ticket, err := db.GetTicket(id)
if err == db.ErrTokenNotFound { if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error pick "+err.Error())) who.WriteMessage(websocket.TextMessage, []byte("error accept "+err.Error()))
return return
} }
if isTaken(choice) { if ticket.Staff != "{}" {
who.WriteMessage(websocket.TextMessage, []byte("error the chosen table is not available")) who.WriteMessage(websocket.TextMessage, []byte("error accept this ticket is already claimed"))
return return
} }
connToStaff[who] = staff conn.Status = 2
connToTable[who] = choice conn.CurrentTicket = id
newStaff(choice, who) onlineStaff[who] = conn
claimedTicket(ticket, conn.Staff, conn.Table, who)
case "accept": case "cancel":
id, err := strconv.Atoi(strings.TrimSpace(message[1])) id, err := strconv.Atoi(strings.TrimSpace(message[1]))
if err != nil { conn, ok := onlineStaff[who]
return
}
staff, ok := connToStaff[who] if err != nil || !ok {
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error accept your session token was found to be invalid. please relogin"))
return return
} }
if connToTable[who] == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error accept you do not have a table chosen"))
}
ticket, err := db.GetTicket(id) ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound { if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error accept "+err.Error())) who.WriteMessage(websocket.TextMessage, []byte("error cancel "+err.Error()))
return return
} }
if ticket.Staff != "{}" { if conn.Staff.Username != ticket.Staff {
who.WriteMessage(websocket.TextMessage, []byte("error accept this ticket is already claimed")) who.WriteMessage(websocket.TextMessage, []byte("error cancel you do not own this ticket"))
return return
} }
claimedTicket(ticket, staff, connToTable[who], who) conn.Status = 1
conn.CurrentTicket = -1
onlineStaff[who] = conn
cancelTicket(id, conn.Table, who)
case "complete": case "complete":
id, err := strconv.Atoi(strings.TrimSpace(message[1])) id, err := strconv.Atoi(strings.TrimSpace(message[1]))
staff := connToStaff[who] conn, ok := onlineStaff[who]
table, ok := connToTable[who]
if err != nil { if err != nil || !ok {
return return
} }
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error complete you are not assigned to any table"))
}
ticket, err := db.GetTicket(id) ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound { if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error complete "+err.Error())) who.WriteMessage(websocket.TextMessage, []byte("error complete "+err.Error()))
return return
} }
if staff.Username != ticket.Staff { if conn.Staff.Username != ticket.Staff {
who.WriteMessage(websocket.TextMessage, []byte("error complete you do not own this ticket")) who.WriteMessage(websocket.TextMessage, []byte("error complete you do not own this ticket"))
return return
} }
finishedTicket(ticket, id, table, who)
case "cancel": conn.Status = 1
id, err := strconv.Atoi(strings.TrimSpace(message[1])) conn.CurrentTicket = -1
staff := connToStaff[who] onlineStaff[who] = conn
table, ok := connToTable[who]
finishedTicket(id, conn.Table, who)
case "pick":
args := strings.SplitN(msg, " ", 3)
if len(args) < 3 {
return
}
choice, err := strconv.Atoi(strings.TrimSpace(args[1]))
if err != nil { if err != nil {
return return
} }
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error cancel you are not assigned to any table")) staff, err := db.GetTokenOwner(strings.TrimSpace(args[2]))
if err == db.ErrTokenNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error pick "+err.Error()))
return
}
if isTaken(choice) {
who.WriteMessage(websocket.TextMessage, []byte("error the chosen table is not available"))
return
}
if onlineStaff[who].Table != -1 {
leaveStaff(onlineStaff[who].Table)
} }
ticket, err := db.GetTicket(id) onlineStaff[who] = staffConnection{
if err == db.ErrTicketNotFound { Conn: who,
who.WriteMessage(websocket.TextMessage, []byte("error cancel "+err.Error())) Staff: staff,
Table: choice,
Status: 1,
CurrentTicket: -1,
}
newStaff(choice, who)
case "status":
if conn, ok := onlineStaff[who]; !ok || conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return return
} }
if staff.Username != ticket.Staff { notifyTicket(who)
who.WriteMessage(websocket.TextMessage, []byte("error cancel you do not own this ticket"))
case "unpick":
conn, ok := onlineStaff[who]
if !ok || conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return return
} }
cancelTicket(ticket, id, table, who)
table := conn.Table
conn.Table = -1
conn.Status = 0
staff := conn.Staff
staff.Username = "{}"
conn.Staff = staff
onlineStaff[who] = conn
leaveStaff(table)
who.WriteMessage(websocket.TextMessage, []byte("success unpick"))
case "valid":
if len(message) < 2 {
return
}
_, err := db.GetTokenOwner(strings.TrimSpace(message[1]))
if err == db.ErrTokenNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error valid "+err.Error()))
return
}
who.WriteMessage(websocket.TextMessage, []byte("success valid"))
default: default:
who.WriteMessage(websocket.TextMessage, []byte("error "+message[0]+" not found")) who.WriteMessage(websocket.TextMessage, []byte("error "+message[0]+" not found"))
@ -135,8 +192,8 @@ func onStaffMessage(who *websocket.Conn, msg string) {
} }
func sendStaffMessage(msg string) { func sendStaffMessage(msg string) {
for who, num := range connToTable { for who, conn := range onlineStaff {
if num == -1 { if conn.Table == -1 {
continue continue
} }
who.WriteMessage(websocket.TextMessage, []byte(msg)) who.WriteMessage(websocket.TextMessage, []byte(msg))
@ -144,33 +201,38 @@ func sendStaffMessage(msg string) {
} }
func onStaffDisconnect(who *websocket.Conn) { func onStaffDisconnect(who *websocket.Conn) {
num, ok := connToTable[who] conn, ok := onlineStaff[who]
delete(connToTable, who) if !ok || conn.Table == -1 {
delete(connToStaff, who) return
if ok && num != -1 {
leaveStaff(connToTable[who])
} }
if conn.Status == 2 {
cancelTicket(conn.CurrentTicket, conn.Table, who)
}
delete(onlineStaff, who)
leaveStaff(conn.Table)
} }
func sendTaken(who *websocket.Conn) { func sendTaken(who *websocket.Conn) {
var taken = "" var taken = ""
for _, num := range connToTable { for _, conn := range onlineStaff {
if num != -1 { if conn.Table != -1 {
taken = taken + " " + strconv.Itoa(num) taken = taken + " " + strconv.Itoa(conn.Table)
} }
} }
if taken != "" { if taken != "" {
who.WriteMessage(websocket.TextMessage, []byte("taken"+taken)) who.WriteMessage(websocket.TextMessage, []byte("info taken"+taken))
} else {
who.WriteMessage(websocket.TextMessage, []byte("info taken"))
} }
} }
func isTaken(table int) bool { func isTaken(table int) bool {
if table < 0 { if table < 1 || table > 5 {
return true return true
} }
for _, num := range connToTable { for _, conn := range onlineStaff {
if table == num { if table == conn.Table {
return true return true
} }
} }