You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_activity_custom.go 7.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package models
  2. import (
  3. "fmt"
  4. "sort"
  5. "strings"
  6. "time"
  7. "code.gitea.io/gitea/modules/log"
  8. "code.gitea.io/gitea/modules/git"
  9. )
  10. type ContributorWithUserId struct {
  11. git.Contributor
  12. UserId int64
  13. IsAdmin bool
  14. RelAvatarLink string
  15. }
  16. func GetRepoKPIStats(repo *Repository) (*git.RepoKPIStats, error) {
  17. wikiPath := ""
  18. if repo.HasWiki() {
  19. wikiPath = repo.WikiPath()
  20. }
  21. repoCreated := time.Unix(int64(repo.CreatedUnix), 0)
  22. return getRepoKPIStats(repo.RepoPath(), repoCreated, wikiPath)
  23. }
  24. func getRepoKPIStats(repoPath string, repoCreated time.Time, wikiPath string) (*git.RepoKPIStats, error) {
  25. stats := &git.RepoKPIStats{}
  26. contributors, err := git.GetContributorsDetail(repoPath, repoCreated)
  27. if err != nil {
  28. return nil, err
  29. }
  30. timeUntil := time.Now()
  31. fourMonthAgo := timeUntil.AddDate(0, -4, 0)
  32. if fourMonthAgo.Before(repoCreated) {
  33. fourMonthAgo = repoCreated
  34. }
  35. recentlyContributors, err := git.GetContributorsDetail(repoPath, fourMonthAgo)
  36. newContributersDict := make(map[string]struct{})
  37. if err != nil {
  38. return nil, err
  39. }
  40. if contributors != nil {
  41. contributorDistinctDict := make(map[string]int, 0)
  42. keyContributorsDict := make(map[string]struct{}, 0)
  43. var commitsCount int64
  44. for _, contributor := range contributors {
  45. if strings.Compare(contributor.Email, "") == 0 {
  46. continue
  47. }
  48. user, err := GetUserByActivateEmail(contributor.Email)
  49. if err == nil {
  50. value, ok := contributorDistinctDict[user.Email]
  51. if !ok {
  52. contributorDistinctDict[user.Email] = contributor.CommitCnt
  53. } else {
  54. contributorDistinctDict[user.Email] = value + contributor.CommitCnt
  55. }
  56. setKeyContributerDict(contributorDistinctDict, user.Email, keyContributorsDict)
  57. } else {
  58. value, ok := contributorDistinctDict[contributor.Email]
  59. if !ok {
  60. contributorDistinctDict[contributor.Email] = contributor.CommitCnt
  61. } else {
  62. contributorDistinctDict[contributor.Email] = value + contributor.CommitCnt
  63. }
  64. setKeyContributerDict(contributorDistinctDict, contributor.Email, keyContributorsDict)
  65. }
  66. commitsCount += int64(contributor.CommitCnt)
  67. }
  68. if recentlyContributors != nil {
  69. resentlyContributorDistinctDict := make(map[string]int, 0)
  70. for _, recentlyContributor := range recentlyContributors {
  71. user, err := GetUserByActivateEmail(recentlyContributor.Email)
  72. if err == nil {
  73. value, ok := resentlyContributorDistinctDict[user.Email]
  74. if !ok {
  75. resentlyContributorDistinctDict[user.Email] = recentlyContributor.CommitCnt
  76. } else {
  77. resentlyContributorDistinctDict[user.Email] = value + recentlyContributor.CommitCnt
  78. }
  79. } else {
  80. value, ok := resentlyContributorDistinctDict[recentlyContributor.Email]
  81. if !ok {
  82. resentlyContributorDistinctDict[recentlyContributor.Email] = recentlyContributor.CommitCnt
  83. } else {
  84. resentlyContributorDistinctDict[recentlyContributor.Email] = value + recentlyContributor.CommitCnt
  85. }
  86. }
  87. }
  88. for k, v := range resentlyContributorDistinctDict {
  89. count, ok := contributorDistinctDict[k]
  90. if ok && count == v {
  91. stats.ContributorsAdded++
  92. }
  93. }
  94. }
  95. stats.Contributors = int64(len(contributorDistinctDict))
  96. stats.KeyContributors = int64(len(keyContributorsDict))
  97. stats.Commits = int64(commitsCount)
  98. }
  99. err = git.SetDevelopAge(repoPath, stats, repoCreated)
  100. if err != nil {
  101. return nil, fmt.Errorf("FillFromGit: %v", err)
  102. }
  103. err = git.SetRepoKPIStats(repoPath, fourMonthAgo, stats, newContributersDict)
  104. if err != nil {
  105. return nil, fmt.Errorf("FillFromGit: %v", err)
  106. }
  107. git.SetWikiPages(wikiPath, stats)
  108. return stats, nil
  109. }
  110. func GetTop10Contributor(repoPath string) ([]*ContributorWithUserId, error) {
  111. contributors, err := git.GetContributors(repoPath)
  112. if err != nil {
  113. return make([]*ContributorWithUserId, 0), err
  114. }
  115. contributorDistinctDict := make(map[string]*ContributorWithUserId, 0)
  116. if contributors != nil {
  117. for _, contributor := range contributors {
  118. if strings.Compare(contributor.Email, "") == 0 {
  119. continue
  120. }
  121. user, err := GetUserByActivateEmail(contributor.Email)
  122. if err == nil {
  123. value, ok := contributorDistinctDict[user.Email]
  124. if !ok {
  125. contributorDistinctDict[user.Email] = &ContributorWithUserId{
  126. git.Contributor{
  127. contributor.CommitCnt,
  128. user.Name,
  129. user.Email,
  130. },
  131. user.ID,
  132. user.IsAdmin,
  133. user.RelAvatarLink(),
  134. }
  135. } else {
  136. value.CommitCnt += contributor.CommitCnt
  137. }
  138. } else {
  139. value, ok := contributorDistinctDict[contributor.Email]
  140. if !ok {
  141. contributorDistinctDict[contributor.Email] = &ContributorWithUserId{
  142. contributor,
  143. -1,
  144. false,
  145. "",
  146. }
  147. } else {
  148. value.CommitCnt += contributor.CommitCnt
  149. }
  150. }
  151. }
  152. v := make([]*ContributorWithUserId, 0, len(contributorDistinctDict))
  153. for _, value := range contributorDistinctDict {
  154. v = append(v, value)
  155. }
  156. sort.Slice(v, func(i, j int) bool {
  157. return v[i].CommitCnt > v[j].CommitCnt
  158. })
  159. if len(v) <= 10 {
  160. return v, nil
  161. } else {
  162. return v[0:10], nil
  163. }
  164. }
  165. return make([]*ContributorWithUserId, 0), nil
  166. }
  167. func setKeyContributerDict(contributorDistinctDict map[string]int, email string, keyContributorsDict map[string]struct{}) {
  168. if contributorDistinctDict[email] >= 3 {
  169. _, ok := keyContributorsDict[email]
  170. if !ok {
  171. keyContributorsDict[email] = struct{}{}
  172. }
  173. }
  174. }
  175. func GetAllUserPublicRepoKPIStats(startTime time.Time, endTime time.Time) (map[string]*git.UserKPIStats, error) {
  176. authors := make(map[string]*git.UserKPIStats)
  177. repositorys, err := GetAllRepositoriesByFilterCols("owner_name", "name", "is_private")
  178. if err != nil {
  179. return nil, err
  180. }
  181. for _, repository := range repositorys {
  182. if repository.IsPrivate {
  183. continue
  184. }
  185. authorsOneRepo, err1 := git.GetUserKPIStats(repository.RepoPath(), startTime, endTime)
  186. if err1 != nil {
  187. log.Warn("get user kpi status err:"+repository.RepoPath(), err1.Error())
  188. continue
  189. }
  190. for key, value := range authorsOneRepo {
  191. if _, ok := authors[key]; !ok {
  192. authors[key] = &git.UserKPIStats{
  193. Name: value.Name,
  194. Email: value.Email,
  195. Commits: 0,
  196. CommitLines: 0,
  197. }
  198. }
  199. if value.Email == "1250125907@qq.com" || value.Email == "peiyongyu-34@163.com" {
  200. log.Info("repo path=" + repository.RepoPath())
  201. }
  202. authors[key].Commits += value.Commits
  203. authors[key].CommitLines += value.CommitLines
  204. }
  205. }
  206. return authors, nil
  207. }
  208. func GetAllUserKPIStats(startTime time.Time, endTime time.Time) (map[string]*git.UserKPIStats, error) {
  209. authors := make(map[string]*git.UserKPIStats)
  210. repositorys, err := GetAllRepositoriesByFilterCols("owner_name", "name")
  211. if err != nil {
  212. return nil, err
  213. }
  214. for _, repository := range repositorys {
  215. authorsOneRepo, err1 := git.GetUserKPIStats(repository.RepoPath(), startTime, endTime)
  216. if err1 != nil {
  217. log.Warn("get user kpi status err:"+repository.RepoPath(), err1.Error())
  218. continue
  219. }
  220. for key, value := range authorsOneRepo {
  221. if _, ok := authors[key]; !ok {
  222. authors[key] = &git.UserKPIStats{
  223. Name: value.Name,
  224. Email: value.Email,
  225. Commits: 0,
  226. CommitLines: 0,
  227. }
  228. }
  229. authors[key].Commits += value.Commits
  230. authors[key].CommitLines += value.CommitLines
  231. }
  232. }
  233. return authors, nil
  234. }