Some checks failed
DevStar Studio Auto Test Pipeline / unit-frontend-test (pull_request) Failing after 41s
DevStar Studio Auto Test Pipeline / unit-backend-test (pull_request) Failing after 32s
DevStar Studio CI/CD Pipeline / build-and-push-x86-64-docker-image (pull_request) Failing after 37s
DevStar E2E Test / e2e-test (pull_request) Has been cancelled
237 lines
7.3 KiB
Go
237 lines
7.3 KiB
Go
// Copyright 2024 The DevStar Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.gitea.io/gitea/models/db"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
devcontainer_model "code.gitea.io/gitea/models/devcontainer"
|
|
"code.gitea.io/gitea/modules/log"
|
|
)
|
|
|
|
// UserStats represents the user's data statistics
|
|
type UserStats struct {
|
|
UserID int64 `json:"user_id"`
|
|
|
|
// Repository statistics
|
|
TotalRepositories int `json:"total_repositories"`
|
|
PublicRepositories int `json:"public_repositories"`
|
|
PrivateRepositories int `json:"private_repositories"`
|
|
|
|
// Storage statistics
|
|
TotalStorage int64 `json:"total_storage"`
|
|
GitStorage int64 `json:"git_storage"`
|
|
LFSStorage int64 `json:"lfs_storage"`
|
|
AssetsStorage int64 `json:"assets_storage"`
|
|
|
|
// DevContainer statistics
|
|
TotalDevContainers int `json:"total_devcontainers"`
|
|
ActiveDevContainers int `json:"active_devcontainers"`
|
|
|
|
// Activity statistics
|
|
TotalCommits int `json:"total_commits"`
|
|
TotalIssues int `json:"total_issues"`
|
|
PullRequests int `json:"pull_requests"`
|
|
ClosedIssues int `json:"closed_issues"`
|
|
MergedPullRequests int `json:"merged_pull_requests"`
|
|
}
|
|
|
|
// GetUserStatistics calculates and returns comprehensive statistics for a user
|
|
func GetUserStatistics(ctx context.Context, userID int64) (*UserStats, error) {
|
|
stats := &UserStats{
|
|
UserID: userID,
|
|
}
|
|
|
|
// Get repository statistics
|
|
if err := getRepoStats(ctx, userID, stats); err != nil {
|
|
log.Error("Failed to get repository statistics for user %d: %v", userID, err)
|
|
return nil, err
|
|
}
|
|
|
|
// Get devcontainer statistics
|
|
if err := getDevContainerStats(ctx, userID, stats); err != nil {
|
|
log.Error("Failed to get devcontainer statistics for user %d: %v", userID, err)
|
|
return nil, err
|
|
}
|
|
|
|
// Get activity statistics (commits, issues, PRs)
|
|
if err := getActivityStats(ctx, userID, stats); err != nil {
|
|
log.Error("Failed to get activity statistics for user %d: %v", userID, err)
|
|
return nil, err
|
|
}
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
// getRepoStats calculates repository-related statistics
|
|
func getRepoStats(ctx context.Context, userID int64, stats *UserStats) error {
|
|
// Count total repositories for the user
|
|
count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{
|
|
OwnerID: userID,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stats.TotalRepositories = int(count)
|
|
|
|
// Get all repositories to calculate storage and visibility breakdown
|
|
repos, _, err := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
|
|
ListOptions: db.ListOptions{
|
|
PageSize: 1000, // Get all repos
|
|
},
|
|
Actor: &user_model.User{ID: userID},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var totalSize, gitSize, lfsSize int64
|
|
publicCount, privateCount := 0, 0
|
|
|
|
for _, repo := range repos {
|
|
// Count by visibility
|
|
if repo.IsPrivate {
|
|
privateCount++
|
|
} else {
|
|
publicCount++
|
|
}
|
|
|
|
// Sum storage sizes
|
|
totalSize += repo.Size
|
|
gitSize += repo.GitSize
|
|
lfsSize += repo.LFSSize
|
|
}
|
|
|
|
stats.PublicRepositories = publicCount
|
|
stats.PrivateRepositories = privateCount
|
|
stats.TotalStorage = totalSize
|
|
stats.GitStorage = gitSize
|
|
stats.LFSStorage = lfsSize
|
|
// Assets storage would need additional calculation from attachments, releases, etc.
|
|
stats.AssetsStorage = 0 // TODO: Implement assets storage calculation
|
|
|
|
return nil
|
|
}
|
|
|
|
// getDevContainerStats calculates devcontainer-related statistics
|
|
func getDevContainerStats(ctx context.Context, userID int64, stats *UserStats) error {
|
|
// Count total devcontainers for the user
|
|
count, err := db.GetEngine(ctx).
|
|
Where("user_id = ?", userID).
|
|
Count(&devcontainer_model.Devcontainer{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stats.TotalDevContainers = int(count)
|
|
|
|
// Count active devcontainers (assuming status 1 means active)
|
|
activeCount, err := db.GetEngine(ctx).
|
|
Where("user_id = ? AND devcontainer_status = ?", userID, 1).
|
|
Count(&devcontainer_model.Devcontainer{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stats.ActiveDevContainers = int(activeCount)
|
|
|
|
return nil
|
|
}
|
|
|
|
// getActivityStats calculates activity-related statistics (commits, issues, PRs)
|
|
func getActivityStats(ctx context.Context, userID int64, stats *UserStats) error {
|
|
// Get user's commits count across all their repositories
|
|
// This is a simplified version - in reality you'd need to query git logs
|
|
commitCount, err := getUserCommitCount(ctx, userID)
|
|
if err != nil {
|
|
log.Warn("Failed to get commit count for user %d: %v", userID, err)
|
|
commitCount = 0 // Continue without commit stats
|
|
}
|
|
stats.TotalCommits = commitCount
|
|
|
|
// Count issues created by user
|
|
issueCount, err := getUserIssueCount(ctx, userID)
|
|
if err != nil {
|
|
log.Warn("Failed to get issue count for user %d: %v", userID, err)
|
|
issueCount = 0
|
|
}
|
|
stats.TotalIssues = issueCount
|
|
|
|
// Count pull requests created by user
|
|
prCount, err := getUserPullRequestCount(ctx, userID)
|
|
if err != nil {
|
|
log.Warn("Failed to get PR count for user %d: %v", userID, err)
|
|
prCount = 0
|
|
}
|
|
stats.PullRequests = prCount
|
|
|
|
// Count closed issues and merged PRs
|
|
closedIssues, err := getUserClosedIssueCount(ctx, userID)
|
|
if err != nil {
|
|
log.Warn("Failed to get closed issue count for user %d: %v", userID, err)
|
|
closedIssues = 0
|
|
}
|
|
stats.ClosedIssues = closedIssues
|
|
|
|
mergedPRs, err := getUserMergedPullRequestCount(ctx, userID)
|
|
if err != nil {
|
|
log.Warn("Failed to get merged PR count for user %d: %v", userID, err)
|
|
mergedPRs = 0
|
|
}
|
|
stats.MergedPullRequests = mergedPRs
|
|
|
|
return nil
|
|
}
|
|
|
|
// getUserCommitCount gets the total number of commits made by the user
|
|
func getUserCommitCount(ctx context.Context, userID int64) (int, error) {
|
|
// This is a placeholder implementation
|
|
// In a real implementation, you would:
|
|
// 1. Get all repositories owned by the user
|
|
// 2. For each repository, query git log for commits by this user's email
|
|
// 3. Sum up all commits
|
|
|
|
user, err := user_model.GetUserByID(ctx, userID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
// For now, return 0 as this would require git log parsing
|
|
// TODO: Implement actual commit counting
|
|
log.Info("Commit counting not yet implemented for user %s (%s)", user.Name, user.Email)
|
|
return 0, nil
|
|
}
|
|
|
|
// getUserIssueCount gets the total number of issues created by the user
|
|
func getUserIssueCount(ctx context.Context, userID int64) (int, error) {
|
|
// This would query the issues table
|
|
// For now, return a placeholder value
|
|
// TODO: Implement actual issue counting
|
|
return 0, nil
|
|
}
|
|
|
|
// getUserPullRequestCount gets the total number of pull requests created by the user
|
|
func getUserPullRequestCount(ctx context.Context, userID int64) (int, error) {
|
|
// This would query the pull_requests table
|
|
// For now, return a placeholder value
|
|
// TODO: Implement actual PR counting
|
|
return 0, nil
|
|
}
|
|
|
|
// getUserClosedIssueCount gets the number of closed issues created by the user
|
|
func getUserClosedIssueCount(ctx context.Context, userID int64) (int, error) {
|
|
// This would query the issues table for closed issues
|
|
// For now, return a placeholder value
|
|
// TODO: Implement actual closed issue counting
|
|
return 0, nil
|
|
}
|
|
|
|
// getUserMergedPullRequestCount gets the number of merged pull requests created by the user
|
|
func getUserMergedPullRequestCount(ctx context.Context, userID int64) (int, error) {
|
|
// This would query the pull_requests table for merged PRs
|
|
// For now, return a placeholder value
|
|
// TODO: Implement actual merged PR counting
|
|
return 0, nil
|
|
} |