Browse Source

Merge remote-tracking branch 'origin/V20211018' into zouap

tags/v1.21.11.1
zouap 4 years ago
parent
commit
510d5336cf
17 changed files with 295 additions and 33 deletions
  1. +9
    -0
      models/attachment.go
  2. +1
    -1
      models/cloudbrain.go
  3. +16
    -0
      models/issue_comment.go
  4. +1
    -1
      models/models.go
  5. +0
    -0
      models/release.go
  6. +1
    -1
      models/repo_list.go
  7. +60
    -0
      models/repo_statistic.go
  8. +25
    -0
      modules/cron/tasks_basic.go
  9. +2
    -1
      routers/private/internal.go
  10. +8
    -1
      routers/private/tool.go
  11. +122
    -0
      routers/repo/repo_statistic.go
  12. +1
    -1
      routers/repo/user_data_analysis.go
  13. +5
    -1
      templates/repo/cloudbrain/index.tmpl
  14. +2
    -2
      templates/repo/datasets/dataset_list.tmpl
  15. +1
    -1
      templates/repo/home.tmpl
  16. +4
    -0
      templates/repo/modelarts/index.tmpl
  17. +37
    -23
      web_src/js/components/EditTopics.vue

+ 9
- 0
models/attachment.go View File

@@ -464,3 +464,12 @@ func CanDelAttachment(isSigned bool, user *User, attach *Attachment) bool {
}
return false
}

func GetAttachmentSizeByDatasetID(datasetID int64) (int64, error) {
total, err := x.Where("dataset_id = ?", datasetID).SumInt(&Attachment{}, "size")
if err != nil {
return 0, err
}

return total, nil
}

+ 1
- 1
models/cloudbrain.go View File

@@ -687,7 +687,7 @@ func CanDelJob(isSigned bool, user *User, job *CloudbrainInfo) bool {
return false
}

if user.ID == job.UserID || user.IsAdmin || permission.AccessMode >= AccessModeAdmin {
if (user.ID == job.UserID && permission.AccessMode >= AccessModeWrite) || user.IsAdmin || permission.AccessMode >= AccessModeAdmin {
return true
}
return false


+ 16
- 0
models/issue_comment.go View File

@@ -1016,3 +1016,19 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID
})
return err
}

func GetCommentCountByRepoID(repoID int64) (int64, error) {
//sql := fmt.Sprintf("select count(1) from comment where issue_id in (select id from issue where repo_id = %d) and type = %d;", repoID, CommentTypeComment)
//res, err := x.Query(sql)
//if err != nil {
// return 0, err
//}
//return int64(binary.BigEndian.Uint64(res[0]["count"])), nil

total, err := x.Where("issue_id in (select id from issue where repo_id = ?) and type = ?", repoID, CommentTypeComment).Count(&Comment{})
if err != nil {
return 0, err
}

return total, nil
}

+ 1
- 1
models/models.go View File

@@ -136,7 +136,7 @@ func init() {
)

tablesStatistic = append(tablesStatistic,
new(FileChunk),
new(RepoStatistic),
new(UserBusinessAnalysis),
)



+ 0
- 0
models/release.go View File


+ 1
- 1
models/repo_list.go View File

@@ -331,7 +331,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
}
if opts.TopicName != "" {
var subQueryCond = builder.NewCond()
subQueryCond = subQueryCond.Or(builder.Eq{"topic.name": opts.TopicName})
subQueryCond = subQueryCond.Or(builder.Eq{"topic.name": strings.ToLower(opts.TopicName)})
subQuery := builder.Select("repo_topic.repo_id").From("repo_topic").
Join("INNER", "topic", "topic.id = repo_topic.topic_id").
Where(subQueryCond).


+ 60
- 0
models/repo_statistic.go View File

@@ -0,0 +1,60 @@
package models

import (
"code.gitea.io/gitea/modules/timeutil"
"fmt"
)

// RepoStatistic statistic info of all repository
type RepoStatistic struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"unique(s) NOT NULL"`
Date string `xorm:"unique(s) NOT NULL"`
NumWatches int64 `xorm:"NOT NULL DEFAULT 0"`
NumStars int64 `xorm:"NOT NULL DEFAULT 0"`
NumForks int64 `xorm:"NOT NULL DEFAULT 0"`
NumDownloads int64 `xorm:"NOT NULL DEFAULT 0"`
NumComments int64 `xorm:"NOT NULL DEFAULT 0"`
NumVisits int64 `xorm:"NOT NULL DEFAULT 0"`
NumClosedIssues int64 `xorm:"NOT NULL DEFAULT 0"`
NumVersions int64 `xorm:"NOT NULL DEFAULT 0"`
//develop months
NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0"`
RepoSize int64 `xorm:"NOT NULL DEFAULT 0"`
DatasetSize int64 `xorm:"NOT NULL DEFAULT 0"`
NumModels int64 `xorm:"NOT NULL DEFAULT 0"`
NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0"`
NumCommits int64 `xorm:"NOT NULL DEFAULT 0"`
NumIssues int64 `xorm:"NOT NULL DEFAULT 0"`
NumPulls int64 `xorm:"NOT NULL DEFAULT 0"`
IssueFixedRate float32 `xorm:"NOT NULL"`
NumContributor int64 `xorm:"NOT NULL DEFAULT 0"`
NumKeyContributor int64 `xorm:"NOT NULL DEFAULT 0"`

CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}

func DeleteRepoStatDaily(date string) error {
sess := xStatistic.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return fmt.Errorf("Begin: %v", err)
}

if _, err := sess.Where("date = ?", date).Delete(&RepoStatistic{}); err != nil {
return fmt.Errorf("Delete: %v", err)
}

if err := sess.Commit(); err != nil {
sess.Close()
return fmt.Errorf("Commit: %v", err)
}

sess.Close()
return nil
}

func InsertRepoStat(repoStat *RepoStatistic) (int64, error) {
return xStatistic.Insert(repoStat)
}

+ 25
- 0
modules/cron/tasks_basic.go View File

@@ -163,6 +163,28 @@ func registerHandleBlockChainUnSuccessCommits() {
})
}

func registerHandleRepoStatistic() {
RegisterTaskFatal("handle_repo_statistic", &BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@daily",
}, func(ctx context.Context, _ *models.User, _ Config) error {
repo.RepoStatisticAuto()
return nil
})
}

func registerHandleUserStatistic() {
RegisterTaskFatal("handle_user_statistic", &BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@daily",
}, func(ctx context.Context, _ *models.User, _ Config) error {
repo.TimingCountData()
return nil
})
}

func initBasicTasks() {
registerUpdateMirrorTask()
registerRepoHealthCheck()
@@ -177,4 +199,7 @@ func initBasicTasks() {
registerHandleBlockChainUnSuccessRepos()
registerHandleBlockChainMergedPulls()
registerHandleBlockChainUnSuccessCommits()

registerHandleRepoStatistic()
registerHandleUserStatistic()
}

+ 2
- 1
routers/private/internal.go View File

@@ -42,7 +42,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/manager/shutdown", Shutdown)
m.Post("/manager/restart", Restart)
m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues)
m.Post("/cmd/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt)
m.Post("/tool/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt)
m.Post("/tool/repo_stat", RepoStatisticManually)

}, CheckInternalToken)
}

routers/private/cmd.go → routers/private/tool.go View File

@@ -5,11 +5,13 @@
package private

import (
"gitea.com/macaron/macaron"
"net/http"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/routers/repo"

"gitea.com/macaron/macaron"
)

func UpdateAllRepoCommitCnt(ctx *macaron.Context) {
@@ -35,3 +37,8 @@ func UpdateAllRepoCommitCnt(ctx *macaron.Context) {
"error_msg": "",
})
}

func RepoStatisticManually(ctx *macaron.Context) {
date := ctx.Query("date")
repo.RepoStatisticDaily(date)
}

+ 122
- 0
routers/repo/repo_statistic.go View File

@@ -0,0 +1,122 @@
package repo

import (
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
)

//auto daily or manually
func RepoStatisticAuto() {
log.Info("", time.Now())
yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
RepoStatisticDaily(yesterday)
}

func RepoStatisticDaily(date string) {
log.Info("%s", date)
if err := models.DeleteRepoStatDaily(date); err != nil {
log.Error("DeleteRepoStatDaily failed: %v", err.Error())
return
}

repos, err := models.GetAllRepositories()
if err != nil {
log.Error("GetAllRepositories failed: %v", err.Error())
return
}

for _, repo := range repos {
log.Info("start statistic: %s", repo.Name)
repoGitStat, err := models.GetRepoKPIStats(repo)
if err != nil {
log.Error("GetRepoKPIStats failed: %s", repo.Name)
log.Error("failed statistic: %s", repo.Name)
continue
}

var issueFixedRate float32
if repo.NumIssues != 0 {
issueFixedRate = float32(repo.NumClosedIssues) / float32(repo.NumIssues)
}

numVersions, err := models.GetReleaseCountByRepoID(repo.ID, models.FindReleasesOptions{})
if err != nil {
log.Error("GetReleaseCountByRepoID failed: %s", repo.Name)
log.Error("failed statistic: %s", repo.Name)
continue
}

datasetSize, err := getDatasetSize(repo)
if err != nil {
log.Error("getDatasetSize failed: %s", repo.Name)
log.Error("failed statistic: %s", repo.Name)
continue
}

numComments, err := models.GetCommentCountByRepoID(repo.ID)
if err != nil {
log.Error("GetCommentCountByRepoID failed: %s", repo.Name)
log.Error("failed statistic: %s", repo.Name)
continue
}

//beginTime, endTime := getStatTime(date)
//numVisits := repository.AppointProjectView(repo.OwnerName, repo.Name, beginTime, endTime)
numVisits := 0

repoStat := models.RepoStatistic{
RepoID: repo.ID,
Date: date,
NumWatches: int64(repo.NumWatches),
NumStars: int64(repo.NumStars),
NumDownloads: repo.CloneCnt,
NumComments: numComments,
NumVisits: int64(numVisits),
NumClosedIssues: int64(repo.NumClosedIssues),
NumVersions: numVersions,
NumDevMonths: repoGitStat.DevelopAge,
RepoSize: repo.Size,
DatasetSize: datasetSize,
NumModels: 0,
NumWikiViews: repoGitStat.WikiPages,
NumCommits: repo.NumCommit,
NumIssues: int64(repo.NumIssues),
NumPulls: int64(repo.NumPulls),
IssueFixedRate: issueFixedRate,
NumContributor: repoGitStat.Contributors,
NumKeyContributor: repoGitStat.KeyContributors,
}

if _, err = models.InsertRepoStat(&repoStat); err != nil {
log.Error("InsertRepoStat failed: %s", repo.Name)
log.Error("failed statistic: %s", repo.Name)
continue
}

log.Info("finish statistic: %s", repo.Name)
}

}

func getDatasetSize(repo *models.Repository) (int64, error) {
dataset, err := models.GetDatasetByRepo(repo)
if err != nil {
return 0, err
}

return models.GetAttachmentSizeByDatasetID(dataset.ID)
}

func getStatTime(timeStr string) (string, string) {
t, _ := time.Parse("2006-01-02", timeStr)
timeNumber := t.Unix()
beginTimeNumber := timeNumber - 8*60*60
endTimeNumber := timeNumber + 16*60*60
beginTime := time.Unix(beginTimeNumber, 0).Format(time.RFC3339)
endTime := time.Unix(endTimeNumber, 0).Format(time.RFC3339)
log.Info("%s, %s", beginTime, endTime)

return beginTime, endTime
}

+ 1
- 1
routers/repo/user_data_analysis.go View File

@@ -8,7 +8,7 @@ import (
"code.gitea.io/gitea/modules/log"
)

func TimeingCountData() {
func TimingCountData() {
//query wiki data
log.Info("start to time count data")
wikiMap := make(map[string]int)


+ 5
- 1
templates/repo/cloudbrain/index.tmpl View File

@@ -318,7 +318,11 @@
</div>

<div class="one wide column">
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a>
{{if .User.Name}}
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a>
{{else}}
<a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a>
{{end}}
</div>
<div class="seven wide column text right">
<div class="ui compact buttons">


+ 2
- 2
templates/repo/datasets/dataset_list.tmpl View File

@@ -5,7 +5,7 @@
{{range .Attachments}}
<div class="ui grid item" id="{{.UUID}}">
<div class="row">
<div class="eight wide column">
<div class="eight wide column" data-tooltip="{{.Name}}">
<span class="ui right">{{.Size | FileSize}}</span>
<a class="title" href="{{.DownloadURL}}?type={{$.Type}}">
{{svg "octicon-cloud-download" 16}} {{.Name}}
@@ -13,7 +13,7 @@
</div>
<div class="eight wide column right aligned">
<div class="ui left mini icon buttons">
<span class="ui basic button" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span>
<span class="ui basic button text left" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right" style="width: 60px; padding-left: 0;">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span>
<span class="ui basic basic button clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy"{{if ne $.Type 0}} style="display:none;"{{end}}>{{svg "octicon-file" 16}}</span>
<span class="ui basic basic button clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span>
</div>


+ 1
- 1
templates/repo/home.tmpl View File

@@ -291,7 +291,7 @@
{{end}} -->
{{range .Topics}}

<a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>
<a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=">{{.Name}}</a>


{{end}}


+ 4
- 0
templates/repo/modelarts/index.tmpl View File

@@ -292,7 +292,11 @@
</div>

<div class="one wide column">
{{if .User.Name}}
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a>
{{else}}
<a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a>
{{end}}
</div>

<div class="seven wide column text right">


+ 37
- 23
web_src/js/components/EditTopics.vue View File

@@ -148,29 +148,37 @@ export default {
params:this.params
}).then((res)=>{
this.array = res.data.topics
this.array.forEach((element,index) => {
if (this.arrayTopics.indexOf(element.topic_name)>-1){
this.showInitTopic.push(true)
}else{
}
else{
this.showInitTopic.push(false)
}
this.showInputValue = true
});
let findelement = this.array.some((item)=>{
return item.topic_name===this.input
})
this.showInputValue = !findelement
});
})
this.showInputValue = true
this.showSearchTopic = true
}
this.showAddTopic = false

},
@@ -201,6 +209,9 @@ export default {
})
},
postTopic(){
if(!this.showInputValue){
return
}
const patter = /^[\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,34}$/
let regexp = patter.test(this.input)
if(!regexp){
@@ -249,7 +260,7 @@ export default {
this.Post(data,topics)
if(this.arrayTopics.length===0){
console.log("add postTopic")
$('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
}else{
$('#repo-topics1').children('span').remove()
@@ -282,7 +293,9 @@ export default {
this.input = ''
if (this.input === ''){
this.array = this.arrayTopics
let data = []
this.showInitTopic = []
this.array.forEach((element,index) => {
@@ -301,6 +314,7 @@ export default {
this.showInputValue = false
this.showSearchTopic = true
this.showAddTopic = false
}
stopPropagation(e);
@@ -332,30 +346,30 @@ computed:{
},
watch: {

input(newValue){
// input(newValue){
if (newValue === ''){
this.array = this.arrayTopics
let data = []
this.showInitTopic = []
this.array.forEach((element,index) => {
// if (newValue === ''){
// this.array = this.arrayTopics
// let data = []
// this.showInitTopic = []
// this.array.forEach((element,index) => {
let item = {}
item.topic_name = element
// let item = {}
// item.topic_name = element
data.push(item)
this.showInitTopic.push(true)
// data.push(item)
// this.showInitTopic.push(true)
});
// });
this.array = data
// this.array = data
this.showInputValue = false
this.showSearchTopic = true
}
}
// this.showInputValue = false
// this.showSearchTopic = true
// }
// }
},
mounted() {
const context = this


Loading…
Cancel
Save