mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2026-01-17 03:52:26 +01:00
140 lines
4.7 KiB
Go
140 lines
4.7 KiB
Go
//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
|
|
//Copyright (C) 2024 HTWKalender support@htwkalender.de
|
|
|
|
//This program is free software: you can redistribute it and/or modify
|
|
//it under the terms of the GNU Affero General Public License as published by
|
|
//the Free Software Foundation, either version 3 of the License, or
|
|
//(at your option) any later version.
|
|
|
|
//This program is distributed in the hope that it will be useful,
|
|
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
//GNU Affero General Public License for more details.
|
|
|
|
//You should have received a copy of the GNU Affero General Public License
|
|
//along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package ical
|
|
|
|
import (
|
|
ics "github.com/arran4/golang-ical"
|
|
"htwkalender/ical/model"
|
|
"htwkalender/ical/service/functions"
|
|
"log/slog"
|
|
"net/url"
|
|
"strings"
|
|
_ "time/tzdata"
|
|
)
|
|
|
|
const (
|
|
Thunderbird = "Thunderbird"
|
|
GoogleCalendar = "Google-Calendar-Importer"
|
|
)
|
|
|
|
// Adds a user-agent specific description and ALTREP to the calendar event.
|
|
func addUserAgentSpecificDescription(vEvent *ics.VEvent, event model.Event, userAgent string) {
|
|
description, altrep := generateDescription(event, userAgent)
|
|
|
|
if userAgentType := identifyUserAgent(userAgent); userAgentType == Thunderbird && altrep != "" {
|
|
vEvent.AddProperty(ics.ComponentPropertyDescription, description, ics.WithAlternativeRepresentation(buildDataURL(altrep)))
|
|
} else {
|
|
vEvent.AddProperty(ics.ComponentPropertyDescription, description)
|
|
}
|
|
}
|
|
|
|
// Generates a description and ALTREP (alternative representation) based on the user agent.
|
|
func generateDescription(event model.Event, userAgent string) (string, string) {
|
|
plainDescription := buildPlainTextDescription(event)
|
|
|
|
switch identifyUserAgent(userAgent) {
|
|
case Thunderbird:
|
|
htmlDescription := generateHTMLDescriptionForThunderbird(event)
|
|
altrep := "text/html," + url.PathEscape(htmlDescription)
|
|
return plainDescription, altrep
|
|
case GoogleCalendar:
|
|
plainDescription += generateRoomLinksForGoogleCalendar(event.Rooms)
|
|
}
|
|
return plainDescription, ""
|
|
}
|
|
|
|
// Builds a plain text description of the event details.
|
|
func buildPlainTextDescription(event model.Event) string {
|
|
var description strings.Builder
|
|
|
|
if !functions.OnlyWhitespace(event.Prof) {
|
|
description.WriteString("Profs: " + event.Prof + "\n")
|
|
}
|
|
if !functions.OnlyWhitespace(event.Course) {
|
|
description.WriteString("Gruppen: " + event.Course + "\n")
|
|
}
|
|
if !functions.OnlyWhitespace(event.EventType) {
|
|
description.WriteString("Typ: " + event.EventType + event.Compulsory + "\n")
|
|
}
|
|
if !functions.OnlyWhitespace(event.Notes) {
|
|
description.WriteString("Notizen: " + event.Notes + "\n")
|
|
}
|
|
|
|
return description.String()
|
|
}
|
|
|
|
// Generates an HTML description for Thunderbird users.
|
|
func generateHTMLDescriptionForThunderbird(event model.Event) string {
|
|
var htmlDescription strings.Builder
|
|
|
|
if !functions.OnlyWhitespace(event.Prof) {
|
|
htmlDescription.WriteString("Profs: " + event.Prof + "<br>")
|
|
}
|
|
if !functions.OnlyWhitespace(event.Course) {
|
|
htmlDescription.WriteString("Gruppen: " + event.Course + "<br>")
|
|
}
|
|
if !functions.OnlyWhitespace(event.EventType) {
|
|
htmlDescription.WriteString("Typ: " + event.EventType + event.Compulsory + "<br>")
|
|
}
|
|
|
|
if !functions.OnlyWhitespace(event.Rooms) {
|
|
htmlDescription.WriteString("Orte: ")
|
|
for _, room := range functions.SeperateRoomString(event.Rooms) {
|
|
roomLink := functions.MapRoom(room, true)
|
|
_, err := htmlDescription.WriteString("<a href=\"https://map.htwk-leipzig.de/room/" + roomLink + "\">" + room + "</a> ")
|
|
if err != nil {
|
|
slog.Error("Error while writing to HTML description", "error", err)
|
|
return ""
|
|
}
|
|
}
|
|
}
|
|
|
|
return htmlDescription.String()
|
|
}
|
|
|
|
// Generates room links formatted for Google Calendar.
|
|
func generateRoomLinksForGoogleCalendar(rooms string) string {
|
|
var description strings.Builder
|
|
roomList := functions.SeperateRoomString(rooms)
|
|
|
|
if !functions.OnlyWhitespace(rooms) {
|
|
description.WriteString("Orte: ")
|
|
for _, room := range roomList {
|
|
roomLink := functions.MapRoom(room, true)
|
|
description.WriteString("<a href=\"https://map.htwk-leipzig.de/room/" + roomLink + "\"> " + room + " </a> ")
|
|
}
|
|
}
|
|
|
|
return description.String()
|
|
}
|
|
|
|
// Identifies the user agent type (e.g., Thunderbird or Google Calendar).
|
|
func identifyUserAgent(userAgent string) string {
|
|
if strings.Contains(userAgent, Thunderbird) {
|
|
return Thunderbird
|
|
}
|
|
if strings.Contains(userAgent, GoogleCalendar) {
|
|
return GoogleCalendar
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Constructs a data URL for the ALTREP representation.
|
|
func buildDataURL(data string) *url.URL {
|
|
return &url.URL{Scheme: "data", Opaque: data}
|
|
}
|