diff --git a/README.md b/README.md index afb2da5d9..1cb142db6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

logoAiForge - 启智AI开发协作平台

-[![release](https://img.shields.io/badge/release-1.21.10.1-blue)](https://git.openi.org.cn/OpenI/aiforge/releases/latest) +[![release](https://img.shields.io/badge/release-1.21.9.2-blue)](https://git.openi.org.cn/OpenI/aiforge/releases/latest) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) diff --git a/models/cloudbrain.go b/models/cloudbrain.go index 5be07f741..4f615ed00 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -65,6 +65,11 @@ type Cloudbrain struct { Repo *Repository `xorm:"-"` } +type CloudbrainInfo struct { + Cloudbrain `xorm:"extends"` + User `xorm:"extends"` +} + type CloudBrainLoginResult struct { Code string Msg string @@ -523,7 +528,7 @@ type NotebookDelResult struct { InstanceID string `json:"instance_id"` } -func Cloudbrains(opts *CloudbrainsOptions) ([]*Cloudbrain, int64, error) { +func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { sess := x.NewSession() defer sess.Close() @@ -583,8 +588,10 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*Cloudbrain, int64, error) { } sess.OrderBy("cloudbrain.created_unix DESC") - cloudbrains := make([]*Cloudbrain, 0, setting.UI.IssuePagingNum) - if err := sess.Where(cond).Find(&cloudbrains); err != nil { + cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) + if err := sess.Table(&Cloudbrain{}).Where(cond). + Join("left", "`user`", "cloudbrain.user_id = `user`.id"). + Find(&cloudbrains); err != nil { return nil, 0, fmt.Errorf("Find: %v", err) } sess.Close() diff --git a/models/models.go b/models/models.go index eee29d2c7..3927dfbf0 100755 --- a/models/models.go +++ b/models/models.go @@ -136,7 +136,9 @@ func init() { ) tablesStatistic = append(tablesStatistic, - new(FileChunk)) + new(FileChunk), + new(UserBusinessAnalysis), + ) gonicNames := []string{"SSL", "UID"} for _, name := range gonicNames { diff --git a/models/repo_watch.go b/models/repo_watch.go index 11cfa8891..6bdef9c7f 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -26,10 +26,11 @@ const ( // Watch is connection request for receiving repository notification. type Watch struct { - ID int64 `xorm:"pk autoincr"` - UserID int64 `xorm:"UNIQUE(watch)"` - RepoID int64 `xorm:"UNIQUE(watch)"` - Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"UNIQUE(watch)"` + RepoID int64 `xorm:"UNIQUE(watch)"` + Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` + CreatedUnix int64 `xorm:"created"` } // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found diff --git a/models/star.go b/models/star.go index 4e84a6e4d..418a76b17 100644 --- a/models/star.go +++ b/models/star.go @@ -4,11 +4,14 @@ package models +import "code.gitea.io/gitea/modules/timeutil" + // Star represents a starred repo by an user. type Star struct { - ID int64 `xorm:"pk autoincr"` - UID int64 `xorm:"UNIQUE(s)"` - RepoID int64 `xorm:"UNIQUE(s)"` + ID int64 `xorm:"pk autoincr"` + UID int64 `xorm:"UNIQUE(s)"` + RepoID int64 `xorm:"UNIQUE(s)"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` } // StarRepo or unstar repository. @@ -39,7 +42,7 @@ func StarRepo(userID, repoID int64, star bool) error { return nil } - if _, err := sess.Delete(&Star{0, userID, repoID}); err != nil { + if _, err := sess.Delete(&Star{0, userID, repoID, 0}); err != nil { return err } if _, err := sess.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoID); err != nil { @@ -59,7 +62,7 @@ func IsStaring(userID, repoID int64) bool { } func isStaring(e Engine, userID, repoID int64) bool { - has, _ := e.Get(&Star{0, userID, repoID}) + has, _ := e.Get(&Star{0, userID, repoID, 0}) return has } diff --git a/models/user.go b/models/user.go index 38f699740..78ab4627a 100755 --- a/models/user.go +++ b/models/user.go @@ -1556,6 +1556,18 @@ func GetUserByActivateEmail(email string) (*User, error) { if len(users) >= 1 { return &users[0],nil }else { + // Finally, if email address is the protected email address:用户邮件地址设置为隐藏电子邮件地址 + if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) { + username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) + user := &User{LowerName: username} + has, err := ctx.e.Get(user) + if err != nil { + return nil, err + } + if has { + return user, nil + } + } return nil, errors.New("cannot find user by email") } } diff --git a/models/user_business_analysis.go b/models/user_business_analysis.go new file mode 100644 index 000000000..9da0694a5 --- /dev/null +++ b/models/user_business_analysis.go @@ -0,0 +1,356 @@ +package models + +import ( + "fmt" + "time" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/timeutil" +) + +type UserBusinessAnalysis struct { + ID int64 `xorm:"pk"` + + CountDate int64 `xorm:"pk"` + + //action :ActionMergePullRequest // 11 + CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"` + + //action :ActionCommitRepo // 5 + CommitCount int `xorm:"NOT NULL DEFAULT 0"` + + //action :ActionCommentIssue // 10 + IssueCount int `xorm:"NOT NULL DEFAULT 0"` + + //comment table current date + CommentCount int `xorm:"NOT NULL DEFAULT 0"` + + //watch table current date + FocusRepoCount int `xorm:"NOT NULL DEFAULT 0"` + + //star table current date + StarRepoCount int `xorm:"NOT NULL DEFAULT 0"` + + //follow table + WatchedCount int `xorm:"NOT NULL DEFAULT 0"` + + // user table + GiteaAgeMonth int `xorm:"NOT NULL DEFAULT 0"` + + // + CommitCodeSize int `xorm:"NOT NULL DEFAULT 0"` + + //attachement table + CommitDatasetSize int `xorm:"NOT NULL DEFAULT 0"` + + //0 + CommitModelCount int `xorm:"NOT NULL DEFAULT 0"` + + //issue, issueassignees + SolveIssueCount int `xorm:"NOT NULL DEFAULT 0"` + + //baike + EncyclopediasCount int `xorm:"NOT NULL DEFAULT 0"` + + //user + RegistDate timeutil.TimeStamp `xorm:"NOT NULL"` + + //user + Email string `xorm:"NOT NULL"` + + //user + Name string `xorm:"NOT NULL"` +} + +func CountData(wikiCountMap map[string]int) { + log.Info("start to count other user info data") + sess := x.NewSession() + defer sess.Close() + sess.Select("`user`.*").Table("user") + userList := make([]*User, 0) + sess.Find(&userList) + + currentTimeNow := time.Now() + log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05")) + + yesterday := currentTimeNow.AddDate(0, 0, -1) + startTime := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, yesterday.Location()) + start_unix := startTime.Unix() + log.Info("DB query time:" + startTime.Format("2006-01-02 15:04:05")) + + endTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) + end_unix := endTime.Unix() + + CountDate := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 1, 0, 0, currentTimeNow.Location()) + + CodeMergeCountMap := queryAction(start_unix, end_unix, 11) + CommitCountMap := queryAction(start_unix, end_unix, 5) + IssueCountMap := queryAction(start_unix, end_unix, 10) + + CommentCountMap := queryComment(start_unix, end_unix) + FocusRepoCountMap := queryWatch(start_unix, end_unix) + StarRepoCountMap := queryStar(start_unix, end_unix) + WatchedCountMap := queryFollow(start_unix, end_unix) + + CommitCodeSizeMap, err := GetAllUserKPIStats() + if err != nil { + log.Info("query commit code errr.") + } else { + log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap))) + } + CommitDatasetSizeMap := queryDatasetSize(start_unix, end_unix) + SolveIssueCountMap := querySolveIssue(start_unix, end_unix) + + for i, userRecord := range userList { + var dateRecord UserBusinessAnalysis + dateRecord.ID = userRecord.ID + log.Info("i=" + fmt.Sprint(i) + " userName=" + userRecord.Name) + dateRecord.CountDate = CountDate.Unix() + dateRecord.Email = userRecord.Email + dateRecord.RegistDate = userRecord.CreatedUnix + dateRecord.Name = userRecord.Name + dateRecord.GiteaAgeMonth = subMonth(currentTimeNow, userRecord.CreatedUnix.AsTime()) + if _, ok := CodeMergeCountMap[dateRecord.ID]; !ok { + dateRecord.CodeMergeCount = 0 + } else { + dateRecord.CodeMergeCount = CodeMergeCountMap[dateRecord.ID] + } + + if _, ok := CommitCountMap[dateRecord.ID]; !ok { + dateRecord.CommitCount = 0 + } else { + dateRecord.CommitCount = CommitCountMap[dateRecord.ID] + } + + if _, ok := IssueCountMap[dateRecord.ID]; !ok { + dateRecord.IssueCount = 0 + } else { + dateRecord.IssueCount = IssueCountMap[dateRecord.ID] + } + + if _, ok := CommentCountMap[dateRecord.ID]; !ok { + dateRecord.CommentCount = 0 + } else { + dateRecord.CommentCount = CommentCountMap[dateRecord.ID] + } + + if _, ok := FocusRepoCountMap[dateRecord.ID]; !ok { + dateRecord.FocusRepoCount = 0 + } else { + dateRecord.FocusRepoCount = FocusRepoCountMap[dateRecord.ID] + } + + if _, ok := StarRepoCountMap[dateRecord.ID]; !ok { + dateRecord.StarRepoCount = 0 + } else { + dateRecord.StarRepoCount = StarRepoCountMap[dateRecord.ID] + } + + if _, ok := WatchedCountMap[dateRecord.ID]; !ok { + dateRecord.WatchedCount = 0 + } else { + dateRecord.WatchedCount = WatchedCountMap[dateRecord.ID] + } + + if _, ok := CommitCodeSizeMap[dateRecord.Email]; !ok { + dateRecord.CommitCodeSize = 0 + } else { + dateRecord.CommitCodeSize = int(CommitCodeSizeMap[dateRecord.Email].CommitLines) + } + + if _, ok := CommitDatasetSizeMap[dateRecord.ID]; !ok { + dateRecord.CommitDatasetSize = 0 + } else { + dateRecord.CommitDatasetSize = CommitDatasetSizeMap[dateRecord.ID] + } + + if _, ok := SolveIssueCountMap[dateRecord.ID]; !ok { + dateRecord.SolveIssueCount = 0 + } else { + dateRecord.SolveIssueCount = SolveIssueCountMap[dateRecord.ID] + } + + if _, ok := wikiCountMap[dateRecord.Name]; !ok { + dateRecord.EncyclopediasCount = 0 + } else { + dateRecord.EncyclopediasCount = wikiCountMap[dateRecord.Name] + } + + dateRecord.CommitModelCount = 0 + + statictisSess := xStatistic.NewSession() + defer statictisSess.Close() + statictisSess.Insert(&dateRecord) + } + +} + +func querySolveIssue(start_unix int64, end_unix int64) map[int64]int { + //select issue_assignees.* from issue_assignees,issue where issue.is_closed=true and issue.id=issue_assignees.issue_id + sess := x.NewSession() + defer sess.Close() + sess.Select("issue_assignees.*").Table("issue_assignees"). + Join("inner", "issue", "issue.id=issue_assignees.issue_id"). + Where("issue.is_closed=true and issue.closed_unix>=" + fmt.Sprint(start_unix) + " and issue.closed_unix<=" + fmt.Sprint(end_unix)) + issueAssigneesList := make([]*IssueAssignees, 0) + sess.Find(&issueAssigneesList) + resultMap := make(map[int64]int) + log.Info("query IssueAssignees size=" + fmt.Sprint(len(issueAssigneesList))) + for _, issueAssigneesRecord := range issueAssigneesList { + if _, ok := resultMap[issueAssigneesRecord.AssigneeID]; !ok { + resultMap[issueAssigneesRecord.AssigneeID] = 1 + } else { + resultMap[issueAssigneesRecord.AssigneeID] += 1 + } + } + return resultMap + +} + +func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]int { + sess := x.NewSession() + defer sess.Close() + sess.Select("id,user_id,op_type,act_user_id").Table("action").Where("op_type=" + fmt.Sprint(actionType) + " and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + actionList := make([]*Action, 0) + sess.Find(&actionList) + resultMap := make(map[int64]int) + log.Info("query action size=" + fmt.Sprint(len(actionList))) + for _, actionRecord := range actionList { + if _, ok := resultMap[actionRecord.UserID]; !ok { + resultMap[actionRecord.UserID] = 1 + } else { + resultMap[actionRecord.UserID] += 1 + } + } + return resultMap +} + +func queryComment(start_unix int64, end_unix int64) map[int64]int { + + sess := x.NewSession() + defer sess.Close() + sess.Select("id,type,poster_id").Table("comment").Where(" created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + commentList := make([]*Comment, 0) + sess.Find(&commentList) + resultMap := make(map[int64]int) + log.Info("query Comment size=" + fmt.Sprint(len(commentList))) + for _, commentRecord := range commentList { + if _, ok := resultMap[commentRecord.PosterID]; !ok { + resultMap[commentRecord.PosterID] = 1 + } else { + resultMap[commentRecord.PosterID] += 1 + } + } + return resultMap +} + +func queryWatch(start_unix int64, end_unix int64) map[int64]int { + + sess := x.NewSession() + defer sess.Close() + sess.Select("id,user_id,repo_id").Table("watch").Where(" created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + watchList := make([]*Watch, 0) + sess.Find(&watchList) + resultMap := make(map[int64]int) + log.Info("query Watch size=" + fmt.Sprint(len(watchList))) + for _, watchRecord := range watchList { + if _, ok := resultMap[watchRecord.UserID]; !ok { + resultMap[watchRecord.UserID] = 1 + } else { + resultMap[watchRecord.UserID] += 1 + } + } + return resultMap + +} + +func queryStar(start_unix int64, end_unix int64) map[int64]int { + + sess := x.NewSession() + defer sess.Close() + sess.Select("id,uid,repo_id").Table("star").Where(" created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + starList := make([]*Star, 0) + sess.Find(&starList) + resultMap := make(map[int64]int) + log.Info("query Star size=" + fmt.Sprint(len(starList))) + for _, starRecord := range starList { + if _, ok := resultMap[starRecord.UID]; !ok { + resultMap[starRecord.UID] = 1 + } else { + resultMap[starRecord.UID] += 1 + } + } + return resultMap + +} + +func queryFollow(start_unix int64, end_unix int64) map[int64]int { + + sess := x.NewSession() + defer sess.Close() + sess.Select("id,user_id,follow_id").Table("follow").Where(" created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + followList := make([]*Follow, 0) + sess.Find(&followList) + resultMap := make(map[int64]int) + log.Info("query Follow size=" + fmt.Sprint(len(followList))) + for _, followRecord := range followList { + if _, ok := resultMap[followRecord.UserID]; !ok { + resultMap[followRecord.UserID] = 1 + } else { + resultMap[followRecord.UserID] += 1 + } + } + return resultMap +} + +func queryDatasetSize(start_unix int64, end_unix int64) map[int64]int { + sess := x.NewSession() + defer sess.Close() + sess.Select("id,uploader_id,size").Table("attachment").Where(" created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)) + attachmentList := make([]*Attachment, 0) + sess.Find(&attachmentList) + resultMap := make(map[int64]int) + log.Info("query Attachment size=" + fmt.Sprint(len(attachmentList))) + for _, attachRecord := range attachmentList { + if _, ok := resultMap[attachRecord.UploaderID]; !ok { + resultMap[attachRecord.UploaderID] = int(attachRecord.Size / (1024 * 1024)) //MB + } else { + resultMap[attachRecord.UploaderID] += int(attachRecord.Size / (1024 * 1024)) //MB + } + } + return resultMap + +} + +func subMonth(t1, t2 time.Time) (month int) { + y1 := t1.Year() + y2 := t2.Year() + m1 := int(t1.Month()) + m2 := int(t2.Month()) + d1 := t1.Day() + d2 := t2.Day() + + yearInterval := y1 - y2 + // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数 + if m1 < m2 || m1 == m2 && d1 < d2 { + yearInterval-- + } + // 获取月数差值 + monthInterval := (m1 + 12) - m2 + if d1 < d2 { + monthInterval-- + } + monthInterval %= 12 + month = yearInterval*12 + monthInterval + return month +} + +func QueryAllRepo() []*Repository { + sess := x.NewSession() + defer sess.Close() + sess.Select("*").Table("repository") + repositoryList := make([]*Repository, 0) + sess.Find(&repositoryList) + + return repositoryList +} diff --git a/models/user_follow.go b/models/user_follow.go index 4bde71cb9..b63535bb9 100644 --- a/models/user_follow.go +++ b/models/user_follow.go @@ -4,11 +4,14 @@ package models +import "code.gitea.io/gitea/modules/timeutil" + // Follow represents relations of user and his/her followers. type Follow struct { - ID int64 `xorm:"pk autoincr"` - UserID int64 `xorm:"UNIQUE(follow)"` - FollowID int64 `xorm:"UNIQUE(follow)"` + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"UNIQUE(follow)"` + FollowID int64 `xorm:"UNIQUE(follow)"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` } // IsFollowing returns true if user is following followID. diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index c5f6d6cdd..a51a402c6 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -206,6 +206,15 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { return commits.Front().Value.(*Commit), nil } +func (repo *Repository) GetCommitByPathAndDays(relpath string, days int) (*list.List, error) { + stdout, err := NewCommand("log", "-1", prettyLogFormat, "--since="+fmt.Sprint(days)+".days").RunInDirBytes(relpath) + if err != nil { + return nil, err + } + + return repo.parsePrettyFormatLogToList(stdout) +} + // CommitsRangeSize the default commits range size var CommitsRangeSize = 50 diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 50e85ba27..bf7be287d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -573,7 +573,7 @@ authorized_oauth2_applications_description = You've granted access to your perso revoke_key = Revoke revoke_oauth2_grant = Revoke Access revoke_oauth2_grant_description = Revoking access for this third party application will prevent this application from accessing your data. Are you sure? -revoke_oauth2_grant_success = You've revoked access successfully. +revoke_oauth2_grant_success = You have revoked access successfully. twofa_desc = Two-factor authentication enhances the security of your account. twofa_is_enrolled = Your account is currently enrolled in two-factor authentication. @@ -770,6 +770,7 @@ cloudbrain_selection = select cloudbrain cloudbrain_platform_selection = Select the cloudbrain platform you want to use: confirm_choice = confirm cloudbran1_tips = Only data in zip format can create cloudbrain tasks +cloudbrain_creator=Creator template.items = Template Items template.git_content = Git Content (Default Branch) @@ -831,6 +832,7 @@ fork = Fork download_archive = Download Repository no_desc = No Description +no_label = No labels quick_guide = Quick Guide clone_this_repo = Clone this repository create_new_repo_command = Creating a new repository on the command line diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 89a6282e5..04b3c2e59 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -772,6 +772,7 @@ cloudbrain_selection=云脑选择 cloudbrain_platform_selection=选择您准备使用的云脑平台: confirm_choice=确定 cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 +cloudbrain_creator=创建者 template.items=模板选项 template.git_content=Git数据(默认分支) @@ -833,6 +834,7 @@ fork=派生 download_archive=下载此项目 no_desc=暂无描述 +no_label = 暂无标签 quick_guide=快速帮助 clone_this_repo=克隆当前项目 create_new_repo_command=从命令行创建一个新的项目 diff --git a/public/img/icons.svg b/public/img/icons.svg new file mode 100644 index 000000000..3a83f8cdf --- /dev/null +++ b/public/img/icons.svg @@ -0,0 +1,1653 @@ + + + + 切图 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 存量 + + + + + + + + + + + + + + + + + + + + + + + + R + + + + + M + + + + + A + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsof + t + + + + + G + + + o + + + o + + + g + + + l + + + e + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 托管 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tts.wav + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CSB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 共享 + + + + + + 默认 + + + + + + GPU + + + + + + NEW + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/img/loading.gif b/public/img/loading.gif new file mode 100644 index 000000000..2c45c7bca Binary files /dev/null and b/public/img/loading.gif differ diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index c30906af4..ccd51a89f 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -69,7 +69,8 @@ func CloudBrainIndex(ctx *context.Context) { timestamp := time.Now().Unix() for i, task := range ciTasks { - if task.Status == string(models.JobRunning) && (timestamp-int64(task.CreatedUnix) > 10) { + log.Info("", task.User.Name) + if task.Status == string(models.JobRunning) && (timestamp-int64(task.Cloudbrain.CreatedUnix) > 10) { ciTasks[i].CanDebug = true } else { ciTasks[i].CanDebug = false diff --git a/routers/repo/user_data_analysis.go b/routers/repo/user_data_analysis.go new file mode 100644 index 000000000..13850af7a --- /dev/null +++ b/routers/repo/user_data_analysis.go @@ -0,0 +1,55 @@ +package repo + +import ( + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" +) + +func TimeingCountData() { + //query wiki data + log.Info("start to time count data") + wikiMap := make(map[string]int) + + currentTimeNow := time.Now() + log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05")) + + yesterday := currentTimeNow.AddDate(0, 0, -1) + + repoList := models.QueryAllRepo() + log.Info("start to query wiki data") + for _, repoRecord := range repoList { + wikiPath := models.WikiPath(repoRecord.OwnerName, repoRecord.Name) + time, err := git.GetLatestCommitTime(wikiPath) + if err == nil { + log.Info("last commit time:" + time.Format("2006-01-02 15:04:05") + " wikiPath=" + wikiPath) + if time.After(yesterday) { + wikiRepo, _, err := FindWikiRepoCommitByWikiPath(wikiPath) + if err != nil { + log.Error("wiki not exist. wikiPath=" + wikiPath) + } else { + log.Info("wiki exist, wikiPath=" + wikiPath) + list, err := wikiRepo.GetCommitByPathAndDays(wikiPath, 1) + if err != nil { + log.Info("err,err=v%", err) + } else { + for logEntry := list.Front(); logEntry != nil; logEntry = logEntry.Next() { + commit := logEntry.Value.(*git.Commit) + log.Info("commit msg=" + commit.CommitMessage + " time=" + commit.Committer.When.Format("2006-01-02 15:04:05") + " user=" + commit.Committer.Name) + if _, ok := wikiMap[commit.Committer.Name]; !ok { + wikiMap[commit.Committer.Name] = 1 + } else { + wikiMap[commit.Committer.Name] += 1 + } + } + } + + } + } + } + } + //other user info data + models.CountData(wikiMap) +} diff --git a/routers/repo/wiki.go b/routers/repo/wiki.go index 5da01f21a..03ab42036 100644 --- a/routers/repo/wiki.go +++ b/routers/repo/wiki.go @@ -82,6 +82,20 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) return commit.GetTreeEntryByPath(unescapedTarget) } +func FindWikiRepoCommitByWikiPath(wikiPath string) (*git.Repository, *git.Commit, error) { + wikiRepo, err := git.OpenRepository(wikiPath) + if err != nil { + log.Info("get wiki error.") + return nil, nil, err + } + + commit, err := wikiRepo.GetBranchCommit("master") + if err != nil { + return wikiRepo, nil, err + } + return wikiRepo, commit, nil +} + func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) { wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath()) if err != nil { @@ -150,6 +164,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { if !entry.IsRegular() { continue } + wikiName, err := wiki_service.FilenameToName(entry.Name()) if err != nil { if models.IsErrWikiInvalidFileName(err) { diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 0dac7824c..c22cb9fa7 100755 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -154,7 +154,7 @@ {{svg "octicon-person" 16}} {{.i18n.Tr "register"}} {{end}} - + {{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} diff --git a/templates/base/head_navbar_home.tmpl b/templates/base/head_navbar_home.tmpl index 2379c1782..e6729da62 100644 --- a/templates/base/head_navbar_home.tmpl +++ b/templates/base/head_navbar_home.tmpl @@ -154,7 +154,7 @@ {{svg "octicon-person" 16}} {{.i18n.Tr "register"}} {{end}} - + {{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} diff --git a/templates/repo/cloudbrain/index.tmpl b/templates/repo/cloudbrain/index.tmpl index 532a8f4ff..f39e0605a 100755 --- a/templates/repo/cloudbrain/index.tmpl +++ b/templates/repo/cloudbrain/index.tmpl @@ -187,6 +187,12 @@ cursor: pointer; pointer-events: none; } + .time-show{ + font-size: 10px; + margin-top: 0.4rem; + display: inline-block; + } + @@ -256,23 +262,37 @@
-
- +
- + + {{if eq .Status "STOPPED"}} + 已停止 + {{else if eq .Status "RUNNING"}} + 运行中 + {{else if eq .Status "FAILED"}} + 运行失败 + {{else if eq .Status "WAITING"}} + 初始化等待 + + {{end}} - {{TimeSinceUnix .CreatedUnix $.Lang}} + {{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}
-
+
+ {{$.i18n.Tr "repo.cloudbrain_creator"}}{{.User.Name}} + +
+
{{if and (ne .Status "WAITING") (ne .JobType "DEBUG")}} diff --git a/templates/repo/datasets/dataset_list.tmpl b/templates/repo/datasets/dataset_list.tmpl index cf6c47926..47716418a 100755 --- a/templates/repo/datasets/dataset_list.tmpl +++ b/templates/repo/datasets/dataset_list.tmpl @@ -1,63 +1,52 @@ + {{if .Attachments}} {{range .Attachments}}
-
+ -
- {{.Size | FileSize}} -
-
- {{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}} -
- -
- {{svg "octicon-file" 16}} -
- -
- {{svg "octicon-file-binary" 16}} -
- - - {{if $.IsSigned}} -
- +
+
+ {{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}} + + {{svg "octicon-file-binary" 16}}
- {{end}} - {{if not .CanDel}} -
- {{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}} + {{if ne .DecompressState 0}} + - {{else}} - {{if $.Permission.CanWrite $.UnitTypeDatasets}} + {{end}} + {{if not .CanDel}} + {{$.i18n.Tr "dataset.delete"}} + {{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}} + {{else}} + {{if $.Permission.CanWrite $.UnitTypeDatasets}} + {{$.i18n.Tr "dataset.delete"}} {{if $.Repository.IsPrivate}} - - {{ else }} -
- + {{end}} + {{else}} + {{$.i18n.Tr "dataset.delete"}} + {{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}} {{end}} - - {{else}} - {{end}} - {{end}} +
+
{{end}} diff --git a/templates/repo/datasets/index.tmpl b/templates/repo/datasets/index.tmpl index 6fa6ccb69..b92d5a1ae 100755 --- a/templates/repo/datasets/index.tmpl +++ b/templates/repo/datasets/index.tmpl @@ -80,7 +80,7 @@
-

{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}

+ {{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}