280 lines
6.9 KiB
Go
280 lines
6.9 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"flag"
|
|
"github.com/gin-gonic/gin"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"net/http"
|
|
)
|
|
|
|
// define global db
|
|
var db, _ = sql.Open("sqlite3", "./database/data.db")
|
|
|
|
// types representing json queries
|
|
|
|
type loginInput struct {
|
|
Name string `json:"name"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type userData struct {
|
|
UID int `json:"uid"`
|
|
Name string `json:"name"`
|
|
Password string `json:"password"`
|
|
Role string `json:"role"`
|
|
Points int `json:"points"`
|
|
}
|
|
|
|
type task struct {
|
|
TID int `json:"tid"`
|
|
Name string `json:"name"`
|
|
Points int `json:"points"`
|
|
}
|
|
|
|
type taskArray struct {
|
|
Tasks []task `json:"tasks"`
|
|
}
|
|
|
|
type newHistoryData struct {
|
|
UID int `json:"uid"`
|
|
TID int `json:"tid"`
|
|
Time string `json:"time"`
|
|
PointsGained int `json:"pointsGained"`
|
|
}
|
|
|
|
type historyData struct {
|
|
User string `json:"user"`
|
|
Task string `json:"task"`
|
|
Time string `json:"time"`
|
|
PointsGained int `json:"pointsGained"`
|
|
}
|
|
|
|
type historyArray struct {
|
|
History []historyData `json:"history"`
|
|
}
|
|
|
|
type userPointsData struct {
|
|
Name string `json:"name"`
|
|
Points int `json:"points"`
|
|
}
|
|
|
|
type userPointsArray struct {
|
|
UserPoints []userPointsData `json:"userPoints"`
|
|
}
|
|
|
|
// log the user into their account
|
|
func login(c *gin.Context) {
|
|
// get the username and password from the request
|
|
var requestedUser loginInput
|
|
if err := c.BindJSON(&requestedUser); err != nil {
|
|
c.IndentedJSON(http.StatusBadRequest, requestedUser)
|
|
return
|
|
}
|
|
// check for user using given credentials
|
|
stmt, err := db.Prepare("SELECT * FROM users WHERE name=?")
|
|
checkErr(err)
|
|
defer stmt.Close()
|
|
var user userData
|
|
err = stmt.QueryRow(requestedUser.Name).Scan(&user.UID, &user.Name, &user.Password, &user.Role, &user.Points)
|
|
if err != nil {
|
|
// search failed user not real
|
|
c.IndentedJSON(http.StatusNotFound, requestedUser)
|
|
panic(err)
|
|
return
|
|
}
|
|
if user.Password != requestedUser.Password {
|
|
// user not real
|
|
c.IndentedJSON(http.StatusNotFound, requestedUser)
|
|
panic(err)
|
|
return
|
|
} else {
|
|
// user is in
|
|
c.IndentedJSON(http.StatusOK, user)
|
|
}
|
|
|
|
}
|
|
|
|
func getTasks(c *gin.Context) {
|
|
// return a list of all the tasks
|
|
var tasks []task
|
|
// get array of all tasks
|
|
rows, err := db.Query("SELECT * FROM activities")
|
|
checkErr(err)
|
|
for rows.Next() {
|
|
var tempTask task
|
|
err = rows.Scan(&tempTask.TID, &tempTask.Name, &tempTask.Points)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotFound, tasks)
|
|
return
|
|
}
|
|
tasks = append(tasks, tempTask)
|
|
}
|
|
rows.Close()
|
|
var jsonTasks taskArray
|
|
jsonTasks.Tasks = tasks
|
|
c.IndentedJSON(http.StatusOK, jsonTasks)
|
|
}
|
|
|
|
func completeTask(c *gin.Context) {
|
|
// get the task data from the request
|
|
var completedTask newHistoryData
|
|
if err := c.BindJSON(&completedTask); err != nil {
|
|
c.IndentedJSON(http.StatusBadRequest, completedTask)
|
|
return
|
|
}
|
|
// insert data to history table
|
|
stmt, err := db.Prepare("INSERT INTO history (uid, taskid, time, pointsGained) VALUES (?, ?, ?, ?)")
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, completedTask)
|
|
return
|
|
}
|
|
_, err = stmt.Exec(completedTask.UID, completedTask.TID, completedTask.Time, completedTask.PointsGained)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, completedTask)
|
|
return
|
|
}
|
|
|
|
// add points to user table
|
|
stmt, err = db.Prepare("UPDATE users SET points = points + ? WHERE uid=?")
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, completedTask)
|
|
return
|
|
}
|
|
_, err = stmt.Exec(completedTask.PointsGained, completedTask.UID)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, completedTask)
|
|
return
|
|
}
|
|
|
|
c.IndentedJSON(http.StatusOK, completedTask)
|
|
}
|
|
|
|
func getHistory(c *gin.Context) {
|
|
// get the log of past points gained
|
|
var history []newHistoryData
|
|
// get array of all history Data
|
|
rows, err := db.Query("SELECT * FROM history")
|
|
checkErr(err)
|
|
for rows.Next() {
|
|
var tempHistoryData newHistoryData
|
|
err = rows.Scan(&tempHistoryData.UID, &tempHistoryData.TID, &tempHistoryData.Time, &tempHistoryData.PointsGained)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotFound, history)
|
|
return
|
|
}
|
|
history = append(history, tempHistoryData)
|
|
}
|
|
rows.Close()
|
|
|
|
var historyRes []historyData
|
|
// make the data human-readable
|
|
for i := 0; i < len(history); i++ {
|
|
var tempHistory historyData
|
|
// get the username
|
|
var tempUser userData
|
|
stmt, err := db.Prepare("SELECT * FROM users WHERE uid=?")
|
|
checkErr(err)
|
|
err = stmt.QueryRow(history[i].UID).Scan(&tempUser.UID, &tempUser.Name, &tempUser.Password, &tempUser.Role, &tempUser.Points)
|
|
checkErr(err)
|
|
tempHistory.User = tempUser.Name
|
|
stmt.Close()
|
|
|
|
// get the task name and points
|
|
var tempTask task
|
|
stmt, err = db.Prepare("SELECT * FROM activities WHERE taskId=?")
|
|
checkErr(err)
|
|
err = stmt.QueryRow(history[i].TID).Scan(&tempTask.TID, &tempTask.Name, &tempTask.Points)
|
|
checkErr(err)
|
|
tempHistory.Task = tempTask.Name
|
|
tempHistory.PointsGained = tempTask.Points
|
|
stmt.Close()
|
|
|
|
tempHistory.Time = history[i].Time
|
|
|
|
historyRes = append(historyRes, tempHistory)
|
|
}
|
|
|
|
var jsonHistory historyArray
|
|
jsonHistory.History = historyRes
|
|
c.IndentedJSON(http.StatusOK, jsonHistory)
|
|
}
|
|
|
|
func addTask(c *gin.Context) {
|
|
// get the data of the new task
|
|
var newTask task
|
|
if err := c.BindJSON(&newTask); err != nil {
|
|
c.IndentedJSON(http.StatusBadRequest, newTask)
|
|
return
|
|
}
|
|
// insert new task into the task table
|
|
stmt, err := db.Prepare("INSERT INTO activities (name, points) VALUES (?,?)")
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, newTask)
|
|
return
|
|
}
|
|
_, err = stmt.Exec(newTask.Name, newTask.Points)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotModified, newTask)
|
|
return
|
|
}
|
|
c.IndentedJSON(http.StatusOK, newTask)
|
|
}
|
|
|
|
func getUserPoints(c *gin.Context) {
|
|
// get the names of all users
|
|
var allUsers []userPointsData
|
|
|
|
rows, err := db.Query("SELECT name, points FROM users WHERE role='user'")
|
|
checkErr(err)
|
|
|
|
// put them in an array of users
|
|
for rows.Next() {
|
|
var tempUser userPointsData
|
|
err = rows.Scan(&tempUser.Name, &tempUser.Points)
|
|
if err != nil {
|
|
c.IndentedJSON(http.StatusNotFound, allUsers)
|
|
return
|
|
}
|
|
allUsers = append(allUsers, tempUser)
|
|
}
|
|
rows.Close()
|
|
|
|
// return to the requester
|
|
var jsonUserPoints userPointsArray
|
|
jsonUserPoints.UserPoints = allUsers
|
|
c.IndentedJSON(http.StatusOK, jsonUserPoints)
|
|
}
|
|
|
|
func main() {
|
|
var port string
|
|
flag.StringVar(&port, "port", "localhost:8080", "define the port you want the program to use to serve")
|
|
flag.Parse()
|
|
//release mode
|
|
//gin.SetMode(gin.ReleaseMode)
|
|
router := gin.Default()
|
|
|
|
// api routes
|
|
router.POST("/login", login)
|
|
router.POST("/completeTask", completeTask)
|
|
router.POST("/addTask", addTask)
|
|
router.GET("/getTasks", getTasks)
|
|
router.GET("/getHistory", getHistory)
|
|
router.GET("/getUserPoints", getUserPoints)
|
|
|
|
// page routes
|
|
router.LoadHTMLGlob("frontend/*")
|
|
router.GET("/", func(c *gin.Context) {
|
|
c.HTML(http.StatusOK, "index.html", gin.H{})
|
|
})
|
|
router.Static("/frontend", "./frontend")
|
|
|
|
router.Run(port)
|
|
}
|
|
|
|
func checkErr(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|