diff --git a/models/repo.go b/models/repo.go index 31d2f5f96..625203c74 100755 --- a/models/repo.go +++ b/models/repo.go @@ -296,7 +296,6 @@ func (repo *Repository) ToCardFormat() *Repository4Card { } type ContributorInfo struct { - UserInfo *User // nil for contributor who is not a registered user RelAvatarLink string UserName string Email string @@ -2973,3 +2972,12 @@ func OperateRepoModelNum(repoId int64, amount int64, engines ...*xorm.Engine) er func OperateRepoAITaskNum(repoId int64, amount int64, engines ...*xorm.Engine) error { return operateRepoCol(repoId, "ai_task_cnt", amount, engines...) } + +func UpdateRepositoryLastFourMonthCommits(repoID int64, amount int64) error { + _, err := x.Exec("update repository set last_four_month_commits = ? where id = ?", amount, repoID) + return err +} +func UpdateRepositoryLastMonthVisits(repoID int64, amount int64) error { + _, err := x.Exec("update repository set last_month_visits = ? where id = ?", amount, repoID) + return err +} diff --git a/models/topic.go b/models/topic.go index 0b19bc1f0..ea5698f4c 100644 --- a/models/topic.go +++ b/models/topic.go @@ -9,6 +9,7 @@ import ( "regexp" "strings" "unicode/utf8" + "xorm.io/xorm" "code.gitea.io/gitea/modules/timeutil" @@ -337,3 +338,16 @@ func GetOrgTopics(orgId int64) ([]Topic, error) { return result, nil } + +func UpdateRepoTopics(repoID int64, topicNames []string, sess ...*xorm.Engine) error { + e := x + if len(sess) > 0 { + e = sess[0] + } + if _, err := e.ID(repoID).Cols("topics").Update(&Repository{ + Topics: topicNames, + }); err != nil { + return err + } + return nil +} diff --git a/modules/redis/redis_key/repo_redis_key.go b/modules/redis/redis_key/repo_redis_key.go new file mode 100644 index 000000000..b2b7ccd0a --- /dev/null +++ b/modules/redis/redis_key/repo_redis_key.go @@ -0,0 +1,9 @@ +package redis_key + +import "fmt" + +const REPO_PREFIX = "repo" + +func RepoTopNContributors(repoId int64, N int) string { + return KeyJoin(REPO_PREFIX, fmt.Sprint(repoId), fmt.Sprint(N), "top_n_contributor") +} diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index f4ff7a329..d2522c9ce 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -177,13 +177,25 @@ func AddTopic(ctx *context.APIContext) { return } - _, err = models.AddTopic(ctx.Repo.Repository.ID, topicName) + topic, err := models.AddTopic(ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("AddTopic failed: %v", err) ctx.InternalServerError(err) return } - + found := false + topicNames := make([]string, len(topics)) + for i, t := range topics { + topicNames[i] = t.Name + if strings.EqualFold(topic.Name, t.Name) { + found = true + break + } + } + if !found && topic.Name != "" { + topicNames = append(topicNames, topic.Name) + } + models.UpdateRepoTopics(ctx.Repo.Repository.ID, topicNames) ctx.Status(http.StatusNoContent) } diff --git a/routers/repo/repo_statistic.go b/routers/repo/repo_statistic.go index dd73a9f3f..26c3c156d 100755 --- a/routers/repo/repo_statistic.go +++ b/routers/repo/repo_statistic.go @@ -287,20 +287,13 @@ func RepoStatisticDaily(date string) { } func SyncStatDataToRepo(repo *models.Repository) { - changed := false //Save the visit number of repository in the last month if lv, err := models.SumLastMonthNumVisits(repo.ID); err == nil { - repo.LastMonthVisits = lv - changed = true + models.UpdateRepositoryLastMonthVisits(repo.ID, lv) } //Save the commits number of repository in the last four month if lc, err := models.SumLastFourMonthNumCommits(repo.ID); err == nil { - repo.LastFourMonthCommits = lc - changed = true - } - - if changed { - models.UpdateRepository(repo, false) + models.UpdateRepositoryLastFourMonthCommits(repo.ID, lc) } } diff --git a/services/repository/contributor.go b/services/repository/contributor.go index 896bc682d..9a86b91dc 100644 --- a/services/repository/contributor.go +++ b/services/repository/contributor.go @@ -3,14 +3,47 @@ package repository import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "encoding/json" + "github.com/patrickmn/go-cache" + "time" ) +var repoContributorCache = cache.New(5*time.Minute, 1*time.Minute) + +type ContributorCacheVal struct { + Contributors []*models.ContributorInfo + Total int +} + func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.ContributorInfo, int) { - var contributorInfos []*models.ContributorInfo + val, _ := redis_client.Get(redis_key.RepoTopNContributors(repo.ID, N)) + if val != "" { + log.Debug("Get RepoTopNContributors from redis,repo.ID = %d value = %v", repo.ID, val) + temp := &ContributorCacheVal{} + json.Unmarshal([]byte(val), temp) + return temp.Contributors, temp.Total + } + + contributorInfos, total := getRepoTopNContributorsFromDisk(repo, N) + log.Debug("Get RepoTopNContributors from disk,repo.ID = %d ", repo.ID) + jsonVal, err := json.Marshal(&ContributorCacheVal{Contributors: contributorInfos, Total: total}) + if err == nil { + redis_client.Setex(redis_key.RepoTopNContributors(repo.ID, N), string(jsonVal), 2*time.Minute) + } + return contributorInfos, total +} + +func getRepoTopNContributorsFromDisk(repo *models.Repository, N int) ([]*models.ContributorInfo, int) { + contributorInfos := make([]*models.ContributorInfo, 0) + branchName := GetDefaultBranchName(repo) if branchName == "" { return contributorInfos, 0 } + contributors, err := git.GetContributors(repo.RepoPath(), branchName) if err == nil && contributors != nil { contributorInfoHash := make(map[string]*models.ContributorInfo) @@ -31,7 +64,7 @@ func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.Contribu } else { // new committer info var newContributor = &models.ContributorInfo{ - user, user.RelAvatarLink(), user.Name, user.Email, c.CommitCnt, + user.RelAvatarLink(), user.Name, user.Email, c.CommitCnt, } contributorInfos = append(contributorInfos, newContributor) contributorInfoHash[user.Email] = newContributor @@ -43,7 +76,7 @@ func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.Contribu existedContributorInfo.CommitCnt += c.CommitCnt } else { var newContributor = &models.ContributorInfo{ - user, "", "", c.Email, c.CommitCnt, + "", "", c.Email, c.CommitCnt, } contributorInfos = append(contributorInfos, newContributor) contributorInfoHash[c.Email] = newContributor