hswaw/site: implement recurring events

Change-Id: Ib3c570d058141c4d8441801010f0f1755ccfc0e7
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1624
Reviewed-by: radex <radex@hackerspace.pl>
diff --git a/go.mod b/go.mod
index f46fcd9..8e323ad 100644
--- a/go.mod
+++ b/go.mod
@@ -92,6 +92,7 @@
 	github.com/spf13/cobra v1.7.0
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.8.4
+	github.com/teambition/rrule-go v1.8.2
 	github.com/ulule/limiter/v3 v3.11.2
 	github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b
 	golang.org/x/crypto v0.11.0
diff --git a/go.sum b/go.sum
index f1bedc6..359fc85 100644
--- a/go.sum
+++ b/go.sum
@@ -1307,6 +1307,8 @@
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8=
+github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4=
 github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
 github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
diff --git a/hswaw/site/calendar/BUILD.bazel b/hswaw/site/calendar/BUILD.bazel
index aae6731..6306e6b 100644
--- a/hswaw/site/calendar/BUILD.bazel
+++ b/hswaw/site/calendar/BUILD.bazel
@@ -12,6 +12,7 @@
     deps = [
         "@com_github_arran4_golang_ical//:golang-ical",
         "@com_github_golang_glog//:glog",
+        "@com_github_teambition_rrule_go//:rrule-go",
     ],
 )
 
diff --git a/hswaw/site/calendar/load.go b/hswaw/site/calendar/load.go
index f9ae146..177ddc8 100644
--- a/hswaw/site/calendar/load.go
+++ b/hswaw/site/calendar/load.go
@@ -12,6 +12,7 @@
 
 	ics "github.com/arran4/golang-ical"
 	"github.com/golang/glog"
+	rrule "github.com/teambition/rrule-go"
 )
 
 const (
@@ -94,6 +95,42 @@
 			glog.Errorf("Event %s has whole-day inconsistencies, start: %s, end: %s, ignoring", uid, start, end)
 		}
 
+		rruleS := event.GetProperty(ics.ComponentPropertyRrule)
+		if rruleS != nil {
+			rrule, err := rrule.StrToRRule(rruleS.Value)
+			if err != nil {
+				glog.Errorf("Event %s has unparseable RRULE, ignoring: %v", uid, err)
+				continue
+			}
+			rrule.DTStart(start.Time)
+
+			duration := end.Time.Sub(start.Time)
+			if start.WholeDay {
+				duration = time.Hour * 24
+			}
+
+			next := rrule.After(now, true)
+			if next.IsZero() {
+				continue
+			}
+			u := &UpcomingEvent{
+				UID:         uid,
+				Summary:     summary,
+				Description: description,
+				Start: &EventTime{
+					Time:     next,
+					WholeDay: start.WholeDay,
+				},
+				End: &EventTime{
+					Time:     next.Add(duration),
+					WholeDay: start.WholeDay,
+				},
+				Tentative: tentative,
+			}
+			out = append(out, u)
+			continue
+		}
+
 		u := &UpcomingEvent{
 			UID:         uid,
 			Summary:     summary,
diff --git a/third_party/go/repositories.bzl b/third_party/go/repositories.bzl
index 9df4bf7..3934e42 100644
--- a/third_party/go/repositories.bzl
+++ b/third_party/go/repositories.bzl
@@ -3803,6 +3803,13 @@
         version = "v0.0.0-20200815063812-42c35b437635",
     )
     go_repository(
+        name = "com_github_teambition_rrule_go",
+        importpath = "github.com/teambition/rrule-go",
+        sum = "h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8=",
+        version = "v1.8.2",
+    )
+
+    go_repository(
         name = "com_github_technoweenie_multipartstreamer",
         importpath = "github.com/technoweenie/multipartstreamer",
         sum = "h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=",