commit a46e67ec297cd981ec27577b25041a96a20b7fd0
parent 1c61378186c012a5cac5be6c146fdd36c11f1279
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Sun, 10 Dec 2023 22:19:30 +0100
feat: select year
Diffstat:
7 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/README.md b/README.md
@@ -10,7 +10,7 @@ go run .
## Usage
For example, to get the availability in the next week:
```
-curl http://127.0.0.1:3737/week/$(($(date +%W)+1))
+curl http://127.0.0.1:3737/week/$(date +%Y)/$(($(date +%W)+1))
```
To query the availability in the current week:
@@ -50,7 +50,7 @@ The application is configurable through environment variables or the
#HIVEDAV_LISTEN_ADDRESS=127.0.0.1
#HIVEDAV_LISTEN_PORT=3737
#HIVEDAV_CALENDAR=0
-#HIVEDAV_HORIZON=0
+#HIVEDAV_HORIZON=1
#HIVEDAV_BOOKING_SUBJ="HiveDAV Booking"
#HIVEDAV_BOOKING_REMINDER=15
#HIVEDAV_SMTP_PORT=587
@@ -75,11 +75,9 @@ There is an example config file provided in `./app.env.example`.
collection in the ["calendar home
set"](https://www.rfc-editor.org/rfc/rfc4791.html#section-6.2.1) which should
be used to read availability data
-* The `HIVEDAV_HORIZON` is the number of years to show (until 31.12.) from now
- in the calendar. 0 means that only the current year is shown. This sets the
-limit for recurring events without end time. Setting it to >0 is possible, but
-has no effect, since the program only allows to show/book by calendar week of
-the current year.
+* The `HIVEDAV_HORIZON` (number in years) limits recurring events without end
+ time. 0 means that only recurring events in the current year are shown.
+Unique events are not affected by `HIVEDAV_HORIZON`.
* `HIVEDAV_BOOKING_SUBJ` is the subject of the calendar invite for new booking
requests
* `HIVEDAV_BOOKING_REMINDER` is the reminder time in minutes before the start
diff --git a/app.env.example b/app.env.example
@@ -3,6 +3,7 @@
#HIVEDAV_HOST=hivedav.example.com
#HIVEDAV_CALDAV_URI=
#HIVEDAV_CALENDAR=0
+#HIVEDAV_HORIZON=1
#HIVEDAV_CALDAV_USER=
#HIVEDAV_CALDAV_PASSWORD=
#HIVEDAV_REFRESH_INTERVAL=30
diff --git a/config/config.go b/config/config.go
@@ -37,7 +37,7 @@ func (c *Config) LoadConfig(path string) (*Config, error) {
viper.SetDefault("HIVEDAV_LISTEN_PORT", 3737)
viper.SetDefault("HIVEDAV_LISTEN_ADDRESS", "[::]")
viper.SetDefault("HIVEDAV_CALENDAR", 0)
- viper.SetDefault("HIVEDAV_HORIZON", 0)
+ viper.SetDefault("HIVEDAV_HORIZON", 1)
viper.SetDefault("HIVEDAV_REFRESH_INTERVAL", 30)
viper.SetDefault("HIVEDAV_BOOKING_SUMMARY", "HiveDAV Booking")
viper.SetDefault("HIVEDAV_BOOKING_LOCATION", "https://meet.jit.si")
diff --git a/main.go b/main.go
@@ -30,6 +30,7 @@ func main() {
log.Printf("HiveDAV %s, %s 🍯\n", hivedavVersion, conf.HiveDavHost)
log.Println("----------------------------------------------------")
log.Printf("Cron interval:\t%d minutes\n", conf.RefreshInterval)
+ log.Printf("Calendar horizon:\t%d year(s)\n", conf.Horizon)
log.Printf("CalDAV server:\t%s\n", conf.CaldavUri)
log.Printf("CalDAV user:\t%s\n", conf.CaldavUser)
@@ -40,9 +41,9 @@ func main() {
router := httprouter.New()
router.GET("/", server.Index)
- router.GET("/week/:week", server.Week)
+ router.GET("/week/:year/:week", server.Week)
router.GET("/list", server.ListCubicles)
- router.GET("/list/:week", server.ListCubiclesInWeek)
+ router.GET("/list/:year/:week", server.ListCubiclesInWeek)
router.POST("/book/:dtstart", server.BookCubicle)
router.GET("/book/:dtstart", server.CubicleForm)
router.ServeFiles("/css/*filepath", http.Dir("./css"))
diff --git a/server.go b/server.go
@@ -119,9 +119,15 @@ func dayOfISOWeek(weekday int, week int, year int) (timeIt time.Time, weekNow in
// check out of bounds week (last week of the year)
limit := time.Date(year, 12, 31, 0, 0, 0, 0, time.Local)
_, limitWeek := limit.ISOWeek()
+ if limitWeek == 1 {
+ // last day of year already in first week of next year
+ // go back a week (years, months, days)
+ limit = limit.AddDate(0, 0, -7)
+ _, limitWeek = limit.ISOWeek()
+ }
if week > limitWeek {
- // set week to maximum
+ // set week to last week of requested year
week = limitWeek
}
@@ -189,20 +195,19 @@ var funcMap = template.FuncMap{
func (s *Server) Week(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
userAgent := req.Header.Get("user-agent")
- timeNow := time.Now()
- weekday := timeNow.Weekday()
- year, week := timeNow.ISOWeek()
-
- // overwrite with requested week
+ // overwrite with requested year and week
+ year, err := strconv.Atoi(ps.ByName("year"))
+ if err != nil { log.Printf("Cannot serve requested year '%d'\n", year)
+ http.Error(w, fmt.Sprintf("Cannot serve requested year '%d'\n", year), http.StatusBadRequest)
+ return
+ }
week, err := strconv.Atoi(ps.ByName("week"))
- if err != nil {
- log.Printf("Cannot serve requested week '%d'\n", week)
+ if err != nil { log.Printf("Cannot serve requested week '%d'\n", week)
http.Error(w, fmt.Sprintf("Cannot serve requested week '%d'\n", week), http.StatusBadRequest)
return
}
monday, week := dayOfISOWeek(1, week, year)
- log.Printf("Current weekday is '%d'\n", weekday)
log.Printf("Serving week '%v' of year '%v'\n", week, year)
log.Printf("Monday is '%v'\n", monday)
@@ -303,9 +308,9 @@ func (s *Server) Week(w http.ResponseWriter, req *http.Request, ps httprouter.Pa
if strings.Contains(userAgent, "curl") {
w.Header().Set("Content-Type", "text/plain")
io.WriteString(w, fmt.Sprintf("Serving week %d of year %d\n", week, year))
- io.WriteString(w, fmt.Sprintf("List cubicle booking commands: 'curl %s/list/%d'\n", s.config.HiveDavHost, week))
- io.WriteString(w, fmt.Sprintf("> Next week: 'curl %s/week/%d'\n", s.config.HiveDavHost, week+1))
- io.WriteString(w, fmt.Sprintf("< Prev week: 'curl %s/week/%d'\n", s.config.HiveDavHost, week-1))
+ io.WriteString(w, fmt.Sprintf("List cubicle booking commands: 'curl %s/list/%d/%d'\n", s.config.HiveDavHost, year, week))
+ io.WriteString(w, fmt.Sprintf("> Next week: 'curl %s/week/%d/%d'\n", s.config.HiveDavHost, year, week+1))
+ io.WriteString(w, fmt.Sprintf("< Prev week: 'curl %s/week/%d/%d'\n", s.config.HiveDavHost, year, week-1))
pt := prettytable.New(termTableData.TableHead)
for _, r := range termTableData.Rows {
// convert to slice of interface
@@ -342,6 +347,7 @@ func (s *Server) Index(w http.ResponseWriter, req *http.Request, _ httprouter.Pa
timeNow := time.Now()
_, currentWeek := timeNow.ISOWeek()
ps := httprouter.Params{
+ httprouter.Param{"year", strconv.Itoa(timeNow.Year())},
httprouter.Param{"week", strconv.Itoa(currentWeek)},
}
s.Week(w, req, ps)
@@ -515,11 +521,13 @@ func (s *Server) ListCubicles(w http.ResponseWriter, req *http.Request, _ httpro
func (s *Server) ListCubiclesInWeek(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
userAgent := req.Header.Get("user-agent")
- timeNow := time.Now()
- weekday := timeNow.Weekday()
- year, week := timeNow.ISOWeek()
-
- // overwrite with requested week
+ // overwrite with requested year and week
+ year, err := strconv.Atoi(ps.ByName("year"))
+ if err != nil {
+ log.Printf("Cannot serve requested year '%d'\n", year)
+ http.Error(w, fmt.Sprintf("Cannot serve requested year '%d'\n", year), http.StatusBadRequest)
+ return
+ }
week, err := strconv.Atoi(ps.ByName("week"))
if err != nil {
log.Printf("Cannot serve requested week '%d'\n", week)
@@ -528,7 +536,6 @@ func (s *Server) ListCubiclesInWeek(w http.ResponseWriter, req *http.Request, ps
}
monday, week := dayOfISOWeek(1, week, year)
- log.Printf("Current weekday is '%d'\n", weekday)
log.Printf("Serving week '%v' of year '%v'\n", week, year)
log.Printf("Monday is '%v'\n", monday)
@@ -584,7 +591,7 @@ func (s *Server) ListCubiclesInWeek(w http.ResponseWriter, req *http.Request, ps
if strings.Contains(userAgent, "curl") {
w.Header().Set("Content-Type", "text/plain")
io.WriteString(w, fmt.Sprintf("Serving week %d of year %d\n", week, year))
- io.WriteString(w, fmt.Sprintf("Back to calendar: 'curl %s/week/%d'\n", s.config.HiveDavHost, week))
+ io.WriteString(w, fmt.Sprintf("Back to calendar: 'curl %s/week/%d/%d'\n", s.config.HiveDavHost, year, week))
pt := prettytable.New(tableData.TableHead)
for _, r := range tableData.Rows {
diff --git a/templates/index.html b/templates/index.html
@@ -9,13 +9,13 @@
Serving week <i>{{ .Week }}</i> of year <i>{{ .Year }}</i>
</p>
<p>
- This site is curlable, try <code>`curl {{ .HiveDavHost }}/week/{{ .Week }}`</code>
+ This site is curlable, try <code>`curl {{ .HiveDavHost }}/week/{{ .Year }}/{{ .Week }}`</code>
</p>
<nav>
<ul>
- <li><a href="/list/{{ .Week }}">List cubicles</a></li>
- <li><a href="/week/{{ prev .Week }}">Prev week</a></li>
- <li><a href="/week/{{ next .Week }}">Next week</a></li>
+ <li><a href="/list/{{ .Year }}/{{ .Week }}">List cubicles</a></li>
+ <li><a href="/week/{{ .Year }}/{{ prev .Week }}">Prev week</a></li>
+ <li><a href="/week/{{ .Year }}/{{ next .Week }}">Next week</a></li>
</ul>
</nav>
<table class="calendar">
diff --git a/templates/listcubicles.html b/templates/listcubicles.html
@@ -9,13 +9,13 @@
Serving week <i>{{ .Week }}</i> of year <i>{{ .Year }}</i>
</p>
<p>
- This site is curlable, try <code>`curl {{ .HiveDavHost }}/list/{{ .Week }}`</code>
+ This site is curlable, try <code>`curl {{ .HiveDavHost }}/list/{{ .Year }}/{{ .Week }}`</code>
</p>
<nav>
<ul>
- <li><a href="/week/{{ .Week }}">Show calendar</a></li>
- <li><a href="/list/{{ prev .Week }}">Prev week</a></li>
- <li><a href="/list/{{ next .Week }}">Next week</a></li>
+ <li><a href="/week/{{ .Year }}/{{ .Week }}">Show calendar</a></li>
+ <li><a href="/list/{{ .Year }}/{{ prev .Week }}">Prev week</a></li>
+ <li><a href="/list/{{ .Year }}/{{ next .Week }}">Next week</a></li>
</ul>
</nav>
<table>