|
|
@ -6,12 +6,17 @@ package misc |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"net/http" |
|
|
|
"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/context" |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"code.gitea.io/gitea/modules/structs" |
|
|
|
"code.gitea.io/gitea/modules/structs" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const cacheKeyNodeInfoUsage = "API_NodeInfoUsage" |
|
|
|
|
|
|
|
|
|
|
|
// NodeInfo returns the NodeInfo for the Gitea instance to allow for federation
|
|
|
|
// NodeInfo returns the NodeInfo for the Gitea instance to allow for federation
|
|
|
|
func NodeInfo(ctx *context.APIContext) { |
|
|
|
func NodeInfo(ctx *context.APIContext) { |
|
|
|
// swagger:operation GET /nodeinfo miscellaneous getNodeInfo
|
|
|
|
// swagger:operation GET /nodeinfo miscellaneous getNodeInfo
|
|
|
@ -23,6 +28,37 @@ func NodeInfo(ctx *context.APIContext) { |
|
|
|
// "200":
|
|
|
|
// "200":
|
|
|
|
// "$ref": "#/responses/NodeInfo"
|
|
|
|
// "$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{ |
|
|
|
nodeInfo := &structs.NodeInfo{ |
|
|
|
Version: "2.1", |
|
|
|
Version: "2.1", |
|
|
|
Software: structs.NodeInfoSoftware{ |
|
|
|
Software: structs.NodeInfoSoftware{ |
|
|
@ -34,12 +70,10 @@ func NodeInfo(ctx *context.APIContext) { |
|
|
|
Protocols: []string{"activitypub"}, |
|
|
|
Protocols: []string{"activitypub"}, |
|
|
|
Services: structs.NodeInfoServices{ |
|
|
|
Services: structs.NodeInfoServices{ |
|
|
|
Inbound: []string{}, |
|
|
|
Inbound: []string{}, |
|
|
|
Outbound: []string{}, |
|
|
|
Outbound: []string{"rss2.0"}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
OpenRegistrations: setting.Service.ShowRegistrationButton, |
|
|
|
OpenRegistrations: setting.Service.ShowRegistrationButton, |
|
|
|
Usage: structs.NodeInfoUsage{ |
|
|
|
Usage: nodeInfoUsage, |
|
|
|
Users: structs.NodeInfoUsageUsers{}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
ctx.JSON(http.StatusOK, nodeInfo) |
|
|
|
ctx.JSON(http.StatusOK, nodeInfo) |
|
|
|
} |
|
|
|
} |
|
|
|