gotodo/main.go
2023-09-03 02:12:43 +02:00

141 lines
3.1 KiB
Go

package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"log"
"encoding/json"
"net/http"
"html/template"
"strconv"
)
type todo struct {
Id int
Title string
Completed bool
}
var maxId int = 0
var ctx = context.Background()
var rdb = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
func GetTodos() []todo {
var cursor uint64 = 0
todosJson, cursor, err := rdb.Scan(ctx, cursor, "todo:*", 20).Result()
if err != nil {
panic(err)
}
var todos []todo = make([]todo, len(todosJson))
for idx, todoJson := range todosJson {
todoJson := rdb.Get(ctx, todoJson).Val()
fmt.Println("Todo: %s", todoJson)
err = json.Unmarshal([]byte(todoJson), &todos[idx])
if err != nil {
panic(err)
}
if todos[idx].Id > maxId {
maxId = todos[idx].Id
}
}
return todos
}
func GetTodoById(id int) todo {
todoJson, err := rdb.Get(ctx, fmt.Sprintf("todo:%d", id)).Result()
if err != nil {
panic(err)
}
var todo todo
err = json.Unmarshal([]byte(todoJson), &todo)
if err != nil {
panic(err)
}
return todo
}
func SetTodo(todo todo) {
todoJson, err := json.Marshal(todo)
if err != nil {
panic(err)
}
key := fmt.Sprintf("todo:%d", todo.Id)
err = rdb.Set(ctx, key, string(todoJson), 0).Err()
if err != nil {
panic(err)
}
fmt.Println("Set todo: %s", todoJson)
}
func DeleteTodoById(id int) {
err := rdb.Del(ctx, fmt.Sprintf("todo:%d", id)).Err()
if err != nil {
panic(err)
}
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("templates/index.html")
t.Execute(w, nil)
}
func TodosHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
r.ParseForm()
todoTitle := r.Form.Get("title")
SetTodo(todo{Id: maxId + 1, Title: todoTitle, Completed: false})
}
todos := GetTodos()
t, _ := template.ParseFiles("templates/todos.html")
t.Execute(w, todos)
}
func ToggleTodoHandler(w http.ResponseWriter, r *http.Request) {
todoId, err := strconv.Atoi(r.URL.Path)
if err != nil {
panic(err)
}
fmt.Println("Todo Id: %d", todoId)
todo := GetTodoById(todoId)
todo.Completed = !todo.Completed
SetTodo(todo)
TodosHandler(w, r)
return
}
func TodoHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "DELETE" {
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprintf(w, "Method %s not allowed", r.Method)
return
}
todoId, err := strconv.Atoi(r.URL.Path)
if err != nil {
panic(err)
}
fmt.Println("Todo Id: %d", todoId)
DeleteTodoById(todoId)
TodosHandler(w, r)
return
}
func main() {
fmt.Println("Starting web server on port 8080")
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/todos", TodosHandler)
togglePath := "/toggle-todo/"
http.Handle(togglePath, http.StripPrefix(togglePath, http.HandlerFunc(ToggleTodoHandler)))
todoPath := "/todo/"
http.Handle(todoPath, http.StripPrefix(todoPath, http.HandlerFunc(TodoHandler)))
log.Fatal(http.ListenAndServe(":8080", nil))
}