Federation: return useful statistic information for nodeinfo (#19561)

Add statistic information for total user count, active user count, issue count and comment count for `/nodeinfo`
This commit is contained in:
6543 2022-05-02 15:35:45 +02:00 committed by GitHub
parent 509d811243
commit e2a3f3d259
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 78 additions and 16 deletions

View file

@ -6,12 +6,17 @@ package misc
import (
"net/http"
"time"
"code.gitea.io/gitea/models"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
)
const cacheKeyNodeInfoUsage = "API_NodeInfoUsage"
// NodeInfo returns the NodeInfo for the Gitea instance to allow for federation
func NodeInfo(ctx *context.APIContext) {
// swagger:operation GET /nodeinfo miscellaneous getNodeInfo
@ -23,6 +28,37 @@ func NodeInfo(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/NodeInfo"
nodeInfoUsage := structs.NodeInfoUsage{}
if setting.Federation.ShareUserStatistics {
info, ok := ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage)
if !ok {
usersTotal := int(user_model.CountUsers(nil))
now := time.Now()
timeOneMonthAgo := now.AddDate(0, -1, 0).Unix()
timeHaveYearAgo := now.AddDate(0, -6, 0).Unix()
usersActiveMonth := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo}))
usersActiveHalfyear := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo}))
allIssues, _ := models.CountIssues(&models.IssuesOptions{})
allComments, _ := models.CountComments(&models.FindCommentsOptions{})
info = structs.NodeInfoUsage{
Users: structs.NodeInfoUsageUsers{
Total: usersTotal,
ActiveMonth: usersActiveMonth,
ActiveHalfyear: usersActiveHalfyear,
},
LocalPosts: int(allIssues),
LocalComments: int(allComments),
}
if err := ctx.Cache.Put(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil {
ctx.InternalServerError(err)
return
}
}
nodeInfoUsage = info
}
nodeInfo := &structs.NodeInfo{
Version: "2.1",
Software: structs.NodeInfoSoftware{
@ -34,12 +70,10 @@ func NodeInfo(ctx *context.APIContext) {
Protocols: []string{"activitypub"},
Services: structs.NodeInfoServices{
Inbound: []string{},
Outbound: []string{},
Outbound: []string{"rss2.0"},
},
OpenRegistrations: setting.Service.ShowRegistrationButton,
Usage: structs.NodeInfoUsage{
Users: structs.NodeInfoUsageUsers{},
},
Usage: nodeInfoUsage,
}
ctx.JSON(http.StatusOK, nodeInfo)
}

View file

@ -600,7 +600,7 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{
// sends a confirmation email if required.
func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) {
// Auto-set admin for the only user.
if user_model.CountUsers() == 1 {
if user_model.CountUsers(nil) == 1 {
u.IsAdmin = true
u.IsActive = true
u.SetLastLogin()