2b2t-queue-tracker/routes/api.go
2025-07-01 17:33:19 +02:00

125 lines
2.8 KiB
Go

package routes
import (
"database/sql"
"encoding/json"
"log"
"net/http"
"time"
"git.1e99.eu/1e99/2b2t/models"
)
func GetPlayerCounts(db *sql.DB, logger *log.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
query := req.URL.Query()
// In minutes
var now = time.Now().Unix() / 60
var timeRange, precision int64
switch query.Get("range") {
case "1d":
timeRange = 60 * 24
precision = 5
case "7d":
timeRange = 7 * 60 * 24
precision = 15
case "30d":
timeRange = 30 * 60 * 24
precision = 60
case "356d":
timeRange = 356 * 60 * 24
precision = 60 * 12
default:
http.Error(res, "invalid time range", http.StatusBadRequest)
return
}
rows, err := db.Query(`
SELECT c.time, c.playing, c.normal_queue, c.priority_queue
FROM player_count c
WHERE
c.time BETWEEN ? AND ? AND
MOD(c.time, ?) = 0;`,
(now - timeRange), now, precision,
)
if err != nil {
http.Error(res, "", http.StatusInternalServerError)
logger.Printf("Failed to query for player count: %s", err)
return
}
defer rows.Close()
counts := []models.PlayerCount{}
for rows.Next() {
var count models.PlayerCount
err = rows.Scan(&count.Time, &count.Playing, &count.NormalQueue, &count.PriorityQueue)
if err != nil {
http.Error(res, "", http.StatusInternalServerError)
logger.Printf("Failed to scan player count row: %s", err)
return
}
counts = append(counts, count)
}
err = rows.Err()
if err != nil {
http.Error(res, "", http.StatusInternalServerError)
logger.Printf("Failed to query for player count: %s", err)
return
}
json.NewEncoder(res).Encode(&counts)
}
}
func SubmitPlayerCounts(db *sql.DB, logger *log.Logger) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
row := db.QueryRow(`
SELECT w.name
FROM worker w
WHERE w.token = ?;`,
req.Header.Get("X-Token"),
)
var name string
err := row.Scan(&name)
switch {
case err == sql.ErrNoRows:
http.Error(res, "", http.StatusUnauthorized)
return
case err != nil:
http.Error(res, "", http.StatusInternalServerError)
logger.Printf("Failed to query for workers: %s", err)
return
}
var count models.PlayerCount
err = json.NewDecoder(req.Body).Decode(&count)
if err != nil {
http.Error(res, "malformed json", http.StatusBadRequest)
return
}
_, err = db.Exec(`
INSERT INTO
player_count (time, playing, normal_queue, priority_queue)
VALUES (?, ?, ?, ?)
ON CONFLICT DO NOTHING;`,
count.Time, count.Playing, count.NormalQueue, count.PriorityQueue,
)
if err != nil {
http.Error(res, "", http.StatusInternalServerError)
logger.Printf("Failed to insert player count data: %s", err)
return
}
logger.Printf("Worker \"%s\" submitted player count %+v", name, count)
}
}