|
@@ -2,16 +2,34 @@ package glance
|
|
|
|
|
|
import (
|
|
import (
|
|
"context"
|
|
"context"
|
|
|
|
+ "fmt"
|
|
"html/template"
|
|
"html/template"
|
|
|
|
+ "log"
|
|
|
|
+ "net/http"
|
|
|
|
+ "os"
|
|
|
|
+ "strings"
|
|
"time"
|
|
"time"
|
|
|
|
+
|
|
|
|
+ ics "github.com/arran4/golang-ical"
|
|
)
|
|
)
|
|
|
|
|
|
var calendarWidgetTemplate = mustParseTemplate("calendar.html", "widget-base.html")
|
|
var calendarWidgetTemplate = mustParseTemplate("calendar.html", "widget-base.html")
|
|
|
|
|
|
|
|
+type CalendarEvent struct {
|
|
|
|
+ StartedDay time.Time
|
|
|
|
+ EventHover string
|
|
|
|
+}
|
|
|
|
+type CalendayDay struct {
|
|
|
|
+ Day int
|
|
|
|
+ IsEvent bool
|
|
|
|
+ Events []CalendarEvent
|
|
|
|
+}
|
|
|
|
+
|
|
type calendarWidget struct {
|
|
type calendarWidget struct {
|
|
widgetBase `yaml:",inline"`
|
|
widgetBase `yaml:",inline"`
|
|
Calendar *calendar
|
|
Calendar *calendar
|
|
StartSunday bool `yaml:"start-sunday"`
|
|
StartSunday bool `yaml:"start-sunday"`
|
|
|
|
+ Icsurl string
|
|
}
|
|
}
|
|
|
|
|
|
func (widget *calendarWidget) initialize() error {
|
|
func (widget *calendarWidget) initialize() error {
|
|
@@ -21,7 +39,8 @@ func (widget *calendarWidget) initialize() error {
|
|
}
|
|
}
|
|
|
|
|
|
func (widget *calendarWidget) update(ctx context.Context) {
|
|
func (widget *calendarWidget) update(ctx context.Context) {
|
|
- widget.Calendar = newCalendar(time.Now(), widget.StartSunday)
|
|
|
|
|
|
+ widget.Calendar = newCalendar(time.Now(), widget.StartSunday, widget.Icsurl)
|
|
|
|
+ fmt.Println(widget.Calendar.Days)
|
|
widget.withError(nil).scheduleNextUpdate()
|
|
widget.withError(nil).scheduleNextUpdate()
|
|
}
|
|
}
|
|
|
|
|
|
@@ -34,12 +53,13 @@ type calendar struct {
|
|
CurrentWeekNumber int
|
|
CurrentWeekNumber int
|
|
CurrentMonthName string
|
|
CurrentMonthName string
|
|
CurrentYear int
|
|
CurrentYear int
|
|
- Days []int
|
|
|
|
|
|
+ Days []CalendayDay
|
|
|
|
+ Icsurl string `yaml:"icsurl"`
|
|
}
|
|
}
|
|
|
|
|
|
// TODO: very inflexible, refactor to allow more customizability
|
|
// TODO: very inflexible, refactor to allow more customizability
|
|
// TODO: allow changing between showing the previous and next week and the entire month
|
|
// TODO: allow changing between showing the previous and next week and the entire month
|
|
-func newCalendar(now time.Time, startSunday bool) *calendar {
|
|
|
|
|
|
+func newCalendar(now time.Time, startSunday bool, icsurl string) *calendar {
|
|
year, week := now.ISOWeek()
|
|
year, week := now.ISOWeek()
|
|
weekday := now.Weekday()
|
|
weekday := now.Weekday()
|
|
if !startSunday {
|
|
if !startSunday {
|
|
@@ -58,18 +78,40 @@ func newCalendar(now time.Time, startSunday bool) *calendar {
|
|
|
|
|
|
startDaysFrom := now.Day() - int(weekday) - 7
|
|
startDaysFrom := now.Day() - int(weekday) - 7
|
|
|
|
|
|
- days := make([]int, 21)
|
|
|
|
|
|
+ days := make([]CalendayDay, 21)
|
|
|
|
+ events, _ := ReadPublicIcs(icsurl)
|
|
|
|
|
|
for i := 0; i < 21; i++ {
|
|
for i := 0; i < 21; i++ {
|
|
day := startDaysFrom + i
|
|
day := startDaysFrom + i
|
|
|
|
+ month := now.Month()
|
|
|
|
|
|
if day < 1 {
|
|
if day < 1 {
|
|
day = previousMonthDays + day
|
|
day = previousMonthDays + day
|
|
|
|
+ month -= 1
|
|
|
|
+
|
|
} else if day > currentMonthDays {
|
|
} else if day > currentMonthDays {
|
|
day = day - currentMonthDays
|
|
day = day - currentMonthDays
|
|
- }
|
|
|
|
|
|
+ month += 1
|
|
|
|
|
|
- days[i] = day
|
|
|
|
|
|
+ }
|
|
|
|
+ if events != nil {
|
|
|
|
+ for _, event := range events {
|
|
|
|
+ var dayEvent CalendarEvent
|
|
|
|
+ startAt, err := event.GetStartAt()
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Panic(err)
|
|
|
|
+ }
|
|
|
|
+ fmt.Println(year)
|
|
|
|
+ // fmt.Println(startAt.Day() == day && startAt.Month() == month)
|
|
|
|
+ if startAt.Day() == day && startAt.Month() == month && startAt.Year() == year {
|
|
|
|
+ dayEvent.StartedDay = startAt
|
|
|
|
+ dayEvent.EventHover = event.GetProperty("SUMMARY").Value
|
|
|
|
+ days[i].IsEvent = true
|
|
|
|
+ days[i].Events = append(days[i].Events, dayEvent)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ days[i].Day = day
|
|
}
|
|
}
|
|
|
|
|
|
return &calendar{
|
|
return &calendar{
|
|
@@ -84,3 +126,29 @@ func newCalendar(now time.Time, startSunday bool) *calendar {
|
|
func daysInMonth(m time.Month, year int) int {
|
|
func daysInMonth(m time.Month, year int) int {
|
|
return time.Date(year, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
|
|
return time.Date(year, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func ParseEventsFromFile(file string) []*ics.VEvent {
|
|
|
|
+ eventString, err := os.ReadFile(file)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Panic(err)
|
|
|
|
+ }
|
|
|
|
+ cal, err := ics.ParseCalendar(strings.NewReader(string(eventString)))
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Panic(err)
|
|
|
|
+ }
|
|
|
|
+ events := cal.Events()
|
|
|
|
+ return events
|
|
|
|
+}
|
|
|
|
+func ReadPublicIcs(url string) ([]*ics.VEvent, error) {
|
|
|
|
+ response, err := http.Get(url)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ defer response.Body.Close()
|
|
|
|
+ cal, err := ics.ParseCalendar(response.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ events := cal.Events()
|
|
|
|
+ return events, nil
|
|
|
|
+}
|