main.go (view raw)
1package main
2
3import (
4 "fmt"
5 "log"
6 "os"
7 "path"
8 "strconv"
9 "time"
10
11 "github.com/gin-gonic/gin"
12 "github.com/joho/godotenv"
13 "gorm.io/driver/sqlite"
14 "gorm.io/gorm"
15)
16
17// Occurrence represents a scheduled event
18type Occurrence struct {
19 ID uint `json:"id" gorm:"primaryKey"`
20 CreatedAt time.Time `json:"created_at"`
21 UpdatedAt time.Time `json:"updated_at"`
22
23 Day uint `json:"day"`
24 Month uint `json:"month"`
25 Year *uint `json:"year"`
26 Name string `json:"name"`
27 Description string `json:"description"`
28 Notify bool `json:"notify"`
29 Notified bool `json:"notified"`
30}
31
32const (
33 dataDir = "data"
34 dbFile = "occurrences.db"
35 defaultNotificationWindow = 3
36 defaultSleepDuration = 1
37 defaultPort = 3000
38)
39
40var (
41 db *gorm.DB
42 port int
43)
44
45func initDB() {
46 if _, err := os.Stat(dataDir); os.IsNotExist(err) {
47 err := os.Mkdir(dataDir, os.ModePerm)
48 if err != nil {
49 log.Fatal("Failed to create directory:", err)
50 }
51 }
52
53 var err error
54 db, err = gorm.Open(sqlite.Open(path.Join(dataDir, dbFile)), &gorm.Config{})
55 if err != nil {
56 log.Fatal("Failed to connect to database:", err)
57 }
58
59 db.AutoMigrate(&Occurrence{})
60}
61
62func loadEnv() {
63 err := godotenv.Load()
64 if err != nil {
65 log.Println("Error loading .env file")
66 }
67
68 NotificationWindow, err = strconv.Atoi(os.Getenv("DAYS_BEFORE_NOTIFICATION"))
69 if err != nil {
70 NotificationWindow = defaultNotificationWindow
71 }
72 log.Println("Notification window (days):", NotificationWindow)
73
74 loadedSleepDuration, err := strconv.Atoi(os.Getenv("HOURS_BETWEEN_CHECKS"))
75 if err != nil {
76 SleepDuration = defaultSleepDuration * time.Hour
77 } else {
78 SleepDuration = time.Duration(loadedSleepDuration) * time.Hour
79 }
80 log.Println("Sleep duration:", SleepDuration)
81
82 port, err = strconv.Atoi(os.Getenv("PORT"))
83 if err != nil {
84 port = defaultPort
85 }
86 log.Println("Port:", port)
87}
88
89func main() {
90 loadEnv()
91 initDB()
92 ParseTemplates()
93
94 go CheckOccurrences()
95
96 router := gin.Default()
97 router.POST("/occurrences", addOccurrence)
98 router.GET("/occurrences", getOccurrences)
99 router.DELETE("/occurrences/:id", deleteOccurrence)
100 router.GET("/", ShowIndexPage)
101
102 router.Run(fmt.Sprintf(":%d", port))
103}