Add Calendar Events widget, integrate ICS calendar parsing, and refine related UI components

This commit is contained in:
2025-12-30 00:59:56 +01:00
parent a29beeda43
commit dfbc6066c9
14 changed files with 275 additions and 27 deletions

89
apis/calendar/main.go Normal file
View File

@@ -0,0 +1,89 @@
package calendar
import (
"ArinDash/config"
"sort"
"time"
"github.com/arran4/golang-ical"
)
type configFile struct {
Calendar calendarConfig
}
type calendarConfig struct {
ICS []ICS
Icon string
}
type ICS struct {
Icon string
URL string
}
type Event struct {
UID string
Summary string
Description string
Start time.Time
End time.Time
Location string
Icon string
}
func FetchEvents() []Event {
cfg := &configFile{}
config.LoadConfig(cfg)
events := make([]Event, 0)
for _, ic := range cfg.Calendar.ICS {
cal, err := ics.ParseCalendarFromUrl(ic.URL)
if err != nil {
panic(err)
}
for _, event := range cal.Events() {
startAt, err := event.GetStartAt()
if err != nil {
startAt = time.Now()
}
endAt, err := event.GetEndAt()
if err != nil {
endAt = startAt
}
events = append(events, Event{
UID: getValue(event, ics.ComponentPropertyUniqueId),
Icon: ic.Icon,
Summary: getValue(event, ics.ComponentPropertySummary),
Description: getValue(event, ics.ComponentPropertyDescription),
Start: startAt,
End: endAt,
Location: getValue(event, ics.ComponentPropertyLocation),
})
}
}
result := filter(events, func(i Event) bool {
return i.End.After(time.Now())
})
sort.Slice(result, func(i, j int) bool {
return result[i].Start.Before(result[j].Start)
})
return result
}
func getValue(event *ics.VEvent, property ics.ComponentProperty) string {
ianaProperty := event.GetProperty(property)
if ianaProperty == nil {
return ""
}
return ianaProperty.Value
}
func filter[T any](ss []T, test func(T) bool) (ret []T) {
for _, s := range ss {
if test(s) {
ret = append(ret, s)
}
}
return
}

View File

@@ -84,6 +84,7 @@ func knownDevices() map[string]Device {
}
func arpDevices() map[string]Device {
exec.Command("ip", "n", "show")
arp := exec.Command("arp", "-a")
var out bytes.Buffer
arp.Stdout = &out

View File

@@ -47,9 +47,17 @@ func FetchNews() News {
config.LoadConfig(cfg)
client := &http.Client{}
if cfg.News.ApiKey == "" {
return News{
Status: "No API key provided",
}
}
req, err := http.NewRequest("GET", apiBaseURL+"?sources="+cfg.News.Sources+"&pageSize=100&apiKey="+cfg.News.ApiKey, nil)
if err != nil {
panic(err)
return News{
Status: err.Error(),
}
}
resp, err := client.Do(req)
if err != nil {

View File

@@ -23,6 +23,11 @@ func FetchCurrentWeather() CurrentWeather {
config.LoadConfig(cfg)
client := &http.Client{}
currentWeather := &CurrentWeather{}
if cfg.OpenWeatherMap.ApiKey == "" {
return CurrentWeather{
ErrorMessage: "No API key provided",
}
}
req, err := http.NewRequest("GET", apiBaseURL+"?id="+cfg.OpenWeatherMap.LocationId+"&units=metric&lang=en&APPID="+cfg.OpenWeatherMap.ApiKey, nil)
if err != nil {

View File

@@ -78,6 +78,9 @@ func Connect() PiHConnector {
cfg := &configFile{}
config.LoadConfig(cfg)
client := &http.Client{}
if cfg.Pihole.Host == "" {
return PiHConnector{}
}
req, err := http.NewRequest("POST", "http://"+cfg.Pihole.Host+"/api/auth", strings.NewReader("{\"password\": \""+cfg.Pihole.Password+"\"}"))
if err != nil {