| @@ -87,6 +87,8 @@ GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(fi | |||
| WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | |||
| WEBPACK_CONFIGS := webpack.config.js | |||
| WEBPACK_CONFIGS_TMP := webpack_temp.config.js | |||
| WEBPACK_CONFIGS_PRO := webpack_pro.config.js | |||
| WEBPACK_DEST := public/js/index.js public/css/index.css | |||
| WEBPACK_DEST_DIRS := public/js public/css public/fonts | |||
| @@ -290,7 +292,7 @@ lint-backend: golangci-lint revive vet swagger-check swagger-validate test-vendo | |||
| .PHONY: lint-frontend | |||
| lint-frontend: node_modules | |||
| npx eslint web_src/js webpack.config.js | |||
| npx eslint web_src/js $(WEBPACK_CONFIGS) | |||
| npx stylelint web_src/less | |||
| .PHONY: watch-frontend | |||
| @@ -504,7 +506,7 @@ install: $(wildcard *.go) | |||
| build: frontend backend | |||
| .PHONY: frontend | |||
| frontend: node-check $(FOMANTIC_DEST) $(WEBPACK_DEST) | |||
| frontend: node-check webpack_prepare $(FOMANTIC_DEST) $(WEBPACK_DEST) webpack_end | |||
| .PHONY: backend | |||
| backend: go-check generate $(EXECUTABLE) | |||
| @@ -596,6 +598,19 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules | |||
| .PHONY: webpack | |||
| webpack: $(WEBPACK_DEST) | |||
| webpack_prepare: | |||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||
| echo "prepare"; \ | |||
| cp $(WEBPACK_CONFIGS) $(WEBPACK_CONFIGS_TMP); \ | |||
| cp $(WEBPACK_CONFIGS_PRO) $(WEBPACK_CONFIGS); \ | |||
| fi | |||
| webpack_end: | |||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||
| echo "end"; \ | |||
| mv $(WEBPACK_CONFIGS_TMP) $(WEBPACK_CONFIGS); \ | |||
| fi | |||
| $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules | |||
| rm -rf $(WEBPACK_DEST_DIRS) | |||
| @@ -3,6 +3,7 @@ package models | |||
| import ( | |||
| "encoding/json" | |||
| "fmt" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| @@ -92,9 +93,10 @@ type Cloudbrain struct { | |||
| JobID string `xorm:"INDEX NOT NULL"` | |||
| JobType string `xorm:"INDEX NOT NULL DEFAULT 'DEBUG'"` | |||
| JobName string | |||
| DisplayJobName string | |||
| Status string | |||
| UserID int64 | |||
| RepoID int64 | |||
| UserID int64 `xorm:"INDEX NOT NULL"` | |||
| RepoID int64 `xorm:"INDEX NOT NULL"` | |||
| SubTaskName string | |||
| ContainerID string | |||
| ContainerIp string | |||
| @@ -144,8 +146,10 @@ type Cloudbrain struct { | |||
| CkptName string //权重文件名称 | |||
| ResultUrl string //推理结果的obs路径 | |||
| User *User `xorm:"-"` | |||
| Repo *Repository `xorm:"-"` | |||
| User *User `xorm:"-"` | |||
| Repo *Repository `xorm:"-"` | |||
| BenchmarkTypeName string `xorm:"-"` | |||
| BenchmarkTypeRankLink string `xorm:"-"` | |||
| } | |||
| type CloudbrainInfo struct { | |||
| @@ -407,9 +411,10 @@ type BenchmarkTypes struct { | |||
| } | |||
| type BenchmarkType struct { | |||
| Id int `json:"id"` | |||
| First string `json:"first"` //一级算法类型名称 | |||
| Second []*BenchmarkDataset `json:"second"` | |||
| Id int `json:"id"` | |||
| RankLink string `json:"rank_link"` | |||
| First string `json:"first"` //一级算法类型名称 | |||
| Second []*BenchmarkDataset `json:"second"` | |||
| } | |||
| type BenchmarkDataset struct { | |||
| @@ -1195,7 +1200,7 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) { | |||
| ) | |||
| cloudbrains := make([]*CloudbrainInfo, 0) | |||
| if err := sess.Select("job_id,job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | |||
| if err := sess.Select("job_id,display_job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | |||
| Find(&cloudbrains); err != nil { | |||
| return nil, 0, fmt.Errorf("Find: %v", err) | |||
| } | |||
| @@ -1204,7 +1209,7 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) { | |||
| uniqueElements := make([]*CloudbrainInfo, 0) | |||
| for _, entry := range cloudbrains { | |||
| if _, value := keys[entry.JobID]; !value { | |||
| keys[entry.JobID] = entry.JobName | |||
| keys[entry.JobID] = entry.DisplayJobName | |||
| uniqueElements = append(uniqueElements, entry) | |||
| } | |||
| } | |||
| @@ -1304,6 +1309,12 @@ func GetCloudbrainByJobID(jobID string) (*Cloudbrain, error) { | |||
| return getRepoCloudBrain(cb) | |||
| } | |||
| func GetCloudbrainByID(id string) (*Cloudbrain, error) { | |||
| idInt64, _ := strconv.ParseInt(id, 10, 64) | |||
| cb := &Cloudbrain{ID: idInt64} | |||
| return getRepoCloudBrain(cb) | |||
| } | |||
| func GetCloudbrainByJobIDAndVersionName(jobID string, versionName string) (*Cloudbrain, error) { | |||
| cb := &Cloudbrain{JobID: jobID, VersionName: versionName} | |||
| return getRepoCloudBrain(cb) | |||
| @@ -1326,6 +1337,12 @@ func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | |||
| return cloudBrains, err | |||
| } | |||
| func GetCloudbrainsByDisplayJobName(repoID int64, jobType string, displayJobName string) ([]*Cloudbrain, error) { | |||
| cloudBrains := make([]*Cloudbrain, 0) | |||
| err := x.Cols("job_id", "job_name", "repo_id", "user_id", "job_type", "display_job_name").Where("repo_id=? AND job_type =? AND lower(display_job_name) = lower(?)", repoID, jobType, displayJobName).Find(&cloudBrains) | |||
| return cloudBrains, err | |||
| } | |||
| func SetCloudbrainStatusByJobID(jobID string, status CloudbrainStatus) (err error) { | |||
| cb := &Cloudbrain{JobID: jobID, Status: string(status)} | |||
| _, err = x.Cols("status").Where("cloudbrain.job_id=?", jobID).Update(cb) | |||
| @@ -4,26 +4,27 @@ | |||
| package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/log" | |||
| ) | |||
| import "code.gitea.io/gitea/modules/log" | |||
| // GetUserDataSetPermission returns the user permissions to the data_set | |||
| func GetUserDataSetPermission(dataSet *Dataset, user *User) (isPermit bool, err error) { | |||
| isPermit = false | |||
| switch dataSet.Status { | |||
| case DatasetStatusDeleted: | |||
| log.Error("the data_set has been deleted") | |||
| case DatasetStatusPrivate: | |||
| if !user.IsAdmin && user.ID != dataSet.UserID { | |||
| log.Error("the user is not admin nor the owner of the data_set") | |||
| if user != nil { | |||
| switch dataSet.Status { | |||
| case DatasetStatusDeleted: | |||
| log.Error("the data_set has been deleted") | |||
| case DatasetStatusPrivate: | |||
| if !user.IsAdmin && user.ID != dataSet.UserID { | |||
| log.Error("the user is not admin nor the owner of the data_set") | |||
| } | |||
| isPermit = true | |||
| case DatasetStatusPublic: | |||
| isPermit = true | |||
| default: | |||
| log.Error("the status of data_set is wrong") | |||
| } | |||
| isPermit = true | |||
| case DatasetStatusPublic: | |||
| isPermit = true | |||
| default: | |||
| log.Error("the status of data_set is wrong") | |||
| } | |||
| return isPermit, nil | |||
| @@ -180,8 +180,8 @@ func CreateOrganization(org, owner *User) (err error) { | |||
| // Add initial creator to organization and owner team. | |||
| if _, err = sess.Insert(&OrgUser{ | |||
| UID: owner.ID, | |||
| OrgID: org.ID, | |||
| UID: owner.ID, | |||
| OrgID: org.ID, | |||
| IsPublic: setting.Service.DefaultOrgMemberVisible, | |||
| }); err != nil { | |||
| return fmt.Errorf("insert org-user relation: %v", err) | |||
| @@ -1543,6 +1543,21 @@ func GetAllRepositoriesCount() (int64, error) { | |||
| return x.Count(repo) | |||
| } | |||
| func GetAllPublicRepositoriesCount() (int64, error) { | |||
| repo := new(Repository) | |||
| return x.Where("is_private = ?", false).Count(repo) | |||
| } | |||
| func GetAllMirrorRepositoriesCount() (int64, error) { | |||
| repo := new(Repository) | |||
| return x.Where("is_mirror = ?", true).Count(repo) | |||
| } | |||
| func GetAllForkRepositoriesCount() (int64, error) { | |||
| repo := new(Repository) | |||
| return x.Where("is_fork = ?", true).Count(repo) | |||
| } | |||
| func GetAllRepositoriesSize() (int64, error) { | |||
| return x.SumInt(&Repository{}, "size") | |||
| } | |||
| @@ -9,43 +9,45 @@ import ( | |||
| // RepoStatistic statistic info of all repository | |||
| type RepoStatistic struct { | |||
| ID int64 `xorm:"pk autoincr" json:"-"` | |||
| RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | |||
| Name string `xorm:"INDEX" json:"name"` | |||
| Alias string `xorm:"INDEX" json:"alias"` | |||
| OwnerName string `json:"ownerName"` | |||
| IsPrivate bool `json:"isPrivate"` | |||
| IsMirror bool `json:"isMirror"` | |||
| Date string `xorm:"unique(s) NOT NULL" json:"date"` | |||
| NumWatches int64 `xorm:"NOT NULL DEFAULT 0" json:"watch"` | |||
| NumWatchesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumStars int64 `xorm:"NOT NULL DEFAULT 0" json:"star"` | |||
| NumStarsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumForks int64 `xorm:"NOT NULL DEFAULT 0" json:"fork"` | |||
| NumForksAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumDownloads int64 `xorm:"NOT NULL DEFAULT 0" json:"download"` | |||
| NumDownloadsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumComments int64 `xorm:"NOT NULL DEFAULT 0" json:"comment"` | |||
| NumCommentsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumVisits int64 `xorm:"NOT NULL DEFAULT 0" json:"view"` | |||
| NumClosedIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issueClosed"` | |||
| NumClosedIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumVersions int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"` | |||
| NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issue"` | |||
| NumIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumPulls int64 `xorm:"NOT NULL DEFAULT 0" json:"pr"` | |||
| NumPullsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| IssueFixedRate float32 `xorm:"NOT NULL" json:"issueClosedRatio"` | |||
| NumContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"contributor"` | |||
| NumContributorAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumKeyContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| ID int64 `xorm:"pk autoincr" json:"-"` | |||
| RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | |||
| Name string `xorm:"INDEX" json:"name"` | |||
| Alias string `xorm:"INDEX" json:"alias"` | |||
| OwnerName string `json:"ownerName"` | |||
| IsPrivate bool `json:"isPrivate"` | |||
| IsMirror bool `json:"isMirror"` | |||
| IsFork bool `json:"isFork"` | |||
| RepoCreatedUnix timeutil.TimeStamp `xorm:"NOT NULL DEFAULT 0" json:"createUnix"` | |||
| Date string `xorm:"unique(s) NOT NULL" json:"date"` | |||
| NumWatches int64 `xorm:"NOT NULL DEFAULT 0" json:"watch"` | |||
| NumWatchesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumStars int64 `xorm:"NOT NULL DEFAULT 0" json:"star"` | |||
| NumStarsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumForks int64 `xorm:"NOT NULL DEFAULT 0" json:"fork"` | |||
| NumForksAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumDownloads int64 `xorm:"NOT NULL DEFAULT 0" json:"download"` | |||
| NumDownloadsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumComments int64 `xorm:"NOT NULL DEFAULT 0" json:"comment"` | |||
| NumCommentsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumVisits int64 `xorm:"NOT NULL DEFAULT 0" json:"view"` | |||
| NumClosedIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issueClosed"` | |||
| NumClosedIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumVersions int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"` | |||
| NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issue"` | |||
| NumIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumPulls int64 `xorm:"NOT NULL DEFAULT 0" json:"pr"` | |||
| NumPullsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| IssueFixedRate float32 `xorm:"NOT NULL" json:"issueClosedRatio"` | |||
| NumContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"contributor"` | |||
| NumContributorAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumKeyContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumContributorsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| NumCommitsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||
| @@ -40,6 +40,11 @@ type SummaryStatistic struct { | |||
| NumRepoLeagueLearn int `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoDataMining int `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoRISC int `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoPublic int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoPrivate int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoFork int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoMirror int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoSelf int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | |||
| } | |||
| @@ -324,3 +324,16 @@ func SaveTopics(repoID int64, topicNames ...string) error { | |||
| return sess.Commit() | |||
| } | |||
| func GetOrgTopics(orgId int64) ([]Topic, error) { | |||
| result := make([]Topic, 0) | |||
| sql := "select distinct(t.*) from repository r " + | |||
| "inner join repo_topic rt on rt.repo_id = r.id " + | |||
| "inner join topic t on rt.topic_id = t.id " + | |||
| "where r.owner_id = ? order by repo_count desc limit 50" | |||
| if e := x.SQL(sql, orgId).Find(&result); e != nil { | |||
| return nil, e | |||
| } | |||
| return result, nil | |||
| } | |||
| @@ -7,6 +7,7 @@ import ( | |||
| type CreateCloudBrainForm struct { | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||
| Image string `form:"image" binding:"Required"` | |||
| Command string `form:"command" binding:"Required"` | |||
| Attachment string `form:"attachment" binding:"Required"` | |||
| @@ -16,11 +16,12 @@ func (f *CreateModelArtsForm) Validate(ctx *macaron.Context, errs binding.Errors | |||
| } | |||
| type CreateModelArtsNotebookForm struct { | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| Attachment string `form:"attachment"` | |||
| Description string `form:"description"` | |||
| Flavor string `form:"flavor" binding:"Required"` | |||
| ImageId string `form:"image_id" binding:"Required"` | |||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| Attachment string `form:"attachment"` | |||
| Description string `form:"description"` | |||
| Flavor string `form:"flavor" binding:"Required"` | |||
| ImageId string `form:"image_id" binding:"Required"` | |||
| } | |||
| func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| @@ -28,6 +29,7 @@ func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs bindin | |||
| } | |||
| type CreateModelArtsTrainJobForm struct { | |||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| Attachment string `form:"attachment" binding:"Required"` | |||
| BootFile string `form:"boot_file" binding:"Required"` | |||
| @@ -47,6 +49,7 @@ type CreateModelArtsTrainJobForm struct { | |||
| } | |||
| type CreateModelArtsInferenceJobForm struct { | |||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| Attachment string `form:"attachment" binding:"Required"` | |||
| BootFile string `form:"boot_file" binding:"Required"` | |||
| @@ -85,30 +85,69 @@ func isAdminOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error | |||
| func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| var ID = ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByID failed:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| ctx.Cloudbrain = job | |||
| if !isAdminOrOwnerOrJobCreater(ctx, job, err) { | |||
| log.Error("!isAdminOrOwnerOrJobCreater error:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| } | |||
| func AdminOrJobCreaterRight(ctx *context.Context) { | |||
| var ID = ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByID failed:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| ctx.Cloudbrain = job | |||
| if !isAdminOrJobCreater(ctx, job, err) { | |||
| log.Error("!isAdminOrJobCreater error:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| } | |||
| func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobID failed:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| ctx.Cloudbrain = job | |||
| if !isAdminOrOwnerOrJobCreater(ctx, job, err) { | |||
| log.Error("!isAdminOrOwnerOrJobCreater failed:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| } | |||
| func AdminOrJobCreaterRight(ctx *context.Context) { | |||
| func AdminOrJobCreaterRightForTrain(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobID failed:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| ctx.Cloudbrain = job | |||
| if !isAdminOrJobCreater(ctx, job, err) { | |||
| log.Error("!isAdminOrJobCreater errot:%v", err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| } | |||
| } | |||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||
| func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| @@ -212,6 +251,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobID, | |||
| JobName: jobName, | |||
| DisplayJobName: displayJobName, | |||
| SubTaskName: SubTaskName, | |||
| JobType: jobType, | |||
| Type: models.TypeCloudBrainOne, | |||
| @@ -229,16 +269,23 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||
| return err | |||
| } | |||
| task, err := models.GetCloudbrainByName(jobName) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByName failed: %v", err.Error()) | |||
| return err | |||
| } | |||
| stringId := strconv.FormatInt(task.ID, 10) | |||
| if string(models.JobTypeBenchmark) == jobType { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateBenchMarkTask) | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | |||
| } else { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateDebugGPUTask) | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | |||
| } | |||
| return nil | |||
| } | |||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string) error { | |||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| @@ -343,6 +390,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string | |||
| RepoID: task.RepoID, | |||
| JobID: jobID, | |||
| JobName: task.JobName, | |||
| DisplayJobName: task.DisplayJobName, | |||
| SubTaskName: task.SubTaskName, | |||
| JobType: task.JobType, | |||
| Type: task.Type, | |||
| @@ -359,7 +407,8 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string | |||
| return err | |||
| } | |||
| *newJobID = jobID | |||
| idString := strconv.FormatInt(newTask.ID, 10) | |||
| *newID = idString | |||
| return nil | |||
| } | |||
| @@ -70,6 +70,7 @@ var ( | |||
| type GenerateTrainJobReq struct { | |||
| JobName string | |||
| DisplayJobName string | |||
| Uuid string | |||
| Description string | |||
| CodeObsPath string | |||
| @@ -95,33 +96,9 @@ type GenerateTrainJobReq struct { | |||
| TotalVersionCount int | |||
| } | |||
| type GenerateTrainJobVersionReq struct { | |||
| JobName string | |||
| Uuid string | |||
| Description string | |||
| CodeObsPath string | |||
| BootFile string | |||
| BootFileUrl string | |||
| DataUrl string | |||
| TrainUrl string | |||
| FlavorCode string | |||
| LogUrl string | |||
| PoolID string | |||
| WorkServerNumber int | |||
| EngineID int64 | |||
| Parameters []models.Parameter | |||
| Params string | |||
| PreVersionId int64 | |||
| CommitID string | |||
| BranchName string | |||
| FlavorName string | |||
| EngineName string | |||
| PreVersionName string | |||
| TotalVersionCount int | |||
| } | |||
| type GenerateInferenceJobReq struct { | |||
| JobName string | |||
| DisplayJobName string | |||
| Uuid string | |||
| Description string | |||
| CodeObsPath string | |||
| @@ -266,7 +243,7 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||
| return nil | |||
| } | |||
| func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, imageId string) error { | |||
| func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, flavor, imageId string) error { | |||
| if poolInfos == nil { | |||
| json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | |||
| } | |||
| @@ -302,6 +279,7 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobResult.ID, | |||
| JobName: jobName, | |||
| DisplayJobName: displayJobName, | |||
| JobType: string(models.JobTypeDebug), | |||
| Type: models.TypeCloudBrainTwo, | |||
| Uuid: uuid, | |||
| @@ -313,7 +291,13 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, | |||
| if err != nil { | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||
| task, err := models.GetCloudbrainByName(jobName) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByName failed: %v", err.Error()) | |||
| return err | |||
| } | |||
| stringId := strconv.FormatInt(task.ID, 10) | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask) | |||
| return nil | |||
| } | |||
| @@ -354,6 +338,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobId, | |||
| JobName: req.JobName, | |||
| DisplayJobName: req.DisplayJobName, | |||
| JobType: string(models.JobTypeTrain), | |||
| Type: models.TypeCloudBrainTwo, | |||
| VersionID: jobResult.VersionID, | |||
| @@ -380,10 +365,10 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| }) | |||
| if err != nil { | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error()) | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.JobName, models.ActionCreateTrainTask) | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.DisplayJobName, models.ActionCreateTrainTask) | |||
| return nil | |||
| } | |||
| @@ -438,6 +423,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | |||
| JobName: req.JobName, | |||
| DisplayJobName: req.DisplayJobName, | |||
| JobType: string(models.JobTypeTrain), | |||
| Type: models.TypeCloudBrainTwo, | |||
| VersionID: jobResult.VersionID, | |||
| @@ -574,6 +560,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobID, | |||
| JobName: req.JobName, | |||
| DisplayJobName: req.DisplayJobName, | |||
| JobType: string(models.JobTypeInference), | |||
| Type: models.TypeCloudBrainTwo, | |||
| VersionID: jobResult.VersionID, | |||
| @@ -608,7 +595,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.JobName, models.ActionCreateInferenceTask) | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateInferenceTask) | |||
| return nil | |||
| } | |||
| @@ -35,7 +35,8 @@ const ( | |||
| //error code | |||
| modelartsIllegalToken = "ModelArts.6401" | |||
| NotebookNotFound = "ModelArts.6404" | |||
| NotebookNoPermission = "ModelArts.6403" | |||
| NotebookNoPermission = "ModelArts.6407" | |||
| NotebookInvalid = "ModelArts.6400" | |||
| ) | |||
| func getRestyClient() *resty.Client { | |||
| @@ -86,5 +86,11 @@ func ForkRepository(doer, owner *models.User, oldRepo *models.Repository, name, | |||
| if err := models.CopyLanguageStat(oldRepo, repo); err != nil { | |||
| log.Error("Copy language stat from oldRepo failed") | |||
| } | |||
| //inherit parent repo's topics | |||
| if len(oldRepo.Topics) > 0 { | |||
| if err := models.SaveTopics(repo.ID, oldRepo.Topics...); err != nil { | |||
| log.Error("SaveTopics failed when fork,e=%v", err) | |||
| } | |||
| } | |||
| return repo, models.CopyLFS(ctx, repo, oldRepo) | |||
| } | |||
| @@ -752,5 +752,5 @@ func licenses() []string { | |||
| // Dataset tasks | |||
| func tasks() []string { | |||
| return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_recognition", "speech_synthesis"} | |||
| return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_synthesis"} | |||
| } | |||
| @@ -6,8 +6,10 @@ package util | |||
| import ( | |||
| "bytes" | |||
| "math/rand" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| // OptionalBool a boolean that can be "null" | |||
| @@ -110,3 +112,16 @@ func AddZero(t int64) (m string) { | |||
| return strconv.FormatInt(t, 10) | |||
| } | |||
| } | |||
| func ConvertDisplayJobNameToJobName(DisplayName string) (JobName string) { | |||
| t := time.Now() | |||
| JobName = "openi" + strings.ToLower(cutNameString(DisplayName, 15)) + "t" + t.Format("20060102150405")[4:] + strconv.Itoa(int(rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000))) | |||
| return JobName | |||
| } | |||
| func cutNameString(str string, lens int) string { | |||
| if len(str) < lens { | |||
| return str | |||
| } | |||
| return str[:lens] | |||
| } | |||
| @@ -235,7 +235,7 @@ page_recommend_org_more=More Organizations | |||
| page_recommend_repo=Recommended Projects | |||
| page_recommend_repo_desc=Excellent AI projects recommendation. To show your project here, | |||
| page_recommend_repo_commit=Click here to submit. | |||
| page_recommend_repo_go=Click here to | |||
| page_recommend_repo_go=Click here to | |||
| page_recommend_repo_more=explore more projects. | |||
| page_dev_env=Collaborative Development Environment | |||
| page_dev_env_desc=Provide a collaborative development environment for AI development, which is the biggest highlight that distinguishes the OpenI AI Collaboration Platform from other traditional Git platforms. | |||
| @@ -795,6 +795,7 @@ current_project=Current Project | |||
| owner_dataset=Owner Dataset | |||
| public_dataset=Public Dataset | |||
| I_liked = I Liked | |||
| use = Use | |||
| [repo] | |||
| owner = Owner | |||
| repo_name = Repository Name | |||
| @@ -859,6 +860,8 @@ model_rename=Duplicate model name, please modify model name. | |||
| debug=Debug | |||
| stop=Stop | |||
| delete=Delete | |||
| more=More | |||
| gpu_type_all=All | |||
| model_download=Model Download | |||
| submit_image=Submit Image | |||
| download=Download | |||
| @@ -888,6 +891,8 @@ cloudbrain_status_createtime = Status/Createtime | |||
| cloudbrain_status_runtime = Running Time | |||
| cloudbrain_jobname_err=Name must start with a lowercase letter or number,can include lowercase letter,number,_ and -,can not end with _, and can be up to 36 characters long. | |||
| cloudbrain_query_fail=Failed to query cloudbrain information. | |||
| cloudbrain.mirror_tag = Mirror Tag | |||
| cloudbrain.mirror_description = Mirror Description | |||
| record_begintime_get_err=Can not get the record begin time. | |||
| parameter_is_wrong=The input parameter is wrong. | |||
| @@ -1264,6 +1269,7 @@ issues.filter_sort.moststars = Most stars | |||
| issues.filter_sort.feweststars = Fewest stars | |||
| issues.filter_sort.mostforks = Most forks | |||
| issues.filter_sort.fewestforks = Fewest forks | |||
| issues.filter_sort.downloadtimes = Most downloaded | |||
| issues.action_open = Open | |||
| issues.action_close = Close | |||
| issues.action_label = Label | |||
| @@ -2098,14 +2104,17 @@ team_unit_disabled = (Disabled) | |||
| selected_couse=Selected Courses | |||
| release_course = Publish Course | |||
| all_keywords=All keywords | |||
| all_org_topics=All | |||
| max_selectedPro= Select up to 9 public projects | |||
| custom_select_courses = Customize selected courses | |||
| custom_select_courses = Customize selected courses | |||
| recommend_remain_pro = Remain | |||
| save_fail_tips = The upper limit is exceeded | |||
| select_again = Select more than 9, please select again! | |||
| custom_select_projects = Customize selected projects | |||
| custom_select_projects = Customize selected projects | |||
| customize = Customize | |||
| selected_project=Selected Projects | |||
| fold = Fold | |||
| unfold = Unfold | |||
| form.name_reserved = The organization name '%s' is reserved. | |||
| form.name_pattern_not_allowed = The pattern '%s' is not allowed in an organization name. | |||
| @@ -2350,6 +2359,9 @@ repos.size = Size | |||
| repos.id=ID | |||
| repos.projectName=Project Name | |||
| repos.isPrivate=Private | |||
| repos.create=Project Create Time | |||
| repos.isFork=Fork | |||
| repos.isMirror=Mirror | |||
| repos.openi=OpenI | |||
| repos.visit=Visit | |||
| repos.download=Code Download | |||
| @@ -2802,3 +2814,20 @@ foot.help = help | |||
| foot.copyright= Copyright: New Generation Artificial Intelligence Open Source Open Platform (OpenI) | |||
| Platform_Tutorial = Tutorial | |||
| foot.advice_feedback = Feedback | |||
| [cloudbrain] | |||
| compute_resource = Computing resources | |||
| task_name = Task name | |||
| task_type = Task type | |||
| gpu_type = GPU type | |||
| mirror = Mirror | |||
| dataset = Dataset | |||
| resource_specification = Resource specification | |||
| dataset_storage_path = Dataset storage path | |||
| model_storage_path = Model storage path | |||
| code_storage_path = Code storage path | |||
| benchmark_path = Benchmark script path | |||
| snn4imagenet_path = Snn4imagenet script path | |||
| brainscore_path = Brainscore script path | |||
| start_command = Start command | |||
| choose_mirror = select mirror | |||
| @@ -799,7 +799,8 @@ select_dataset=选择数据集 | |||
| current_project=当前项目 | |||
| owner_dataset=我的数据集 | |||
| public_dataset=公开数据集 | |||
| I_liked=我点赞的 | |||
| I_liked=我收藏的 | |||
| use=使用 | |||
| [repo] | |||
| owner=拥有者 | |||
| repo_name=项目名称 | |||
| @@ -865,6 +866,8 @@ debug=调试 | |||
| debug_again=再次调试 | |||
| stop=停止 | |||
| delete=删除 | |||
| more=更多 | |||
| gpu_type_all=全部 | |||
| model_download=结果下载 | |||
| submit_image=提交镜像 | |||
| download=模型下载 | |||
| @@ -893,6 +896,8 @@ cloudbrain_status_createtime=状态/创建时间 | |||
| cloudbrain_status_runtime = 运行时长 | |||
| cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | |||
| cloudbrain_query_fail=查询云脑任务失败。 | |||
| cloudbrain.mirror_tag = 镜像标签 | |||
| cloudbrain.mirror_description = 镜像描述 | |||
| record_begintime_get_err=无法获取统计开始时间。 | |||
| parameter_is_wrong=输入参数错误,请检查输入参数。 | |||
| @@ -2106,8 +2111,9 @@ team_permission_desc=权限 | |||
| team_unit_desc=允许访问项目单元 | |||
| team_unit_disabled=(已禁用) | |||
| selected_couse=精选课程 | |||
| release_course = 发布课程 | |||
| release_course = 发布课程 | |||
| all_keywords=全部关键字 | |||
| all_org_topics=全部 | |||
| max_selectedPro= 最多可选9个公开项目 | |||
| custom_select_courses = 自定义精选课程 | |||
| recommend_remain_pro = 还能推荐 | |||
| @@ -2116,6 +2122,8 @@ select_again = 选择超过9个,请重新选择! | |||
| custom_select_projects = 自定义精选项目 | |||
| customize = 自定义 | |||
| selected_project=精选项目 | |||
| fold = 收起 | |||
| unfold = 展开 | |||
| form.name_reserved=组织名称 '%s' 是被保留的。 | |||
| form.name_pattern_not_allowed=组织名称中不允许使用 "%s"。 | |||
| @@ -2361,6 +2369,9 @@ repos.size=大小 | |||
| repos.id=ID | |||
| repos.projectName=项目名称 | |||
| repos.isPrivate=私有 | |||
| repos.create=项目创建时间 | |||
| repos.isFork=派生 | |||
| repos.isMirror=镜像 | |||
| repos.openi=OpenI指数 | |||
| repos.visit=浏览量 | |||
| repos.download=代码下载量 | |||
| @@ -2813,3 +2824,20 @@ foot.help=帮助 | |||
| foot.copyright= 版权所有:新一代人工智能开源开放平台(OpenI) | |||
| Platform_Tutorial=新手指引 | |||
| foot.advice_feedback = 意见反馈 | |||
| [cloudbrain] | |||
| compute_resource = 计算资源 | |||
| task_name = 任务名称 | |||
| task_type = 任务类型 | |||
| gpu_type = GPU类型 | |||
| mirror = 镜像 | |||
| dataset = 数据集 | |||
| resource_specification = 资源规格 | |||
| dataset_storage_path = 数据集存放路径 | |||
| model_storage_path = 模型存放路径 | |||
| code_storage_path = 代码存放路径 | |||
| benchmark_path = benchmark脚本存放路径 | |||
| snn4imagenet_path = snn4imagenet脚本存放路径 | |||
| brainscore_path = brainscore脚本存放路径 | |||
| start_command = 启动命令 | |||
| choose_mirror = 选择镜像或输入镜像地址 | |||
| @@ -113,12 +113,18 @@ socket.onmessage = function (e) { | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" +getRepotext(record) + "</a>" | |||
| } | |||
| else if(record.OpType == "9" || record.OpType == "5"){ | |||
| branch = "<a href=\"" + getRepoLink(record) + "/src/branch/" + record.RefName + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| else if(record.OpType == "5"){ | |||
| branch = "<a href=\"" + getRepoLink(record) + "/src/branch/" + encodeURI(record.RefName) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| actionName = actionName.replace("{branch}",branch); | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | |||
| }else if(record.OpType == "17"){ | |||
| }else if(record.OpType == "9"){ | |||
| branch = "<a href=\"" + getRepoLink(record) + "/src/tag/" + encodeURI(record.RefName) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| actionName = actionName.replace("{branch}",branch); | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | |||
| } | |||
| else if(record.OpType == "17"){ | |||
| actionName = actionName.replace("{deleteBranchName}",record.RefName); | |||
| var repoLink = "<a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | |||
| actionName = actionName.replace("{repoName}",repoLink); | |||
| @@ -129,7 +135,11 @@ socket.onmessage = function (e) { | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | |||
| } | |||
| else if(record.OpType == "24" || record.OpType == "25" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "29" || record.OpType == "30"){ | |||
| else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"){ | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| } | |||
| else if(record.OpType == "25" || record.OpType == "29"){ | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| } | |||
| @@ -152,20 +162,21 @@ socket.onmessage = function (e) { | |||
| function getTaskLink(record){ | |||
| var re = getRepoLink(record); | |||
| if(record.OpType == 24){ | |||
| return re + "/datasets?type=" + record.Content; | |||
| re = re + "/datasets?type=" + record.Content; | |||
| }else if(record.OpType == 25){ | |||
| return re + "/cloudbrain/" + record.RefName; | |||
| re = re + "/cloudbrain/" + record.Content; | |||
| }else if(record.OpType == 26){ | |||
| return re + "/modelarts/notebook/" + record.Content; | |||
| re = re + "/modelarts/notebook/" + record.Content; | |||
| }else if(record.OpType == 27){ | |||
| return re + "/modelarts/train-job/" + record.Content; | |||
| re = re + "/modelarts/train-job/" + record.Content; | |||
| }else if(record.OpType == 28){ | |||
| return re + "/modelarts/inference-job/" + record.Content; | |||
| re = re + "/modelarts/inference-job/" + record.Content; | |||
| }else if(record.OpType == 29){ | |||
| return re + "/cloudbrain/benchmark/" + record.RefName; | |||
| re = re + "/cloudbrain/benchmark/" + record.Content; | |||
| }else if(record.OpType == 30){ | |||
| return re + "/modelmanage/show_model_info?name=" + record.RefName; | |||
| re = re + "/modelmanage/show_model_info?name=" + record.RefName; | |||
| } | |||
| re = encodeURI(re); | |||
| return re; | |||
| } | |||
| @@ -180,7 +191,7 @@ function getMsg(record){ | |||
| } | |||
| html += " <img class=\"ui avatar image\" src=\"/user/avatar/" + name + "/-1\" alt=\"\">" | |||
| html += " <div class=\"middle aligned content nowrap\">" | |||
| html += " <a href=\"/" + name + "\" title=\"\">" + name + "</a>" | |||
| html += " <a href=\"/" + encodeURI(name) + "\" title=\"\">" + name + "</a>" | |||
| return html; | |||
| } | |||
| @@ -192,7 +203,7 @@ function getRepotext(record){ | |||
| } | |||
| } | |||
| function getRepoLink(record){ | |||
| return record.Repo.OwnerName + "/" + record.Repo.Name; | |||
| return encodeURI(record.Repo.OwnerName + "/" + record.Repo.Name); | |||
| } | |||
| @@ -224,7 +235,7 @@ function getTime(UpdatedUnix,currentTime){ | |||
| } | |||
| function getPRLink(record){ | |||
| return "/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/pulls/" + getIssueId(record); | |||
| return encodeURI("/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/pulls/" + getIssueId(record)); | |||
| } | |||
| function getPRText(record){ | |||
| if(record.Repo.Alias){ | |||
| @@ -237,7 +248,7 @@ function getPRText(record){ | |||
| function getIssueLink(record){ | |||
| return "/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/issues/" + getIssueId(record); | |||
| return encodeURI("/" + record.Repo.OwnerName + "/" + record.Repo.Name + "/issues/" + getIssueId(record)); | |||
| } | |||
| function getIssueId(record){ | |||
| @@ -179,7 +179,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||
| } | |||
| func allValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string { | |||
| return map[string]string{getCellName("A", row): rs.JobName, getCellName("B", row): rs.JobType, getCellName("C", row): rs.Status, getCellName("D", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("E", row): getDurationTime(rs), | |||
| return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): rs.JobType, getCellName("C", row): rs.Status, getCellName("D", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("E", row): getDurationTime(rs), | |||
| getCellName("F", row): rs.ComputeResource, getCellName("G", row): rs.Name, getCellName("H", row): getRepoPathName(rs), getCellName("I", row): rs.JobName, | |||
| } | |||
| } | |||
| @@ -880,13 +880,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }, reqAdmin()) | |||
| }, reqAnyRepoReader()) | |||
| m.Group("/cloudbrain", func() { | |||
| m.Get("/:jobid", repo.GetCloudbrainTask) | |||
| m.Get("/:jobname/log", repo.CloudbrainGetLog) | |||
| m.Get("/:id", repo.GetCloudbrainTask) | |||
| m.Get("/:id/log", repo.CloudbrainGetLog) | |||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | |||
| m.Group("/modelarts", func() { | |||
| m.Group("/notebook", func() { | |||
| //m.Get("/:jobid", repo.GetModelArtsNotebook) | |||
| m.Get("/:jobid", repo.GetModelArtsNotebook2) | |||
| m.Get("/:id", repo.GetModelArtsNotebook2) | |||
| }) | |||
| m.Group("/train-job", func() { | |||
| m.Group("/:jobid", func() { | |||
| @@ -49,22 +49,23 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| err error | |||
| ) | |||
| // jobName := ctx.Params(":jobname") | |||
| // job, err := models.GetCloudbrainByName(jobName) | |||
| jobID := ctx.Params(":jobid") | |||
| repoID := ctx.Repo.Repository.ID | |||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| ctx.NotFound(err) | |||
| log.Error("GetCloudbrainByID failed:", err) | |||
| return | |||
| } | |||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("GetJob failed:", err) | |||
| return | |||
| } | |||
| result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("ConvertToJobResultPayload failed:", err) | |||
| return | |||
| } | |||
| @@ -86,7 +87,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": result.Config.JobID, | |||
| "ID": ID, | |||
| "JobName": result.Config.JobName, | |||
| "JobStatus": result.JobStatus.State, | |||
| "SubState": result.JobStatus.SubState, | |||
| @@ -97,8 +98,8 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| } | |||
| func CloudbrainGetLog(ctx *context.Context) { | |||
| jobName := ctx.Params(":jobname") | |||
| job, err := models.GetCloudbrainByName(jobName) | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | |||
| ctx.ServerError(err.Error(), err) | |||
| @@ -145,7 +146,7 @@ func CloudbrainGetLog(ctx *context.Context) { | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobName": jobName, | |||
| "JobName": job.JobName, | |||
| "Content": content, | |||
| }) | |||
| @@ -56,14 +56,13 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||
| err error | |||
| ) | |||
| jobID := ctx.Params(":jobid") | |||
| repoID := ctx.Repo.Repository.ID | |||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| return | |||
| } | |||
| result, err := modelarts.GetNotebook2(jobID) | |||
| result, err := modelarts.GetNotebook2(job.JobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| return | |||
| @@ -76,7 +75,7 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": jobID, | |||
| "ID": ID, | |||
| "JobName": job.JobName, | |||
| "JobStatus": result.Status, | |||
| }) | |||
| @@ -21,6 +21,7 @@ import ( | |||
| const DEFAULT_PAGE_SIZE = 10 | |||
| const DATE_FORMAT = "2006-01-02" | |||
| const EXCEL_DATE_FORMAT = "20060102" | |||
| const CREATE_TIME_FORMAT = "2006/01/02 15:04:05" | |||
| type ProjectsPeriodData struct { | |||
| RecordBeginTime string `json:"recordBeginTime"` | |||
| @@ -291,41 +292,41 @@ func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, p | |||
| func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | |||
| return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"), | |||
| "J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor")} | |||
| return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.isFork"), "F1": ctx.Tr("admin.repos.isMirror"), "G1": ctx.Tr("admin.repos.openi"), "H1": ctx.Tr("admin.repos.visit"), "I1": ctx.Tr("admin.repos.download"), "J1": ctx.Tr("admin.repos.pr"), "K1": ctx.Tr("admin.repos.commit"), | |||
| "L1": ctx.Tr("admin.repos.watches"), "M1": ctx.Tr("admin.repos.stars"), "N1": ctx.Tr("admin.repos.forks"), "O1": ctx.Tr("admin.repos.issues"), "P1": ctx.Tr("admin.repos.closedIssues"), "Q1": ctx.Tr("admin.repos.contributor"), "R1": ctx.Tr("admin.repos.create")} | |||
| } | |||
| func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | |||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||
| getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10), | |||
| getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10), | |||
| getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), | |||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): getBoolDisplay(rs.IsFork, ctx), getCellName("F", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("G", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||
| getCellName("H", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("I", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("J", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("K", row): strconv.FormatInt(rs.NumCommits, 10), | |||
| getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumIssues, 10), | |||
| getCellName("P", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("Q", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("R", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT), | |||
| } | |||
| } | |||
| func allProjectsOpenIHeader() map[string]string { | |||
| return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "是否私有", "E1": "OpenI指数", | |||
| "F1": "影响力", "G1": "成熟度", "H1": "活跃度", "I1": "项目健康度", "J1": "团队健康度", "K1": "项目发展趋势", | |||
| "L1": "关注数", "M1": "点赞数", "N1": "派生数", "O1": "代码下载量", "P1": "评论数", "Q1": "浏览量", "R1": "已解决任务数", "S1": "版本发布数量", "T1": "有效开发年龄", | |||
| "U1": "数据集", "V1": "模型数", "W1": "百科页面数量", "X1": "提交数", "Y1": "任务数", "Z1": "PR数", "AA1": "版本发布数量", "AB1": "任务完成比例", "AC1": "贡献者数", "AD1": "关键贡献者数", | |||
| "AE1": "新人增长量", "AF1": "代码规模增长量", "AG1": "任务增长量", "AH1": "新人增长量", "AI1": "提交增长量", "AJ1": "评论增长量", | |||
| return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "私有", "E1": "迁移", "F1": "镜像", "G1": "OpenI指数", | |||
| "H1": "影响力", "I1": "成熟度", "J1": "活跃度", "K1": "项目健康度", "L1": "团队健康度", "M1": "项目发展趋势", | |||
| "N1": "关注数", "O1": "点赞数", "P1": "派生数", "Q1": "代码下载量", "R1": "评论数", "S1": "浏览量", "T1": "已解决任务数", "U1": "版本发布数量", "V1": "有效开发年龄", | |||
| "W1": "数据集", "X1": "模型数", "Y1": "百科页面数量", "Z1": "提交数", "AA1": "任务数", "AB1": "PR数", "AC1": "版本发布数量", "AD1": "任务完成比例", "AE1": "贡献者数", "AF1": "关键贡献者数", | |||
| "AG1": "新人增长量", "AH1": "代码规模增长量", "AI1": "任务增长量", "AJ1": "新人增长量", "AK1": "提交增长量", "AL1": "评论增长量", "AM1": "项目创建时间", | |||
| } | |||
| } | |||
| func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | |||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||
| getCellName("F", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("G", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("H", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64), | |||
| getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumDownloads, 10), | |||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): getBoolDisplay(rs.IsFork, ctx), getCellName("F", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("G", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||
| getCellName("H", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("L", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("M", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64), | |||
| getCellName("N", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("O", row): strconv.FormatInt(rs.NumStars, 10), getCellName("P", row): strconv.FormatInt(rs.NumForks, 10), getCellName("Q", row): strconv.FormatInt(rs.NumDownloads, 10), | |||
| getCellName("P", row): strconv.FormatInt(rs.NumComments, 10), getCellName("Q", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("R", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("S", row): strconv.FormatInt(rs.NumVersions, 10), | |||
| getCellName("T", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("U", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("V", row): strconv.FormatInt(rs.NumModels, 10), getCellName("W", row): strconv.FormatInt(rs.NumWikiViews, 10), | |||
| getCellName("X", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("Y", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("Z", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AA", row): strconv.FormatInt(rs.NumVersions, 10), | |||
| getCellName("AB", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AC", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AD", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AE", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), | |||
| getCellName("AF", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AG", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AH", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), | |||
| getCellName("R", row): strconv.FormatInt(rs.NumComments, 10), getCellName("S", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("T", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("U", row): strconv.FormatInt(rs.NumVersions, 10), | |||
| getCellName("V", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("W", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("X", row): strconv.FormatInt(rs.NumModels, 10), getCellName("Y", row): strconv.FormatInt(rs.NumWikiViews, 10), | |||
| getCellName("Z", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("AA", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("AB", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AC", row): strconv.FormatInt(rs.NumVersions, 10), | |||
| getCellName("AD", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AE", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AF", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AG", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), | |||
| getCellName("AH", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AK", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AL", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), getCellName("AM", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT), | |||
| } | |||
| } | |||
| @@ -334,8 +335,8 @@ func getCellName(col string, row int) string { | |||
| return col + strconv.Itoa(row) | |||
| } | |||
| func getIsPrivateDisplay(private bool, ctx *context.Context) string { | |||
| if private { | |||
| func getBoolDisplay(value bool, ctx *context.Context) string { | |||
| if value { | |||
| return ctx.Tr("admin.repos.yes") | |||
| } else { | |||
| return ctx.Tr("admin.repos.no") | |||
| @@ -482,11 +483,11 @@ func generateOpenICountSql(latestDate string) string { | |||
| } | |||
| func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | |||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||
| "(SELECT repo_id,sum(num_visits) as num_visits " + | |||
| " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | |||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | |||
| "(SELECT repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" + | |||
| "(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" + | |||
| " where A.repo_id=B.repo_id" | |||
| if q != "" { | |||
| @@ -497,7 +498,7 @@ func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate strin | |||
| } | |||
| func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | |||
| sql := "SELECT id, repo_id, date, num_watches, num_stars, num_forks, num_downloads, num_comments, num_visits, num_closed_issues, num_versions, num_dev_months, repo_size, dataset_size, num_models, num_wiki_views, num_commits, num_issues, num_pulls, issue_fixed_rate, num_contributor, num_key_contributor, num_contributors_growth, num_commits_growth, num_commit_lines_growth, num_issues_growth, num_comments_growth, impact, completeness, liveness, project_health, team_health, growth, radar_total, name,alias, is_private, owner_name FROM " + | |||
| sql := "SELECT id, repo_id, date, num_watches, num_stars, num_forks, num_downloads, num_comments, num_visits, num_closed_issues, num_versions, num_dev_months, repo_size, dataset_size, num_models, num_wiki_views, num_commits, num_issues, num_pulls, issue_fixed_rate, num_contributor, num_key_contributor, num_contributors_growth, num_commits_growth, num_commit_lines_growth, num_issues_growth, num_comments_growth, impact, completeness, liveness, project_health, team_health, growth, radar_total, name,alias, is_private,is_mirror,is_fork,repo_created_unix, owner_name FROM " + | |||
| " public.repo_statistic where date='" + latestDate + "'" | |||
| sql = sql + " order by radar_total desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | |||
| @@ -506,11 +507,11 @@ func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | |||
| func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | |||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||
| "(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " + | |||
| " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | |||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | |||
| "(SELECT repo_id,name,alias,owner_name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||
| "(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||
| " where A.repo_id=B.repo_id" | |||
| if q != "" { | |||
| sql = sql + " and LOWER(B.alias) like '%" + strings.ToLower(q) + "%'" | |||
| @@ -94,6 +94,13 @@ func Home(ctx *context.Context) { | |||
| recommendCourseKeyWords, _ := repository.GetRecommendCourseKeyWords() | |||
| ctx.Data["CoursesKeywords"] = recommendCourseKeyWords | |||
| } else { | |||
| orgTopics, err := models.GetOrgTopics(org.ID) | |||
| if err != nil { | |||
| ctx.Error(500, "GetOrgTopics failed") | |||
| return | |||
| } | |||
| ctx.Data["OrgTopics"] = orgTopics | |||
| } | |||
| repos, count, err = models.SearchRepository(&models.SearchRepoOptions{ | |||
| @@ -416,6 +416,10 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||
| copy(updates[1:], updates) | |||
| updates[0] = &option | |||
| } | |||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | |||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | |||
| } | |||
| } | |||
| } | |||
| @@ -521,10 +525,6 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||
| } | |||
| } | |||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | |||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | |||
| } | |||
| ctx.JSON(http.StatusOK, private.HookPostReceiveResult{ | |||
| Results: results, | |||
| RepoWasEmpty: wasEmpty, | |||
| @@ -564,7 +564,12 @@ func GetSuccessChunks(ctx *context.Context) { | |||
| return | |||
| } | |||
| } else { | |||
| isExist, err = storage.ObsHasObject(setting.BasePath + models.AttachmentRelativePath(fileChunk.UUID) + "/" + fileName) | |||
| oldFileName := fileName | |||
| oldAttachment, _ := models.GetAttachmentByUUID(fileChunk.UUID) | |||
| if oldAttachment != nil { | |||
| oldFileName = oldAttachment.Name | |||
| } | |||
| isExist, err = storage.ObsHasObject(setting.BasePath + models.AttachmentRelativePath(fileChunk.UUID) + "/" + oldFileName) | |||
| if err != nil { | |||
| ctx.ServerError("ObsHasObject failed", err) | |||
| return | |||
| @@ -76,8 +76,8 @@ func jobNamePrefixValid(s string) string { | |||
| func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| t := time.Now() | |||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = displayJobName | |||
| result, err := cloudbrain.GetImages() | |||
| if err != nil { | |||
| @@ -178,7 +178,8 @@ func CloudBrainNew(ctx *context.Context) { | |||
| func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| jobName := form.JobName | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| image := form.Image | |||
| uuid := form.Attachment | |||
| jobType := form.JobType | |||
| @@ -186,8 +187,26 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| gpuQueue := form.GpuType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := form.ResourceSpecId | |||
| repo := ctx.Repo.Repository | |||
| if !jobNamePattern.MatchString(jobName) { | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||
| if err == nil { | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||
| return | |||
| } | |||
| } | |||
| if !jobNamePattern.MatchString(displayJobName) { | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainNew, &form) | |||
| return | |||
| } | |||
| @@ -214,21 +233,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| } | |||
| } | |||
| _, err = models.GetCloudbrainByName(jobName) | |||
| if err == nil { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||
| return | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||
| return | |||
| } | |||
| } | |||
| repo := ctx.Repo.Repository | |||
| downloadCode(repo, codePath) | |||
| uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | |||
| @@ -260,7 +264,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/") | |||
| } | |||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, | |||
| @@ -275,11 +279,10 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| } | |||
| func CloudBrainRestart(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| var ID = ctx.Params(":id") | |||
| var resultCode = "0" | |||
| var errorMsg = "" | |||
| var status = string(models.JobWaiting) | |||
| task := ctx.Cloudbrain | |||
| for { | |||
| if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) { | |||
| @@ -318,7 +321,7 @@ func CloudBrainRestart(ctx *context.Context) { | |||
| } | |||
| } | |||
| err = cloudbrain.RestartTask(ctx, task, &jobID) | |||
| err = cloudbrain.RestartTask(ctx, task, &ID) | |||
| if err != nil { | |||
| log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"]) | |||
| resultCode = "-1" | |||
| @@ -333,7 +336,7 @@ func CloudBrainRestart(ctx *context.Context) { | |||
| "result_code": resultCode, | |||
| "error_msg": errorMsg, | |||
| "status": status, | |||
| "job_id": jobID, | |||
| "id": ID, | |||
| }) | |||
| } | |||
| @@ -341,6 +344,8 @@ func CloudBrainBenchMarkShow(ctx *context.Context) { | |||
| if benchmarkTypes == nil { | |||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", setting.BenchmarkTypes, err, ctx.Data["MsgID"]) | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| } | |||
| cloudBrainShow(ctx, tplCloudBrainBenchmarkShow) | |||
| @@ -352,14 +357,16 @@ func CloudBrainShow(ctx *context.Context) { | |||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| var jobName = ctx.Params(":jobname") | |||
| var ID = ctx.Params(":id") | |||
| debugListType := ctx.Query("debugListType") | |||
| task, err := models.GetCloudbrainByName(jobName) | |||
| task, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Info("error:" + err.Error()) | |||
| ctx.Data["error"] = err.Error() | |||
| } | |||
| result, err := cloudbrain.GetJob(task.JobID) | |||
| if err != nil { | |||
| log.Info("error:" + err.Error()) | |||
| ctx.Data["error"] = err.Error() | |||
| } | |||
| if result != nil { | |||
| @@ -406,7 +413,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||
| } else { | |||
| duration = int64(task.UpdatedUnix) - int64(task.CreatedUnix) | |||
| } | |||
| if benchmarkTypes != nil { | |||
| if task.BenchmarkTypeID > 0 { | |||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||
| if task.BenchmarkTypeID == benchmarkType.Id { | |||
| ctx.Data["BenchmarkTypeName"] = benchmarkType.First | |||
| @@ -423,8 +430,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||
| ctx.Data["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | |||
| ctx.Data["task"] = task | |||
| // ctx.Data["jobID"] = task.JobID | |||
| ctx.Data["jobName"] = task.JobName | |||
| ctx.Data["displayJobName"] = task.DisplayJobName | |||
| version_list_task := make([]*models.Cloudbrain, 0) | |||
| version_list_task = append(version_list_task, task) | |||
| ctx.Data["version_list_task"] = version_list_task | |||
| @@ -433,7 +440,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||
| } | |||
| func CloudBrainDebug(ctx *context.Context) { | |||
| debugUrl := setting.DebugServerHost + "jpylab_" + ctx.Cloudbrain.JobID + "_" + ctx.Cloudbrain.SubTaskName | |||
| task := ctx.Cloudbrain | |||
| debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName | |||
| ctx.Redirect(debugUrl) | |||
| } | |||
| @@ -460,7 +468,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain | |||
| } | |||
| func CloudBrainStop(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| var ID = ctx.Params(":id") | |||
| var resultCode = "0" | |||
| var errorMsg = "" | |||
| var status = "" | |||
| @@ -474,7 +482,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
| break | |||
| } | |||
| err := cloudbrain.StopJob(jobID) | |||
| err := cloudbrain.StopJob(task.JobID) | |||
| if err != nil { | |||
| log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | |||
| resultCode = "-1" | |||
| @@ -499,7 +507,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
| "result_code": resultCode, | |||
| "error_msg": errorMsg, | |||
| "status": status, | |||
| "job_id": jobID, | |||
| "id": ID, | |||
| }) | |||
| } | |||
| @@ -621,10 +629,10 @@ func deleteCloudbrainJob(ctx *context.Context) error { | |||
| func CloudBrainShowModels(ctx *context.Context) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| jobID := ctx.Params(":jobid") | |||
| ID := ctx.Params(":id") | |||
| parentDir := ctx.Query("parentDir") | |||
| dirArray := strings.Split(parentDir, "/") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| task, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("no such job!", ctx.Data["msgID"]) | |||
| ctx.ServerError("no such job:", err) | |||
| @@ -659,7 +667,7 @@ func CloudBrainShowModels(ctx *context.Context) { | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["task"] = task | |||
| ctx.Data["JobID"] = jobID | |||
| ctx.Data["ID"] = ID | |||
| ctx.HTML(200, tplCloudBrainShowModels) | |||
| } | |||
| @@ -728,8 +736,8 @@ func GetRate(ctx *context.Context) { | |||
| return | |||
| } | |||
| var jobID = ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| var ID = ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| ctx.ServerError("GetCloudbrainByJobID failed", err) | |||
| return | |||
| @@ -1053,6 +1061,13 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| return | |||
| } | |||
| if benchmarkTypes == nil { | |||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||
| ctx.ServerError("Get BenchmarkTypes faild:", err) | |||
| return | |||
| } | |||
| } | |||
| for i, task := range ciTasks { | |||
| ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | |||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | |||
| @@ -1063,6 +1078,16 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| duration = int64(task.Cloudbrain.UpdatedUnix) - int64(task.Cloudbrain.CreatedUnix) | |||
| } | |||
| ciTasks[i].TrainJobDuration = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | |||
| ciTasks[i].BenchmarkTypeName = "" | |||
| if task.BenchmarkTypeID > 0 { | |||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||
| if task.BenchmarkTypeID == benchmarkType.Id { | |||
| ciTasks[i].BenchmarkTypeRankLink = benchmarkType.RankLink | |||
| ciTasks[i].BenchmarkTypeName = benchmarkType.First | |||
| break | |||
| } | |||
| } | |||
| } | |||
| } | |||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | |||
| @@ -1203,7 +1228,8 @@ func getBenchmarkResourceSpec(resourceSpecID int) (int, error) { | |||
| func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| jobName := form.JobName | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| image := form.Image | |||
| gpuQueue := form.GpuType | |||
| command := cloudbrain.CommandBenchmark | |||
| @@ -1215,6 +1241,26 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| ctx.Data["description"] = form.Description | |||
| ctx.Data["benchmarkTypeID"] = benchmarkTypeID | |||
| ctx.Data["benchmark_child_types_id_hidden"] = benchmarkChildTypeID | |||
| repo := ctx.Repo.Repository | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeBenchmark), displayJobName) | |||
| if err == nil { | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| } | |||
| if !jobNamePattern.MatchString(jobName) { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | |||
| @@ -1260,21 +1306,6 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| } | |||
| } | |||
| _, err = models.GetCloudbrainByName(jobName) | |||
| if err == nil { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("GetCloudbrainByName failed, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| } | |||
| repo := ctx.Repo.Repository | |||
| os.RemoveAll(codePath) | |||
| if err := downloadCode(repo, codePath); err != nil { | |||
| log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | |||
| @@ -1338,7 +1369,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| //return | |||
| } | |||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, | |||
| @@ -25,6 +25,7 @@ import ( | |||
| "code.gitea.io/gitea/modules/obs" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "code.gitea.io/gitea/modules/util" | |||
| ) | |||
| const ( | |||
| @@ -112,8 +113,8 @@ func NotebookNew(ctx *context.Context) { | |||
| func notebookNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| t := time.Now() | |||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = displayJobName | |||
| attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -183,11 +184,13 @@ func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) | |||
| func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | |||
| ctx.Data["PageIsNotebook"] = true | |||
| jobName := form.JobName | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| flavor := form.Flavor | |||
| imageId := form.ImageId | |||
| repo := ctx.Repo.Repository | |||
| count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -203,12 +206,15 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||
| return | |||
| } | |||
| } | |||
| _, err = models.GetCloudbrainByName(jobName) | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||
| if err == nil { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| notebookNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) | |||
| return | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| notebookNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| @@ -218,7 +224,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||
| } | |||
| } | |||
| err = modelarts.GenerateNotebook2(ctx, jobName, uuid, description, flavor, imageId) | |||
| err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, flavor, imageId) | |||
| if err != nil { | |||
| log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | |||
| notebookNewDataPrepare(ctx) | |||
| @@ -232,15 +238,15 @@ func NotebookShow(ctx *context.Context) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| debugListType := ctx.Query("debugListType") | |||
| var jobID = ctx.Params(":jobid") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| var ID = ctx.Params(":id") | |||
| task, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | |||
| return | |||
| } | |||
| result, err := modelarts.GetNotebook2(jobID) | |||
| result, err := modelarts.GetNotebook2(task.JobID) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | |||
| @@ -272,7 +278,7 @@ func NotebookShow(ctx *context.Context) { | |||
| ctx.Data["datasetDownloadLink"] = datasetDownloadLink | |||
| ctx.Data["task"] = task | |||
| ctx.Data["jobID"] = jobID | |||
| ctx.Data["ID"] = ID | |||
| ctx.Data["jobName"] = task.JobName | |||
| ctx.Data["result"] = result | |||
| ctx.Data["debugListType"] = debugListType | |||
| @@ -307,9 +313,8 @@ func NotebookDebug(ctx *context.Context) { | |||
| } | |||
| func NotebookDebug2(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| result, err := modelarts.GetNotebook2(jobID) | |||
| task := ctx.Cloudbrain | |||
| result, err := modelarts.GetNotebook2(task.JobID) | |||
| if err != nil { | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | |||
| return | |||
| @@ -319,16 +324,16 @@ func NotebookDebug2(ctx *context.Context) { | |||
| } | |||
| func NotebookManage(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| var ID = ctx.Params(":id") | |||
| var action = ctx.Params(":action") | |||
| var resultCode = "0" | |||
| var errorMsg = "" | |||
| var status = "" | |||
| for { | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| task, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobID failed:%v", err, ctx.Data["MsgID"]) | |||
| log.Error("get task(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||
| resultCode = "-1" | |||
| errorMsg = "system error" | |||
| break | |||
| @@ -393,7 +398,7 @@ func NotebookManage(ctx *context.Context) { | |||
| param := models.NotebookAction{ | |||
| Action: action, | |||
| } | |||
| res, err := modelarts.ManageNotebook2(jobID, param) | |||
| res, err := modelarts.ManageNotebook2(task.JobID, param) | |||
| if err != nil { | |||
| log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||
| resultCode = "-1" | |||
| @@ -422,35 +427,34 @@ func NotebookManage(ctx *context.Context) { | |||
| "result_code": resultCode, | |||
| "error_msg": errorMsg, | |||
| "status": status, | |||
| "job_id": jobID, | |||
| "id": ID, | |||
| }) | |||
| } | |||
| func NotebookDel(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| var listType = ctx.Query("debugListType") | |||
| task := ctx.Cloudbrain | |||
| if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) { | |||
| log.Error("the job(%s) has not been stopped", task.JobName) | |||
| ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped")) | |||
| ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) | |||
| return | |||
| } | |||
| _, err := modelarts.DelNotebook2(jobID) | |||
| _, err := modelarts.DelNotebook2(task.JobID) | |||
| if err != nil { | |||
| log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | |||
| if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) { | |||
| if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) || strings.Contains(err.Error(), modelarts.NotebookInvalid) { | |||
| log.Info("old notebook version") | |||
| } else { | |||
| ctx.ServerError("DelNotebook2 failed", err) | |||
| ctx.RenderWithErr(err.Error(), tplDebugJobIndex, nil) | |||
| return | |||
| } | |||
| } | |||
| err = models.DeleteJob(task) | |||
| if err != nil { | |||
| ctx.ServerError("DeleteJob failed", err) | |||
| ctx.RenderWithErr(err.Error(), tplDebugJobIndex, nil) | |||
| return | |||
| } | |||
| @@ -531,8 +535,8 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||
| //} | |||
| t := time.Now() | |||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = displayJobName | |||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -569,8 +573,6 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||
| ctx.Data["train_url"] = outputObsPath | |||
| ctx.Data["params"] = "" | |||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||
| @@ -601,8 +603,8 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||
| //} | |||
| t := time.Now() | |||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = displayJobName | |||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -639,9 +641,6 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||
| ctx.Data["train_url"] = outputObsPath | |||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | |||
| if err != nil { | |||
| ctx.ServerError("getConfigList failed:", err) | |||
| @@ -688,8 +687,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||
| return err | |||
| } | |||
| t := time.Now() | |||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = task.DisplayJobName | |||
| ctx.Data["job_name"] = task.JobName | |||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
| @@ -734,9 +732,6 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["params"] = Parameters.Parameter | |||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||
| ctx.Data["train_url"] = outputObsPath | |||
| branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0) | |||
| if err != nil { | |||
| ctx.ServerError("GetBranches error:", err) | |||
| @@ -858,7 +853,8 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai | |||
| func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) { | |||
| ctx.Data["PageIsTrainJob"] = true | |||
| VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | |||
| jobName := form.JobName | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| workServerNumber := form.WorkServerNumber | |||
| @@ -901,6 +897,23 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| //Determine whether the task name of the task in the project is duplicated | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) | |||
| if err == nil { | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| trainJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| trainJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| } | |||
| //todo: del the codeLocalPath | |||
| _, err = ioutil.ReadDir(codeLocalPath) | |||
| @@ -914,9 +927,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | |||
| Branch: branch_name, | |||
| }); err != nil { | |||
| log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err) | |||
| log.Error("Create task failed, server timed out: %s (%v)", repo.FullName(), err) | |||
| trainJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsTrainJobNew, &form) | |||
| ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| @@ -1010,6 +1023,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| req := &modelarts.GenerateTrainJobReq{ | |||
| JobName: jobName, | |||
| DisplayJobName: displayJobName, | |||
| DataUrl: dataPath, | |||
| Description: description, | |||
| CodeObsPath: codeObsPath, | |||
| @@ -1076,6 +1090,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| } | |||
| VersionOutputPath := modelarts.GetOutputPathByCount(latestTask.TotalVersionCount + 1) | |||
| displayJobName := form.DisplayJobName | |||
| jobName := form.JobName | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| @@ -1098,7 +1113,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| EngineName := form.EngineName | |||
| isLatestVersion := modelarts.IsLatestVersion | |||
| //判断权限 | |||
| canNewJob, _ := canUserCreateTrainJobVersion(ctx, latestTask.UserID) | |||
| if !canNewJob { | |||
| ctx.RenderWithErr("user cann't new trainjob", tplModelArtsTrainJobVersionNew, &form) | |||
| @@ -1116,22 +1130,16 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| _, err = ioutil.ReadDir(codeLocalPath) | |||
| if err == nil { | |||
| os.RemoveAll(codeLocalPath) | |||
| } else { | |||
| log.Error("创建任务失败,原代码还未删除,请重试!: %s (%v)", repo.FullName(), err) | |||
| versionErrorDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("创建任务失败,原代码还未删除,请重试!", tplModelArtsTrainJobVersionNew, &form) | |||
| return | |||
| } | |||
| // os.RemoveAll(codeLocalPath) | |||
| gitRepo, _ := git.OpenRepository(repo.RepoPath()) | |||
| commitID, _ := gitRepo.GetBranchCommitID(branch_name) | |||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | |||
| Branch: branch_name, | |||
| }); err != nil { | |||
| log.Error("创建任务失败,任务名称已存在!: %s (%v)", repo.FullName(), err) | |||
| log.Error("Failed git clone repo to local(!: %s (%v)", repo.FullName(), err) | |||
| versionErrorDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("创建任务失败,任务名称已存在!", tplModelArtsTrainJobVersionNew, &form) | |||
| ctx.RenderWithErr("Failed git clone repo to local!", tplModelArtsTrainJobVersionNew, &form) | |||
| return | |||
| } | |||
| @@ -1237,7 +1245,8 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| return | |||
| } | |||
| req := &modelarts.GenerateTrainJobReq{ | |||
| JobName: task.JobName, | |||
| JobName: jobName, | |||
| DisplayJobName: displayJobName, | |||
| DataUrl: dataPath, | |||
| Description: description, | |||
| CodeObsPath: codeObsPath, | |||
| @@ -1467,7 +1476,7 @@ func TrainJobShow(ctx *context.Context) { | |||
| pager.SetDefaultParams(ctx) | |||
| ctx.Data["Page"] = pager | |||
| ctx.Data["jobID"] = jobID | |||
| ctx.Data["jobName"] = VersionListTasks[0].JobName | |||
| ctx.Data["displayJobName"] = VersionListTasks[0].DisplayJobName | |||
| ctx.Data["version_list_task"] = VersionListTasks | |||
| ctx.Data["version_list_count"] = VersionListCount | |||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | |||
| @@ -1668,7 +1677,8 @@ func getConfigList(perPage, page int, sortBy, order, searchContent, configType s | |||
| func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) { | |||
| ctx.Data["PageIsTrainJob"] = true | |||
| VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | |||
| jobName := form.JobName | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| workServerNumber := form.WorkServerNumber | |||
| @@ -1696,13 +1706,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| ckptUrl := form.TrainUrl + form.CkptName | |||
| if err := paramCheckCreateInferenceJob(form); err != nil { | |||
| log.Error("paramCheckCreateInferenceJob failed:(%v)", err) | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
| @@ -1718,6 +1721,31 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| } | |||
| } | |||
| if err := paramCheckCreateInferenceJob(form); err != nil { | |||
| log.Error("paramCheckCreateInferenceJob failed:(%v)", err) | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| //Determine whether the task name of the task in the project is duplicated | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeInference), displayJobName) | |||
| if err == nil { | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("system error", tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| } | |||
| //todo: del the codeLocalPath | |||
| _, err = ioutil.ReadDir(codeLocalPath) | |||
| if err == nil { | |||
| @@ -1730,9 +1758,9 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | |||
| Branch: branch_name, | |||
| }); err != nil { | |||
| log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err) | |||
| log.Error("Create task failed, server timed out: %s (%v)", repo.FullName(), err) | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsInferenceJobNew, &form) | |||
| ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| @@ -1789,6 +1817,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| req := &modelarts.GenerateInferenceJobReq{ | |||
| JobName: jobName, | |||
| DisplayJobName: displayJobName, | |||
| DataUrl: dataPath, | |||
| Description: description, | |||
| CodeObsPath: codeObsPath, | |||
| @@ -1801,7 +1830,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| LogUrl: logObsPath, | |||
| PoolID: poolID, | |||
| Uuid: uuid, | |||
| Parameters: param, //modelarts训练时用到 | |||
| Parameters: param, //modelarts train parameters | |||
| CommitID: commitID, | |||
| BranchName: branch_name, | |||
| Params: form.Params, | |||
| @@ -1817,13 +1846,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| ResultUrl: resultObsPath, | |||
| } | |||
| //将params转换Parameters.Parameter,出错时返回给前端 | |||
| // var Parameters modelarts.Parameters | |||
| // if err := json.Unmarshal([]byte(params), &Parameters); err != nil { | |||
| // ctx.ServerError("json.Unmarshal failed:", err) | |||
| // return | |||
| // } | |||
| err = modelarts.GenerateInferenceJob(ctx, req) | |||
| if err != nil { | |||
| log.Error("GenerateTrainJob failed:%v", err.Error()) | |||
| @@ -1899,8 +1921,8 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| t := time.Now() | |||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["display_job_name"] = displayJobName | |||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -2075,6 +2097,7 @@ func InferenceJobShow(ctx *context.Context) { | |||
| ctx.Data["labelName"] = LabelName | |||
| ctx.Data["jobID"] = jobID | |||
| ctx.Data["jobName"] = task.JobName | |||
| ctx.Data["displayJobName"] = task.DisplayJobName | |||
| ctx.Data["task"] = task | |||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||
| @@ -2121,12 +2144,11 @@ func ResultDownload(ctx *context.Context) { | |||
| err error | |||
| ) | |||
| var jobID = ctx.Params(":jobid") | |||
| versionName := ctx.Query("version_name") | |||
| parentDir := ctx.Query("parent_dir") | |||
| fileName := ctx.Query("file_name") | |||
| log.Info("DownloadResult start.") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| task := ctx.Cloudbrain | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| } | |||
| @@ -2180,7 +2202,7 @@ func DownloadMultiResultFile(ctx *context.Context) { | |||
| //count++ | |||
| // models.ModifyModelDownloadCount(id) | |||
| returnFileName := task.JobName + ".zip" | |||
| returnFileName := task.DisplayJobName + ".zip" | |||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+returnFileName) | |||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||
| w := zip.NewWriter(ctx.Resp) | |||
| @@ -110,6 +110,8 @@ func RepoStatisticDaily(date string) { | |||
| Alias: repo.Alias, | |||
| IsPrivate: repo.IsPrivate, | |||
| IsMirror: repo.IsMirror, | |||
| IsFork: repo.IsFork, | |||
| RepoCreatedUnix: repo.CreatedUnix, | |||
| OwnerName: repo.OwnerName, | |||
| NumWatches: int64(repo.NumWatches), | |||
| NumStars: int64(repo.NumStars), | |||
| @@ -39,6 +39,27 @@ func SummaryStatisticDaily(date string) { | |||
| log.Error("can not get repository number", err) | |||
| repositoryNumer = 0 | |||
| } | |||
| publicRepositoryNumer, err := models.GetAllPublicRepositoriesCount() | |||
| if err != nil { | |||
| log.Error("can not get public repository number", err) | |||
| publicRepositoryNumer = 0 | |||
| } | |||
| privateRepositoryNumer := repositoryNumer - publicRepositoryNumer | |||
| mirrorRepositoryNumber, err := models.GetAllMirrorRepositoriesCount() | |||
| if err != nil { | |||
| log.Error("can not get mirror repository number", err) | |||
| mirrorRepositoryNumber = 0 | |||
| } | |||
| forkRepositoryNumber, err := models.GetAllForkRepositoriesCount() | |||
| if err != nil { | |||
| log.Error("can not get fork mirror repository number", err) | |||
| forkRepositoryNumber = 0 | |||
| } | |||
| selfRepositoryNumber := repositoryNumer - mirrorRepositoryNumber - forkRepositoryNumber | |||
| //repository size | |||
| repositorySize, err := models.GetAllRepositoriesSize() | |||
| if err != nil { | |||
| @@ -73,6 +94,11 @@ func SummaryStatisticDaily(date string) { | |||
| DatasetSize: allDatasetSize, | |||
| NumOrganizations: organizationNumber, | |||
| NumRepos: repositoryNumer, | |||
| NumRepoFork: forkRepositoryNumber, | |||
| NumRepoMirror: mirrorRepositoryNumber, | |||
| NumRepoPrivate: privateRepositoryNumer, | |||
| NumRepoPublic: publicRepositoryNumer, | |||
| NumRepoSelf: selfRepositoryNumber, | |||
| NumRepoBigModel: topicsCount[0], | |||
| NumRepoAI: topicsCount[1], | |||
| NumRepoVision: topicsCount[2], | |||
| @@ -580,7 +580,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Group("", func() { | |||
| m.Get("/attachments/:uuid", repo.GetAttachment) | |||
| }, reqSignIn) | |||
| }) | |||
| m.Group("/attachments", func() { | |||
| m.Post("", repo.UploadAttachment) | |||
| @@ -1005,10 +1005,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }, context.RepoRef()) | |||
| m.Group("/cloudbrain", func() { | |||
| m.Group("/:jobname", func() { | |||
| m.Group("/:id", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) | |||
| }) | |||
| m.Group("/:jobid", func() { | |||
| m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) | |||
| m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||
| @@ -1023,10 +1021,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Group("/benchmark", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) | |||
| m.Group("/:jobname", func() { | |||
| m.Group("/:id", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | |||
| }) | |||
| m.Group("/:jobid", func() { | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | |||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | |||
| @@ -1074,7 +1070,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew) | |||
| m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsNotebookForm{}), repo.NotebookCreate) | |||
| */ | |||
| m.Group("/:jobid", func() { | |||
| m.Group("/:id", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.NotebookShow) | |||
| m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug2) | |||
| m.Post("/:action", reqRepoCloudBrainWriter, repo.NotebookManage) | |||
| @@ -1088,11 +1084,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("", reqRepoCloudBrainReader, repo.TrainJobIndex) | |||
| m.Group("/:jobid", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.TrainJobShow) | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobStop) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobDel) | |||
| m.Get("/model_download", cloudbrain.AdminOrJobCreaterRight, repo.ModelDownload) | |||
| m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.TrainJobNewVersion) | |||
| m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobStop) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobDel) | |||
| m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload) | |||
| m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobNewVersion) | |||
| m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||
| }) | |||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.TrainJobNew) | |||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreate) | |||
| @@ -1104,7 +1100,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("", reqRepoCloudBrainReader, repo.InferenceJobIndex) | |||
| m.Group("/:jobid", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.InferenceJobShow) | |||
| m.Get("/result_download", cloudbrain.AdminOrJobCreaterRight, repo.ResultDownload) | |||
| m.Get("/result_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ResultDownload) | |||
| m.Get("/downloadall", repo.DownloadMultiResultFile) | |||
| }) | |||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.InferenceJobNew) | |||
| @@ -64,22 +64,29 @@ | |||
| <div class="ui grid stackable item"> | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| {{$JobID := '0'}} | |||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | |||
| {{$JobID = .Cloudbrain.ID}} | |||
| {{else}} | |||
| {{$JobID = .JobID}} | |||
| {{end}} | |||
| <!-- {{$JobID}} --> | |||
| <div class="two wide column nowrap"> | |||
| {{if or (eq .JobType "DEBUG") (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{.JobName}}{{else}}/modelarts/notebook/{{.JobID}}{{end}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/train-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/train-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| @@ -89,8 +96,8 @@ | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span class="job-status" id="{{$JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| @@ -99,7 +106,7 @@ | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap"> | |||
| @@ -119,19 +126,19 @@ | |||
| </div> | |||
| <!-- 云脑侧名称 --> | |||
| <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <span class="fitted">{{.JobName}}</span> | |||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| <div class="ui compact buttons"> | |||
| <form id="debugAgainForm-{{.JobID}}"> | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -141,22 +148,22 @@ | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| {{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{.JobID}}/stop' data-jobid="{{.JobID}}"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' data-jobid="{{$JobID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </form> | |||
| {{else}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{end}}/{{.JobID}}/del?isadminpage=true' method="post"> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{end}}/{{$JobID}}/del?isadminpage=true' method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{.JobID}}/del_version?isadminpage=true" data-version="{{.VersionName}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true" data-version="{{.VersionName}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -164,25 +171,31 @@ | |||
| </div> | |||
| </div> | |||
| {{else}} | |||
| {{$JobID := '0'}} | |||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | |||
| {{$JobID = .Cloudbrain.ID}} | |||
| {{else}} | |||
| {{$JobID = .JobID}} | |||
| {{end}} | |||
| <div class="ui grid stackable item"> | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="two wide column nowrap"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| @@ -192,8 +205,8 @@ | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{.JobID}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| @@ -202,7 +215,7 @@ | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap"> | |||
| @@ -227,14 +240,14 @@ | |||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <div class="ui compact buttons"> | |||
| <form id="debugAgainForm-{{.JobID}}"> | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic disabled button' > | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{.JobID}}" class='ui basic disabled button' > | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -243,14 +256,14 @@ | |||
| {{end}} | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button" data-jobid="{{.JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic disabled button" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='' method="post"> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='' method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -27,7 +27,7 @@ | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">使用</button> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
| </div> | |||
| </div> | |||
| @@ -45,7 +45,7 @@ | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">使用</button> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
| </div> | |||
| </div> | |||
| @@ -62,7 +62,7 @@ | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">使用</button> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
| </div> | |||
| </div> | |||
| @@ -79,7 +79,7 @@ | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">使用</button> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
| </div> | |||
| </div> | |||
| @@ -53,8 +53,8 @@ | |||
| </div> | |||
| <div class="swiper-slide"> | |||
| <div class="ui card"> | |||
| <a class="image" href="https://git.openi.org.cn/JD_Group"> | |||
| <img src="/img/org-jd@2x-80.jpg" alt="京东" title="京东"> | |||
| <a class="image" href="https://git.openi.org.cn/JDOpenISCT"> | |||
| <img src="/img/org-jd@2x-80.jpg" alt="京东智能供应链开源工具" title="京东智能供应链开源工具"> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| @@ -1,3 +1,4 @@ | |||
| {{template "base/head" .}} | |||
| <div class="organization profile"> | |||
| {{/* overflow: auto is the clearfix - this avoids the image going beyond | |||
| @@ -22,22 +23,55 @@ | |||
| <div class="ui container"> | |||
| {{template "org/navber" .}} | |||
| {{template "org/select_pro" .}} | |||
| <div class="ui stackable grid"> | |||
| <div class="ui sixteen wide computer column"> | |||
| <div class="ui mobile reversed stackable grid"> | |||
| <div class="ui sixteen wide tablet sixteen wide computer column margin-bottom20 pad-botom maxheight" id='key_tag'> | |||
| {{if .OrgTopics}} | |||
| <a class="{{if eq $.Keyword "" }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?" onclick="iscontinueStatus()" id="tag_a">{{$.i18n.Tr "org.all_org_topics"}}</a> | |||
| {{end}} | |||
| {{range .OrgTopics}} | |||
| {{if ne .Name ""}} | |||
| <a class="{{if eq $.Keyword .Name }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?q={{.Name}}" onclick="iscontinueStatus()"> | |||
| {{.Name}} | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| {{if .OrgTopics}} | |||
| <a class=" tag_key ui small tag_lable topic omit icon_a" onclick="isUnfold()" id="icon_btn" > | |||
| <i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> | |||
|  {{.i18n.Tr "org.unfold"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui stackable grid"> | |||
| <div class="ui sixteen wide computer column"> | |||
| <div class="ui mobile reversed stackable grid"> | |||
| <div class="ui ten wide tablet eleven wide computer column"> | |||
| {{if .CanCreateOrgRepo}} | |||
| <!-- {{if .CanCreateOrgRepo}} | |||
| <div class="text right"> | |||
| <a class="ui green button" href="{{AppSubUrl}}/repo/create?org={{.Org.ID}}">{{.i18n.Tr "new_repo"}}</a> | |||
| </div> | |||
| {{end}} | |||
| {{end}} --> | |||
| {{template "org/repo_list" .}} | |||
| {{template "base/paginate" .}} | |||
| </div> | |||
| <div class="ui sixteen wide mobile six wide tablet five wide computer column"> | |||
| <h4 class="ui top attached header"> | |||
| {{if .CanCreateOrgRepo}} | |||
| <div class="text right"> | |||
| <a class="ui green button" href="{{AppSubUrl}}/repo/create?org={{.Org.ID}}">{{.i18n.Tr "new_repo"}}</a> | |||
| </div> | |||
| {{end}} | |||
| <h4 class="ui top attached header" style="margin-top: 10px;"> | |||
| <strong>{{.i18n.Tr "org.people"}}</strong> | |||
| <div class="ui right"> | |||
| <a class="text grey" href="{{.OrgLink}}/members">{{.MembersTotal}} {{svg "octicon-chevron-right" 16}}</a> | |||
| @@ -99,3 +133,42 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| function isUnfold(){ | |||
| // var isTrue = document.getElementById("tag_a").getAttribute("data-tag") | |||
| var isContain= document.querySelector("#key_tag").classList.contains("maxheight"); | |||
| if(isContain){ | |||
| document.querySelector("#key_tag").classList.remove("maxheight"); | |||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | |||
| localStorage.setItem("isunfold",true) | |||
| }else{ | |||
| document.querySelector("#key_tag").classList.add("maxheight"); | |||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||
| localStorage.setItem("isunfold",false) | |||
| } | |||
| } | |||
| function isShowIconBtn(){ | |||
| var key_height = document.getElementById("key_tag").offsetHeight | |||
| var parent = document.getElementById("key_tag") | |||
| var child = document.getElementById("icon_btn") | |||
| if (key_height < 88){ | |||
| parent.removeChild(child) | |||
| } | |||
| } | |||
| function iscontinueStatus(){ | |||
| var isunfold = localStorage.getItem("isunfold") | |||
| if (isunfold == "true" || isunfold == true){ | |||
| document.querySelector("#key_tag").classList.remove("maxheight"); | |||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | |||
| }else{ | |||
| document.querySelector("#key_tag").classList.add("maxheight"); | |||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||
| } | |||
| } | |||
| isShowIconBtn() | |||
| iscontinueStatus() | |||
| </script> | |||
| @@ -32,27 +32,13 @@ | |||
| .organization-info >.container { | |||
| padding-bottom:0px !important; | |||
| } | |||
| .tag_bg{ | |||
| background-color: #0366D6 !important; | |||
| color:#FFFFFF !important; | |||
| } | |||
| .course{ | |||
| padding:10px 0 15px !important; | |||
| } | |||
| .course_color{ | |||
| color: #FA8C16; | |||
| } | |||
| .tag_lable{ | |||
| border: 1px solid rgba(232, 232, 232, 100) ; | |||
| border-radius: 4px; | |||
| color: rgba(65, 80, 88, 100); | |||
| font-family: Microsoft Yahei; | |||
| font-size: 14px; | |||
| padding: 0.3em 0.5em; | |||
| height: 30px; | |||
| text-align: center; | |||
| margin: 0.2em; | |||
| } | |||
| .tag_lable_first{ | |||
| border: 1px solid rgba(232, 232, 232, 100) ; | |||
| border-radius: 4px; | |||
| @@ -65,17 +51,11 @@ | |||
| margin: 0.2em; | |||
| margin-left: none; | |||
| } | |||
| .tag_key{ | |||
| max-width:100%; | |||
| margin: 3px 3px; | |||
| display:inline-flex; | |||
| } | |||
| .bpadding{ | |||
| padding:10px 40px | |||
| } | |||
| .omit{ | |||
| overflow: hidden; white-space: nowrap; text-overflow: ellipsis; | |||
| } | |||
| .noborder{ | |||
| border: none !important; | |||
| } | |||
| @@ -83,7 +63,7 @@ | |||
| text-align: center; | |||
| margin-top: 5px; | |||
| margin-top: 10px; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -39,7 +39,7 @@ | |||
| </div> | |||
| </div> | |||
| <div class="column right aligned"> | |||
| <a class="ui compact orange basic icon button" href="{{$.RepoLink}}/cloudbrain/123/rate?isObjectDetcionAll=true" style="box-shadow: none;" target="_blank"><i class="large ri-trophy-fill middle aligned icon"></i>基准测试排行榜</a> | |||
| <a class="ui compact orange basic icon button" href="https://openi.org.cn/projects/Benchmark/#algType" style="box-shadow: none;" target="_blank"><i class="large ri-trophy-fill middle aligned icon"></i>基准测试排行榜</a> | |||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/benchmark/create">{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a> | |||
| {{else}} | |||
| @@ -76,9 +76,12 @@ | |||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| <span>{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| @@ -99,23 +102,28 @@ | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0"> | |||
| <a class="title" href="{{$.Link}}/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.Cloudbrain.ID}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <a style="font-size: 12px;" href="{{.BenchmarkTypeRankLink}}" target="_blank"> | |||
| {{.BenchmarkTypeName}} | |||
| </a> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center padding0"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="two wide column text center padding0"> | |||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;" id="duration-{{.Cloudbrain.ID}}">{{.TrainJobDuration}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="two wide column text center padding0"> | |||
| @@ -133,10 +141,10 @@ | |||
| <div class="three wide column text center padding0"> | |||
| <div class="ui compact buttons" > | |||
| <!-- 停止任务 --> | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/stop" data-jobid="{{.JobID}}"> | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| @@ -146,15 +154,16 @@ | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/rate" target="_blank"> | |||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| 评分 | |||
| </a> | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-delete-{{.JobID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -82,7 +82,7 @@ | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" autofocus required maxlength="254"> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="254"> | |||
| </div> | |||
| <div class="unite min_title inline field"> | |||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||
| @@ -124,7 +124,7 @@ | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label> | |||
| <span> </span> | |||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像或输入镜像地址" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||
| <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | |||
| {{range .images}} | |||
| @@ -150,13 +150,13 @@ | |||
| <div class="inline unite min_title field required"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" value="train.py" tabindex="3" autofocus required maxlength="254" > | |||
| <a href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||
| <a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||
| </div> | |||
| <div class="inline unite min_title field required"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" tabindex="3" autofocus required maxlength="254" > | |||
| <a href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||
| </div> | |||
| @@ -190,6 +190,13 @@ | |||
| function setChildType(){ | |||
| let type_id = $('#benchmark_types_id').val(); | |||
| if(type_id == 3){ | |||
| $('#train_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| $('#test_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| }else{ | |||
| $('#train_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| $('#test_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| } | |||
| let child_selected_id = $('#benchmark_child_types_id_hidden').val(); | |||
| $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => { | |||
| const n_length = data['child_types'].length | |||
| @@ -183,7 +183,7 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.evaluate_job"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">{{.jobName}}</div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| </h4> | |||
| {{range $k ,$v := .version_list_task}} | |||
| @@ -229,7 +229,7 @@ td, th { | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{.JobName}} | |||
| {{.DisplayJobName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| @@ -6,7 +6,7 @@ | |||
| <td class="name four wide"> | |||
| <span class="truncate"> | |||
| <span class="octicon octicon-file-directory"></span> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/models?parentDir={{.ParenDir}}{{else}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/download_model?parentDir={{.ParenDir}}&fileName={{.FileName}}&jobName={{$.task.JobName}}{{end}}"> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/cloudbrain/{{$.task.ID}}/models?parentDir={{.ParenDir}}{{else}}{{$.RepoLink}}/cloudbrain/{{$.task.ID}}/download_model?parentDir={{.ParenDir}}&fileName={{.FileName}}&jobName={{$.task.JobName}}{{end}}"> | |||
| <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | |||
| </a> | |||
| </span> | |||
| @@ -1,7 +1,7 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| /* 遮罩层css效果图 */ | |||
| #mask { | |||
| position: fixed; | |||
| top: 0px; | |||
| @@ -18,7 +18,7 @@ | |||
| color: #000000 | |||
| } | |||
| /* 加载圈css效果图 */ | |||
| #loadingPage { | |||
| margin: 200px auto; | |||
| width: 50px; | |||
| @@ -27,7 +27,7 @@ | |||
| font-size: 10px; | |||
| display: block; | |||
| } | |||
| #loadingPage>div { | |||
| background-color: green; | |||
| height: 100%; | |||
| @@ -36,27 +36,27 @@ | |||
| -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out; | |||
| animation: sk-stretchdelay 1.2s infinite ease-in-out; | |||
| } | |||
| #loadingPage .rect2 { | |||
| -webkit-animation-delay: -1.1s; | |||
| animation-delay: -1.1s; | |||
| } | |||
| #loadingPage .rect3 { | |||
| -webkit-animation-delay: -1.0s; | |||
| animation-delay: -1.0s; | |||
| } | |||
| #loadingPage .rect4 { | |||
| -webkit-animation-delay: -0.9s; | |||
| animation-delay: -0.9s; | |||
| } | |||
| #loadingPage .rect5 { | |||
| -webkit-animation-delay: -0.8s; | |||
| animation-delay: -0.8s; | |||
| } | |||
| @-webkit-keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| @@ -67,7 +67,7 @@ | |||
| -webkit-transform: scaleY(1.0) | |||
| } | |||
| } | |||
| @keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| @@ -80,7 +80,7 @@ | |||
| -webkit-transform: scaleY(1.0); | |||
| } | |||
| } | |||
| .inline.required.field.cloudbrain_benchmark { | |||
| display: none; | |||
| } | |||
| @@ -155,7 +155,7 @@ | |||
| </h3> | |||
| <div class="ui attached segment"> | |||
| <div class="inline required field"> | |||
| <label>计算资源</label> | |||
| <label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="active item" href="{{.RepoLink}}/cloudbrain/create"> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||
| @@ -173,12 +173,12 @@ | |||
| </div> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>任务名称</label> | |||
| <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>任务类型</label> | |||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||
| <option name="job_type" value="DEBUG">DEBUG</option> | |||
| {{if .is_snn4imagenet_enabled}} | |||
| @@ -206,7 +206,7 @@ | |||
| <input id="store_category" type="hidden" name="get_benchmark_category"> | |||
| <div class="inline required field"> | |||
| <label>GPU类型</label> | |||
| <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||
| {{range .gpu_types}} | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| @@ -215,8 +215,8 @@ | |||
| </div> | |||
| <div class="inline required field" style="position: relative;"> | |||
| <label>镜像</label> | |||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像" name="image" required autofocus maxlength="255"> | |||
| <label>{{.i18n.Tr "cloudbrain.mirror"}}</label> | |||
| <input type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||
| <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | |||
| {{range .images}} | |||
| @@ -230,7 +230,7 @@ | |||
| {{template "custom/select_dataset" .}} | |||
| <div class="inline required field"> | |||
| <label>资源规格</label> | |||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||
| {{range .resource_specs}} | |||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
| @@ -239,31 +239,31 @@ | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>数据集存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.dataset_storage_path"}}</label> | |||
| <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>模型存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.model_storage_path"}}</label> | |||
| <input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>代码存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.code_storage_path"}}</label> | |||
| <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_benchmark"> | |||
| <label>benchmark脚本存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.benchmark_path"}}</label> | |||
| <input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_snn4imagenet"> | |||
| <label>snn4imagenet脚本存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.snn4imagenet_path"}}</label> | |||
| <input name="snn4imagenet_path" id="cloudbrain_snn4imagenet_path" value="{{.snn4imagenet_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_brainscore"> | |||
| <label>brainscore脚本存放路径</label> | |||
| <label>{{.i18n.Tr "cloudbrain.brainscore_path"}}</label> | |||
| <input name="brainscore_path" id="cloudbrain_brainscore_path" value="{{.brainscore_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field" hidden> | |||
| <label>启动命令</label> | |||
| <label>{{.i18n.Tr "cloudbrain.start_command"}}</label> | |||
| <textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea> | |||
| </div> | |||
| @@ -277,7 +277,7 @@ | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -298,7 +298,7 @@ | |||
| $(".icon.icons").css("visibility","hidden") | |||
| } | |||
| form.onsubmit = function(e){ | |||
| let value_task = $("input[name='job_name']").val() | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let value_image = $("input[name='image']").val() | |||
| let value_data = $("input[name='attachment']").val() | |||
| let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | |||
| @@ -310,9 +310,9 @@ | |||
| return false | |||
| } | |||
| let min_value_task = value_task.toLowerCase() | |||
| $("input[name='job_name']").attr("value",min_value_task) | |||
| $("input[name='display_job_name']").attr("value",min_value_task) | |||
| document.getElementById("mask").style.display = "block" | |||
| } | |||
| // 页面加载完毕后遮罩层隐藏 | |||
| @@ -321,21 +321,21 @@ | |||
| document.getElementById("mask").style.display = "none" | |||
| } | |||
| } | |||
| $('#cloudbrain_benchmark_category') | |||
| .dropdown({ | |||
| placeholder: "选择数据集类别", | |||
| }) | |||
| }) | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| // $('#cloudbrain_image').select2({ | |||
| // placeholder: "选择镜像" | |||
| // }); | |||
| $(".ui.button.reset").click(function(e){ | |||
| e.preventDefault() | |||
| $('#cloudbrain_benchmark_category') | |||
| @@ -374,4 +374,4 @@ | |||
| }) | |||
| console.log({{.RepoLink}}) | |||
| </script> | |||
| </script> | |||
| @@ -16,14 +16,14 @@ | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| {{with .task}} | |||
| <div class="active section">{{.JobName}}</div> | |||
| <div class="active section">{{.DisplayJobName}}</div> | |||
| {{end}} | |||
| </div> | |||
| </h4> | |||
| <div> | |||
| <div class="ui yellow segment"> | |||
| {{with .task}} | |||
| <p>任务名称: {{.JobName}}</p> | |||
| <p>任务名称: {{.DisplayJobName}}</p> | |||
| {{end}} | |||
| </div> | |||
| <div class="ui green segment"> | |||
| @@ -189,7 +189,7 @@ | |||
| margin-top: 0.4rem; | |||
| display: inline-block; | |||
| } | |||
| </style> | |||
| <!-- 弹窗 --> | |||
| @@ -208,10 +208,10 @@ | |||
| {{template "repo/header" .}} | |||
| {{template "base/alert" .}} | |||
| <!-- 提示框 --> | |||
| <!-- 列表容器 --> | |||
| <div class="ui container"> | |||
| <div class="ui two column stackable grid"> | |||
| <div class="column"> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| @@ -227,12 +227,12 @@ | |||
| <div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <div class="item" data-value="all">全部</div> | |||
| <div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||
| <div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||
| <div class="item" data-value="NPU">NPU</div> | |||
| </div> | |||
| </div> | |||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| {{else}} | |||
| <a class="ui disabled button">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| @@ -272,29 +272,29 @@ | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| </div> | |||
| <div class="five wide column text center"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{range .Tasks}} | |||
| <div class="ui grid stackable item"> | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="four wide column"> | |||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.JobName}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.JobID}}{{end}}?debugListType={{$.debugListType}}' title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.Cloudbrain.ID}}{{end}}' title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <!--任务状态 --> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.JobID}}" data-resource="{{.ComputeResource}}"> | |||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| @@ -313,22 +313,22 @@ | |||
| {{end}} | |||
| </div> | |||
| <div class="five wide column text center"> | |||
| <div class="ui compact buttons"> | |||
| <div class="ui compact buttons"> | |||
| <!-- {{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}}/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| 评分 | |||
| </a> | |||
| {{end}} --> | |||
| <!-- 调试 --> | |||
| <form id="debugAgainForm-{{.JobID}}"> | |||
| <form id="debugAgainForm-{{.Cloudbrain.ID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDebug}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/' data-linkpath='{{$.Link}}'> | |||
| <a id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/' data-linkpath='{{$.Link}}'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -344,12 +344,12 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </form> | |||
| <!-- 停止 --> | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/stop" data-jobid="{{.JobID}}"> | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -359,11 +359,11 @@ | |||
| {{end}} | |||
| </form> | |||
| <!-- 删除 --> | |||
| <form id="delForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="{{$.ListType}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-delete-{{.JobID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -371,18 +371,18 @@ | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | |||
| <div class="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | |||
| <div class="text">更多</div> | |||
| <div class="text">{{$.i18n.Tr "repo.more"}}</div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu" style="right: auto;"> | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <!-- 接收结果 --> | |||
| <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> | |||
| {{if .CanDebug}} | |||
| <a id="model-image-{{.JobID}}" class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button'>{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| <a id="model-image-{{.Cloudbrain.ID}}" class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button'>{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| {{else}} | |||
| <a class="imageBtn ui basic disabled button">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| {{end}} | |||
| @@ -390,14 +390,14 @@ | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <!-- 模型下载 --> | |||
| {{if .CanDebug}} | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/models" target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/models" target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||
| {{else}} | |||
| <a class="ui basic disabled button">{{$.i18n.Tr "repo.download"}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{if and (ne .JobType "DEBUG") (eq .Cloudbrain.Type 0)}} | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/rate" target="_blank"> | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| 评分 | |||
| </a> | |||
| </div> | |||
| @@ -408,28 +408,28 @@ | |||
| </div> | |||
| <!-- 镜像列表弹窗 --> | |||
| <div id="imageModal" class="modal" style="display: none;"> | |||
| <div class="modal-content"> | |||
| <div class="modal-content"> | |||
| <!-- 表格 --> | |||
| <div class="ui form"> | |||
| <form id="commitImageForm" action="{{$.RepoLink}}/cloudbrain/{{.JobID}}/commit_image" method="post" target="iframeContent"> | |||
| <form id="commitImageForm" action="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image" method="post" target="iframeContent"> | |||
| {{$.CsrfTokenHtml}} | |||
| <div class="row"> | |||
| <p style="display: inline;">提交任务镜像</p> | |||
| <span class="close">×</span> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| <div class="inline required field dis"> | |||
| <label>镜像标签:</label> | |||
| <label> {{$.i18n.Tr "repo.cloudbrain.mirror_tag"}}:</label> | |||
| <input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:75%"> | |||
| </div> | |||
| <div class="inline field"> | |||
| <label class="label_after">镜像描述:</label> | |||
| <label class="label_after">{{$.i18n.Tr "repo.cloudbrain.mirror_description"}}:</label> | |||
| <textarea name="description" maxlength="255" rows="8" style="width:75%;margin-left: 0.2em;"></textarea> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui green button" onclick="showmask()"> | |||
| @@ -438,7 +438,7 @@ | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -484,8 +484,8 @@ | |||
| let url={{.RepoLink}} | |||
| let redirect_to = {{$.Link}} | |||
| let getParam=getQueryVariable('debugListType') | |||
| let dropdownValue = ['all','',false].includes(getParam)? '全部' : getParam | |||
| let dropdownValue = ['all','',false].includes(getParam)? '{{$.i18n.Tr "repo.gpu_type_all"}}' : getParam | |||
| // localStorage.setItem('all',location.href) | |||
| function getQueryVariable(variable) | |||
| { | |||
| @@ -506,7 +506,7 @@ | |||
| }) | |||
| $('.ui.selection.dropdown').dropdown({ | |||
| onChange:function(value){ | |||
| location.href = `${url}/debugjob?debugListType=${value}` | |||
| } | |||
| }) | |||
| @@ -566,5 +566,5 @@ | |||
| } | |||
| }) | |||
| } | |||
| </script> | |||
| </script> | |||
| @@ -105,9 +105,9 @@ | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <!-- 模型版本 --> | |||
| @@ -174,7 +174,7 @@ | |||
| <div class="ui compact buttons"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -67,7 +67,7 @@ | |||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 60%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | |||
| </div> | |||
| @@ -414,8 +414,8 @@ | |||
| } | |||
| ] | |||
| }, | |||
| job_name:{ | |||
| identifier : 'job_name', | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||
| @@ -174,7 +174,7 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.infer_job"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">{{.jobName}}</div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| </h4> | |||
| {{with .task}} | |||
| @@ -199,7 +199,7 @@ td, th { | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{.JobName}} | |||
| {{.DisplayJobName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| @@ -48,7 +48,7 @@ | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>任务名称</label> | |||
| <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| @@ -107,7 +107,7 @@ | |||
| $('#messageInfo').css('display','none') | |||
| form.onsubmit = function(e){ | |||
| let value_task = $("input[name='job_name']").val() | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | |||
| @@ -121,7 +121,7 @@ | |||
| let min_value_task = value_task.toLowerCase() | |||
| $("input[name='job_name']").attr("value",min_value_task) | |||
| $("input[name='display_job_name']").attr("value",min_value_task) | |||
| document.getElementById("mask").style.display = "block" | |||
| } | |||
| @@ -16,14 +16,14 @@ | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| {{with .task}} | |||
| <div class="active section">{{.JobName}}</div> | |||
| <div class="active section">{{.DisplayJobName}}</div> | |||
| {{end}} | |||
| </div> | |||
| </h4> | |||
| <div> | |||
| <div class="ui yellow segment"> | |||
| {{with .task}} | |||
| <p>任务名称: {{.JobName}}</p> | |||
| <p>任务名称: {{.DisplayJobName}}</p> | |||
| {{end}} | |||
| </div> | |||
| <div class="ui green segment"> | |||
| @@ -102,9 +102,9 @@ | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <!-- 版本数量 --> | |||
| @@ -157,7 +157,7 @@ | |||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -80,7 +80,7 @@ | |||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 60%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | |||
| </div> | |||
| @@ -391,8 +391,8 @@ | |||
| } | |||
| ] | |||
| }, | |||
| job_name:{ | |||
| identifier : 'job_name', | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||
| @@ -183,7 +183,7 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.train_job"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">{{.jobName}}</div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| </h4> | |||
| {{range $k ,$v := .version_list_task}} | |||
| @@ -260,7 +260,7 @@ td, th { | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{.JobName}} | |||
| {{.DisplayJobName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| @@ -558,7 +558,7 @@ td, th { | |||
| onShow:function(){ | |||
| $('input[name="Version"]').addClass('model_disabled') | |||
| // $('input[name="JobId"]').text(obj.JobName) | |||
| $('#JobName').val(obj.JobName).addClass('model_disabled') | |||
| $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | |||
| $('input[name="JobId"]').val(obj.JobID) | |||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | |||
| $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | |||
| @@ -82,11 +82,12 @@ | |||
| {{end}} | |||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||
| <input type="hidden" id="display_job_name" name="display_job_name" value="{{.display_job_name}}"> | |||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input type="hidden" style="width: 60%;" name="job_name" id="trainjob_job_name" value="{{.job_name}}"> | |||
| <input style="width: 60%;" value="{{.job_name}}" tabindex="3" disabled > | |||
| <input type="hidden" style="width: 60%;" name="job_name" id="job_name" value="{{.job_name}}"> | |||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" value="{{.display_job_name}}" tabindex="3" disabled > | |||
| </div> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.parents_version"}}</label> | |||
| @@ -426,6 +427,15 @@ | |||
| } | |||
| ] | |||
| }, | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||
| } | |||
| ] | |||
| }, | |||
| attachment:{ | |||
| identifier : 'attachment', | |||
| rules: [ | |||
| @@ -483,6 +493,15 @@ | |||
| } | |||
| ] | |||
| }, | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||
| } | |||
| ] | |||
| }, | |||
| attachment:{ | |||
| identifier : 'attachment', | |||
| rules: [ | |||
| @@ -221,15 +221,16 @@ | |||
| } | |||
| function loadTrainList(){ | |||
| $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | |||
| console.log(data) | |||
| const n_length = data.length | |||
| let train_html='' | |||
| for (let i=0;i<n_length;i++){ | |||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].JobName}</div>` | |||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].DisplayJobName}</div>` | |||
| train_html += '</div>' | |||
| } | |||
| $("#job-name").append(train_html) | |||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | |||
| $('#choice_model .default.text').text(data[0].JobName) | |||
| $('#choice_model .default.text').text(data[0].DisplayJobName) | |||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | |||
| loadTrainVersion() | |||
| @@ -73,7 +73,7 @@ | |||
| {{else if eq .GetOpType 24}} | |||
| {{$.i18n.Tr "action.upload_dataset" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 25}} | |||
| {{$.i18n.Tr "action.task_gpudebugjob" .GetRepoLink .RefName .RefName | Str2html}} | |||
| {{$.i18n.Tr "action.task_gpudebugjob" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 26}} | |||
| {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 27}} | |||
| @@ -81,7 +81,7 @@ | |||
| {{else if eq .GetOpType 28}} | |||
| {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 29}} | |||
| {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .RefName .RefName | Str2html}} | |||
| {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 30}} | |||
| {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | |||
| {{end}} | |||
| @@ -3,52 +3,52 @@ export default async function initCloudrain() { | |||
| $(document).ready(loadJobStatus); | |||
| function loadJobStatus() { | |||
| $(".job-status").each((index, job) => { | |||
| const jobID = job.dataset.jobid; | |||
| const ID = job.dataset.jobid; | |||
| const repoPath = job.dataset.repopath; | |||
| // const computeResource = job.dataset.resource | |||
| const versionname = job.dataset.version | |||
| const status_text = $(`#${jobID}-text`).text() | |||
| const status_text = $(`#${ID}-text`).text() | |||
| const finalState = ['STOPPED','CREATE_FAILED','UNAVAILABLE','DELETED','RESIZE_FAILED','SUCCEEDED','IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUBMIT_MODEL_FAILED','DEPLOY_SERVICE_FAILED','CHECK_FAILED'] | |||
| if (finalState.includes(status_text)) { | |||
| return | |||
| } | |||
| // const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||
| $.get(`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, (data) => { | |||
| const jobID = data.JobID | |||
| $.get(`/api/v1/repos/${repoPath}/${ID}?version_name=${versionname}`, (data) => { | |||
| const ID = data.ID || data.JobID | |||
| const status = data.JobStatus | |||
| const duration = data.JobDuration | |||
| $('#duration-'+jobID).text(duration) | |||
| $('#duration-'+ID).text(duration) | |||
| if (status != status_text) { | |||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||
| $('#' + jobID+ '-text').text(status) | |||
| finalState.includes(status) && $('#' + jobID + '-stop').removeClass('blue').addClass('disabled') | |||
| $('#' + ID+'-icon').removeClass().addClass(status) | |||
| $('#' + ID+ '-text').text(status) | |||
| finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+ID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| // $('#model-debug-'+jobID).removeClass('blue') | |||
| // $('#model-debug-'+jobID).addClass('disabled') | |||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||
| // $('#model-debug-'+ID).removeClass('blue') | |||
| // $('#model-debug-'+ID).addClass('disabled') | |||
| $('#model-image-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#ai-debug-'+jobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#ai-stop-'+jobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+ID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||
| $('#ai-stop-'+jobID).removeClass('blue').addClass('disabled') | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED","COMPLETED"].includes(status)){ | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(status)){ | |||
| $('#ai-delete-'+jobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#ai-delete-'+jobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| @@ -104,25 +104,25 @@ export default async function initCloudrain() { | |||
| assertDelete(this) | |||
| } | |||
| }) | |||
| function stopDebug(JobID,stopUrl){ | |||
| function stopDebug(ID,stopUrl){ | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:stopUrl, | |||
| data:$('#stopForm-'+JobID).serialize(), | |||
| data:$('#stopForm-'+ID).serialize(), | |||
| success:function(res){ | |||
| if(res.result_code==="0"){ | |||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + JobID+ '-text').text(res.status) | |||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + ID+ '-text').text(res.status) | |||
| if(res.status==="STOPPED"){ | |||
| $('#ai-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||
| $('#ai-image-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+JobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||
| $('#ai-image-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-model-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| else{ | |||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }else{ | |||
| @@ -136,42 +136,41 @@ export default async function initCloudrain() { | |||
| }) | |||
| } | |||
| $('.ui.basic.ai_stop').click(function() { | |||
| const jobID = this.dataset.jobid | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| stopDebug(jobID,repoPath) | |||
| stopDebug(ID,repoPath) | |||
| }) | |||
| function stopVersion(version_name,jobID,repoPath){ | |||
| const url = `/api/v1/repos/${repoPath}/${jobID}/stop_version` | |||
| function stopVersion(version_name,ID,repoPath){ | |||
| const url = `/api/v1/repos/${repoPath}/${ID}/stop_version` | |||
| $.post(url,{version_name:version_name},(data)=>{ | |||
| if(data.StatusOK===0){ | |||
| $('#ai-stop-'+jobID).removeClass('blue') | |||
| $('#ai-stop-'+jobID).addClass('disabled') | |||
| refreshStatus(version_name,jobID,repoPath) | |||
| $('#ai-stop-'+ID).removeClass('blue') | |||
| $('#ai-stop-'+ID).addClass('disabled') | |||
| refreshStatus(version_name,ID,repoPath) | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| function refreshStatus(version_name,jobID,repoPath){ | |||
| function refreshStatus(version_name,ID,repoPath){ | |||
| const url = `/api/v1/repos/${repoPath}/${jobID}/?version_name${version_name}` | |||
| const url = `/api/v1/repos/${repoPath}/${ID}/?version_name${version_name}` | |||
| $.get(url,(data)=>{ | |||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||
| $(`#${ID}-icon`).attr("class",data.JobStatus) | |||
| // detail status and duration | |||
| $(`#${jobID}-text`).text(data.JobStatus) | |||
| $(`#${ID}-text`).text(data.JobStatus) | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| $('.ui.basic.ai_stop_version').click(function() { | |||
| const jobID = this.dataset.jobid | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| const versionName = this.dataset.version | |||
| stopVersion(versionName,jobID,repoPath) | |||
| stopVersion(versionName,ID,repoPath) | |||
| }) | |||
| function getModelInfo(repoPath,modelName,versionName,jobName){ | |||
| console.log("getModelInfo") | |||
| $.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`,(data)=>{ | |||
| if(data.length===0){ | |||
| $(`#${jobName}`).popup('toggle') | |||
| @@ -195,27 +194,27 @@ export default async function initCloudrain() { | |||
| const jobName = this.dataset.jobname | |||
| getModelInfo(repoPath,modelName,versionName,jobName) | |||
| }) | |||
| function debugAgain(JobID,debugUrl,redirect_to){ | |||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||
| function debugAgain(ID,debugUrl,redirect_to){ | |||
| if($('#' + ID+ '-text').text()==="RUNNING"){ | |||
| window.open(debugUrl+'debug') | |||
| }else{ | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:debugUrl+'restart?redirect_to='+redirect_to, | |||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||
| data:$('#debugAgainForm-'+ID).serialize(), | |||
| success:function(res){ | |||
| if(res['WechatRedirectUrl']){ | |||
| window.location.href=res['WechatRedirectUrl'] | |||
| } | |||
| else if(res.result_code==="0"){ | |||
| if(res.job_id!==JobID){ | |||
| if(res.id!==ID){ | |||
| location.reload() | |||
| }else{ | |||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + JobID+ '-text').text(res.status) | |||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+JobID).text("调试").css("margin","0 1rem") | |||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + ID+ '-text').text(res.status) | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+ID).text("调试").css("margin","0 1rem") | |||
| } | |||
| }else{ | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| @@ -228,10 +227,10 @@ export default async function initCloudrain() { | |||
| } | |||
| } | |||
| $('.ui.basic.ai_debug').click(function() { | |||
| const jobID = this.dataset.jobid | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| const redirect_to = this.dataset.linkpath | |||
| debugAgain(jobID,repoPath,redirect_to) | |||
| debugAgain(ID,repoPath,redirect_to) | |||
| }) | |||
| } | |||
| @@ -703,9 +703,11 @@ display: block; | |||
| margin-bottom: -50px; | |||
| } | |||
| .repo-header .repo-buttons{ | |||
| position: absolute; | |||
| right: 15px; | |||
| margin-bottom: -60px; | |||
| position: relative; | |||
| top: 1rem; | |||
| width: 100%; | |||
| display: flex; | |||
| justify-content: flex-end; | |||
| } | |||
| .repo-buttons .ui.labeled.button>.button{ | |||
| box-shadow: none !important; | |||
| @@ -738,4 +740,47 @@ display: block; | |||
| } | |||
| .el-pagination.is-background .el-pager li:hover { | |||
| color: #5bb973 !important; | |||
| } | |||
| } | |||
| .tag_key{ | |||
| max-width:100%; | |||
| margin: 3px 3px; | |||
| display:inline-flex; | |||
| } | |||
| .tag_lable{ | |||
| border: 1px solid rgba(232, 232, 232, 100) ; | |||
| border-radius: 4px; | |||
| color: rgba(65, 80, 88, 100); | |||
| font-family: Microsoft Yahei; | |||
| font-size: 14px; | |||
| padding: 0.3em 0.5em; | |||
| height: 30px; | |||
| text-align: center; | |||
| margin: 0.2em; | |||
| } | |||
| .omit{ | |||
| overflow: hidden; white-space: nowrap; text-overflow: ellipsis; | |||
| } | |||
| .tag_bg{ | |||
| background-color: #0366D6 !important; | |||
| color:#FFFFFF !important; | |||
| } | |||
| .margin-bottom20{ | |||
| margin-bottom: 20px; | |||
| } | |||
| .maxheight{ | |||
| max-height: 88px; | |||
| overflow: hidden; | |||
| } | |||
| .pad-botom{ | |||
| padding-bottom:0px !important; | |||
| } | |||
| .icon_a{ | |||
| position: absolute; | |||
| right: 0; | |||
| bottom: .2em; | |||
| background: #FFF; | |||
| border: none !important; | |||
| color: #0366d6 !important; | |||
| box-shadow: -15px 0px 10px #fff; | |||
| } | |||
| @@ -0,0 +1,274 @@ | |||
| const cssnano = require('cssnano'); | |||
| const fastGlob = require('fast-glob'); | |||
| const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries'); | |||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |||
| const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); | |||
| const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | |||
| const PostCSSPresetEnv = require('postcss-preset-env'); | |||
| const PostCSSSafeParser = require('postcss-safe-parser'); | |||
| const SpriteLoaderPlugin = require('svg-sprite-loader/plugin'); | |||
| const TerserPlugin = require('terser-webpack-plugin'); | |||
| const VueLoaderPlugin = require('vue-loader/lib/plugin'); | |||
| const {statSync} = require('fs'); | |||
| const {resolve, parse} = require('path'); | |||
| //const {SourceMapDevToolPlugin} = require('webpack'); | |||
| const glob = (pattern) => fastGlob.sync(pattern, {cwd: __dirname, absolute: true}); | |||
| const themes = {}; | |||
| for (const path of glob('web_src/less/themes/*.less')) { | |||
| themes[parse(path).name] = [path]; | |||
| } | |||
| const isProduction = process.env.NODE_ENV !== 'development'; | |||
| module.exports = { | |||
| mode: isProduction ? 'production' : 'development', | |||
| entry: { | |||
| index: [ | |||
| resolve(__dirname, 'web_src/js/index.js'), | |||
| resolve(__dirname, 'web_src/less/index.less'), | |||
| ], | |||
| swagger: [ | |||
| resolve(__dirname, 'web_src/js/standalone/swagger.js'), | |||
| ], | |||
| jquery: [ | |||
| resolve(__dirname, 'web_src/js/jquery.js'), | |||
| ], | |||
| icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'), | |||
| ...themes, | |||
| }, | |||
| devtool: false, | |||
| output: { | |||
| path: resolve(__dirname, 'public'), | |||
| filename: 'js/[name].js', | |||
| chunkFilename: 'js/[name].js', | |||
| }, | |||
| node:{ | |||
| fs: 'empty' | |||
| }, | |||
| optimization: { | |||
| minimize: isProduction, | |||
| minimizer: [ | |||
| new TerserPlugin({ | |||
| sourceMap: true, | |||
| extractComments: false, | |||
| terserOptions: { | |||
| keep_fnames: /^(HTML|SVG)/, // https://github.com/fgnass/domino/issues/144 | |||
| output: { | |||
| comments: false, | |||
| }, | |||
| }, | |||
| }), | |||
| new OptimizeCSSAssetsPlugin({ | |||
| cssProcessor: cssnano, | |||
| cssProcessorOptions: { | |||
| parser: PostCSSSafeParser, | |||
| }, | |||
| cssProcessorPluginOptions: { | |||
| preset: [ | |||
| 'default', | |||
| { | |||
| discardComments: { | |||
| removeAll: true, | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| }), | |||
| ], | |||
| splitChunks: { | |||
| chunks: 'async', | |||
| name: (_, chunks) => chunks.map((item) => item.name).join('-'), | |||
| cacheGroups: { | |||
| // this bundles all monaco's languages into one file instead of emitting 1-65.js files | |||
| monaco: { | |||
| test: /monaco-editor/, | |||
| name: 'monaco', | |||
| chunks: 'async' | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| module: { | |||
| rules: [ | |||
| { | |||
| test: /\.vue$/, | |||
| exclude: /node_modules/, | |||
| loader: 'vue-loader', | |||
| }, | |||
| { | |||
| test: require.resolve('jquery-datetimepicker'), | |||
| use: 'imports-loader?define=>false,exports=>false', | |||
| }, | |||
| { | |||
| test: /\.worker\.js$/, | |||
| exclude: /monaco/, | |||
| use: [ | |||
| { | |||
| loader: 'worker-loader', | |||
| options: { | |||
| name: '[name].js', | |||
| inline: true, | |||
| fallback: false, | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| test: /\.ts$/, | |||
| use: [ | |||
| { | |||
| loader: "ts-loader", | |||
| } | |||
| ], | |||
| exclude: /node_modules/ | |||
| }, | |||
| { | |||
| test: /\.js$/, | |||
| exclude: /node_modules/, | |||
| use: [ | |||
| { | |||
| loader: 'babel-loader', | |||
| options: { | |||
| cacheDirectory: true, | |||
| cacheCompression: false, | |||
| cacheIdentifier: [ | |||
| resolve(__dirname, 'package.json'), | |||
| resolve(__dirname, 'package-lock.json'), | |||
| resolve(__dirname, 'webpack.config.js'), | |||
| ].map((path) => statSync(path).mtime.getTime()).join(':'), | |||
| sourceMaps: true, | |||
| presets: [ | |||
| [ | |||
| '@babel/preset-env', | |||
| { | |||
| useBuiltIns: 'usage', | |||
| corejs: 3, | |||
| }, | |||
| ], | |||
| ], | |||
| plugins: [ | |||
| [ | |||
| '@babel/plugin-transform-runtime', | |||
| { | |||
| regenerator: true, | |||
| } | |||
| ], | |||
| '@babel/plugin-proposal-object-rest-spread', | |||
| ], | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| test: /\.(less|css)$/i, | |||
| use: [ | |||
| { | |||
| loader: MiniCssExtractPlugin.loader, | |||
| }, | |||
| { | |||
| loader: 'css-loader', | |||
| options: { | |||
| importLoaders: 2, | |||
| url: (_url, resourcePath) => { | |||
| // only resolve URLs for dependencies | |||
| return resourcePath.includes('node_modules'); | |||
| }, | |||
| } | |||
| }, | |||
| { | |||
| loader: 'postcss-loader', | |||
| options: { | |||
| plugins: () => [ | |||
| PostCSSPresetEnv(), | |||
| ], | |||
| }, | |||
| }, | |||
| { | |||
| loader: 'less-loader', | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| test: /\.svg$/, | |||
| use: [ | |||
| { | |||
| loader: 'svg-sprite-loader', | |||
| options: { | |||
| extract: true, | |||
| spriteFilename: 'img/svg/icons.svg', | |||
| symbolId: (path) => { | |||
| const {name} = parse(path); | |||
| if (/@primer[/\\]octicons/.test(path)) { | |||
| return `octicon-${name}`; | |||
| } | |||
| return name; | |||
| }, | |||
| }, | |||
| }, | |||
| { | |||
| loader: 'svgo-loader', | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| test: /\.(ttf|woff2?)$/, | |||
| use: [ | |||
| { | |||
| loader: 'file-loader', | |||
| options: { | |||
| name: '[name].[ext]', | |||
| outputPath: 'fonts/', | |||
| publicPath: (url) => `../fonts/${url}`, // seems required for monaco's font | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| ], | |||
| }, | |||
| plugins: [ | |||
| new VueLoaderPlugin(), | |||
| // avoid generating useless js output files for css- and svg-only chunks | |||
| new FixStyleOnlyEntriesPlugin({ | |||
| extensions: ['less', 'scss', 'css', 'svg'], | |||
| silent: true, | |||
| }), | |||
| new MiniCssExtractPlugin({ | |||
| filename: 'css/[name].css', | |||
| chunkFilename: 'css/[name].css', | |||
| }), | |||
| //new SourceMapDevToolPlugin({ | |||
| //filename: 'js/[name].js.map', | |||
| //include: [ | |||
| //'js/index.js', | |||
| //], | |||
| //}), | |||
| new SpriteLoaderPlugin({ | |||
| plainSprite: true, | |||
| }), | |||
| new MonacoWebpackPlugin({ | |||
| filename: 'js/monaco-[name].worker.js', | |||
| }) | |||
| ], | |||
| performance: { | |||
| hints: false, | |||
| maxEntrypointSize: Infinity, | |||
| maxAssetSize: Infinity, | |||
| }, | |||
| resolve: { | |||
| symlinks: false, | |||
| alias: { | |||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | |||
| }, | |||
| extensions: ['.tsx', '.ts', '.js'] | |||
| }, | |||
| watchOptions: { | |||
| ignored: [ | |||
| 'node_modules/**', | |||
| ], | |||
| }, | |||
| stats: { | |||
| children: false, | |||
| }, | |||
| }; | |||