Merge branch '56-e-tag-identifier-for-a-specific-version-of-a-resource' into 'development'

Resolve "e-tag identifier for a specific version of a resource"

See merge request htwk-software/htwkalender!74
This commit is contained in:
Elmar Kresse
2024-10-04 23:14:44 +00:00
4 changed files with 33 additions and 6 deletions

View File

@ -37,6 +37,14 @@ func (events Events) Sort() {
})
}
func (events Events) String() string {
var str strings.Builder
for _, event := range events {
str.WriteString(event.String())
}
return str.String()
}
type AnonymizedEventDTO struct {
Day string `db:"Day" json:"day"`
Week string `db:"Week" json:"week"`
@ -109,3 +117,7 @@ func (e *Event) GetName() string {
func (e *Event) SetName(name string) {
e.Name = name
}
func (e *Event) String() string {
return e.UUID + e.Day + e.Week + e.Start.String() + e.End.String() + e.Name + e.EventType + e.Compulsory + e.Prof + e.Rooms + e.Notes + e.BookedAt + e.Course + e.Semester
}

View File

@ -92,3 +92,7 @@ func ToJSONTime(timeString string) JSONTime {
}
return JSONTime(t)
}
func (j JSONTime) String() string {
return time.Time(j).Format(DefaultDateLayout)
}

View File

@ -23,6 +23,7 @@ import (
"htwkalender/ical/model"
"htwkalender/ical/service/connector"
htwkalenderGrpc "htwkalender/ical/service/connector/grpc"
"htwkalender/ical/service/functions"
"log/slog"
"time"
)
@ -31,7 +32,7 @@ const expirationTime = 5 * time.Minute
var FeedDeletedError = fmt.Errorf("feed deleted")
func Feed(app model.AppType, token string) (string, error) {
func Feed(app model.AppType, token string) (string, string, error) {
var events model.Events
modules := map[string]model.FeedCollection{}
@ -47,17 +48,17 @@ func Feed(app model.AppType, token string) (string, error) {
// get feed by token
feed, err := htwkalenderGrpc.GetFeed(token, app.GrpcClient)
if err != nil {
return "", err
return "", "", err
}
if feed.Deleted {
return "", FeedDeletedError
return "", "", FeedDeletedError
}
// Get all events for modules
events, err = htwkalenderGrpc.GetEvents(feed.Modules, app.GrpcClient)
if err != nil {
return "", err
return "", "", err
}
// Sort events by start date
@ -68,11 +69,14 @@ func Feed(app model.AppType, token string) (string, error) {
}
}
// Generate one Hash for E-TAG from all events and modules
etag := functions.HashString(events.String() + fmt.Sprint(modules))
b := bytes.Buffer{}
goics.NewICalEncode(&b).Encode(IcalModel{Events: events, Mapping: modules})
icalFeed := &model.FeedModel{Content: b.String(), ExpiresAt: model.JSONTime(time.Now().Add(expirationTime))}
return icalFeed.Content, nil
return icalFeed.Content, etag, nil
}
func FeedRecord(app model.AppType, token string) (model.FeedRecord, error) {

View File

@ -34,7 +34,8 @@ func AddFeedRoutes(app model.AppType) {
app.Fiber.Get("/api/feed", func(c fiber.Ctx) error {
token := c.Query("token")
results, err := ical.Feed(app, token)
ifNoneMatch := c.Get("If-None-Match")
results, eTag, err := ical.Feed(app, token)
if errors.Is(err, ical.FeedDeletedError) {
return c.SendStatus(fiber.StatusGone)
@ -44,10 +45,16 @@ func AddFeedRoutes(app model.AppType) {
slog.Error("Failed to get feed", "error", err, "token", token)
return c.SendStatus(fiber.StatusNotFound)
}
if ifNoneMatch == eTag && ifNoneMatch != "" {
return c.SendStatus(fiber.StatusNotModified)
}
c.Response().Header.Set("Content-type", "text/calendar")
c.Response().Header.Set("charset", "utf-8")
c.Response().Header.Set("Content-Disposition", "inline")
c.Response().Header.Set("filename", "calendar.ics")
c.Response().Header.Set("ETag", eTag)
return c.SendString(results)
})