diff --git a/backend/service/addRoute.go b/backend/service/addRoute.go index f0abc62..2bf004b 100644 --- a/backend/service/addRoute.go +++ b/backend/service/addRoute.go @@ -9,6 +9,7 @@ import ( "htwkalender/service/fetch" "htwkalender/service/ical" "htwkalender/service/room" + "io" "net/http" "os" ) @@ -71,6 +72,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + // API Endpoint to get all events for a specific room on a specific day app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, @@ -90,12 +92,19 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + // API Endpoint to create a new iCal feed app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodPost, Path: "/api/createFeed", Handler: func(c echo.Context) error { - return ical.CreateIndividualFeed(c, app) + requestBody, _ := io.ReadAll(c.Request().Body) + result, err := ical.CreateIndividualFeed(requestBody, app) + if err != nil { + return c.JSON(http.StatusInternalServerError, err) + } + return c.JSON(http.StatusOK, result) + }, Middlewares: []echo.MiddlewareFunc{ apis.ActivityLogger(app), diff --git a/backend/service/addSchedule.go b/backend/service/addSchedule.go index fa36aff..e50201c 100644 --- a/backend/service/addSchedule.go +++ b/backend/service/addSchedule.go @@ -13,7 +13,10 @@ func AddSchedules(app *pocketbase.PocketBase) { app.OnBeforeServe().Add(func(e *core.ServeEvent) error { scheduler := cron.New() - scheduler.MustAdd("updateCourse", "*/60 * * * *", func() { + // Every hour update all courses (5 segments - minute, hour, day, month, weekday) "0 * * * *" + // Every three hours update all courses (5 segments - minute, hour, day, month, weekday) "0 */3 * * *" + // Every 10 minutes update all courses (5 segments - minute, hour, day, month, weekday) "*/10 * * * *" + scheduler.MustAdd("updateCourse", "*/10 * * * *", func() { courses := events.GetAllCourses(app) diff --git a/backend/service/db/dbEvents.go b/backend/service/db/dbEvents.go index a89fdc6..c1113a6 100644 --- a/backend/service/db/dbEvents.go +++ b/backend/service/db/dbEvents.go @@ -77,6 +77,8 @@ func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app return &event, err } +// GetPlanForModules returns all events for the given modules with the given course +// used for the ical feed func GetPlanForModules(app *pocketbase.PocketBase, modules []model.FeedCollection) model.Events { // build query functions with name equals elements in modules for dbx query diff --git a/backend/service/events/eventService.go b/backend/service/events/eventService.go index 2ae6a4c..48a9172 100644 --- a/backend/service/events/eventService.go +++ b/backend/service/events/eventService.go @@ -82,17 +82,6 @@ func DeleteAllEventsByCourseAndSemester(app *pocketbase.PocketBase, course strin // If the update was not successful, an error is returned func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) error { - var err error - err = DeleteAllEventsByCourseAndSemester(app, course, "ws") - if err != nil { - return err - } - - err = DeleteAllEventsByCourseAndSemester(app, course, "ss") - if err != nil { - return err - } - //new string array with one element (course) var courses []string courses = append(courses, course) @@ -108,11 +97,68 @@ func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) error { seminarGroups = fetch.ReplaceEmptyEventNames(seminarGroups) - _, dbError = db.SaveEvents(seminarGroups, collection, app) + //check if events in the seminarGroups Events are already in the database + //if yes, keep the database as it is + //if no, delete all events for the course and the semester and save the new events + //if there are no events in the database, save the new events - if dbError != nil { - return apis.NewNotFoundError("Events could not be saved", dbError) + //get all events for the course and the semester + events, err := db.GetAllModulesForCourse(app, course, "ws") + if err != nil { + return apis.NewNotFoundError("Events could not be found", err) + } + + //if there are no events in the database, save the new events + if len(events) == 0 { + _, dbError = db.SaveEvents(seminarGroups, collection, app) + if dbError != nil { + return apis.NewNotFoundError("Events could not be saved", dbError) + } + return nil + } + + //check if events in the seminarGroups Events are already in the database + //if yes, keep the database as it is + //if no, delete all events for the course and the semester and save the new events + for _, seminarGroup := range seminarGroups { + for _, event := range seminarGroup.Events { + // if the event is not in the database, delete all events for the course and the semester and save the new events + if !ContainsEvent(events, event) { + + err = DeleteAllEventsByCourseAndSemester(app, course, "ws") + if err != nil { + return err + } + + err = DeleteAllEventsByCourseAndSemester(app, course, "ss") + if err != nil { + return err + } + + //save the new events + _, dbError = db.SaveEvents(seminarGroups, collection, app) + if dbError != nil { + return apis.NewNotFoundError("Events could not be saved", dbError) + } + return nil + } + } } return nil } + +func ContainsEvent(events model.Events, event model.Event) bool { + for _, e := range events { + if e.Name == event.Name && + e.Prof == event.Prof && + e.Rooms == event.Rooms && + e.Semester == event.Semester && + e.Start == event.Start && + e.End == event.End && + e.Course == event.Course { + return true + } + } + return false +} diff --git a/backend/service/ical/ical.go b/backend/service/ical/ical.go index 17f66f5..a0ad8d4 100644 --- a/backend/service/ical/ical.go +++ b/backend/service/ical/ical.go @@ -9,7 +9,6 @@ import ( "github.com/pocketbase/pocketbase/apis" "htwkalender/model" "htwkalender/service/db" - "io" "net/http" "time" ) @@ -63,18 +62,12 @@ func writeSuccess(message string, w http.ResponseWriter) { } } -func CreateIndividualFeed(c echo.Context, app *pocketbase.PocketBase) error { - - // read json from request body +func CreateIndividualFeed(requestBody []byte, app *pocketbase.PocketBase) (string, error) { var modules []model.FeedCollection - requestBodyBytes, err := io.ReadAll(c.Request().Body) - if err != nil { - return apis.NewApiError(400, "Could not bind request body", err) - } - err = json.Unmarshal(requestBodyBytes, &modules) + err := json.Unmarshal(requestBody, &modules) if err != nil { - return apis.NewApiError(400, "Could not bind request body", err) + return "", apis.NewNotFoundError("Could not parse request body", err) } var feed model.Feed @@ -83,13 +76,13 @@ func CreateIndividualFeed(c echo.Context, app *pocketbase.PocketBase) error { collection, dbError := db.FindCollection(app, "feeds") if dbError != nil { - return apis.NewNotFoundError("Collection not found", dbError) + return "", apis.NewNotFoundError("Collection could not be found", dbError) } record, err := db.SaveFeed(feed, collection, app) if err != nil { - return apis.NewNotFoundError("Feed could not be saved", dbError) + return "", apis.NewNotFoundError("Could not save feed", err) } - return c.JSON(http.StatusOK, record.Id) + return record.Id, nil }