From 2131f370ee409e28199a4572d4c83b4ad87ca14d Mon Sep 17 00:00:00 2001 From: gurkenhabicht Date: Mon, 6 Jan 2025 11:07:53 +0100 Subject: [PATCH] init --- .gitignore | 2 + go.mod | 10 ++ go.sum | 6 + gomatic.sql | 11 ++ main.go | 288 +++++++++++++++++++++++++++++++++++++++ rename.sh | 5 + static/index.html | 8 ++ templates/agentList.html | 14 ++ templates/backup.html | 43 ++++++ templates/home.html | 44 ++++++ templates/index.html | 27 ++++ 11 files changed, 458 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 gomatic.sql create mode 100644 main.go create mode 100644 rename.sh create mode 100644 static/index.html create mode 100644 templates/agentList.html create mode 100644 templates/backup.html create mode 100644 templates/home.html create mode 100644 templates/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4e7964 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +gontrol +bin/ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b16a01d --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module gontrol + +go 1.23.4 + +require ( + github.com/go-sql-driver/mysql v1.8.1 + github.com/gorilla/websocket v1.5.3 +) + +require filippo.io/edwards25519 v1.1.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5142118 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= diff --git a/gomatic.sql b/gomatic.sql new file mode 100644 index 0000000..9636525 --- /dev/null +++ b/gomatic.sql @@ -0,0 +1,11 @@ +/* create database 'gomatic'; */ + +drop table if exists agents; +create table agents ( + agentId int, + agentName varchar(255), + initialContact timestamp, + lastContact timestamp +); + +insert into agents values ( 99, "testAgent", NOW(), NOW()); diff --git a/main.go b/main.go new file mode 100644 index 0000000..a170dab --- /dev/null +++ b/main.go @@ -0,0 +1,288 @@ +package main + +import ( + "context" + "os" + "strings" + "time" + + // "errors" + "fmt" + "io" + "io/ioutil" + + // "net" + "database/sql" + "html/template" + "log" + "net/http" + "sync" + "syscall" + + "os/signal" + + _ "github.com/go-sql-driver/mysql" + "github.com/gorilla/websocket" +) + +var tmpl *template.Template +var db *sql.DB + +const ( + keyServerAddr = "serverAddr" + dbHost = "172.17.0.2" + dbUser = "root" + dbPort = 3306 + dbPassword = "root" + dbName = "gomatic" +) + +type Agent struct { + agentId int + agentName string + initialContact string + lastContact string +} + +func init() { + tmpl, _ = template.ParseGlob("templates/*.html") +} + +func initDB () { + var err error + dbOpen := fmt.Sprintf("%s:%s@(%s:%d)/%s?parseTime=true", dbUser,dbPassword, dbHost, dbPort, dbName) + db, err = sql.Open("mysql", dbOpen) + if err != nil { + log.Fatal(err) + } + + if err = db.Ping(); err != nil { + log.Fatal(err) + } + log.Println("Connected to database") +} + +func fetchAgents(w http.ResponseWriter, r *http.Request) { + agents, _ := getAgents(db) + + log.Printf("%s",agents) + tmpl.ExecuteTemplate(w, "agentList", agents) +} + +func getAgents(dbPointer *sql.DB) ([]Agent, error) { + query := "Select agentId, agentName, initialContact, lastContact from agents" + rows, err := dbPointer.Query(query) + + if err != nil { + return nil, err + } + defer rows.Close() + + var agents []Agent + for rows.Next() { + var agent Agent + + rowErr := rows.Scan(&agent.agentId, &agent.agentName, &agent.initialContact, &agent.lastContact) + if rowErr != nil { + return nil, err + } + agents = append(agents, agent) + } + + if err = rows.Err(); err != nil { + return nil, err + } + + return agents, nil + // return agents, rows.Err() +} + +func getRoot(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + hasFirst := r.URL.Query().Has("first") + first := r.URL.Query().Get("first") + hasSecond := r.URL.Query().Has("second") + second := r.URL.Query().Get("second") + + body, err := ioutil.ReadAll(r.Body) + + if err != nil { + fmt.Printf("Could not read body: %s\n", err) + } + + fmt.Printf("%s: got / request. first(%t)=%s, second(%t)=%s body:\n%s\n", + ctx.Value(keyServerAddr), + hasFirst, first, + hasSecond, second, + body, + ) + + // fmt.Printf("%s: got / request\n", ctx.Value(keyServerAddr)) + io.WriteString(w, "This is my website!\n") +} + +func getHello(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + fmt.Printf("%s: go /hello request\n", ctx.Value(keyServerAddr)) + + myName := r.PostFormValue("myName") + if myName == "" { + w.Header().Set("x-missing-field", "myName") + w.WriteHeader(http.StatusBadRequest) + return + } + + io.WriteString(w, fmt.Sprintf("Hello, %s!\n", myName)) +} + +func getHomepage(w http.ResponseWriter, r *http.Request) { + tmpl.ExecuteTemplate(w, "index.html", nil) +} + +func agentHandler(w http.ResponseWriter, r *http.Request) { + parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/agents/"), "/") + if len (parts) < 1 || parts[0] == "" { + http.Error(w, "Agent ID required", http.StatusBadRequest) + return + } + + agentId := parts[0] + + switch r.Method { + case http.MethodGet: + getAgent(w, r, agentId) + // case http.MethodPost: + // createAgent(w, r, agentId) + // case http.MethodPut: + // updateAgent(w, r, agentId) + // case http.MethodDelete: + // deleteAgent(w, r, agentId) + default: + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + } +} + +type webSocketHandler struct { + upgrader websocket.Upgrader +} + +func getAgent(w http.ResponseWriter, r *http.Request, agentId string) { + query := "Select agentId, agentName, initialContact, lastContact from agents where agentId = ?" + var agent Agent + err := db.QueryRow(query, agentId).Scan(&agentId, &agent.agentName, &agent.initialContact, &agent.lastContact) + if err == sql.ErrNoRows { + http.Error(w, "Agent not found", http.StatusNotFound) + return + } else if err != nil { + http.Error(w, "Failed to fetch agent", http.StatusInternalServerError) + return + } + + // return agent, nil + +} + +func (wsh webSocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + c, err := wsh.upgrader.Upgrade(w, r, nil) + if err != nil { + log.Printf("Error %s when upgrading connection to websocket", err) + return + } + defer c.Close() + + for { + mt, message, err := c.ReadMessage() + if err != nil { + log.Printf("Error reading: message: %s", err) + } + + log.Printf("Received message: %s", message) + if err = c.WriteMessage(mt, message); err !=nil { + log.Printf("Error writing the message: %s", err) + break + } + } +} + +func main() { + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var wg sync.WaitGroup + + webSocketHandler := webSocketHandler { + upgrader: websocket.Upgrader{}, + } + + webSocketMux := http.NewServeMux() + webSocketMux.Handle("/data", webSocketHandler) + websocketServer := &http.Server{ + Addr: ":5555", + Handler: webSocketMux, + } + + webMux := http.NewServeMux() + webMux.HandleFunc("/", getHomepage) + webMux.HandleFunc("/index", getRoot) + webMux.HandleFunc("/hello", getHello) + webMux.HandleFunc("/agents", fetchAgents) + // webMux.HandleFunc("/newagentform", getAgentForm) + // webMux.HandleFunc("/getagentupdateform/{agentId}", getAgentUpdateForm) + webMux.HandleFunc("/agents/{agentId}", agentHandler) + // webMux.HandleFunc + + + initDB() + defer db.Close() + + webServer := &http.Server { + Addr: ":3333", + Handler: webMux, + // BaseContext: func(l net.Listener) context.Context { + // ctx = context.WithValue(ctx, keyServerAddr, l.Addr().String()) + // return ctx + // }, + } + + wg.Add(1) + go func() { + defer wg.Done() + log.Println("Websocket server is running on port 5555") + if err := websocketServer.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("Websocket server failed: %s", err) + } + }() + + wg.Add(1) + go func() { + defer wg.Done() + log.Println("Web server is running on port 3333") + + if err := webServer.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("Web server failed: %s", err) + } + }() + + shutdownCh := make(chan os.Signal, 1) + signal.Notify(shutdownCh, os.Interrupt, syscall.SIGTERM) + + <-shutdownCh + log.Println("Shutdown signal received") + + shutdownCtx, shutdownCancel := context.WithTimeout(ctx, 10*time.Second) + defer shutdownCancel() + + if err := websocketServer.Shutdown(shutdownCtx); err != nil { + log.Printf("error shutting down websocket server: %s", err) + } + + if err := webServer.Shutdown(shutdownCtx); err != nil { + log.Printf("Error shutting down web server: %s", err) + } + + wg.Wait() + log.Println("All servers stopped") +} diff --git a/rename.sh b/rename.sh new file mode 100644 index 0000000..f636780 --- /dev/null +++ b/rename.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# +go mod edit -module "${2}" +find . -type f -name '*.go' -exec sed -i -e "s,\"${1}/,\"${2}/,g" {} \; +find . -type f -name '*.go' -exec sed -i -e "s,\"${1}\",\"${2}\",g" {} \; diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..c4e64fb --- /dev/null +++ b/static/index.html @@ -0,0 +1,8 @@ + + + Static Website + + +

Static Website

+ + diff --git a/templates/agentList.html b/templates/agentList.html new file mode 100644 index 0000000..d11a95f --- /dev/null +++ b/templates/agentList.html @@ -0,0 +1,14 @@ +{{define "agentList"}} + + +{{end}} diff --git a/templates/backup.html b/templates/backup.html new file mode 100644 index 0000000..11827cf --- /dev/null +++ b/templates/backup.html @@ -0,0 +1,43 @@ + + + + + + + + + To Do App + + + +
+ +
+

Tasks

+ +
+ Add New Item +
+ +
+ +
+ +
+ +
+

Add New Task

+ +
+ hello + {{template "addTaskForm"}} +
+ +
+ +
+ + + diff --git a/templates/home.html b/templates/home.html new file mode 100644 index 0000000..84cd0d8 --- /dev/null +++ b/templates/home.html @@ -0,0 +1,44 @@ + + + + + + + + + Gomatic Agents + + + + Test + + + +

Tasks

+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..f408eb3 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,27 @@ + + + + + + + + + To Do App + + + +
+ +
+

Tasks

+ + +
+ +
+ + +
+ + +