🔥 Removes db integration

This commit is contained in:
Daniel Svitan 2025-04-10 21:24:46 +02:00
parent afec6d69c7
commit 09077515db
2 changed files with 74 additions and 145 deletions

View File

@ -1,76 +0,0 @@
package main
import (
"fmt"
"os"
"time"
"github.com/google/uuid"
"github.com/labstack/gommon/log"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var db *gorm.DB
func ConnectDbFromEnv() {
dbHost := os.Getenv("DB_HOST")
if dbHost == "" {
log.Fatal("No DB_HOST")
}
dbPort := os.Getenv("DB_PORT")
if dbPort == "" {
log.Fatal("No DB_PORT")
}
dbName := os.Getenv("DB_NAME")
if dbName == "" {
log.Fatal("No DB_NAME")
}
dbUser := os.Getenv("DB_USER")
if dbUser == "" {
log.Fatal("No DB_USER")
}
dbPassword := os.Getenv("DB_PASSWORD")
if dbPassword == "" {
log.Fatal("No DB_PASSWORD")
}
dbSslMode := os.Getenv("DB_SSLMODE")
if dbSslMode == "" {
log.Fatal("No DB_SSLMODE")
}
dsn := fmt.Sprintf(
"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=Europe/Bratislava",
dbHost,
dbPort,
dbUser,
dbPassword,
dbName,
dbSslMode,
)
var err error
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err == nil {
err2 := db.AutoMigrate(&Dummy{})
if err2 != nil {
fmt.Printf("db migration error: %v\n", err2)
}
}
if err != nil {
log.Fatal(err)
}
}
type Dummy struct {
ID uuid.UUID `gorm:"primaryKey;type:uuid;unique" json:"id"`
Name string `json:"name"`
Connected bool `json:"connected"`
ConnectedAt time.Time `json:"connectedAt"`
DisconnectedAt time.Time `json:"disconnectedAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

View File

@ -22,9 +22,15 @@ import (
const TimeFormat = "2006-01-02 15:04:05" const TimeFormat = "2006-01-02 15:04:05"
type Client struct { type Client struct {
Obj *Dummy `json:"obj"` ID uuid.UUID `json:"id"`
conn *websocket.Conn `json:"-"` Name string `json:"name"`
ExitWanted bool `json:"exitWanted"` Connected bool `json:"connected"`
ConnectedAt time.Time `json:"connectedAt"`
DisconnectedAt time.Time `json:"disconnectedAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ExitWanted bool `json:"exitWanted"`
conn *websocket.Conn `json:"-"`
} }
var clients = []*Client{} var clients = []*Client{}
@ -60,33 +66,34 @@ func idparam(next func(echo.Context, uuid.UUID) error) echo.HandlerFunc {
return next(c, id) return next(c, id)
} }
}
func filename(dataDir string, id string) string {
return fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02"), id)
} }
func main() { func main() {
_ = godotenv.Load() _ = godotenv.Load()
dataDir = os.Getenv("DATA_DIR") dataDir = os.Getenv("DATA_DIR")
if dataDir == "" { if dataDir == "" {
log.Fatal("KEY_DIR is not defined") log.Fatal("DATA_DIR is not defined")
} }
token = os.Getenv("TOKEN") token = os.Getenv("TOKEN")
if token == "" { if token == "" {
log.Fatal("TOKEN is not defined") log.Fatal("TOKEN is not defined")
} }
ConnectDbFromEnv()
f, err := os.OpenFile(path.Join(dataDir, "startup"), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644) f, err := os.OpenFile(path.Join(dataDir, "startup"), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil { if err != nil {
log.Fatalf("KEY_DIR %s is not writable (%v)\n", dataDir, err) log.Fatalf("DATA_DIR %s is not writable (%v)\n", dataDir, err)
} }
_, err = f.Write([]byte(fmt.Sprintf("%s\n", time.Now().Format(TimeFormat)))) _, err = f.Write([]byte(fmt.Sprintf("%s\n", time.Now().Format(TimeFormat))))
if err != nil { if err != nil {
log.Fatalf("KEY_DIR test file couldn't be written to (%v)\n", err) log.Fatalf("DATA_DIR test file couldn't be written to (%v)\n", err)
} }
err = f.Close() err = f.Close()
if err != nil { if err != nil {
log.Fatalf("KEY_DIR test file couldn't be closed (%v)\n", err) log.Fatalf("DATA_DIR test file couldn't be closed (%v)\n", err)
} }
app := echo.New() app := echo.New()
@ -140,27 +147,40 @@ func main() {
app.GET("/keys", keys) app.GET("/keys", keys)
// administration // administration
app.GET("/admin/clients", func(c echo.Context) error { app.GET("/admin/clients", authed(func(c echo.Context) error {
if c.Request().Header.Get("Authorization") != token { return c.JSON(http.StatusOK, clients)
return c.NoContent(http.StatusUnauthorized) }))
app.GET("/admin/logs", authed(func(c echo.Context) error {
files, err := os.ReadDir(dataDir)
if err != nil {
return c.NoContent(http.StatusInternalServerError)
} }
return c.JSON(http.StatusOK, clients) filenames := []string{}
}) for _, file := range files {
filenames = append(filenames, file.Name())
}
return c.JSON(http.StatusOK, filenames)
}))
app.GET("/admin/:id", authed(idparam(func(c echo.Context, id uuid.UUID) error { app.GET("/admin/:id", authed(idparam(func(c echo.Context, id uuid.UUID) error {
for _, client := range clients { for _, client := range clients {
if client.Obj.ID == id { if client.ID == id {
return c.JSON(http.StatusOK, client) return c.JSON(http.StatusOK, client)
} }
} }
return c.NoContent(http.StatusNotFound) return c.NoContent(http.StatusNotFound)
}))) })))
app.GET("/admin/:id/logs", authed(idparam(func(c echo.Context, id uuid.UUID) error { app.GET("/admin/:id/logs", authed(idparam(func(c echo.Context, id uuid.UUID) error {
date := c.Param("date") date := c.Param("date")
if date == "" { if date == "" {
date = time.Now().Format("2006-01-02") date = time.Now().Format("2006-01-02")
} }
skipRaw := c.Param("skip") skipRaw := c.Param("skip")
skip := 0 skip := 0
if skipRaw != "" { if skipRaw != "" {
@ -169,6 +189,7 @@ func main() {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "skip is not a number"}) return c.JSON(http.StatusBadRequest, echo.Map{"message": "skip is not a number"})
} }
} }
takeRaw := c.Param("take") takeRaw := c.Param("take")
take := 1024 take := 1024
if takeRaw != "" { if takeRaw != "" {
@ -178,14 +199,16 @@ func main() {
} }
} }
f, err := os.OpenFile(fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02"), id), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644) f, err := os.OpenFile(filename(dataDir, id.String()), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil { if err != nil {
return c.JSON(http.StatusNotFound, echo.Map{"message": "file not found"}) return c.JSON(http.StatusNotFound, echo.Map{"message": "file not found"})
} }
_, err = f.Seek(int64(skip), io.SeekStart) if skip != 0 {
if err != nil { _, err = f.Seek(int64(skip), io.SeekStart)
return c.NoContent(http.StatusInternalServerError) if err != nil {
return c.NoContent(http.StatusInternalServerError)
}
} }
bytes := make([]byte, take) bytes := make([]byte, take)
@ -196,24 +219,27 @@ func main() {
return c.JSON(http.StatusOK, bytes) return c.JSON(http.StatusOK, bytes)
}))) })))
app.POST("/admin/:id/name", authed(idparam(func(c echo.Context, id uuid.UUID) error { app.POST("/admin/:id/name", authed(idparam(func(c echo.Context, id uuid.UUID) error {
name := c.Param("name")
if name == "" {
return c.JSON(http.StatusBadRequest, "missing field 'name'")
}
for _, client := range clients { for _, client := range clients {
if client.Obj.ID == id { if client.ID == id {
client.Obj.Name = c.Param("name") client.Name = name
client.Obj.UpdatedAt = time.Now() client.UpdatedAt = time.Now()
tx := db.Save(client.Obj)
if tx.Error != nil {
return c.NoContent(http.StatusInternalServerError)
}
return c.JSON(http.StatusOK, echo.Map{"message": "ok"}) return c.JSON(http.StatusOK, echo.Map{"message": "ok"})
} }
} }
return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"}) return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"})
}))) })))
app.POST("/admin/:id/exit", authed(idparam(func(c echo.Context, id uuid.UUID) error { app.POST("/admin/:id/exit", authed(idparam(func(c echo.Context, id uuid.UUID) error {
for _, client := range clients { for _, client := range clients {
if client.Obj.ID == id { if client.ID == id {
client.ExitWanted = true client.ExitWanted = true
return c.JSON(http.StatusOK, echo.Map{"message": "ok"}) return c.JSON(http.StatusOK, echo.Map{"message": "ok"})
} }
@ -234,51 +260,36 @@ func keys(c echo.Context) error {
now := time.Now() now := time.Now()
client := Client{ client := Client{
Obj: &Dummy{ ID: uuid.New(),
ID: uuid.New(), Name: "Dummy",
Name: "Dummy", Connected: true,
Connected: true, ConnectedAt: now,
ConnectedAt: now, DisconnectedAt: now,
DisconnectedAt: now, CreatedAt: now,
CreatedAt: now, UpdatedAt: now,
UpdatedAt: now, ExitWanted: false,
}, conn: ws,
conn: ws,
ExitWanted: false,
} }
tx := db.Create(client.Obj)
if tx.Error != nil {
log.Error(err)
fmt.Printf("%s client %s crashed (couldn't create record)\n", time.Now().Format(TimeFormat), client.Obj.ID.String())
client.ExitWanted = true
client.Obj.Connected = false
client.Obj.DisconnectedAt = time.Now()
return c.NoContent(http.StatusInternalServerError)
}
clients = append(clients, &client) clients = append(clients, &client)
fmt.Printf("%s client %s connected\n", time.Now().Format(TimeFormat), client.Obj.ID.String()) fmt.Printf("%s client %s connected\n", time.Now().Format(TimeFormat), client.ID.String())
err = ws.WriteMessage(websocket.TextMessage, []byte("welcome")) err = ws.WriteMessage(websocket.TextMessage, []byte("welcome"))
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} }
f, err := os.OpenFile(fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02"), client.Obj.ID.String()), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644) f, err := os.OpenFile(filename(dataDir, client.ID.String()), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.Obj.ID) fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.ID)
now = time.Now() now = time.Now()
client.ExitWanted = true client.ExitWanted = true
client.Obj.Connected = false client.Connected = false
client.Obj.DisconnectedAt = now client.DisconnectedAt = now
client.Obj.UpdatedAt = now client.UpdatedAt = now
tx = db.Save(client.Obj)
if tx.Error != nil {
log.Error(err)
}
return c.NoContent(http.StatusInternalServerError) return c.NoContent(http.StatusInternalServerError)
} }
defer f.Close() defer f.Close()
@ -289,20 +300,15 @@ func keys(c echo.Context) error {
now = time.Now() now = time.Now()
client.ExitWanted = true client.ExitWanted = true
client.Obj.Connected = false client.Connected = false
client.Obj.DisconnectedAt = now client.DisconnectedAt = now
client.Obj.UpdatedAt = now client.UpdatedAt = now
tx = db.Save(client.Obj)
if tx.Error != nil {
log.Error(err)
}
} }
for { for {
if client.ExitWanted { if client.ExitWanted {
close() close()
fmt.Printf("%s client %s disconnected\n", time.Now().Format(TimeFormat), client.Obj.ID.String()) fmt.Printf("%s client %s disconnected\n", time.Now().Format(TimeFormat), client.ID.String())
break break
} }
@ -310,7 +316,7 @@ func keys(c echo.Context) error {
if err != nil { if err != nil {
log.Error(err) log.Error(err)
close() close()
fmt.Printf("%s client %s crashed (websocket error)\n", time.Now().Format(TimeFormat), client.Obj.ID.String()) fmt.Printf("%s client %s crashed (websocket error)\n", time.Now().Format(TimeFormat), client.ID.String())
return c.NoContent(http.StatusInternalServerError) return c.NoContent(http.StatusInternalServerError)
} }
@ -318,10 +324,9 @@ func keys(c echo.Context) error {
if err != nil { if err != nil {
log.Error(err) log.Error(err)
close() close()
fmt.Printf("%s client %s crashed (file write error)\n", time.Now().Format(TimeFormat), client.Obj.ID.String()) fmt.Printf("%s client %s crashed (file write error)\n", time.Now().Format(TimeFormat), client.ID.String())
return c.NoContent(http.StatusInternalServerError) return c.NoContent(http.StatusInternalServerError)
} }
} }
return c.NoContent(http.StatusOK) return c.NoContent(http.StatusOK)