all repos — cameraman @ 585f171daa720446f46b066ded55d5da8d56c93c

handlers.go (view raw)

  1package main
  2
  3import (
  4	"encoding/json"
  5	"errors"
  6	"fmt"
  7	"net/http"
  8	"strconv"
  9	"time"
 10)
 11
 12const errJson = "{\"error\": %s}"
 13
 14func returnError(w http.ResponseWriter, err error, status int) {
 15	http.Error(w, fmt.Sprintf(errJson, err.Error()), status)
 16}
 17
 18func validateDate(month, day uint, year *uint) error {
 19	if month < 1 || month > 12 {
 20		return errors.New("invalid month: must be between 1 and 12")
 21	}
 22
 23	if day < 1 || day > 31 {
 24		return errors.New("invalid day: must be between 1 and 31")
 25	}
 26
 27	var testYear uint
 28	if year == nil {
 29		testYear = 2023
 30	} else {
 31		testYear = *year
 32	}
 33
 34	// Construct a date and use time package to validate
 35	dateStr := fmt.Sprintf("%04d-%02d-%02d", testYear, month, day)
 36	_, err := time.Parse("2006-01-02", dateStr)
 37	if err != nil {
 38		return errors.New("invalid day for the given month")
 39	}
 40
 41	return nil
 42}
 43
 44func updateOccurrence(w http.ResponseWriter, input Occurrence) {
 45	var occurrence Occurrence
 46	if err := db.First(&occurrence, input.ID).Error; err != nil {
 47		returnError(w, err, http.StatusBadRequest)
 48		return
 49	}
 50
 51	// Update existing record with new values
 52	if input.Day != 0 || input.Month != 0 {
 53		if err := validateDate(input.Month, input.Day, input.Year); err != nil {
 54			returnError(w, err, http.StatusBadRequest)
 55			return
 56		}
 57		occurrence.Day = input.Day
 58		occurrence.Month = input.Month
 59		occurrence.Year = input.Year
 60	}
 61	if input.Name != "" {
 62		occurrence.Name = input.Name
 63	}
 64	if input.Description != "" {
 65		occurrence.Description = input.Description
 66	}
 67	occurrence.Notify = input.Notify
 68	occurrence.Notified = input.Notified
 69	db.Save(&occurrence)
 70	json.NewEncoder(w).Encode(occurrence)
 71}
 72
 73func addOccurrence(w http.ResponseWriter, r *http.Request) {
 74	var input Occurrence
 75	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
 76		returnError(w, err, http.StatusBadRequest)
 77		return
 78	}
 79
 80	if input.ID != 0 {
 81		updateOccurrence(w, input)
 82		return
 83	}
 84
 85	if err := validateDate(input.Month, input.Day, input.Year); err != nil {
 86		returnError(w, err, http.StatusBadRequest)
 87		return
 88	}
 89
 90	db.Create(&input)
 91	json.NewEncoder(w).Encode(input)
 92}
 93
 94func getOccurrences(w http.ResponseWriter, r *http.Request) {
 95	var occurrences []Occurrence
 96	db.Find(&occurrences)
 97	json.NewEncoder(w).Encode(occurrences)
 98}
 99
100func deleteOccurrence(w http.ResponseWriter, r *http.Request) {
101	id, err := strconv.ParseUint(r.PathValue("id"), 10, 64)
102	if err != nil {
103		returnError(w, err, http.StatusBadRequest)
104		return
105	}
106
107	var occurrence Occurrence
108
109	if err := db.First(&occurrence, id).Error; err != nil {
110		returnError(w, err, http.StatusNotFound)
111		return
112	}
113
114	db.Delete(&occurrence)
115	w.WriteHeader(http.StatusNoContent)
116}