//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 . package service import ( "htwkalender/data-manager/model/serviceModel" "htwkalender/data-manager/service/course" "htwkalender/data-manager/service/fetch/sport" v1 "htwkalender/data-manager/service/fetch/v1" v2 "htwkalender/data-manager/service/fetch/v2" "htwkalender/data-manager/service/functions/time" "htwkalender/data-manager/service/room" "log/slog" "net/http" "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" ) func AddRoutes(services serviceModel.Service) { services.App.OnServe().BindFunc(func(se *core.ServeEvent) error { se.Router.GET("/api/fetch/events", func(e *core.RequestEvent) error { savedEvents, err := v2.ParseEventsFromRemote(services.App) if err != nil { slog.Error("Failed to parse events from remote: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to parse events from remote") } else { return e.JSON(http.StatusOK, savedEvents) } }).Bind(apis.RequireSuperuserAuth()) se.Router.GET("/api/fetch/daily/events", func(e *core.RequestEvent) error { clock := time.RealClock{} course.UpdateCourse(services, clock) return e.JSON(http.StatusOK, "Daily events fetched") }).Bind(apis.RequireSuperuserAuth()) se.Router.GET("/api/fetch/group", func(e *core.RequestEvent) error { seminarGroupString := e.Request.URL.Query().Get("seminarGroup") if seminarGroupString == "" { return e.JSON(http.StatusBadRequest, "Seminar group could not be empty") } else { //find seminar group by name seminarGroup, err := services.CourseService.FindCourseByCourseName(seminarGroupString) if err != nil { return e.JSON(http.StatusBadRequest, "Failed to find seminar group") } events, err := services.EventService.UpdateModulesForCourse(seminarGroup) if err != nil { return e.JSON(http.StatusBadRequest, "Failed to fetch seminar group") } return e.JSON(http.StatusOK, events) } }).Bind(apis.RequireSuperuserAuth()) se.Router.GET("/api/fetch/groups", func(e *core.RequestEvent) error { groups, err := v1.FetchSeminarGroups(services.App) if err != nil { slog.Error("Failed to fetch seminar groups: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to fetch seminar groups") } else { return e.JSON(http.StatusOK, groups) } }).Bind(apis.RequireSuperuserAuth()) se.Router.GET("/api/fetch/sports", func(e *core.RequestEvent) error { sportEvents, err := sport.FetchAndUpdateSportEvents(services.App) if err != nil { slog.Error("Failed to fetch sport events: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to fetch sport events") } else { return e.JSON(http.StatusOK, sportEvents) } }).Bind(apis.RequireSuperuserAuth()) se.Router.DELETE("/api/modules", func(e *core.RequestEvent) error { err := services.EventService.DeleteAllEvents() if err != nil { return e.JSON(http.StatusBadRequest, "Failed to delete events") } return e.JSON(http.StatusOK, "Events deleted") }).Bind(apis.RequireSuperuserAuth()) se.Router.GET("/api/rooms", func(e *core.RequestEvent) error { rooms, err := room.GetRooms(services.App) if err != nil { return e.JSON(http.StatusBadRequest, "Failed to get rooms") } return e.JSON(http.StatusOK, rooms) }) se.Router.GET("/api/schedule/day", func(e *core.RequestEvent) error { roomParam := e.Request.URL.Query().Get("room") date := e.Request.URL.Query().Get("date") roomSchedule, err := room.GetRoomScheduleForDay(services.App, roomParam, date) if err != nil { slog.Error("Failed to get room schedule for day: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get room schedule for day") } return e.JSON(http.StatusOK, roomSchedule) }) se.Router.GET("/api/schedule", func(e *core.RequestEvent) error { roomParam := e.Request.URL.Query().Get("room") to := e.Request.URL.Query().Get("to") from := e.Request.URL.Query().Get("from") mapped := e.Request.URL.Query().Get("mapped") roomSchedule, err := room.GetRoomSchedule(services.App, roomParam, from, to, mapped) if err != nil { slog.Error("Failed to get room schedule: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get room schedule") } return e.JSON(http.StatusOK, roomSchedule) }) se.Router.GET("/api/rooms/free", func(e *core.RequestEvent) error { from, err := time.ParseTime(e.Request.URL.Query().Get("from")) if err != nil { slog.Error("Failed to parse time: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to parse time") } to, err := time.ParseTime(e.Request.URL.Query().Get("to")) if err != nil { slog.Error("Failed to parse time: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to parse time") } rooms, err := room.GetFreeRooms(services.App, from, to) if err != nil { slog.Error("Failed to get free rooms: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get free rooms") } return e.JSON(http.StatusOK, rooms) }) se.Router.GET("/api/course/modules", func(e *core.RequestEvent) error { modules, err := services.EventService.GetModulesForCourseDistinct( e.Request.URL.Query().Get("course"), e.Request.URL.Query().Get("semester"), ) if err != nil { slog.Error("Failed to get modules for course and semester: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get modules for course and semester") } return e.JSON(http.StatusOK, modules) }) se.Router.GET("/api/modules", func(e *core.RequestEvent) error { modules, err := services.EventService.GetAllModulesDistinct() if err != nil { slog.Error("Failed to get modules: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get modules") } return e.JSON(http.StatusOK, modules) }) se.Router.GET("/api/module", func(e *core.RequestEvent) error { requestModule := e.Request.URL.Query().Get("uuid") module, err := services.EventService.GetModuleByUUID(requestModule) if err != nil { slog.Error("Failed to get module: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get module") } return e.JSON(http.StatusOK, module) }) se.Router.GET("/api/courses", func(e *core.RequestEvent) error { semester := e.Request.URL.Query().Get("semester") if semester == "" { courses := services.CourseService.GetAllCourses() return e.JSON(200, courses) } else { seminarGroups := services.CourseService.GetAllCoursesForSemester(semester) courseStringList := make([]string, 0) for _, seminarGroup := range seminarGroups { courseStringList = append(courseStringList, seminarGroup.Course) } return e.JSON(200, courseStringList) } }) se.Router.GET("/api/courses/events", func(e *core.RequestEvent) error { semester := e.Request.URL.Query().Get("semester") courses, err := services.CourseService.GetAllCoursesForSemesterWithEvents(semester) if err != nil { slog.Error("Failed to get courses for semester with events: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get courses for semester with events") } else { return e.JSON(http.StatusOK, courses) } }) se.Router.GET("/api/events/types", func(e *core.RequestEvent) error { eventTypes, err := services.EventService.GetEventTypes() if err != nil { slog.Error("Failed to get event types", "error", err) return e.JSON(http.StatusBadRequest, "Failed to get event types") } else { return e.JSON(http.StatusOK, eventTypes) } }) se.Router.DELETE("/api/events", func(e *core.RequestEvent) error { err := services.EventService.DeleteAllEventsByCourseAndSemester( e.Request.URL.Query().Get("course"), e.Request.URL.Query().Get("semester"), ) if err != nil { slog.Error("Failed to delete events: ", "error", err) return e.JSON(http.StatusBadRequest, "Failed to delete events") } else { return e.JSON(http.StatusOK, "Events deleted") } }).Bind(apis.RequireSuperuserAuth()) addFeedRoutes(se, services.App) return se.Next() }) }