From 311a039edc8f91666c8d05acd94aabab20833ffe Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:26:24 +0300 Subject: feat: edit map image Former-commit-id: 288e6772dda69a9543a01db85069c95476addd4e --- backend/controllers/modController.go | 55 ++++++++++++++++++ backend/models/requests.go | 4 ++ backend/routes/routes.go | 1 + docs/docs.go | 104 ++++++++++++++++++++++++++++++++++- docs/swagger.json | 104 ++++++++++++++++++++++++++++++++++- docs/swagger.yaml | 63 ++++++++++++++++++++- 6 files changed, 328 insertions(+), 3 deletions(-) diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index ff79e3e..98fb165 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -264,3 +264,58 @@ func DeleteMapSummary(c *gin.Context) { Data: request, }) } + +// PUT Map Image +// +// @Description Edit map image with specified map id. +// @Tags maps +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param id path int true "Map ID" +// @Param request body models.EditMapImageRequest true "Body" +// @Success 200 {object} models.Response{data=models.EditMapImageRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/image [put] +func EditMapImage(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + var moderator bool + for _, title := range user.(models.User).Titles { + if title == "Moderator" { + moderator = true + } + } + if !moderator { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("Insufficient permissions.")) + return + } + // Bind parameter and body + id := c.Param("id") + mapID, err := strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + var request models.EditMapImageRequest + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Update database with new data + sql := `UPDATE maps SET image = $2 WHERE id = $1` + _, err = database.DB.Exec(sql, mapID, request.Image) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Return response + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully updated map image.", + Data: request, + }) +} diff --git a/backend/models/requests.go b/backend/models/requests.go index f275203..fac05b6 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -27,6 +27,10 @@ type DeleteMapSummaryRequest struct { RouteID int `json:"route_id" binding:"required"` } +type EditMapImageRequest struct { + Image string `json:"image" binding:"required"` +} + type RecordRequest struct { HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` diff --git a/backend/routes/routes.go b/backend/routes/routes.go index a39c8c4..1377d32 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -29,6 +29,7 @@ func InitRoutes(router *gin.Engine) { v1.POST("/maps/:id/summary", middleware.CheckAuth, controllers.CreateMapSummary) v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) v1.DELETE("/maps/:id/summary", middleware.CheckAuth, controllers.DeleteMapSummary) + v1.PUT("/maps/:id/image", middleware.CheckAuth, controllers.EditMapImage) v1.GET("/maps/:id/leaderboards", controllers.FetchMapLeaderboards) v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) v1.GET("/rankings", controllers.Rankings) diff --git a/docs/docs.go b/docs/docs.go index 57984f4..13d4cf6 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -229,6 +229,68 @@ const docTemplate = `{ } } }, + "/maps/{id}/image": { + "put": { + "description": "Edit map image with specified map id.", + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/maps/{id}/leaderboards": { "get": { "description": "Get map leaderboards with specified id.", @@ -344,7 +406,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.Response" + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RecordResponse" + } + } + } + ] } }, "400": { @@ -1047,6 +1121,17 @@ const docTemplate = `{ } } }, + "models.EditMapImageRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + } + } + }, "models.EditMapSummaryRequest": { "type": "object", "required": [ @@ -1084,6 +1169,9 @@ const docTemplate = `{ "id": { "type": "integer" }, + "is_coop": { + "type": "boolean" + }, "name": { "type": "string" } @@ -1112,6 +1200,9 @@ const docTemplate = `{ "image": { "type": "string" }, + "is_coop": { + "type": "boolean" + }, "map_name": { "type": "string" } @@ -1242,6 +1333,17 @@ const docTemplate = `{ } } }, + "models.RecordResponse": { + "type": "object", + "properties": { + "score_count": { + "type": "integer" + }, + "score_time": { + "type": "integer" + } + } + }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index ef422ab..f644288 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -222,6 +222,68 @@ } } }, + "/maps/{id}/image": { + "put": { + "description": "Edit map image with specified map id.", + "produces": [ + "application/json" + ], + "tags": [ + "maps" + ], + "parameters": [ + { + "type": "string", + "description": "JWT Token", + "name": "Authorization", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Map ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.EditMapImageRequest" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/maps/{id}/leaderboards": { "get": { "description": "Get map leaderboards with specified id.", @@ -337,7 +399,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/models.Response" + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RecordResponse" + } + } + } + ] } }, "400": { @@ -1040,6 +1114,17 @@ } } }, + "models.EditMapImageRequest": { + "type": "object", + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string" + } + } + }, "models.EditMapSummaryRequest": { "type": "object", "required": [ @@ -1077,6 +1162,9 @@ "id": { "type": "integer" }, + "is_coop": { + "type": "boolean" + }, "name": { "type": "string" } @@ -1105,6 +1193,9 @@ "image": { "type": "string" }, + "is_coop": { + "type": "boolean" + }, "map_name": { "type": "string" } @@ -1235,6 +1326,17 @@ } } }, + "models.RecordResponse": { + "type": "object", + "properties": { + "score_count": { + "type": "integer" + }, + "score_time": { + "type": "integer" + } + } + }, "models.Response": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 2fed413..3b706ea 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -61,6 +61,13 @@ definitions: required: - route_id type: object + models.EditMapImageRequest: + properties: + image: + type: string + required: + - image + type: object models.EditMapSummaryRequest: properties: description: @@ -87,6 +94,8 @@ definitions: properties: id: type: integer + is_coop: + type: boolean name: type: string type: object @@ -105,6 +114,8 @@ definitions: type: integer image: type: string + is_coop: + type: boolean map_name: type: string type: object @@ -189,6 +200,13 @@ definitions: $ref: '#/definitions/models.UserRanking' type: array type: object + models.RecordResponse: + properties: + score_count: + type: integer + score_time: + type: integer + type: object models.Response: properties: data: {} @@ -364,6 +382,44 @@ paths: $ref: '#/definitions/models.Response' tags: - login + /maps/{id}/image: + put: + description: Edit map image with specified map id. + parameters: + - description: JWT Token + in: header + name: Authorization + required: true + type: string + - description: Map ID + in: path + name: id + required: true + type: integer + - description: Body + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.EditMapImageRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.EditMapImageRequest' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Response' + tags: + - maps /maps/{id}/leaderboards: get: description: Get map leaderboards with specified id. @@ -435,7 +491,12 @@ paths: "200": description: OK schema: - $ref: '#/definitions/models.Response' + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.RecordResponse' + type: object "400": description: Bad Request schema: -- cgit v1.2.3