From 6759237eda5b7ddfe9284c81900cc9deed1f6bf9 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 23 Oct 2018 04:57:42 +0200 Subject: User action heatmap (#5131) * Added basic heatmap data * Added extra case for sqlite * Built basic heatmap into user profile * Get contribution data from api & styling * Fixed lint & added extra group by statements for all database types * generated swagger spec * generated swagger spec * generated swagger spec * fixed swagger spec * fmt * Added tests * Added setting to enable/disable user heatmap * Added locale for loading text * Removed UseTiDB * Updated librejs & moment.js * Fixed import order * Fixed heatmap in postgresql * Update docs/content/doc/advanced/config-cheat-sheet.en-us.md Co-Authored-By: kolaente * Added copyright header * Fixed a bug to show the heatmap for the actual user instead of the currently logged in * Added integration test for heatmaps * Added a heatmap on the dashboard * Fixed timestamp parsing * Hide heatmap on mobile * optimized postgresql group by query * Improved sqlite group by statement --- routers/api/v1/api.go | 8 ++++++++ routers/api/v1/swagger/user.go | 8 ++++++++ routers/api/v1/user/user.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) (limited to 'routers/api/v1') diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 3a539f6ce7..b12cb1374a 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -324,6 +324,13 @@ func mustEnableIssuesOrPulls(ctx *context.Context) { } } +func mustEnableUserHeatmap(ctx *context.Context) { + if !setting.Service.EnableUserHeatmap { + ctx.Status(404) + return + } +} + // RegisterRoutes registers all v1 APIs routes to web application. // FIXME: custom form error response func RegisterRoutes(m *macaron.Macaron) { @@ -348,6 +355,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/:username", func() { m.Get("", user.GetInfo) + m.Get("/heatmap", mustEnableUserHeatmap, user.GetUserHeatmapData) m.Get("/repos", user.ListUserRepos) m.Group("/tokens", func() { diff --git a/routers/api/v1/swagger/user.go b/routers/api/v1/swagger/user.go index 7ae046a9b0..caaf7df705 100644 --- a/routers/api/v1/swagger/user.go +++ b/routers/api/v1/swagger/user.go @@ -5,6 +5,7 @@ package swagger import ( + "code.gitea.io/gitea/models" api "code.gitea.io/sdk/gitea" ) @@ -34,3 +35,10 @@ type swaggerModelEditUserOption struct { // in:body Options api.EditUserOption } + +// UserHeatmapData +// swagger:response UserHeatmapData +type swaggerResponseUserHeatmapData struct { + // in:body + Body []models.UserHeatmapData `json:"body"` +} diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index 51d69aa2c3..f76b443661 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -5,6 +5,7 @@ package user import ( + "net/http" "strings" "code.gitea.io/gitea/models" @@ -133,3 +134,41 @@ func GetAuthenticatedUser(ctx *context.APIContext) { // "$ref": "#/responses/User" ctx.JSON(200, ctx.User.APIFormat()) } + +// GetUserHeatmapData is the handler to get a users heatmap +func GetUserHeatmapData(ctx *context.APIContext) { + // swagger:operation GET /users/{username}/heatmap user userGetHeatmapData + // --- + // summary: Get a user's heatmap + // produces: + // - application/json + // parameters: + // - name: username + // in: path + // description: username of user to get + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/UserHeatmapData" + // "404": + // "$ref": "#/responses/notFound" + + // Get the user to throw an error if it does not exist + user, err := models.GetUserByName(ctx.Params(":username")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.Status(http.StatusNotFound) + } else { + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + } + return + } + + heatmap, err := models.GetUserHeatmapDataByUser(user) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err) + return + } + ctx.JSON(200, heatmap) +} -- cgit v1.2.3