141 lines
3.1 KiB
Go
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))
|
|
}
|