Mercurial > public > pacobot
changeset 10:5c124578fed2
fix timer bug
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sat, 15 Mar 2025 17:03:53 +0000 |
parents | 228ab74e8321 |
children | 6d91c612310a |
files | api/handlers.go api/store.go bot/bot.go bot/timer.go main.go socket/conn.go www/index.html |
diffstat | 7 files changed, 188 insertions(+), 275 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/handlers.go Sat Mar 15 17:03:53 2025 +0000 @@ -0,0 +1,72 @@ +package api + +import ( + "net/http" + + "github.com/denniscmcom/pacobot/auth" + "github.com/denniscmcom/pacobot/socket" + "github.com/gin-gonic/gin" +) + +func GetUserHandler(c *gin.Context) { + userName := c.Query("username") + user := auth.GetUser(userName, getAccessToken()) + + c.JSON(http.StatusOK, gin.H{ + "message": user.Data[len(user.Data)-1].Id, + }) +} + +func AuthHandler(c *gin.Context) { + authUrl := auth.GetAuthUrl() + c.Redirect(http.StatusMovedPermanently, authUrl) +} + +func AuthValidateHandler(c *gin.Context) { + msg := "failed" + + if auth.IsAuthTokenValid(getAccessToken()) { + msg = "ok" + } + + c.JSON(http.StatusOK, gin.H{ + "message": msg, + }) +} + +func AuthRefreshHandler(c *gin.Context) { + authRes := auth.RefreshAuthToken(getAccessToken(), getRefreshToken()) + setAccessToken(authRes.AccessToken) + setRefreshToken(authRes.RefreshToken) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func AuthRevokeHandler(c *gin.Context) { + auth.RevokeAuthToken(getAccessToken()) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func TwitchCallbackHandler(c *gin.Context) { + authCode := c.Query("code") + authRes := auth.GetAuthToken(authCode) + authStore.Store("accessToken", authRes.AccessToken) + authStore.Store("refreshToken", authRes.RefreshToken) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func ConnectHandler(c *gin.Context) { + go socket.Connect(getAccessToken()) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/store.go Sat Mar 15 17:03:53 2025 +0000 @@ -0,0 +1,36 @@ +package api + +import ( + "log" + "sync" +) + +var authStore sync.Map + +func setAccessToken(accessToken string) { + authStore.Store("accessToken", accessToken) +} + +func setRefreshToken(refreshToken string) { + authStore.Store("refreshToken", refreshToken) +} + +func getAccessToken() string { + value, exists := authStore.Load("accessToken") + + if !exists { + log.Fatal("api: access token not found") + } + + return value.(string) +} + +func getRefreshToken() string { + value, exists := authStore.Load("refreshToken") + + if !exists { + log.Fatal("api: refresh token not found") + } + + return value.(string) +}
--- a/bot/bot.go Thu Mar 13 18:27:25 2025 +0000 +++ b/bot/bot.go Sat Mar 15 17:03:53 2025 +0000 @@ -1,15 +1,10 @@ package bot import ( - "fmt" "log" - "os" "strconv" - "time" ) -var quitTimer chan bool - func HandleCmd(cmd []string) { cmdReceived := cmd[0] log.Printf("bot: %s command received", cmdReceived) @@ -19,70 +14,9 @@ seconds, err := strconv.Atoi(cmd[1]) if err != nil { - log.Fatal("err: invalid command arguments") - } - - if quitTimer != nil { - quitTimer <- true - + log.Fatal("bot: invalid command arguments") } - quitTimer = make(chan bool) - - go func() { - filename := "F:/Media/Twitch/Bot/timer.txt" - - file, err := os.Create(filename) - - if err != nil { - log.Fatal(err) - } - - defer file.Close() - - countdown := time.Duration(seconds) * time.Second - ticker := time.NewTicker(time.Second) - defer ticker.Stop() - - log.Printf("bot: timer started with duration %d seconds", seconds) - - for countdown > 0 { - select { - case <-ticker.C: - totalSeconds := int(countdown.Seconds()) - minutes := totalSeconds / 60 - seconds := totalSeconds % 60 - countdownMsg := fmt.Sprintf("%02d:%02d", minutes, seconds) - - file.Seek(0, 0) - _, err = file.WriteString("") - - if err != nil { - log.Fatal(err) - } - - _, err = file.WriteString(countdownMsg) - - if err != nil { - log.Fatal(err) - } - - log.Printf("bot: timer updated to %s", countdownMsg) - - countdown -= time.Second - case <-quitTimer: - file.Seek(0, 0) - _, err = file.WriteString("") - - if err != nil { - log.Fatal(err) - } - - log.Println("bot: timer stopped") - - return - } - } - }() + startTimer(seconds) } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bot/timer.go Sat Mar 15 17:03:53 2025 +0000 @@ -0,0 +1,65 @@ +package bot + +import ( + "fmt" + "log" + "os" + "time" +) + +var quit chan struct{} + +func startTimer(seconds int) { + if quit != nil { + close(quit) + } + + quit = make(chan struct{}) + + go func() { + filename := "F:/Media/Twitch/Bot/timer.txt" + file, err := os.Create(filename) + + if err != nil { + log.Fatal(err) + } + + defer file.Close() + countdown := time.Duration(seconds) * time.Second + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + log.Printf("bot: timer started with duration %d seconds", seconds) + + for countdown >= 0 { + select { + case <-ticker.C: + totalSeconds := int(countdown.Seconds()) + minutes := totalSeconds / 60 + seconds := totalSeconds % 60 + countdownMsg := fmt.Sprintf("%02d:%02d", minutes, seconds) + + file.Seek(0, 0) + _, err = file.WriteString("") + + if err != nil { + log.Fatal(err) + } + + _, err = file.WriteString(countdownMsg) + + if err != nil { + log.Fatal(err) + } + + log.Printf("bot: timer updated to %s", countdownMsg) + + countdown -= time.Second + case <-quit: + log.Println("bot: timer stopped") + + return + } + } + }() +}
--- a/main.go Thu Mar 13 18:27:25 2025 +0000 +++ b/main.go Sat Mar 15 17:03:53 2025 +0000 @@ -1,97 +1,22 @@ package main import ( - "log" - "net/http" - - "github.com/denniscmcom/pacobot/auth" - "github.com/denniscmcom/pacobot/bot" - "github.com/denniscmcom/pacobot/socket" + "github.com/denniscmcom/pacobot/api" "github.com/gin-gonic/gin" ) -type PageData struct { - Title string -} - func main() { gin.SetMode(gin.DebugMode) r := gin.Default() - r.LoadHTMLGlob("./www/*.html") - var authRes auth.AuthRes - - r.GET("/", func(c *gin.Context) { - c.HTML(http.StatusOK, "index.html", gin.H{ - "Title": "Index", - }) - }) - - r.GET("/user", func(c *gin.Context) { - userName := c.Query("username") - user := auth.GetUser(userName, authRes.AccessToken) - - c.JSON(http.StatusOK, gin.H{ - "message": user.Data[len(user.Data)-1].Id, - }) - }) - - r.GET("/auth", func(c *gin.Context) { - authUrl := auth.GetAuthUrl() - - c.Redirect(http.StatusMovedPermanently, authUrl) - }) - - r.GET("/auth-validate", func(c *gin.Context) { - msg := "failed" - - if auth.IsAuthTokenValid(authRes.AccessToken) { - msg = "ok" - } - - c.JSON(http.StatusOK, gin.H{ - "message": msg, - }) - }) - - r.GET("/auth-refresh", func(c *gin.Context) { - authRes = auth.RefreshAuthToken(authRes.AccessToken, authRes.RefreshToken) - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) - }) - - r.GET("/auth-revoke", func(c *gin.Context) { - auth.RevokeAuthToken(authRes.AccessToken) - - c.JSON(http.StatusOK, gin.H{ - "message": "ok", - }) - }) - - r.GET("/twitch-auth-code-callback", func(c *gin.Context) { - authCode := c.Query("code") - authRes = auth.GetAuthToken(authCode) - - c.Redirect(http.StatusMovedPermanently, "/") - }) - - r.GET("/connect", func(c *gin.Context) { - go socket.Connect(authRes.AccessToken) - - c.Redirect(http.StatusMovedPermanently, "/") - }) - - r.POST("/timer", func(c *gin.Context) { - form := c.Request.PostForm - log.Println(form) - timesec := form.Get("tiempo-oculto") - log.Println(timesec) - args := []string{"timer", timesec} - bot.HandleCmd(args) - }) + r.GET("/user", api.GetUserHandler) + r.GET("/auth", api.AuthHandler) + r.GET("/auth-validate", api.AuthValidateHandler) + r.GET("/auth-refresh", api.AuthRefreshHandler) + r.GET("/auth-revoke", api.AuthRevokeHandler) + r.GET("/twitch-auth-code-callback", api.TwitchCallbackHandler) + r.GET("/connect", api.ConnectHandler) r.Run() }
--- a/socket/conn.go Thu Mar 13 18:27:25 2025 +0000 +++ b/socket/conn.go Sat Mar 15 17:03:53 2025 +0000 @@ -2,7 +2,6 @@ import ( "encoding/json" - "fmt" "log" "net/url" "os" @@ -33,7 +32,7 @@ log.Println("socket: connected") var timeout time.Ticker - done := make(chan bool) + done := make(chan struct{}) go readMsg(done, conn, &timeout, authToken) @@ -58,7 +57,8 @@ } } -func readMsg(done chan bool, conn *websocket.Conn, timeout *time.Ticker, authToken string) { +func readMsg(done chan struct{}, conn *websocket.Conn, timeout *time.Ticker, authToken string) { + defer close(done) var timeout_secs time.Duration for { @@ -114,29 +114,16 @@ log.Fatal(err) } - // TODO: Add to a function - jsonFormatted, err := json.MarshalIndent(resNotifChannelChatMsg, "", " ") - - if err != nil { - log.Fatalf("socket: error al formatear") - } - - // log.Println(resNotifChannelChatMsg.Payload.Event) - fmt.Print(string(jsonFormatted)) - chatMsg := resNotifChannelChatMsg.Payload.Event.Msg.Text - log.Println(chatMsg) if strings.HasPrefix(chatMsg, "!") { - bot.HandleCmd(strings.Split(chatMsg[1:], " ")) + go bot.HandleCmd(strings.Split(chatMsg[1:], " ")) } } default: - log.Fatalf("%s: message type not implemented", msgType) + log.Fatalf("socket: %s message type not implemented", msgType) } } - - done <- true } func closeConn(conn *websocket.Conn) {
--- a/www/index.html Thu Mar 13 18:27:25 2025 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -<!DOCTYPE html> -<html lang="es"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Redirección con Gin</title> - <style> - body { - font-family: Arial, sans-serif; - background-color: #f0f0f0; - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; - } - - .container { - text-align: center; - background-color: white; - padding: 20px; - border-radius: 8px; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); - } - - h1 { - margin-bottom: 20px; - } - - .btn { - background-color: #4CAF50; - color: white; - padding: 10px 20px; - margin: 10px; - border: none; - border-radius: 5px; - cursor: pointer; - font-size: 16px; - transition: background-color 0.3s ease; - } - - .btn:hover { - background-color: #45a049; - } - - #tiempo-mostrar { - font-size: 20px; - margin-top: 10px; - } - </style> -</head> - -<body> - <div class="container"> - <h1>Minutos del timer</h1> - <div> - <button id="decrementar-btn" class="btn">-</button> - <span id="tiempo-mostrar">0</span> - <button id="incrementar-btn" class="btn">+</button> - </div> - <br> - <form action="/timer" method="POST" id="form-timer"> - <input type="hidden" id="tiempo-oculto" name="time" value="0"> - <br> - <button type="button" id="btn-auth" class="btn">Ir a Auth</button> - <button type="submit" class="btn">Ir a Connect</button> - </form> - </div> - - <script> - const disminuirBtn = document.getElementById('decrementar-btn'); - const aumentarBtn = document.getElementById('incrementar-btn'); - const mostrarTiempo = document.getElementById('tiempo-mostrar'); - const tiempoInput = document.getElementById('tiempo-oculto'); - const formTimer = document.getElementById('form-timer'); - const btnAuth = document.getElementById('btn-auth'); - - let tiempo = 0; - - disminuirBtn.addEventListener('click', function () { - if (tiempo > 0) { - tiempo--; - mostrarTiempo.textContent = tiempo; - tiempoInput.value = tiempo; - } - }); - - aumentarBtn.addEventListener('click', function () { - tiempo++; - mostrarTiempo.textContent = tiempo; - tiempoInput.value = tiempo; - }); - - formTimer.addEventListener('submit', function () { - tiempoInput.value = tiempo * 60; - }); - - btnAuth.addEventListener('click', function () { - window.location.href = '/auth'; - }); - </script> - -</body> - -</html> \ No newline at end of file