main.go (view raw)
1package main
2
3import (
4 "embed"
5 "flag"
6 "html/template"
7 "net/http"
8 "strconv"
9
10 "github.com/charmbracelet/log"
11 "github.com/gin-gonic/gin"
12
13 todo "github.com/1set/todotxt"
14)
15
16//go:embed static/* templates/*
17var fs embed.FS
18
19func main() {
20 configPath := flag.String("config", "config.yaml", "Path to config file")
21 flag.Parse()
22
23 config := getConfig(*configPath)
24 router := gin.Default()
25
26 templ := template.Must(template.New("").ParseFS(fs, "templates/*.html"))
27 router.SetHTMLTemplate(templ)
28
29 router.StaticFS("/static", http.FS(fs))
30
31 router.GET("/", loadTasksList)
32 router.POST("/", loadTasksList)
33
34 server := http.Server{
35 Addr: ":4443",
36 Handler: router,
37 TLSConfig: getTLSConfig(config),
38 }
39 defer server.Close()
40 log.Fatal(server.ListenAndServeTLS("", ""))
41}
42
43func loadTasksList(c *gin.Context) {
44 taskList := getTaskList("todo.txt")
45
46 id := c.PostForm("taskId")
47 content := c.PostForm("taskContent")
48
49 if id != "" {
50 taskId, err := strconv.Atoi(id)
51 if err != nil {
52 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
53 return
54 }
55
56 if updatedTask, err := taskList.GetTask(taskId); err != nil {
57 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "taskId": taskId})
58 return
59 } else {
60 if c.PostForm("checked") == "on" {
61 updatedTask.Complete()
62 } else {
63 updatedTask.Reopen()
64 }
65 }
66 taskList.WriteToPath("todo.txt")
67 } else if content != "" {
68 newTask, _ := todo.ParseTask(content)
69 taskList.AddTask(newTask)
70 taskList.WriteToPath("todo.txt")
71 }
72
73 c.HTML(http.StatusOK, "tasks-list.html", gin.H{
74 "tasks": taskList,
75 })
76}
77
78func getTaskList(todoFilePath string) todo.TaskList {
79 if tasklist, err := todo.LoadFromPath(todoFilePath); err != nil {
80 log.Fatalf("Can't load file %s", todoFilePath)
81 return nil
82 } else {
83 return tasklist
84 }
85}