commit 6e27b739602bf1e78dc05fe20e909b49a2571368 Author: Isaac Shoebottom Date: Thu Aug 22 17:23:11 2024 -0300 Initial working version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43267d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Intellij IDEA +.idea/ + +# Generated data store +data/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d44f689 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM golang:alpine as builder +WORKDIR /app +COPY . . +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" . +FROM scratch +WORKDIR /app +COPY --from=builder /app/medication /usr/bin/ +ENTRYPOINT ["medication"] \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8a95c11 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module medication + +go 1.23.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/index.html b/index.html new file mode 100644 index 0000000..bbd7f09 --- /dev/null +++ b/index.html @@ -0,0 +1,30 @@ + + + + + {{.Title}} + + + +
+

{{.Message}}

+ {{if .ShowForm}} +
+ + +
+ {{end}} +
+ \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..ce98eae --- /dev/null +++ b/main.go @@ -0,0 +1,148 @@ +package main + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" + "os" + "time" +) + +type Timestamp struct { + Current int64 `json:"current"` + Next int64 `json:"next"` +} + +type Store struct { + Username string `json:"username"` + Timestamps []int64 `json:"timestamps"` +} + +type PageData struct { + Title string + ShowForm bool + Message string +} + +func main() { + // Check if directory exists, if not create it + if _, err := os.Stat("./data"); os.IsNotExist(err) { + err := os.Mkdir("./data", 0755) + if err != nil { + fmt.Println("Error creating directory, check permissions") + os.Exit(1) + } + } + + // Set environment variables + RESET := os.Getenv("RESET") + if RESET == "true" { + if err := os.Remove("./data/taken.json"); err != nil { + fmt.Println("Error removing file, check permissions") + } + } + API_KEY := os.Getenv("API_KEY") + fmt.Println("API_KEY: ", API_KEY) + + // Start server + http.HandleFunc("/", index) + if err := http.ListenAndServe(":8080", nil); err != nil { + fmt.Println("Error starting server") + os.Exit(1) + } +} + +func handlePost() PageData { + current := time.Now().Unix() + var day int64 = 60 * 60 * 24 + next := current + day + + // If there is no file, create one + if _, err := os.Stat("./data/taken.json"); os.IsNotExist(err) { + if _, err := os.Create("./data/taken.json"); err != nil { + fmt.Println("Error creating file, check permissions") + os.Exit(1) + } + } + + // Write to file + if file, err := os.OpenFile("./data/taken.json", os.O_RDWR, os.ModePerm); err != nil { + fmt.Println("Error opening file, check permissions") + os.Exit(1) + } else { + encoder := json.NewEncoder(file) + if err = encoder.Encode(Timestamp{current, next}); err != nil { + fmt.Println("Error encoding file") + os.Exit(1) + } + if err = file.Close(); err != nil { + fmt.Println("Error closing file") + os.Exit(1) + } + } + + return PageData{ + Title: "Form submitted", + ShowForm: false, + Message: "Form submitted", + } +} + +func checkFile() PageData { + // Check if file exists + file, err := os.Open("./data/taken.json") + if err != nil { + fmt.Println("Error opening file, check perms or likely does not exist") + return PageData{ + Title: "Form page", + Message: "Hello first time user, please enter API key to submit form", + ShowForm: true, + } + } + // Decode file + info := Timestamp{} + decoder := json.NewDecoder(file) + if err := decoder.Decode(&info); err != nil { + fmt.Println("Error decoding file") + } + if err := file.Close(); err != nil { + fmt.Println("Error closing file") + } + if time.Now().Unix() > info.Next { + return PageData{ + Title: "Form page", + Message: "Already submmited form today, please wait until tomorrow", + ShowForm: false, + } + } + return PageData{ + Title: "Form page", + Message: "Please enter API key to submit form", + ShowForm: true, + } +} + +func index(w http.ResponseWriter, r *http.Request) { + tmpl := template.Must(template.ParseFiles("index.html")) + var data PageData + if r.Method == "GET" { + fmt.Println("GET request received") + data = checkFile() + } + if r.Method == "POST" { + fmt.Println("POST request received") + if err := r.ParseForm(); err != nil { + http.Error(w, "Error parsing form", http.StatusBadRequest) + return + } + if r.Form.Get("key") != os.Getenv("API_KEY") { + http.Error(w, "Invalid API key", http.StatusUnauthorized) + return + } + data = handlePost() + } + if err := tmpl.Execute(w, data); err != nil { + http.Error(w, "Error rendering template", http.StatusInternalServerError) + } +}