From eda4d09ac19f4fcf8aba2a8e1722ccaad5123afa Mon Sep 17 00:00:00 2001 From: ruba Date: Mon, 27 Apr 2026 10:59:59 -0500 Subject: [PATCH] feat: add Mazevo event routes for building- and room-specific querying --- api/controllers/mazevo.go | 104 +++++++++++++++++++++++++++++++++++++ api/controllers/section.go | 2 +- api/docs/docs.go | 103 ++++++++++++++++++++++++++++++++++++ api/docs/swagger.yaml | 73 ++++++++++++++++++++++++++ api/routes/mazevo.go | 2 + api/schema/objects.go | 2 +- 6 files changed, 284 insertions(+), 2 deletions(-) diff --git a/api/controllers/mazevo.go b/api/controllers/mazevo.go index 5372c172..0c97527a 100644 --- a/api/controllers/mazevo.go +++ b/api/controllers/mazevo.go @@ -47,3 +47,107 @@ func MazevoEvents(c *gin.Context) { respond(c, http.StatusOK, "success", mazevoEvents) } + +// @Id mazevoEventsByBuilding +// @Router /mazevo/{date}/{building} [get] +// @Tags Events +// @Description "Returns all sections with MazevoEvent meetings on the specified date in the specified building" +// @Produce json +// @Param date path string true "date (ISO format) to retrieve mazevo events" +// @Param building path string true "building abbreviation of the event location" +// @Success 200 {object} schema.APIResponse[schema.MultiBuildingEvents[schema.MazevoEvent]] "All MazevoEvents sections with meetings on the specified date in the specified building" +// @Failure 500 {object} schema.APIResponse[string] "A string describing the error" +// @Failure 404 {object} schema.APIResponse[string] "A string describing the error" +func MazevoEventsByBuilding(c *gin.Context) { + ctx, cancel := context.WithTimeout(c.Request.Context(), 10*time.Second) + defer cancel() + + date := c.Param("date") + building := c.Param("building") + + var mazevoEvents schema.MultiBuildingEvents[schema.MazevoEvent] + var mazevoEventsByBuilding schema.SingleBuildingEvents[schema.MazevoEvent] + + // find and parse matching date + err := mazevoCollection.FindOne(ctx, bson.M{"date": date}).Decode(&mazevoEvents) + if err != nil { + if errors.Is(err, mongo.ErrNoDocuments) { + mazevoEvents.Date = date + mazevoEvents.Buildings = []schema.SingleBuildingEvents[schema.MazevoEvent]{} + } else { + respondWithInternalError(c, err) + return + } + } + + // filter by the specified building + for _, b := range mazevoEvents.Buildings { + if b.Building == building { + mazevoEventsByBuilding = b + break + } + } + + // if no building found return an error + if mazevoEventsByBuilding.Building == "" { + respond(c, http.StatusNotFound, "error", "No events found for the specified building") + return + } + + respond(c, http.StatusOK, "success", mazevoEventsByBuilding) +} + +// @Id mazevoEventsByRoom +// @Router /mazevo/{date}/{building}/{room} [get] +// @Tags Events +// @Description "Returns all sections with MazevoEvent meetings on the specified date in the specified building and room" +// @Produce json +// @Param date path string true "date (ISO format) to retrieve mazevo events" +// @Param building path string true "building abbreviation of the event location" +// @Param room path string true "room number" +// @Success 200 {object} schema.APIResponse[schema.MultiBuildingEvents[schema.MazevoEvent]] "All MazevoEvents sections with meetings on the specified date in the specified building" +// @Failure 500 {object} schema.APIResponse[string] "A string describing the error" +// @Failure 404 {object} schema.APIResponse[string] +func MazevoEventsByRoom(c *gin.Context) { + ctx, cancel := context.WithTimeout(c.Request.Context(), 10*time.Second) + defer cancel() + + date := c.Param("date") + building := c.Param("building") + room := c.Param("room") + + var mazevoEvents schema.MultiBuildingEvents[schema.MazevoEvent] + var mazevoEventsByRoom schema.RoomEvents[schema.MazevoEvent] + + // find and parse matching date + err := mazevoCollection.FindOne(ctx, bson.M{"date": date}).Decode(&mazevoEvents) + if err != nil { + if errors.Is(err, mongo.ErrNoDocuments) { + mazevoEvents.Date = date + mazevoEvents.Buildings = []schema.SingleBuildingEvents[schema.MazevoEvent]{} + } else { + respondWithInternalError(c, err) + return + } + } + + // filter for the specified building and room + for _, b := range mazevoEvents.Buildings { + if b.Building == building { + for _, r := range b.Rooms { + if r.Room == room { + mazevoEventsByRoom = r + break + } + } + break + } + } + + if mazevoEventsByRoom.Room == "" { + respond(c, http.StatusNotFound, "error", "No events found for that specific building and room") + return + } + + respond(c, http.StatusOK, "success", mazevoEventsByRoom) +} diff --git a/api/controllers/section.go b/api/controllers/section.go index 58fcbd2d..c89323c3 100644 --- a/api/controllers/section.go +++ b/api/controllers/section.go @@ -355,4 +355,4 @@ func buildSectionPipeline(endpoint string, sectionQuery bson.M, paginate map[str } return append(append(append(baseStages, lookupStages...), replaceStages...), paginateStages...) -} \ No newline at end of file +} diff --git a/api/docs/docs.go b/api/docs/docs.go index 10311e52..caddc364 100644 --- a/api/docs/docs.go +++ b/api/docs/docs.go @@ -1563,6 +1563,109 @@ const docTemplate = `{ } } }, + "/mazevo/{date}/{building}": { + "get": { + "description": "\"Returns all sections with MazevoEvent meetings on the specified date in the specified building\"", + "produces": [ + "application/json" + ], + "tags": [ + "Events" + ], + "operationId": "mazevoEventsByBuilding", + "parameters": [ + { + "type": "string", + "description": "date (ISO format) to retrieve mazevo events", + "name": "date", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "building abbreviation of the event location", + "name": "building", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "All MazevoEvents sections with meetings on the specified date in the specified building", + "schema": { + "$ref": "#/definitions/schema.APIResponse-schema_MultiBuildingEvents-schema_MazevoEvent" + } + }, + "404": { + "description": "A string describing the error", + "schema": { + "$ref": "#/definitions/schema.APIResponse-string" + } + }, + "500": { + "description": "A string describing the error", + "schema": { + "$ref": "#/definitions/schema.APIResponse-string" + } + } + } + } + }, + "/mazevo/{date}/{building}/{room}": { + "get": { + "description": "\"Returns all sections with MazevoEvent meetings on the specified date in the specified building and room\"", + "produces": [ + "application/json" + ], + "tags": [ + "Events" + ], + "operationId": "mazevoEventsByRoom", + "parameters": [ + { + "type": "string", + "description": "date (ISO format) to retrieve mazevo events", + "name": "date", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "building abbreviation of the event location", + "name": "building", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "room number", + "name": "room", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "All MazevoEvents sections with meetings on the specified date in the specified building", + "schema": { + "$ref": "#/definitions/schema.APIResponse-schema_MultiBuildingEvents-schema_MazevoEvent" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/schema.APIResponse-string" + } + }, + "500": { + "description": "A string describing the error", + "schema": { + "$ref": "#/definitions/schema.APIResponse-string" + } + } + } + } + }, "/professor": { "get": { "description": "\"Returns paginated list of professors matching the query's string-typed key-value pairs. See offset for more details on pagination.\"", diff --git a/api/docs/swagger.yaml b/api/docs/swagger.yaml index 26d21c22..79586121 100644 --- a/api/docs/swagger.yaml +++ b/api/docs/swagger.yaml @@ -2034,6 +2034,79 @@ paths: $ref: '#/definitions/schema.APIResponse-string' tags: - Events + /mazevo/{date}/{building}: + get: + description: '"Returns all sections with MazevoEvent meetings on the specified + date in the specified building"' + operationId: mazevoEventsByBuilding + parameters: + - description: date (ISO format) to retrieve mazevo events + in: path + name: date + required: true + type: string + - description: building abbreviation of the event location + in: path + name: building + required: true + type: string + produces: + - application/json + responses: + "200": + description: All MazevoEvents sections with meetings on the specified date + in the specified building + schema: + $ref: '#/definitions/schema.APIResponse-schema_MultiBuildingEvents-schema_MazevoEvent' + "404": + description: A string describing the error + schema: + $ref: '#/definitions/schema.APIResponse-string' + "500": + description: A string describing the error + schema: + $ref: '#/definitions/schema.APIResponse-string' + tags: + - Events + /mazevo/{date}/{building}/{room}: + get: + description: '"Returns all sections with MazevoEvent meetings on the specified + date in the specified building and room"' + operationId: mazevoEventsByRoom + parameters: + - description: date (ISO format) to retrieve mazevo events + in: path + name: date + required: true + type: string + - description: building abbreviation of the event location + in: path + name: building + required: true + type: string + - description: room number + in: path + name: room + required: true + type: string + produces: + - application/json + responses: + "200": + description: All MazevoEvents sections with meetings on the specified date + in the specified building + schema: + $ref: '#/definitions/schema.APIResponse-schema_MultiBuildingEvents-schema_MazevoEvent' + "404": + description: Not Found + schema: + $ref: '#/definitions/schema.APIResponse-string' + "500": + description: A string describing the error + schema: + $ref: '#/definitions/schema.APIResponse-string' + tags: + - Events /professor: get: description: '"Returns paginated list of professors matching the query''s string-typed diff --git a/api/routes/mazevo.go b/api/routes/mazevo.go index ef401481..3fe61ac9 100644 --- a/api/routes/mazevo.go +++ b/api/routes/mazevo.go @@ -11,4 +11,6 @@ func MazevoRoute(router *gin.Engine) { mazevoGroup.OPTIONS("", controllers.Preflight) mazevoGroup.GET(":date", controllers.MazevoEvents) + mazevoGroup.GET(":date/:building", controllers.MazevoEventsByBuilding) + mazevoGroup.GET(":date/:building/:room", controllers.MazevoEventsByRoom) } diff --git a/api/schema/objects.go b/api/schema/objects.go index 21f2191d..8e79592a 100644 --- a/api/schema/objects.go +++ b/api/schema/objects.go @@ -328,7 +328,7 @@ type AcademicCalendar struct { MidtermsDue string `bson:"midterms_due" json:"midterms_due"` UniversityClosings [][]string `bson:"university_closings" json:"university_closings"` NoClasses [][]string `bson:"no_classes" json:"no_classes"` - URL string `bson:"url" json:"url"` + URL string `bson:"url" json:"url"` } type AcademicCalendarSession struct { Name string `bson:"name" json:"name"`