Browse Source

Merge branch 'V20211018' into issue426

pull/500/head
avadesian 3 years ago
parent
commit
1ab7426006
29 changed files with 644 additions and 79 deletions
  1. +10
    -3
      models/cloudbrain.go
  2. +3
    -1
      models/models.go
  3. +5
    -4
      models/repo_watch.go
  4. +8
    -5
      models/star.go
  5. +346
    -0
      models/user_business_analysis.go
  6. +6
    -3
      models/user_follow.go
  7. +9
    -0
      modules/git/repo_commit.go
  8. +26
    -0
      modules/git/repo_stats_custom.go
  9. +2
    -1
      options/locale/locale_en-US.ini
  10. +1
    -0
      options/locale/locale_zh-CN.ini
  11. +2
    -1
      routers/repo/cloudbrain.go
  12. +59
    -0
      routers/repo/user_data_analysis.go
  13. +15
    -0
      routers/repo/wiki.go
  14. +2
    -2
      templates/explore/dataset_search.tmpl
  15. +2
    -2
      templates/explore/search.tmpl
  16. +32
    -16
      templates/repo/cloudbrain/index.tmpl
  17. +2
    -2
      templates/repo/datasets/index.tmpl
  18. +18
    -8
      templates/repo/issue/labels.tmpl
  19. +8
    -2
      templates/repo/issue/list.tmpl
  20. +8
    -2
      templates/repo/issue/milestone_issues.tmpl
  21. +22
    -6
      templates/repo/issue/milestone_new.tmpl
  22. +19
    -8
      templates/repo/issue/milestones.tmpl
  23. +1
    -1
      templates/repo/issue/navbar.tmpl
  24. +15
    -3
      templates/repo/issue/new.tmpl
  25. +1
    -1
      templates/repo/issue/search.tmpl
  26. +7
    -2
      templates/repo/issue/view.tmpl
  27. +1
    -1
      templates/repo/modelarts/index.tmpl
  28. +1
    -1
      templates/user/dashboard/issues.tmpl
  29. +13
    -4
      web_src/less/openi.less

+ 10
- 3
models/cloudbrain.go View File

@@ -65,6 +65,11 @@ type Cloudbrain struct {
Repo *Repository `xorm:"-"` Repo *Repository `xorm:"-"`
} }


type CloudbrainInfo struct {
Cloudbrain `xorm:"extends"`
User `xorm:"extends"`
}

type CloudBrainLoginResult struct { type CloudBrainLoginResult struct {
Code string Code string
Msg string Msg string
@@ -523,7 +528,7 @@ type NotebookDelResult struct {
InstanceID string `json:"instance_id"` InstanceID string `json:"instance_id"`
} }


func Cloudbrains(opts *CloudbrainsOptions) ([]*Cloudbrain, int64, error) {
func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()


@@ -583,8 +588,10 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*Cloudbrain, int64, error) {
} }


sess.OrderBy("cloudbrain.created_unix DESC") 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) return nil, 0, fmt.Errorf("Find: %v", err)
} }
sess.Close() sess.Close()


+ 3
- 1
models/models.go View File

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


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


gonicNames := []string{"SSL", "UID"} gonicNames := []string{"SSL", "UID"}
for _, name := range gonicNames { for _, name := range gonicNames {


+ 5
- 4
models/repo_watch.go View File

@@ -26,10 +26,11 @@ const (


// Watch is connection request for receiving repository notification. // Watch is connection request for receiving repository notification.
type Watch struct { 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 // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found


+ 8
- 5
models/star.go View File

@@ -4,11 +4,14 @@


package models package models


import "code.gitea.io/gitea/modules/timeutil"

// Star represents a starred repo by an user. // Star represents a starred repo by an user.
type Star struct { 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. // StarRepo or unstar repository.
@@ -39,7 +42,7 @@ func StarRepo(userID, repoID int64, star bool) error {
return nil 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 return err
} }
if _, err := sess.Exec("UPDATE `repository` SET num_stars = num_stars - 1 WHERE id = ?", repoID); err != nil { 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 { 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 return has
} }




+ 346
- 0
models/user_business_analysis.go View File

@@ -0,0 +1,346 @@
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
}

+ 6
- 3
models/user_follow.go View File

@@ -4,11 +4,14 @@


package models package models


import "code.gitea.io/gitea/modules/timeutil"

// Follow represents relations of user and his/her followers. // Follow represents relations of user and his/her followers.
type Follow struct { 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. // IsFollowing returns true if user is following followID.


+ 9
- 0
modules/git/repo_commit.go View File

@@ -206,6 +206,15 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
return commits.Front().Value.(*Commit), nil 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 // CommitsRangeSize the default commits range size
var CommitsRangeSize = 50 var CommitsRangeSize = 50




+ 26
- 0
modules/git/repo_stats_custom.go View File

@@ -13,6 +13,7 @@ import (
type RepoKPIStats struct { type RepoKPIStats struct {
Contributors int64 Contributors int64
KeyContributors int64 KeyContributors int64
DevelopAge int64
ContributorsAdded int64 ContributorsAdded int64
CommitsAdded int64 CommitsAdded int64
CommitLinesModified int64 CommitLinesModified int64
@@ -66,6 +67,10 @@ func GetRepoKPIStats(repoPath string) (*RepoKPIStats, error) {


} }


err = setDevelopAge(repoPath, stats)
if err != nil {
return nil, fmt.Errorf("FillFromGit: %v", err)
}
err = setRepoKPIStats(repoPath, fourMonthAgo, stats, newContributersDict) err = setRepoKPIStats(repoPath, fourMonthAgo, stats, newContributersDict)


if err != nil { if err != nil {
@@ -75,6 +80,27 @@ func GetRepoKPIStats(repoPath string) (*RepoKPIStats, error) {


} }


func setDevelopAge(repoPath string, stats *RepoKPIStats) error {
args := []string{"log", "--no-merges", "--branches=*", "--format=%cd", "--date=short"}
stdout, err := NewCommand(args...).RunInDirBytes(repoPath)
if err != nil {
return err
}
scanner := bufio.NewScanner(bytes.NewReader(stdout))
scanner.Split(bufio.ScanLines)
developMonth := make(map[string]struct{})
for scanner.Scan() {
l := strings.TrimSpace(scanner.Text())
month := l[0:strings.LastIndex(l, "-")]
if _, ok := developMonth[month]; !ok {
developMonth[month] = struct{}{}
}
}

stats.DevelopAge = int64(len(developMonth))
return nil
}

//获取一天内的用户贡献指标 //获取一天内的用户贡献指标
func GetUserKPIStats(repoPath string) (map[string]*UserKPIStats, error) { func GetUserKPIStats(repoPath string) (map[string]*UserKPIStats, error) {
timeUntil := time.Now() timeUntil := time.Now()


+ 2
- 1
options/locale/locale_en-US.ini View File

@@ -573,7 +573,7 @@ authorized_oauth2_applications_description = You've granted access to your perso
revoke_key = Revoke revoke_key = Revoke
revoke_oauth2_grant = Revoke Access 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_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_desc = Two-factor authentication enhances the security of your account.
twofa_is_enrolled = Your account is currently <strong>enrolled</strong> in two-factor authentication. twofa_is_enrolled = Your account is currently <strong>enrolled</strong> in two-factor authentication.
@@ -770,6 +770,7 @@ cloudbrain_selection = select cloudbrain
cloudbrain_platform_selection = Select the cloudbrain platform you want to use: cloudbrain_platform_selection = Select the cloudbrain platform you want to use:
confirm_choice = confirm confirm_choice = confirm
cloudbran1_tips = Only data in zip format can create cloudbrain tasks cloudbran1_tips = Only data in zip format can create cloudbrain tasks
cloudbrain_creator=Creator


template.items = Template Items template.items = Template Items
template.git_content = Git Content (Default Branch) template.git_content = Git Content (Default Branch)


+ 1
- 0
options/locale/locale_zh-CN.ini View File

@@ -772,6 +772,7 @@ cloudbrain_selection=云脑选择
cloudbrain_platform_selection=选择您准备使用的云脑平台: cloudbrain_platform_selection=选择您准备使用的云脑平台:
confirm_choice=确定 confirm_choice=确定
cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 cloudbran1_tips=只有zip格式的数据集才能发起云脑任务
cloudbrain_creator=创建者


template.items=模板选项 template.items=模板选项
template.git_content=Git数据(默认分支) template.git_content=Git数据(默认分支)


+ 2
- 1
routers/repo/cloudbrain.go View File

@@ -69,7 +69,8 @@ func CloudBrainIndex(ctx *context.Context) {


timestamp := time.Now().Unix() timestamp := time.Now().Unix()
for i, task := range ciTasks { 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 ciTasks[i].CanDebug = true
} else { } else {
ciTasks[i].CanDebug = false ciTasks[i].CanDebug = false


+ 59
- 0
routers/repo/user_data_analysis.go View File

@@ -0,0 +1,59 @@
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, err := models.GetAllRepositories()
if err != nil {
log.Error("query repo error.")
return
}
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)
}

+ 15
- 0
routers/repo/wiki.go View File

@@ -82,6 +82,20 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
return commit.GetTreeEntryByPath(unescapedTarget) 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) { func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath()) wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
if err != nil { if err != nil {
@@ -150,6 +164,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
if !entry.IsRegular() { if !entry.IsRegular() {
continue continue
} }

wikiName, err := wiki_service.FilenameToName(entry.Name()) wikiName, err := wiki_service.FilenameToName(entry.Name())
if err != nil { if err != nil {
if models.IsErrWikiInvalidFileName(err) { if models.IsErrWikiInvalidFileName(err) {


+ 2
- 2
templates/explore/dataset_search.tmpl View File

@@ -1,12 +1,12 @@
<div class="repos--seach"> <div class="repos--seach">
<div class="ui container"> <div class="ui container">
<div class="ui two column centered grid"> <div class="ui two column centered grid">
<form class="mobile ten wide tablet computer column ui form ignore-dirty">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="{{$.SortType}}"> <input type="hidden" name="sort" value="{{$.SortType}}">
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
<button class="ui green button">{{.i18n.Tr "explore.search"}}</button>
</div> </div>
</form> </form>
</div> </div>


+ 2
- 2
templates/explore/search.tmpl View File

@@ -1,11 +1,11 @@
<div class="repos--seach"> <div class="repos--seach">
<div class="ui container"> <div class="ui container">
<div class="ui two column centered grid"> <div class="ui two column centered grid">
<form class="sixteen wide mobile eight fourteen tablet fourteen wide computer column ui form ignore-dirty">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty">
<div class="ui fluid action input"> <div class="ui fluid action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
<button class="ui green button">{{.i18n.Tr "explore.search"}}</button>
</div> </div>
</form> </form>
</div> </div>


+ 32
- 16
templates/repo/cloudbrain/index.tmpl View File

@@ -262,33 +262,46 @@
<div class="row"> <div class="row">


<!-- 任务名 --> <!-- 任务名 -->
<div class="six wide column">
<a class="title" href="{{$.Link}}/{{.JobID}}">
<div class="five wide column">
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}">
<span class="fitted">{{svg "octicon-tasklist" 16}}</span> <span class="fitted">{{svg "octicon-tasklist" 16}}</span>
<span class="fitted">{{.JobName}}</span>
<span class="fitted text_over" style="width: 90%;">{{.JobName}}</span>
</a> </a>
</div> </div>


<div class="three wide column"> <div class="three wide column">
<!--任务状态 --> <!--任务状态 -->
<!-- <span class="ui compact button job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
{{.Status}}
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
<!-- {{.Status}} -->
<!-- {{if eq .Status "RUNNING"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-stop"></i><span style="margin-left: 0.4em;font-size: 12px;">运行中</span></span>
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-stop"></i><span style="margin-left: 0.4em;font-size: 12px;">运行中</span></span>
{{else}}
{{.Status}}
{{end}} -->
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="{{.Status}}"></i><span style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
</span>
<!-- <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" >
{{if eq .Status "STOPPED"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-stop"></i><span style="margin-left: 0.4em;font-size: 12px;">已停止</span></span>
{{else if eq .Status "RUNNING"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行中</span></span>
{{else if eq .Status "FAILED"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行失败</span></span>
{{else if eq .Status "WAITING"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="showCircle"></i><span style="margin-left: 0.4em;font-size: 12px;">初始化等待</span></span>
{{end}}
</span> --> </span> -->
{{if eq .Status "STOPPED"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-stop"></i><span style="margin-left: 0.4em;font-size: 12px;">已停止</span></span>
{{else if eq .Status "RUNNING"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行中</span></span>
{{else if eq .Status "FAILED"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行失败</span></span>
{{else if eq .Status "WAITING"}}
<span style="display:flex;position: relative; justify-content: flex-start;"><i class="showCircle"></i><span style="margin-left: 0.4em;font-size: 12px;">初始化等待</span></span>
{{end}}
<!-- 任务创建时间 --> <!-- 任务创建时间 -->
<span class="time-show">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>
<span class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div> </div>


<div class="seven wide column text right">
<div class="two wide column">
<span style="display: block;">{{$.i18n.Tr "repo.cloudbrain_creator"}}</span><span class="text_over" title="{{.User.Name}}">{{.User.Name}}</span>

</div>
<div class="six wide column text right">
<div class="ui compact buttons" style="margin-right:10px;"> <div class="ui compact buttons" style="margin-right:10px;">
{{if and (ne .Status "WAITING") (ne .JobType "DEBUG")}} {{if and (ne .Status "WAITING") (ne .JobType "DEBUG")}}
<a class="ui basic button" href="{{$.Link}}/{{.JobID}}/rate" target="_blank"> <a class="ui basic button" href="{{$.Link}}/{{.JobID}}/rate" target="_blank">
@@ -452,15 +465,18 @@
$(document).ready(loadJobStatus); $(document).ready(loadJobStatus);
function loadJobStatus() { function loadJobStatus() {
$(".job-status").each((index, job) => { $(".job-status").each((index, job) => {
console.log("---------",index,job)
const jobID = job.dataset.jobid; const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath; const repoPath = job.dataset.repopath;
if (job.textContent.trim() == 'STOPPED') { if (job.textContent.trim() == 'STOPPED') {
return return
} }


$.get(`/api/v1/repos/${repoPath}/cloudbrain/${jobID}`, (data) => { $.get(`/api/v1/repos/${repoPath}/cloudbrain/${jobID}`, (data) => {
const jobID = data.JobID const jobID = data.JobID
const status = data.JobStatus const status = data.JobStatus
console.log("status",status)
if (status != job.textContent.trim()) { if (status != job.textContent.trim()) {
//$('#' + jobID).text(status) //$('#' + jobID).text(status)
//if (status == 'STOPPED') { //if (status == 'STOPPED') {


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

@@ -37,7 +37,7 @@
</div> </div>
{{if .Permission.CanWrite $.UnitTypeDatasets}} {{if .Permission.CanWrite $.UnitTypeDatasets}}
<div class="column four wide right aligned"> <div class="column four wide right aligned">
<a class="ui button primary" href="javascript:void(0)" id="dataset-edit">
<a class="ui green button" href="javascript:void(0)" id="dataset-edit">
{{.i18n.Tr "dataset.edit"}} {{.i18n.Tr "dataset.edit"}}
</a> </a>
</div> </div>
@@ -66,7 +66,7 @@
<input name="type" value="{{.Type}}" type="hidden" /> <input name="type" value="{{.Type}}" type="hidden" />
<div class="sixteen wide column"> <div class="sixteen wide column">
<a class="ui button" id="cancel">{{.i18n.Tr "cancel"}}</a> <a class="ui button" id="cancel">{{.i18n.Tr "cancel"}}</a>
<button class="ui primary button" id="submit">{{.i18n.Tr "dataset.update_dataset"}}</button>
<button class="ui green button" id="submit">{{.i18n.Tr "dataset.update_dataset"}}</button>
</div> </div>
</div> </div>




+ 18
- 8
templates/repo/issue/labels.tmpl View File

@@ -2,14 +2,24 @@
<div class="repository labels"> <div class="repository labels">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
<div class="ui right">
<div class="ui green new-label button">{{.i18n.Tr "repo.issues.new_label"}}</div>
</div>
{{end}}
</div>
<div class="ui two column stackable grid">
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<div class="action section">{{.Title | RenderEmoji}}</div>
</div>
</div>
<div class="column right aligned">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
<div class="ui right">
<div class="ui green new-label button">{{.i18n.Tr "repo.issues.new_label"}}</div>
</div>
{{end}}
</div>
</div>
<div class="ui divider"></div> <div class="ui divider"></div>
{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}} {{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
{{template "repo/issue/labels/label_new" .}} {{template "repo/issue/labels/label_new" .}}


+ 8
- 2
templates/repo/issue/list.tmpl View File

@@ -3,14 +3,20 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="ui three column stackable grid"> <div class="ui three column stackable grid">
<div class="column">
{{template "repo/issue/navbar" .}}
<div class="column" style="display: flex;align-items: center;">
<!-- <div class="ui large breadcrumb">
<a href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
</div> -->
{{template "repo/issue/navbar" .}}
</div> </div>
<div class="column center aligned"> <div class="column center aligned">
{{template "repo/issue/search" .}} {{template "repo/issue/search" .}}
</div> </div>
{{if not .Repository.IsArchived}} {{if not .Repository.IsArchived}}
<div class="column right aligned"> <div class="column right aligned">
{{if .PageIsIssueList}} {{if .PageIsIssueList}}
<a class="ui green button" href="{{.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> <a class="ui green button" href="{{.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a>
{{else}} {{else}}


+ 8
- 2
templates/repo/issue/milestone_issues.tmpl View File

@@ -3,8 +3,14 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="ui three column stackable grid"> <div class="ui three column stackable grid">
<div class="column">
<h3>{{.Milestone.Name}}</h3>
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<a class="section" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a>
<div class="divider"> / </div>
<div class="action section">{{.Milestone.Name}}</div>
</div>
</div> </div>
<div class="column center aligned"> <div class="column center aligned">




+ 22
- 6
templates/repo/issue/milestone_new.tmpl View File

@@ -2,13 +2,29 @@
<div class="repository new milestone"> <div class="repository new milestone">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) .PageIsEditMilestone}}
<div class="ui right floated secondary menu">
<a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.i18n.Tr "repo.milestones.new"}}</a>
<div class="ui two column stackable grid">
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<a class="section" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a>
<div class="divider"> / </div>
{{if .PageIsEditMilestone}}
<div class="action section">{{.i18n.Tr "repo.milestones.edit"}}</div>
{{else}}
<div class="action section">{{.i18n.Tr "repo.milestones.new"}}</div>
{{end}}
</div>
</div> </div>
{{end}}
<div class="column right aligned">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) .PageIsEditMilestone}}
<div class="ui right floated secondary menu">
<a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.i18n.Tr "repo.milestones.new"}}</a>
</div>
{{end}}
</div>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>
<h2 class="ui dividing header"> <h2 class="ui dividing header">


+ 19
- 8
templates/repo/issue/milestones.tmpl View File

@@ -2,14 +2,25 @@
<div class="repository milestones"> <div class="repository milestones">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
<div class="ui right">
<a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.milestones.new"}}</a>
</div>
{{end}}
</div>
<div class="ui two column stackable grid">
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<div class="action section">{{.Title | RenderEmoji}}</div>
</div>
</div>
{{if not .Repository.IsArchived}}
<div class="column right aligned">
{{template "repo/issue/navbar" .}}
{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
<div class="ui right">
<a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.milestones.new"}}</a>
</div>
{{end}}
</div>
{{end}}
</div>
<div class="ui divider"></div> <div class="ui divider"></div>
{{template "base/alert" .}} {{template "base/alert" .}}
<div class="ui tiny basic buttons"> <div class="ui tiny basic buttons">


+ 1
- 1
templates/repo/issue/navbar.tmpl View File

@@ -1,4 +1,4 @@
<div class="ui compact left small menu">
<div class="ui compact small menu" style="margin-right: 1rem;">
<a class="{{if .PageIsLabels}}active{{end}} item" href="{{.RepoLink}}/labels">{{.i18n.Tr "repo.labels"}}</a> <a class="{{if .PageIsLabels}}active{{end}} item" href="{{.RepoLink}}/labels">{{.i18n.Tr "repo.labels"}}</a>
<a class="{{if .PageIsMilestones}}active{{end}} item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a> <a class="{{if .PageIsMilestones}}active{{end}} item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a>
</div> </div>

+ 15
- 3
templates/repo/issue/new.tmpl View File

@@ -2,9 +2,21 @@
<div class="repository new issue"> <div class="repository new issue">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="navbar">
{{template "repo/issue/navbar" .}}
</div>
<div class="ui two column stackable grid">
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<div class="action section">{{.i18n.Tr "repo.issues.new"}}</div>
</div>
</div>
<div class="column right aligned">
{{template "repo/issue/navbar" .}}
</div>
</div>
<div class="ui divider"></div> <div class="ui divider"></div>
{{template "repo/issue/new_form" .}} {{template "repo/issue/new_form" .}}
</div> </div>


+ 1
- 1
templates/repo/issue/search.tmpl View File

@@ -7,7 +7,7 @@
<input type="hidden" name="assignee" value="{{$.AssigneeID}}"/> <input type="hidden" name="assignee" value="{{$.AssigneeID}}"/>
<div class="ui search action input"> <div class="ui search action input">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<button class="ui blue button" type="submit">{{.i18n.Tr "explore.search"}}</button>
<button class="ui green button" type="submit">{{.i18n.Tr "explore.search"}}</button>
</div> </div>
</div> </div>
</form> </form>

+ 7
- 2
templates/repo/issue/view.tmpl View File

@@ -3,11 +3,16 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="ui two column stackable grid"> <div class="ui two column stackable grid">
<div class="column">
{{template "repo/issue/navbar" .}}
<div class="column" style="display: flex;align-items: center;">
<div class="ui large breadcrumb">
<a class="section" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a>
<div class="divider"> / </div>
<div class="action section">{{.Title | RenderEmoji}}</div>
</div>
</div> </div>
{{if not .Repository.IsArchived}} {{if not .Repository.IsArchived}}
<div class="column right aligned"> <div class="column right aligned">
{{template "repo/issue/navbar" .}}
{{if .PageIsIssueList}} {{if .PageIsIssueList}}
<a class="ui green button" href="{{.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> <a class="ui green button" href="{{.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a>
{{else}} {{else}}


+ 1
- 1
templates/repo/modelarts/index.tmpl View File

@@ -262,7 +262,7 @@
{{.Status}} {{.Status}}
</span> </span>
<!-- 任务创建时间 --> <!-- 任务创建时间 -->
<span class="">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>
<span class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div> </div>


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


+ 1
- 1
templates/user/dashboard/issues.tmpl View File

@@ -74,7 +74,7 @@
<input type="hidden" name="state" value="{{$.State}}"/> <input type="hidden" name="state" value="{{$.State}}"/>
<div class="ui search action input"> <div class="ui search action input">
<input name="q" value="{{$.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> <input name="q" value="{{$.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
<button class="ui blue button" type="submit">{{.i18n.Tr "explore.search"}}</button>
<button class="ui green button" type="submit">{{.i18n.Tr "explore.search"}}</button>
</div> </div>
</div> </div>
</form> </form>


+ 13
- 4
web_src/less/openi.less View File

@@ -224,12 +224,21 @@ footer .column{margin-bottom:0!important; padding-bottom:0!important;}
// icon cloudbrain // icon cloudbrain
.i-round{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;} .i-round{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;}
.i-bg-organ{background-position: -496px -52px;} .i-bg-organ{background-position: -496px -52px;}
.i-bg-stop{background-position: -459px -52px;}
.i-bg-running{background-position: -478px -52px;}
.STOPPED{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;background-position: -459px -52px;}
.RUNNING{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;background-position: -478px -52px;}
.i-bg-orange{background-position: -495px -51px;} .i-bg-orange{background-position: -495px -51px;}
.i-bg-red{background-position: -532px -52px;}
.FAILED{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;background-position: -532px -52px;}
.i-bg-green{background-position: -441px -52px;} .i-bg-green{background-position: -441px -52px;}
.i-bg-used{background-position: -514px -52px;} .i-bg-used{background-position: -514px -52px;}
.icon-bind{background-position: -550px -52px;} .icon-bind{background-position: -550px -52px;}
.icon-unbind{background-position: -568px -52px;} .icon-unbind{background-position: -568px -52px;}
.showCircle{display:inline-block;background-image:url('/img/loading.gif');background-repeat:no-repeat;width:16px;height:16px;background-size:16px 16px;margin-right:5px;}
.WAITING{display:inline-block;background-image:url('/img/loading.gif');background-repeat:no-repeat;width:16px;height:16px;background-size:16px 16px;margin-right:5px;}
.text_over{
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
width: 100%;
}


Loading…
Cancel
Save