1
0
Fork 0
mirror of https://github.com/Luzifer/go-holidays.git synced 2024-12-26 13:51:18 +00:00
go-holidays/cmd/holiday-api/main.go
Knut Ahlers c361e5ea47
Allow to query localized name
Signed-off-by: Knut Ahlers <knut@ahlers.me>
2021-12-27 05:04:34 +01:00

130 lines
2.9 KiB
Go

package main
import (
_ "embed"
"encoding/json"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/Luzifer/go-holidays/holidays"
"github.com/Luzifer/rconfig/v2"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
)
var (
cfg = struct {
Listen string `flag:"listen" default:":3000" description:"IP/Port to listen on"`
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
}{}
//go:embed index.html
indexHTML []byte
version = "dev"
)
func init() {
if err := rconfig.Parse(&cfg); err != nil {
log.Fatalf("Unable to parse commandline options: %s", err)
}
if cfg.VersionAndExit {
fmt.Printf("holiday-api %s\n", version)
os.Exit(0)
}
}
func main() {
r := mux.NewRouter()
parts := []string{"", "{country-code:[a-z-]+}", "{year:[0-9]{4}}", "{month:[0-9]{2}}", "{day:[0-9]{2}}"}
for i := 2; i <= len(parts); i++ {
p := strings.Join(parts[:i], "/")
r.HandleFunc(p, handleHolidays)
r.HandleFunc(strings.Join([]string{p, "{format:[a-z]+}"}, "."), handleHolidays)
}
r.HandleFunc("/", handleReadme)
srv := &http.Server{
Addr: cfg.Listen,
Handler: r,
ReadTimeout: time.Second,
WriteTimeout: time.Second,
}
log.Println(srv.ListenAndServe())
}
func handleHolidays(res http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var (
countryCode = vars["country-code"]
format = vars["format"]
locale = r.FormValue("locale")
year = time.Now().Year()
)
if format == "" {
format = "json"
}
if y, ok := vars["year"]; ok {
var err error
if year, err = strconv.Atoi(y); err != nil {
http.Error(res, "You need to specify the year as a 4 character number", http.StatusBadRequest)
return
}
}
check := strings.TrimRight(strings.Join([]string{strconv.Itoa(year), vars["month"], vars["day"]}, "-"), "-")
days, err := holidays.GetHolidays(countryCode, year)
if err != nil {
http.Error(res, "An error ocurred: "+err.Error(), http.StatusInternalServerError)
return
}
outputSet := []holidays.Holiday{}
for _, h := range days {
if strings.HasPrefix(h.Date, check) {
outputSet = append(outputSet, h)
}
}
switch format {
case "ics":
cal := iCalendar{}
for _, h := range outputSet {
name := h.Name
if h.LocalizedName != nil && h.LocalizedName[locale] != "" {
name = h.LocalizedName[locale]
}
cal.Events = append(cal.Events, iCalendarEvent{
Summary: name,
Date: h.ParsedDate,
UID: fmt.Sprintf("%s_%s@hoiday-api.fyi", countryCode, h.ParsedDate.Format("20060102")),
})
}
res.Header().Set("Content-Type", "text/calendar")
fmt.Fprintln(res, cal.String())
case "json":
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(outputSet)
default:
http.Error(res, fmt.Sprintf("Unknown format: %s", format), http.StatusBadRequest)
return
}
}
func handleReadme(res http.ResponseWriter, r *http.Request) {
res.Write(indexHTML)
}