| @@ -44,6 +44,12 @@ | |||||
| -webkit-line-clamp: 2; | -webkit-line-clamp: 2; | ||||
| -webkit-box-orient: vertical; | -webkit-box-orient: vertical; | ||||
| } | } | ||||
| .ui.label{ | |||||
| font-weight: normal; | |||||
| } | |||||
| .active { | |||||
| color: #0366D6 !important; | |||||
| } | |||||
| .opacity5{ opacity:0.5;} | .opacity5{ opacity:0.5;} | ||||
| .radius15{ border-radius:1.5rem !important; } | .radius15{ border-radius:1.5rem !important; } | ||||
| @@ -250,9 +256,13 @@ | |||||
| box-shadow: none !important; | box-shadow: none !important; | ||||
| } | } | ||||
| .homeorg-list .card .ui.small.header .content{ | .homeorg-list .card .ui.small.header .content{ | ||||
| width: calc(100% - 3.25em); | |||||
| width: calc(100% - 3.75em); | |||||
| } | } | ||||
| .homepro-list{ | |||||
| .homepro-tit{ | |||||
| z-index: 9; | |||||
| position: relative; | |||||
| } | |||||
| .homepro-list, .homeorg-list{ | |||||
| position: relative; | position: relative; | ||||
| z-index: 9; | z-index: 9; | ||||
| padding: 1.0em 1.0em 3.0em; | padding: 1.0em 1.0em 3.0em; | ||||
| @@ -261,42 +271,156 @@ | |||||
| .homepro-list .ui.card{ | .homepro-list .ui.card{ | ||||
| border-radius: 15px; | border-radius: 15px; | ||||
| background-color: #FFF; | background-color: #FFF; | ||||
| box-shadow: 0px 5px 10px 0px rgba(105, 192, 255, 30); | |||||
| border: 1px solid rgba(105, 192, 255, 40); | |||||
| box-shadow: 0px 5px 10px 0px rgba(105, 192, 255, .3); | |||||
| border: 1px solid rgba(105, 192, 255, .4); | |||||
| min-height: 10.8em; | min-height: 10.8em; | ||||
| } | } | ||||
| .homepro-list .ui.card>.content>.header{ | .homepro-list .ui.card>.content>.header{ | ||||
| line-height: 40px !important; | line-height: 40px !important; | ||||
| } | } | ||||
| .homepro-list .swiper-pagination-bullet-active{ | |||||
| .homepro-list .swiper-pagination-bullet-active, .homeorg-list .swiper-pagination-bullet-active{ | |||||
| width: 40px; | width: 40px; | ||||
| border-radius: 4px; | |||||
| border-radius: 4px; | |||||
| } | } | ||||
| .i-env > div{ | .i-env > div{ | ||||
| position: relative; | position: relative; | ||||
| } | } | ||||
| /**seach**/ | |||||
| /**搜索导航条适配窄屏**/ | |||||
| .seachnav{ | |||||
| overflow-x: auto; | |||||
| overflow-y: hidden; | |||||
| scrollbar-width: none; /* firefox */ | |||||
| -ms-overflow-style: none; /* IE 10+ */ | |||||
| } | |||||
| .seachnav::-webkit-scrollbar { | |||||
| display: none; /* Chrome Safari */ | |||||
| } | |||||
| .ui.green.button, .ui.green.buttons .button{ | |||||
| background-color: #5BB973; | |||||
| } | |||||
| .seach .repos--seach{ | |||||
| padding-bottom: 0; | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu{ | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .item > i{ | |||||
| margin-right: 5px; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .active.item{ | |||||
| border-bottom-width: 2px; | |||||
| margin: 0 0 -1px; | |||||
| } | |||||
| .seach .ui.menu .active.item>.label { | |||||
| background: #1684FC; | |||||
| color: #FFF; | |||||
| } | |||||
| .seach .ui.menu .item>.label:not(.active.item>.label) { | |||||
| background: #e8e8e8; | |||||
| color: rgba(0,0,0,.6); | |||||
| } | |||||
| .highlight{ | |||||
| color: red; | |||||
| } | |||||
| .ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||||
| width: calc(100% - 3.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| .seach .ui.list .list>.item .header, .seach .ui.list>.item .header{ | |||||
| margin-bottom: 0.5em; | |||||
| font-size: 1.4rem !important; | |||||
| font-weight: normal; | |||||
| } | |||||
| .seach .time, .seach .time a{ | |||||
| font-size: 12px; | |||||
| color: grey; | |||||
| } | |||||
| .seach .list .item.members .ui.avatar.image { | |||||
| width: 3.2em; | |||||
| height: 3.2em; | |||||
| } | |||||
| .ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content { | |||||
| width: calc(100% - 4.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| @media only screen and (max-width: 767px) { | @media only screen and (max-width: 767px) { | ||||
| .am-mt-30{ margin-top: 1.5rem !important;} | .am-mt-30{ margin-top: 1.5rem !important;} | ||||
| .ui.secondary.hometop.segment{ | .ui.secondary.hometop.segment{ | ||||
| margin-bottom: 2.0rem; | |||||
| margin-bottom: 5.0rem; | |||||
| } | } | ||||
| .bannerpic, .i-code-pic{ | |||||
| .bannerpic{ | |||||
| display: none; | display: none; | ||||
| } | } | ||||
| .i-code h2::before { | |||||
| left: calc(-5.0rem + 6px); | |||||
| #homenews{ | |||||
| bottom: -3em; | |||||
| } | } | ||||
| .i-code h2.am-bw::before{ | |||||
| left: calc(-4.0rem + 6px); | |||||
| #homenews > p { | |||||
| margin-left: 1.0em; | |||||
| } | |||||
| .homenews{ | |||||
| padding-left: 1.3em !important; | |||||
| border-radius: 1.5em; | |||||
| } | |||||
| .homenews::before{ | |||||
| left: 2em; | |||||
| } | |||||
| .homepro-tit > p{ | |||||
| background: #FFF; | |||||
| } | |||||
| .homeorg{ | |||||
| padding-left: 3.5em; | |||||
| } | |||||
| .homeorg-tit::after { | |||||
| left: -2.3em; | |||||
| } | |||||
| .homeorg-list{ | |||||
| margin: 0 0 2.0em !important; | |||||
| } | |||||
| .homeorg-list > .column{ | |||||
| width: 3em !important; | |||||
| margin-left: -0.5em; | |||||
| padding: 0.5rem 0 0 !important; | |||||
| } | |||||
| .homeorg-list .card{ | |||||
| background: none !important; | |||||
| } | |||||
| .homeorg-list .card > .content{ | |||||
| padding: 0 !important; | |||||
| } | |||||
| .homeorg-list > .column .card .ui.header>img{ | |||||
| width: 3.0em; | |||||
| height: 3.0em; | |||||
| border-radius: 2.0em; | |||||
| border: 2px solid #FFF; | |||||
| } | |||||
| .homeorg-list > .column .card .ui.header > .content{ | |||||
| display: none; | |||||
| } | } | ||||
| .leftline01{ | .leftline01{ | ||||
| width: calc(50% - 4.0rem); | |||||
| width: 4.0em; | |||||
| bottom: 4em; | |||||
| border-radius: 0 0 0 3.0em; | |||||
| } | } | ||||
| .leftline02{ | |||||
| left: calc(50% - 1.0rem); | |||||
| top: calc(-3.5rem - 2px); | |||||
| .leftline02, .leftline02-2{ | |||||
| left: 6.0em; | |||||
| top: calc(-4.0em - 2px); | |||||
| border-radius: 0 3.0em 3.0em 0; | |||||
| width: calc(50% - 6.0em); | |||||
| } | |||||
| .leftline02-2 { | |||||
| width: calc(50% - 8.0em); | |||||
| } | |||||
| .i-env .ui.cards>.card>.content .description{ | |||||
| display: none; | |||||
| } | } | ||||
| } | } | ||||
| @@ -49,6 +49,14 @@ const ( | |||||
| ActionApprovePullRequest // 21 | ActionApprovePullRequest // 21 | ||||
| ActionRejectPullRequest // 22 | ActionRejectPullRequest // 22 | ||||
| ActionCommentPull // 23 | ActionCommentPull // 23 | ||||
| ActionUploadAttachment //24 | |||||
| ActionCreateDebugGPUTask //25 | |||||
| ActionCreateDebugNPUTask //26 | |||||
| ActionCreateTrainTask //27 | |||||
| ActionCreateInferenceTask // 28 | |||||
| ActionCreateBenchMarkTask //29 | |||||
| ActionCreateNewModelTask //30 | |||||
| ) | ) | ||||
| // Action represents user operation type and other information to | // Action represents user operation type and other information to | ||||
| @@ -88,12 +88,25 @@ func (a *Attachment) APIFormat() *api.Attachment { | |||||
| Size: a.Size, | Size: a.Size, | ||||
| UUID: a.UUID, | UUID: a.UUID, | ||||
| DownloadURL: a.DownloadURL(), | DownloadURL: a.DownloadURL(), | ||||
| S3DownloadURL: a.S3DownloadURL(), | |||||
| } | } | ||||
| } | } | ||||
| // DownloadURL returns the download url of the attached file | // DownloadURL returns the download url of the attached file | ||||
| func (a *Attachment) DownloadURL() string { | func (a *Attachment) DownloadURL() string { | ||||
| return fmt.Sprintf("%sattachments/%s", setting.AppURL, a.UUID) | |||||
| return fmt.Sprintf("%sattachments/%s?type=%d", setting.AppURL, a.UUID, a.Type) | |||||
| } | |||||
| // S3DownloadURL returns the s3 download url of the attached file | |||||
| func (a *Attachment) S3DownloadURL() string { | |||||
| url := "" | |||||
| if a.Type == TypeCloudBrainOne { | |||||
| url, _ = storage.Attachments.PresignedGetURL(setting.Attachment.Minio.BasePath+AttachmentRelativePath(a.UUID), a.Name) | |||||
| } else if a.Type == TypeCloudBrainTwo { | |||||
| url, _ = storage.ObsGetPreSignedUrl(a.UUID, a.Name) | |||||
| } | |||||
| return url | |||||
| } | } | ||||
| // AttachmentRelativePath returns the relative path | // AttachmentRelativePath returns the relative path | ||||
| @@ -102,7 +102,7 @@ type Cloudbrain struct { | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| Duration int64 | Duration int64 | ||||
| TrainJobDuration string | TrainJobDuration string | ||||
| Image string //GPU镜像名称 | |||||
| Image string //镜像名称 | |||||
| GpuQueue string //GPU类型即GPU队列 | GpuQueue string //GPU类型即GPU队列 | ||||
| ResourceSpecId int //GPU规格id | ResourceSpecId int //GPU规格id | ||||
| DeletedAt time.Time `xorm:"deleted"` | DeletedAt time.Time `xorm:"deleted"` | ||||
| @@ -219,17 +219,20 @@ type GetImagesPayload struct { | |||||
| type CloudbrainsOptions struct { | type CloudbrainsOptions struct { | ||||
| ListOptions | ListOptions | ||||
| RepoID int64 // include all repos if empty | |||||
| UserID int64 | |||||
| JobID string | |||||
| SortType string | |||||
| CloudbrainIDs []int64 | |||||
| // JobStatus CloudbrainStatus | |||||
| RepoID int64 // include all repos if empty | |||||
| UserID int64 | |||||
| JobID string | |||||
| SortType string | |||||
| CloudbrainIDs []int64 | |||||
| JobStatus []string | |||||
| JobStatusNot bool | |||||
| Keyword string | |||||
| Type int | Type int | ||||
| JobTypes []string | JobTypes []string | ||||
| VersionName string | VersionName string | ||||
| IsLatestVersion string | IsLatestVersion string | ||||
| JobTypeNot bool | JobTypeNot bool | ||||
| NeedRepoInfo bool | |||||
| } | } | ||||
| type TaskPod struct { | type TaskPod struct { | ||||
| @@ -449,6 +452,16 @@ type FlavorInfo struct { | |||||
| Desc string `json:"desc"` | Desc string `json:"desc"` | ||||
| } | } | ||||
| type ImageInfosModelArts struct { | |||||
| ImageInfo []*ImageInfoModelArts `json:"image_info"` | |||||
| } | |||||
| type ImageInfoModelArts struct { | |||||
| Id string `json:"id"` | |||||
| Value string `json:"value"` | |||||
| Desc string `json:"desc"` | |||||
| } | |||||
| type PoolInfos struct { | type PoolInfos struct { | ||||
| PoolInfo []*PoolInfo `json:"pool_info"` | PoolInfo []*PoolInfo `json:"pool_info"` | ||||
| } | } | ||||
| @@ -1072,16 +1085,39 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| } | } | ||||
| if (opts.IsLatestVersion) != "" { | if (opts.IsLatestVersion) != "" { | ||||
| cond = cond.And( | |||||
| builder.Eq{"cloudbrain.is_latest_version": opts.IsLatestVersion}, | |||||
| ) | |||||
| cond = cond.And(builder.Or(builder.And(builder.Eq{"cloudbrain.is_latest_version": opts.IsLatestVersion}, builder.Eq{"cloudbrain.job_type": "TRAIN"}), builder.Neq{"cloudbrain.job_type": "TRAIN"})) | |||||
| } | } | ||||
| if len(opts.CloudbrainIDs) > 0 { | if len(opts.CloudbrainIDs) > 0 { | ||||
| cond = cond.And(builder.In("cloudbrain.id", opts.CloudbrainIDs)) | cond = cond.And(builder.In("cloudbrain.id", opts.CloudbrainIDs)) | ||||
| } | } | ||||
| count, err := sess.Where(cond).Count(new(Cloudbrain)) | |||||
| if len(opts.JobStatus) > 0 { | |||||
| if opts.JobStatusNot { | |||||
| cond = cond.And( | |||||
| builder.NotIn("cloudbrain.status", opts.JobStatus), | |||||
| ) | |||||
| } else { | |||||
| cond = cond.And( | |||||
| builder.In("cloudbrain.status", opts.JobStatus), | |||||
| ) | |||||
| } | |||||
| } | |||||
| var count int64 | |||||
| var err error | |||||
| condition := "cloudbrain.user_id = `user`.id" | |||||
| if len(opts.Keyword) == 0 { | |||||
| count, err = sess.Where(cond).Count(new(Cloudbrain)) | |||||
| } else { | |||||
| lowerKeyWord := strings.ToLower(opts.Keyword) | |||||
| cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) | |||||
| count, err = sess.Table(&Cloudbrain{}).Where(cond). | |||||
| Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | |||||
| } | |||||
| if err != nil { | if err != nil { | ||||
| return nil, 0, fmt.Errorf("Count: %v", err) | return nil, 0, fmt.Errorf("Count: %v", err) | ||||
| } | } | ||||
| @@ -1099,11 +1135,25 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| sess.OrderBy("cloudbrain.created_unix DESC") | sess.OrderBy("cloudbrain.created_unix DESC") | ||||
| cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | ||||
| if err := sess.Table(&Cloudbrain{}).Where(cond). | if err := sess.Table(&Cloudbrain{}).Where(cond). | ||||
| Join("left", "`user`", "cloudbrain.user_id = `user`.id"). | |||||
| Join("left", "`user`", condition). | |||||
| Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
| return nil, 0, fmt.Errorf("Find: %v", err) | return nil, 0, fmt.Errorf("Find: %v", err) | ||||
| } | } | ||||
| if opts.NeedRepoInfo { | |||||
| var ids []int64 | |||||
| for _, task := range cloudbrains { | |||||
| ids = append(ids, task.RepoID) | |||||
| } | |||||
| repositoryMap, err := GetRepositoriesMapByIDs(ids) | |||||
| if err == nil { | |||||
| for _, task := range cloudbrains { | |||||
| task.Repo = repositoryMap[task.RepoID] | |||||
| } | |||||
| } | |||||
| } | |||||
| return cloudbrains, count, nil | return cloudbrains, count, nil | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ type RepoStatistic struct { | |||||
| ID int64 `xorm:"pk autoincr" json:"-"` | ID int64 `xorm:"pk autoincr" json:"-"` | ||||
| RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | ||||
| Name string `xorm:"INDEX" json:"name"` | Name string `xorm:"INDEX" json:"name"` | ||||
| Alias string `xorm:"INDEX" json:"alias"` | |||||
| OwnerName string `json:"ownerName"` | OwnerName string `json:"ownerName"` | ||||
| IsPrivate bool `json:"isPrivate"` | IsPrivate bool `json:"isPrivate"` | ||||
| IsMirror bool `json:"isMirror"` | IsMirror bool `json:"isMirror"` | ||||
| @@ -63,6 +64,13 @@ type RepoStatistic struct { | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated" json:"-"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated" json:"-"` | ||||
| } | } | ||||
| func (repo *RepoStatistic) DisplayName() string { | |||||
| if repo.Alias == "" { | |||||
| return repo.Name | |||||
| } | |||||
| return repo.Alias | |||||
| } | |||||
| func DeleteRepoStatDaily(date string) error { | func DeleteRepoStatDaily(date string) error { | ||||
| sess := xStatistic.NewSession() | sess := xStatistic.NewSession() | ||||
| defer sess.Close() | defer sess.Close() | ||||
| @@ -19,7 +19,8 @@ type CreateModelArtsNotebookForm struct { | |||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| Attachment string `form:"attachment"` | Attachment string `form:"attachment"` | ||||
| Description string `form:"description"` | Description string `form:"description"` | ||||
| Flavor string `form:"flavor"` | |||||
| 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 { | func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @@ -1,16 +1,17 @@ | |||||
| package cloudbrain | package cloudbrain | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "strconv" | "strconv" | ||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -221,13 +222,19 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
| ComputeResource: models.GPUResource, | ComputeResource: models.GPUResource, | ||||
| BenchmarkTypeID: benchmarkTypeID, | BenchmarkTypeID: benchmarkTypeID, | ||||
| BenchmarkChildTypeID: benchmarkChildTypeID, | BenchmarkChildTypeID: benchmarkChildTypeID, | ||||
| Description: description, | |||||
| Description: description, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| if string(models.JobTypeBenchmark) == jobType { | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateBenchMarkTask) | |||||
| } else { | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateDebugGPUTask) | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -6,12 +6,14 @@ | |||||
| package context | package context | ||||
| import ( | import ( | ||||
| "encoding/base64" | |||||
| "net/http" | |||||
| "strings" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "encoding/base64" | |||||
| "net/http" | |||||
| "gitea.com/macaron/csrf" | "gitea.com/macaron/csrf" | ||||
| "gitea.com/macaron/macaron" | "gitea.com/macaron/macaron" | ||||
| @@ -96,7 +98,14 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||
| return | return | ||||
| } | } | ||||
| ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | |||||
| tempUrl := ctx.Req.URL.RequestURI() | |||||
| if strings.Contains(tempUrl, "action/star?") || strings.Contains(tempUrl, "action/watch?") { | |||||
| redirectForStarAndWatch(ctx, tempUrl) | |||||
| } else { | |||||
| ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | |||||
| } | |||||
| ctx.Redirect(setting.AppSubURL + "/user/login") | ctx.Redirect(setting.AppSubURL + "/user/login") | ||||
| return | return | ||||
| } else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | } else if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | ||||
| @@ -195,6 +204,17 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||
| } | } | ||||
| } | } | ||||
| func redirectForStarAndWatch(ctx *Context, tempUrl string) { | |||||
| splits := strings.Split(tempUrl, "?") | |||||
| if len(splits) > 1 { | |||||
| redirectArguments := strings.Split(splits[1], "=") | |||||
| if len(redirectArguments) > 0 && redirectArguments[0] == "redirect_to" { | |||||
| ctx.SetCookie("redirect_to", setting.AppSubURL+strings.Replace(redirectArguments[1], "%2f", "/", -1), 0, setting.AppSubURL) | |||||
| } | |||||
| } | |||||
| } | |||||
| func basicAuth(ctx *Context) bool { | func basicAuth(ctx *Context) bool { | ||||
| var siteAuth = base64.StdEncoding.EncodeToString([]byte(setting.CBAuthUser + ":" + setting.CBAuthPassword)) | var siteAuth = base64.StdEncoding.EncodeToString([]byte(setting.CBAuthUser + ":" + setting.CBAuthPassword)) | ||||
| auth := ctx.Req.Header.Get("Authorization") | auth := ctx.Req.Header.Get("Authorization") | ||||
| @@ -2,6 +2,7 @@ package modelarts | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | |||||
| "fmt" | "fmt" | ||||
| "path" | "path" | ||||
| "strconv" | "strconv" | ||||
| @@ -9,14 +10,15 @@ import ( | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| ) | ) | ||||
| const ( | const ( | ||||
| //notebook | //notebook | ||||
| storageTypeOBS = "obs" | |||||
| autoStopDuration = 4 * 60 * 60 | |||||
| storageTypeOBS = "obs" | |||||
| autoStopDuration = 4 * 60 * 60 | |||||
| autoStopDurationMs = 4 * 60 * 60 * 1000 | autoStopDurationMs = 4 * 60 * 60 * 1000 | ||||
| DataSetMountPath = "/home/ma-user/work" | DataSetMountPath = "/home/ma-user/work" | ||||
| @@ -63,6 +65,7 @@ const ( | |||||
| var ( | var ( | ||||
| poolInfos *models.PoolInfos | poolInfos *models.PoolInfos | ||||
| FlavorInfos *models.FlavorInfos | FlavorInfos *models.FlavorInfos | ||||
| ImageInfos *models.ImageInfosModelArts | |||||
| ) | ) | ||||
| type GenerateTrainJobReq struct { | type GenerateTrainJobReq struct { | ||||
| @@ -259,35 +262,42 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor string) error { | |||||
| func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, imageId string) error { | |||||
| if poolInfos == nil { | if poolInfos == nil { | ||||
| json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | ||||
| } | } | ||||
| imageName, err := GetNotebookImageName(imageId) | |||||
| if err != nil { | |||||
| log.Error("GetNotebookImageName failed: %v", err.Error()) | |||||
| return err | |||||
| } | |||||
| jobResult, err := createNotebook2(models.CreateNotebook2Params{ | jobResult, err := createNotebook2(models.CreateNotebook2Params{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| Description: description, | Description: description, | ||||
| Flavor: flavor, | Flavor: flavor, | ||||
| Duration: autoStopDurationMs, | Duration: autoStopDurationMs, | ||||
| ImageID: "59a6e9f5-93c0-44dd-85b0-82f390c5d53a", | |||||
| ImageID: imageId, | |||||
| PoolID: poolInfos.PoolInfo[0].PoolId, | PoolID: poolInfos.PoolInfo[0].PoolId, | ||||
| Feature: models.NotebookFeature, | Feature: models.NotebookFeature, | ||||
| Volume: models.VolumeReq{ | |||||
| Capacity: 100, | |||||
| Category: models.EVSCategory, | |||||
| Ownership: models.ManagedOwnership, | |||||
| Volume: models.VolumeReq{ | |||||
| Capacity: setting.Capacity, | |||||
| Category: models.EVSCategory, | |||||
| Ownership: models.ManagedOwnership, | |||||
| }, | }, | ||||
| WorkspaceID: "0", | |||||
| WorkspaceID: "0", | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("createNotebook2 failed: %v", err.Error()) | log.Error("createNotebook2 failed: %v", err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | err = models.CreateCloudbrain(&models.Cloudbrain{ | ||||
| Status: string(models.JobWaiting), | |||||
| Status: jobResult.Status, | |||||
| UserID: ctx.User.ID, | UserID: ctx.User.ID, | ||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: jobResult.ID, | JobID: jobResult.ID, | ||||
| @@ -296,12 +306,14 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor | |||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| Uuid: uuid, | Uuid: uuid, | ||||
| ComputeResource: models.NPUResource, | ComputeResource: models.NPUResource, | ||||
| Image: imageName, | |||||
| Description: description, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -335,12 +347,12 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| jobId := strconv.FormatInt(jobResult.JobID, 10) | |||||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | err = models.CreateCloudbrain(&models.Cloudbrain{ | ||||
| Status: TransTrainJobStatus(jobResult.Status), | Status: TransTrainJobStatus(jobResult.Status), | ||||
| UserID: ctx.User.ID, | UserID: ctx.User.ID, | ||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | |||||
| JobID: jobId, | |||||
| JobName: req.JobName, | JobName: req.JobName, | ||||
| JobType: string(models.JobTypeTrain), | JobType: string(models.JobTypeTrain), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| @@ -371,7 +383,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.JobName, models.ActionCreateTrainTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -555,12 +567,12 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
| log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| jobID := strconv.FormatInt(jobResult.JobID, 10) | |||||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | err = models.CreateCloudbrain(&models.Cloudbrain{ | ||||
| Status: TransTrainJobStatus(jobResult.Status), | Status: TransTrainJobStatus(jobResult.Status), | ||||
| UserID: ctx.User.ID, | UserID: ctx.User.ID, | ||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | |||||
| JobID: jobID, | |||||
| JobName: req.JobName, | JobName: req.JobName, | ||||
| JobType: string(models.JobTypeInference), | JobType: string(models.JobTypeInference), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| @@ -583,6 +595,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
| EngineName: req.EngineName, | EngineName: req.EngineName, | ||||
| LabelName: req.LabelName, | LabelName: req.LabelName, | ||||
| IsLatestVersion: req.IsLatestVersion, | IsLatestVersion: req.IsLatestVersion, | ||||
| ComputeResource: models.NPUResource, | |||||
| VersionCount: req.VersionCount, | VersionCount: req.VersionCount, | ||||
| TotalVersionCount: req.TotalVersionCount, | TotalVersionCount: req.TotalVersionCount, | ||||
| ModelName: req.ModelName, | ModelName: req.ModelName, | ||||
| @@ -595,6 +608,29 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.JobName, models.ActionCreateInferenceTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| func GetNotebookImageName(imageId string) (string, error) { | |||||
| var validImage = false | |||||
| var imageName = "" | |||||
| if ImageInfos == nil { | |||||
| json.Unmarshal([]byte(setting.ImageInfos), &ImageInfos) | |||||
| } | |||||
| for _, imageInfo := range ImageInfos.ImageInfo { | |||||
| if imageInfo.Id == imageId { | |||||
| validImage = true | |||||
| imageName = imageInfo.Value | |||||
| } | |||||
| } | |||||
| if !validImage { | |||||
| log.Error("the image id(%s) is invalid", imageId) | |||||
| return imageName, errors.New("the image id is invalid") | |||||
| } | |||||
| return imageName, nil | |||||
| } | |||||
| @@ -330,3 +330,18 @@ func (a *actionNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Rep | |||||
| log.Error("notifyWatchers: %v", err) | log.Error("notifyWatchers: %v", err) | ||||
| } | } | ||||
| } | } | ||||
| func (a *actionNotifier) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) { | |||||
| if err := models.NotifyWatchers(&models.Action{ | |||||
| ActUserID: doer.ID, | |||||
| ActUser: doer, | |||||
| OpType: optype, | |||||
| RepoID: repo.ID, | |||||
| Repo: repo, | |||||
| IsPrivate: repo.IsPrivate, | |||||
| RefName: name, | |||||
| Content: id, | |||||
| }); err != nil { | |||||
| log.Error("notifyWatchers: %v", err) | |||||
| } | |||||
| } | |||||
| @@ -54,4 +54,6 @@ type Notifier interface { | |||||
| NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) | NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) | ||||
| NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) | NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) | ||||
| NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) | NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) | ||||
| NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) | |||||
| } | } | ||||
| @@ -154,3 +154,7 @@ func (*NullNotifier) NotifySyncCreateRef(doer *models.User, repo *models.Reposit | |||||
| // NotifySyncDeleteRef places a place holder function | // NotifySyncDeleteRef places a place holder function | ||||
| func (*NullNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) { | func (*NullNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) { | ||||
| } | } | ||||
| func (*NullNotifier) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) { | |||||
| } | |||||
| @@ -37,6 +37,13 @@ func NewContext() { | |||||
| RegisterNotifier(action.NewNotifier()) | RegisterNotifier(action.NewNotifier()) | ||||
| } | } | ||||
| // NotifyUploadAttachment notifies attachment upload message to notifiers | |||||
| func NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) { | |||||
| for _, notifier := range notifiers { | |||||
| notifier.NotifyOtherTask(doer, repo, id, name, optype) | |||||
| } | |||||
| } | |||||
| // NotifyCreateIssueComment notifies issue comment related message to notifiers | // NotifyCreateIssueComment notifies issue comment related message to notifiers | ||||
| func NotifyCreateIssueComment(doer *models.User, repo *models.Repository, | func NotifyCreateIssueComment(doer *models.User, repo *models.Repository, | ||||
| issue *models.Issue, comment *models.Comment) { | issue *models.Issue, comment *models.Comment) { | ||||
| @@ -512,7 +512,9 @@ var ( | |||||
| ProfileID string | ProfileID string | ||||
| PoolInfos string | PoolInfos string | ||||
| Flavor string | Flavor string | ||||
| DebugHost string | |||||
| DebugHost string | |||||
| ImageInfos string | |||||
| Capacity int | |||||
| //train-job | //train-job | ||||
| ResourcePools string | ResourcePools string | ||||
| Engines string | Engines string | ||||
| @@ -1334,7 +1336,8 @@ func NewContext() { | |||||
| ProfileID = sec.Key("PROFILE_ID").MustString("") | ProfileID = sec.Key("PROFILE_ID").MustString("") | ||||
| PoolInfos = sec.Key("POOL_INFOS").MustString("") | PoolInfos = sec.Key("POOL_INFOS").MustString("") | ||||
| Flavor = sec.Key("FLAVOR").MustString("") | Flavor = sec.Key("FLAVOR").MustString("") | ||||
| DebugHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | |||||
| ImageInfos = sec.Key("IMAGE_INFOS").MustString("") | |||||
| Capacity = sec.Key("IMAGE_INFOS").MustInt(100) | |||||
| ResourcePools = sec.Key("Resource_Pools").MustString("") | ResourcePools = sec.Key("Resource_Pools").MustString("") | ||||
| Engines = sec.Key("Engines").MustString("") | Engines = sec.Key("Engines").MustString("") | ||||
| EngineVersions = sec.Key("Engine_Versions").MustString("") | EngineVersions = sec.Key("Engine_Versions").MustString("") | ||||
| @@ -16,9 +16,10 @@ type Attachment struct { | |||||
| Size int64 `json:"size"` | Size int64 `json:"size"` | ||||
| DownloadCount int64 `json:"download_count"` | DownloadCount int64 `json:"download_count"` | ||||
| // swagger:strfmt date-time | // swagger:strfmt date-time | ||||
| Created time.Time `json:"created_at"` | |||||
| UUID string `json:"uuid"` | |||||
| DownloadURL string `json:"browser_download_url"` | |||||
| Created time.Time `json:"created_at"` | |||||
| UUID string `json:"uuid"` | |||||
| DownloadURL string `json:"browser_download_url"` | |||||
| S3DownloadURL string | |||||
| } | } | ||||
| // EditAttachmentOptions options for editing attachments | // EditAttachmentOptions options for editing attachments | ||||
| @@ -864,9 +864,13 @@ confirm_choice = confirm | |||||
| cloudbran1_tips = Only data in zip format can create cloudbrain tasks | cloudbran1_tips = Only data in zip format can create cloudbrain tasks | ||||
| cloudbrain_creator=Creator | cloudbrain_creator=Creator | ||||
| cloudbrain_task = Task Name | cloudbrain_task = Task Name | ||||
| cloudbrain_task_type = Task Type | |||||
| cloudbrain_task_name=Cloud Brain Task Name | |||||
| cloudbrain_operate = Operate | cloudbrain_operate = Operate | ||||
| cloudbrain_status_createtime = Status/Createtime | cloudbrain_status_createtime = Status/Createtime | ||||
| cloudbrain_status_runtime = Running Time | 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. | |||||
| record_begintime_get_err=Can not get the record begin time. | record_begintime_get_err=Can not get the record begin time. | ||||
| parameter_is_wrong=The input parameter is wrong. | parameter_is_wrong=The input parameter is wrong. | ||||
| @@ -2059,6 +2063,9 @@ people = People | |||||
| teams = Teams | teams = Teams | ||||
| lower_members = members | lower_members = members | ||||
| lower_repositories = repositories | lower_repositories = repositories | ||||
| lower_member=member | |||||
| lower_repository = repository | |||||
| create_new_team = New Team | create_new_team = New Team | ||||
| create_team = Create Team | create_team = Create Team | ||||
| org_desc = Description | org_desc = Description | ||||
| @@ -2078,6 +2085,9 @@ custom_select_courses = Customize selected courses | |||||
| recommend_remain_pro = Remain | recommend_remain_pro = Remain | ||||
| save_fail_tips = The upper limit is exceeded | save_fail_tips = The upper limit is exceeded | ||||
| select_again = Select more than 9, please select again! | select_again = Select more than 9, please select again! | ||||
| custom_select_projects = Customize selected projects | |||||
| customize = Customize | |||||
| selected_project=Selected Projects | |||||
| form.name_reserved = The organization name '%s' is reserved. | form.name_reserved = The organization name '%s' is reserved. | ||||
| form.name_pattern_not_allowed = The pattern '%s' is not allowed in an organization name. | form.name_pattern_not_allowed = The pattern '%s' is not allowed in an organization name. | ||||
| @@ -2338,6 +2348,12 @@ datasets.owner=Owner | |||||
| datasets.name=name | datasets.name=name | ||||
| datasets.private=Private | datasets.private=Private | ||||
| cloudbrain.all_task_types=All Task Types | |||||
| cloudbrain.all_computing_resources=All Computing Resources | |||||
| cloudbrain.all_status=All Status | |||||
| cloudbrain.download_report=Download Report | |||||
| cloudbrain.cloudbrain_name=Cloudbrain Name | |||||
| hooks.desc = Webhooks automatically make HTTP POST requests to a server when certain openi events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the <a target="_blank" rel="noopener" href="https://docs.openi.io/en-us/webhooks/">webhooks guide</a>. | hooks.desc = Webhooks automatically make HTTP POST requests to a server when certain openi events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the <a target="_blank" rel="noopener" href="https://docs.openi.io/en-us/webhooks/">webhooks guide</a>. | ||||
| hooks.add_webhook = Add Default Webhook | hooks.add_webhook = Add Default Webhook | ||||
| hooks.update_webhook = Update Default Webhook | hooks.update_webhook = Update Default Webhook | ||||
| @@ -2677,6 +2693,13 @@ mirror_sync_create = synced new reference <a href="%s/src/%s">%[2]s</a> to <a hr | |||||
| mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror | mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror | ||||
| approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>` | approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>` | ||||
| reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>` | reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>` | ||||
| upload_dataset=`upload dataset <a href="%s/datasets?type=%s">%s</a>` | |||||
| task_gpudebugjob=`created CPU/GPU type debugging task<a href="%s/cloudbrain/%s">%s</a>` | |||||
| task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>` | |||||
| task_trainjob=`created training task<a href="%s/modelarts/train-job/%s">%s</a>` | |||||
| task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s">%s</a>` | |||||
| task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>` | |||||
| task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago = %s ago | ago = %s ago | ||||
| @@ -2751,6 +2774,7 @@ head.dataset = Datasets | |||||
| foot.council = Council | foot.council = Council | ||||
| foot.technical_committee = Technical Committee | foot.technical_committee = Technical Committee | ||||
| foot.join = Join OpenI | foot.join = Join OpenI | ||||
| foot.agreement=Use agreement | |||||
| foot.news = News | foot.news = News | ||||
| foot.community_news = Community News | foot.community_news = Community News | ||||
| foot.member_news = Member news | foot.member_news = Member news | ||||
| @@ -868,10 +868,13 @@ confirm_choice=确定 | |||||
| cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 | cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 | ||||
| cloudbrain_creator=创建者 | cloudbrain_creator=创建者 | ||||
| cloudbrain_task=任务名称 | cloudbrain_task=任务名称 | ||||
| cloudbrain_task_type=任务类型 | |||||
| cloudbrain_task_name=云脑侧任务名称 | |||||
| cloudbrain_operate=操作 | cloudbrain_operate=操作 | ||||
| cloudbrain_status_createtime=状态/创建时间 | cloudbrain_status_createtime=状态/创建时间 | ||||
| cloudbrain_status_runtime = 运行时长 | cloudbrain_status_runtime = 运行时长 | ||||
| cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | ||||
| cloudbrain_query_fail=查询云脑任务失败。 | |||||
| record_begintime_get_err=无法获取统计开始时间。 | record_begintime_get_err=无法获取统计开始时间。 | ||||
| parameter_is_wrong=输入参数错误,请检查输入参数。 | parameter_is_wrong=输入参数错误,请检查输入参数。 | ||||
| @@ -2069,6 +2072,8 @@ people=组织成员 | |||||
| teams=组织团队 | teams=组织团队 | ||||
| lower_members=名成员 | lower_members=名成员 | ||||
| lower_repositories=个项目 | lower_repositories=个项目 | ||||
| lower_member=名成员 | |||||
| lower_repository=个项目 | |||||
| create_new_team=新建团队 | create_new_team=新建团队 | ||||
| create_team=创建团队 | create_team=创建团队 | ||||
| org_desc=组织描述 | org_desc=组织描述 | ||||
| @@ -2088,6 +2093,9 @@ custom_select_courses = 自定义精选课程 | |||||
| recommend_remain_pro = 还能推荐 | recommend_remain_pro = 还能推荐 | ||||
| save_fail_tips = 最多可选9个,保存失败 | save_fail_tips = 最多可选9个,保存失败 | ||||
| select_again = 选择超过9个,请重新选择! | select_again = 选择超过9个,请重新选择! | ||||
| custom_select_projects = 自定义精选项目 | |||||
| customize = 自定义 | |||||
| selected_project=精选项目 | |||||
| form.name_reserved=组织名称 '%s' 是被保留的。 | form.name_reserved=组织名称 '%s' 是被保留的。 | ||||
| form.name_pattern_not_allowed=组织名称中不允许使用 "%s"。 | form.name_pattern_not_allowed=组织名称中不允许使用 "%s"。 | ||||
| @@ -2349,6 +2357,12 @@ datasets.owner=所有者 | |||||
| datasets.name=名称 | datasets.name=名称 | ||||
| datasets.private=私有 | datasets.private=私有 | ||||
| cloudbrain.all_task_types=全部任务类型 | |||||
| cloudbrain.all_computing_resources=全部计算资源 | |||||
| cloudbrain.all_status=全部状态 | |||||
| cloudbrain.download_report=下载此报告 | |||||
| cloudbrain.cloudbrain_name=云脑侧名称 | |||||
| hooks.desc=当某些 openi 事件触发时, Web 钩子会自动向服务器发出 HTTP POST 请求。此处定义的 Web 钩子是默认值, 将复制到所有新建项目中。参阅 <a target="_blank" rel="noopener" href="https://docs.openi.io/en-us/webhooks/">Web钩子指南</a> 获取更多内容。 | hooks.desc=当某些 openi 事件触发时, Web 钩子会自动向服务器发出 HTTP POST 请求。此处定义的 Web 钩子是默认值, 将复制到所有新建项目中。参阅 <a target="_blank" rel="noopener" href="https://docs.openi.io/en-us/webhooks/">Web钩子指南</a> 获取更多内容。 | ||||
| hooks.add_webhook=新增默认Web钩子 | hooks.add_webhook=新增默认Web钩子 | ||||
| hooks.update_webhook=更新默认Web钩子 | hooks.update_webhook=更新默认Web钩子 | ||||
| @@ -2415,7 +2429,7 @@ auths.sspi_auto_activate_users_helper=允许 SSPI 认证自动激活新用户 | |||||
| auths.sspi_strip_domain_names=从用户名中删除域名部分 | auths.sspi_strip_domain_names=从用户名中删除域名部分 | ||||
| auths.sspi_strip_domain_names_helper=如果选中此项,域名将从登录名中删除(例如,"DOMAIN\user"和"user@example.org",两者都将变成只是“用户”)。 | auths.sspi_strip_domain_names_helper=如果选中此项,域名将从登录名中删除(例如,"DOMAIN\user"和"user@example.org",两者都将变成只是“用户”)。 | ||||
| auths.sspi_separator_replacement=要使用的分隔符代替\, / 和 @ | auths.sspi_separator_replacement=要使用的分隔符代替\, / 和 @ | ||||
| auths.sspi_separator_replacement_helper=用于替换下级登录名称分隔符的字符 (例如) "DOMAIN\user") 中的 \ 和用户主名字(如"user@example.org中的 @ )。 | |||||
| auths.sspi_separator_replacement_helper=用于替换下级登录名称分隔符的字符 (例如) "DOMAIN\user") 中的 \ 和用户主名字(如"user@example.org"中的 @ )。 | |||||
| auths.sspi_default_language=默认语言 | auths.sspi_default_language=默认语言 | ||||
| auths.sspi_default_language_helper=SSPI 认证方法为用户自动创建的默认语言。如果您想要自动检测到语言,请留空。 | auths.sspi_default_language_helper=SSPI 认证方法为用户自动创建的默认语言。如果您想要自动检测到语言,请留空。 | ||||
| auths.tips=帮助提示 | auths.tips=帮助提示 | ||||
| @@ -2688,6 +2702,13 @@ mirror_sync_create=从镜像同步了新的引用 <a href="%s/src/%s">%[2]s</a> | |||||
| mirror_sync_delete=从镜像同步并从 <a href="%[1]s">%[3]s</a> 删除了引用 <code>%[2]s</code> | mirror_sync_delete=从镜像同步并从 <a href="%[1]s">%[3]s</a> 删除了引用 <code>%[2]s</code> | ||||
| approve_pull_request=`同意了 <a href="%s/pulls/%s">%s#%[2]s</a>` | approve_pull_request=`同意了 <a href="%s/pulls/%s">%s#%[2]s</a>` | ||||
| reject_pull_request=`建议变更 <a href="%s/pulls/%s">%s#%[2]s</a>` | reject_pull_request=`建议变更 <a href="%s/pulls/%s">%s#%[2]s</a>` | ||||
| upload_dataset=`上传了数据集文件 <a href="%s/datasets?type=%s">%s</a>` | |||||
| task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%s">%s</a>` | |||||
| task_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>` | |||||
| task_trainjob=`创建了训练任务 <a href="%s/modelarts/train-job/%s">%s</a>` | |||||
| task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s">%s</a>` | |||||
| task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | |||||
| task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago=%s前 | ago=%s前 | ||||
| @@ -2762,6 +2783,7 @@ head.dataset=数据集 | |||||
| foot.council=理事会 | foot.council=理事会 | ||||
| foot.technical_committee=技术委员会 | foot.technical_committee=技术委员会 | ||||
| foot.join=加入启智 | foot.join=加入启智 | ||||
| foot.agreement=使用协议 | |||||
| foot.news=动态 | foot.news=动态 | ||||
| foot.community_news=社区动态 | foot.community_news=社区动态 | ||||
| foot.member_news=成员动态 | foot.member_news=成员动态 | ||||
| @@ -13879,6 +13879,130 @@ | |||||
| "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", | "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", | ||||
| "dev": true | "dev": true | ||||
| }, | }, | ||||
| "ts-loader": { | |||||
| "version": "4.0.0", | |||||
| "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.0.0.tgz", | |||||
| "integrity": "sha512-iissbnuJkqbB3YAmnWyEbmdNcGcoiiXopKHKyqdoCrFQVi9pnplXeveQDXJnQOCYNNcb2pjT2zzSYTX6c9QtAA==", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "chalk": "^2.3.0", | |||||
| "enhanced-resolve": "^4.0.0", | |||||
| "loader-utils": "^1.0.2", | |||||
| "micromatch": "^3.1.4", | |||||
| "semver": "^5.0.1" | |||||
| }, | |||||
| "dependencies": { | |||||
| "braces": { | |||||
| "version": "2.3.2", | |||||
| "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", | |||||
| "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "arr-flatten": "^1.1.0", | |||||
| "array-unique": "^0.3.2", | |||||
| "extend-shallow": "^2.0.1", | |||||
| "fill-range": "^4.0.0", | |||||
| "isobject": "^3.0.1", | |||||
| "repeat-element": "^1.1.2", | |||||
| "snapdragon": "^0.8.1", | |||||
| "snapdragon-node": "^2.0.1", | |||||
| "split-string": "^3.0.2", | |||||
| "to-regex": "^3.0.1" | |||||
| }, | |||||
| "dependencies": { | |||||
| "extend-shallow": { | |||||
| "version": "2.0.1", | |||||
| "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", | |||||
| "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "is-extendable": "^0.1.0" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "fill-range": { | |||||
| "version": "4.0.0", | |||||
| "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", | |||||
| "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "extend-shallow": "^2.0.1", | |||||
| "is-number": "^3.0.0", | |||||
| "repeat-string": "^1.6.1", | |||||
| "to-regex-range": "^2.1.0" | |||||
| }, | |||||
| "dependencies": { | |||||
| "extend-shallow": { | |||||
| "version": "2.0.1", | |||||
| "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", | |||||
| "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "is-extendable": "^0.1.0" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "is-number": { | |||||
| "version": "3.0.0", | |||||
| "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", | |||||
| "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "kind-of": "^3.0.2" | |||||
| }, | |||||
| "dependencies": { | |||||
| "kind-of": { | |||||
| "version": "3.2.2", | |||||
| "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", | |||||
| "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "is-buffer": "^1.1.5" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "isobject": { | |||||
| "version": "3.0.1", | |||||
| "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", | |||||
| "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", | |||||
| "dev": true | |||||
| }, | |||||
| "micromatch": { | |||||
| "version": "3.1.10", | |||||
| "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", | |||||
| "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "arr-diff": "^4.0.0", | |||||
| "array-unique": "^0.3.2", | |||||
| "braces": "^2.3.1", | |||||
| "define-property": "^2.0.2", | |||||
| "extend-shallow": "^3.0.2", | |||||
| "extglob": "^2.0.4", | |||||
| "fragment-cache": "^0.2.1", | |||||
| "kind-of": "^6.0.2", | |||||
| "nanomatch": "^1.2.9", | |||||
| "object.pick": "^1.3.0", | |||||
| "regex-not": "^1.0.0", | |||||
| "snapdragon": "^0.8.1", | |||||
| "to-regex": "^3.0.2" | |||||
| } | |||||
| }, | |||||
| "to-regex-range": { | |||||
| "version": "2.1.1", | |||||
| "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", | |||||
| "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", | |||||
| "dev": true, | |||||
| "requires": { | |||||
| "is-number": "^3.0.0", | |||||
| "repeat-string": "^1.6.1" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "tslib": { | "tslib": { | ||||
| "version": "1.13.0", | "version": "1.13.0", | ||||
| "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", | ||||
| @@ -13938,6 +14062,12 @@ | |||||
| "is-typedarray": "^1.0.0" | "is-typedarray": "^1.0.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "typescript": { | |||||
| "version": "4.5.5", | |||||
| "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", | |||||
| "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", | |||||
| "dev": true | |||||
| }, | |||||
| "ua-parser-js": { | "ua-parser-js": { | ||||
| "version": "0.7.21", | "version": "0.7.21", | ||||
| "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", | ||||
| @@ -71,6 +71,8 @@ | |||||
| "script-loader": "0.7.2", | "script-loader": "0.7.2", | ||||
| "stylelint": "13.3.3", | "stylelint": "13.3.3", | ||||
| "stylelint-config-standard": "20.0.0", | "stylelint-config-standard": "20.0.0", | ||||
| "ts-loader": "4.0.0", | |||||
| "typescript": "4.5.5", | |||||
| "updates": "10.2.11" | "updates": "10.2.11" | ||||
| }, | }, | ||||
| "browserslist": [ | "browserslist": [ | ||||
| @@ -6,7 +6,6 @@ if(isEmpty(token)){ | |||||
| token = meta.attr("content"); | token = meta.attr("content"); | ||||
| } | } | ||||
| } | } | ||||
| var swiperNewMessage = new Swiper(".newslist", { | var swiperNewMessage = new Swiper(".newslist", { | ||||
| direction: "vertical", | direction: "vertical", | ||||
| slidesPerView: 10, | slidesPerView: 10, | ||||
| @@ -17,7 +16,7 @@ var swiperNewMessage = new Swiper(".newslist", { | |||||
| }, | }, | ||||
| }); | }); | ||||
| var swiperRepo = new Swiper(".homepro-list", { | var swiperRepo = new Swiper(".homepro-list", { | ||||
| slidesPerView: 3, | |||||
| slidesPerView: 1, | |||||
| slidesPerColumn: 2, | slidesPerColumn: 2, | ||||
| slidesPerColumnFill:'row', | slidesPerColumnFill:'row', | ||||
| spaceBetween: 30, | spaceBetween: 30, | ||||
| @@ -29,6 +28,37 @@ var swiperRepo = new Swiper(".homepro-list", { | |||||
| delay: 2500, | delay: 2500, | ||||
| disableOnInteraction: false, | disableOnInteraction: false, | ||||
| }, | }, | ||||
| breakpoints: { | |||||
| 768: { | |||||
| slidesPerView: 2, | |||||
| }, | |||||
| 1024: { | |||||
| slidesPerView: 3, | |||||
| }, | |||||
| }, | |||||
| }); | |||||
| var swiperOrg = new Swiper(".homeorg-list", { | |||||
| slidesPerView: 1, | |||||
| slidesPerColumn: 4, | |||||
| slidesPerColumnFill:'row', | |||||
| spaceBetween: 15, | |||||
| pagination: { | |||||
| el: ".swiper-pagination", | |||||
| clickable: true, | |||||
| }, | |||||
| autoplay: { | |||||
| delay: 4500, | |||||
| disableOnInteraction: false, | |||||
| }, | |||||
| breakpoints: { | |||||
| 768: { | |||||
| slidesPerView: 2, | |||||
| }, | |||||
| 1024: { | |||||
| slidesPerView: 3, | |||||
| }, | |||||
| }, | |||||
| }); | }); | ||||
| var output = document.getElementById("newmessage"); | var output = document.getElementById("newmessage"); | ||||
| @@ -96,11 +126,14 @@ socket.onmessage = function (e) { | |||||
| actionName = actionName.replace("{oldRepoName}",record.Content); | actionName = actionName.replace("{oldRepoName}",record.Content); | ||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | 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"){ | |||||
| html += recordPrefix + actionName; | |||||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||||
| } | } | ||||
| else{ | else{ | ||||
| continue; | continue; | ||||
| } | } | ||||
| if(record.Repo != null){ | if(record.Repo != null){ | ||||
| var time = getTime(record.CreatedUnix,currentTime); | var time = getTime(record.CreatedUnix,currentTime); | ||||
| html += " " + time; | html += " " + time; | ||||
| @@ -108,13 +141,32 @@ socket.onmessage = function (e) { | |||||
| html += "</div>"; | html += "</div>"; | ||||
| html += "</div>"; | html += "</div>"; | ||||
| } | } | ||||
| } | } | ||||
| output.innerHTML = html; | output.innerHTML = html; | ||||
| swiperNewMessage.updateSlides(); | swiperNewMessage.updateSlides(); | ||||
| swiperNewMessage.updateProgress(); | swiperNewMessage.updateProgress(); | ||||
| }; | }; | ||||
| function getTaskLink(record){ | |||||
| var re = getRepoLink(record); | |||||
| if(record.OpType == 24){ | |||||
| return re + "/datasets?type=" + record.Content; | |||||
| }else if(record.OpType == 25){ | |||||
| return re + "/cloudbrain/" + record.RefName; | |||||
| }else if(record.OpType == 26){ | |||||
| return re + "/modelarts/notebook/" + record.Content; | |||||
| }else if(record.OpType == 27){ | |||||
| return re + "/modelarts/train-job/" + record.Content; | |||||
| }else if(record.OpType == 28){ | |||||
| return re + "/modelarts/inference-job/" + record.Content; | |||||
| }else if(record.OpType == 29){ | |||||
| return re + "/cloudbrain/benchmark/" + record.RefName; | |||||
| }else if(record.OpType == 30){ | |||||
| return re + "/modelmanage/show_model_info?name=" + record.RefName; | |||||
| } | |||||
| return re; | |||||
| } | |||||
| function getMsg(record){ | function getMsg(record){ | ||||
| var html =""; | var html =""; | ||||
| html += "<div class=\"swiper-slide item\">"; | html += "<div class=\"swiper-slide item\">"; | ||||
| @@ -246,7 +298,14 @@ var actionNameZH={ | |||||
| "15":"重新开启了合并请求", | "15":"重新开启了合并请求", | ||||
| "17":"从 {repoName} 删除分支 {deleteBranchName}", | "17":"从 {repoName} 删除分支 {deleteBranchName}", | ||||
| "22":"建议变更", | "22":"建议变更", | ||||
| "23":"评论了合并请求" | |||||
| "23":"评论了合并请求", | |||||
| "24":"上传了数据集文件", | |||||
| "25":"创建了CPU/GPU类型调试任务", | |||||
| "26":"创建了NPU类型调试任务", | |||||
| "27":"创建了训练任务", | |||||
| "28":"创建了推理任务", | |||||
| "29":"创建了评测任务", | |||||
| "30":"导入了新模型" | |||||
| }; | }; | ||||
| var actionNameEN={ | var actionNameEN={ | ||||
| @@ -264,7 +323,14 @@ var actionNameEN={ | |||||
| "15":" reopened pull request", | "15":" reopened pull request", | ||||
| "17":" deleted branch {deleteBranchName} from {repoName}", | "17":" deleted branch {deleteBranchName} from {repoName}", | ||||
| "22":" proposed changes", | "22":" proposed changes", | ||||
| "23":" commented on pull request" | |||||
| "23":" commented on pull request", | |||||
| "24":" upload dataset ", | |||||
| "25":" created CPU/GPU type debugging task ", | |||||
| "26":" created NPU type debugging task ", | |||||
| "27":" created training task", | |||||
| "28":" created reasoning task", | |||||
| "29":" created profiling task", | |||||
| "30":" created new model" | |||||
| }; | }; | ||||
| var repoAndOrgZH={ | var repoAndOrgZH={ | ||||
| @@ -392,7 +458,7 @@ function displayOrg(json){ | |||||
| if (json != null && json.length > 0){ | if (json != null && json.length > 0){ | ||||
| for(var i = 0; i < json.length;i++){ | for(var i = 0; i < json.length;i++){ | ||||
| var record = json[i] | var record = json[i] | ||||
| html += "<div class=\"column\">"; | |||||
| html += "<div class=\"swiper-slide\">"; | |||||
| html += " <a href=\"/" + record["Name"] + "\" class=\"ui fluid card\">"; | html += " <a href=\"/" + record["Name"] + "\" class=\"ui fluid card\">"; | ||||
| html += " <div class=\"content\">"; | html += " <div class=\"content\">"; | ||||
| html += " <div class=\"ui small header\">"; | html += " <div class=\"ui small header\">"; | ||||
| @@ -408,4 +474,5 @@ function displayOrg(json){ | |||||
| } | } | ||||
| } | } | ||||
| orgDiv.innerHTML = html; | orgDiv.innerHTML = html; | ||||
| swiperOrg.updateSlides(); | |||||
| } | } | ||||
| @@ -0,0 +1,225 @@ | |||||
| package admin | |||||
| import ( | |||||
| "net/http" | |||||
| "net/url" | |||||
| "strconv" | |||||
| "strings" | |||||
| "time" | |||||
| "github.com/360EntSecGroup-Skylar/excelize/v2" | |||||
| "code.gitea.io/gitea/modules/modelarts" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| ) | |||||
| const ( | |||||
| tplCloudBrains base.TplName = "admin/cloudbrain/list" | |||||
| EXCEL_DATE_FORMAT = "20060102150405" | |||||
| CREATE_TIME_FORMAT = "2006/01/02 15:04:05.00" | |||||
| ) | |||||
| func CloudBrains(ctx *context.Context) { | |||||
| ctx.Data["Title"] = ctx.Tr("admin.cloudBrains") | |||||
| ctx.Data["PageIsAdmin"] = true | |||||
| ctx.Data["PageIsAdminCloudBrains"] = true | |||||
| listType := ctx.Query("listType") | |||||
| jobType := ctx.Query("jobType") | |||||
| jobStatus := ctx.Query("jobStatus") | |||||
| ctx.Data["ListType"] = listType | |||||
| ctx.Data["JobType"] = jobType | |||||
| ctx.Data["JobStatus"] = jobStatus | |||||
| page := ctx.QueryInt("page") | |||||
| if page <= 0 { | |||||
| page = 1 | |||||
| } | |||||
| debugType := modelarts.DebugType | |||||
| if listType == models.GPUResource { | |||||
| debugType = models.TypeCloudBrainOne | |||||
| } else if listType == models.NPUResource { | |||||
| debugType = models.TypeCloudBrainTwo | |||||
| } | |||||
| var jobTypes []string | |||||
| jobTypeNot := false | |||||
| if jobType == string(models.JobTypeDebug) { | |||||
| jobTypes = append(jobTypes, string(models.JobTypeSnn4imagenet), string(models.JobTypeBrainScore), string(models.JobTypeDebug)) | |||||
| } else if jobType != "all" && jobType != "" { | |||||
| jobTypes = append(jobTypes, jobType) | |||||
| } | |||||
| var jobStatuses []string | |||||
| jobStatusNot := false | |||||
| if jobStatus == "other" { | |||||
| jobStatusNot = true | |||||
| jobStatuses = append(jobStatuses, string(models.ModelArtsTrainJobWaiting), string(models.ModelArtsTrainJobFailed), string(models.ModelArtsRunning), string(models.ModelArtsTrainJobCompleted), | |||||
| string(models.ModelArtsStarting), string(models.ModelArtsRestarting), string(models.ModelArtsStartFailed), | |||||
| string(models.ModelArtsStopping), string(models.ModelArtsStopped)) | |||||
| } else if jobStatus != "all" && jobStatus != "" { | |||||
| jobStatuses = append(jobStatuses, jobStatus) | |||||
| } | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.IssuePagingNum, | |||||
| }, | |||||
| Keyword: keyword, | |||||
| Type: debugType, | |||||
| JobTypeNot: jobTypeNot, | |||||
| JobStatusNot: jobStatusNot, | |||||
| JobStatus: jobStatuses, | |||||
| JobTypes: jobTypes, | |||||
| NeedRepoInfo: true, | |||||
| IsLatestVersion: modelarts.IsLatestVersion, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("Get job failed:", err) | |||||
| return | |||||
| } | |||||
| for i, task := range ciTasks { | |||||
| ciTasks[i].CanDebug = true | |||||
| ciTasks[i].CanDel = true | |||||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | |||||
| } | |||||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, getTotalPage(count, setting.UI.IssuePagingNum)) | |||||
| pager.SetDefaultParams(ctx) | |||||
| pager.AddParam(ctx, "listType", "ListType") | |||||
| ctx.Data["Page"] = pager | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| ctx.Data["Tasks"] = ciTasks | |||||
| ctx.Data["CanCreate"] = true | |||||
| ctx.Data["Keyword"] = keyword | |||||
| ctx.HTML(200, tplCloudBrains) | |||||
| } | |||||
| func DownloadCloudBrains(ctx *context.Context) { | |||||
| page := 1 | |||||
| pageSize := 300 | |||||
| var cloudBrain = ctx.Tr("repo.cloudbrain") | |||||
| fileName := getFileName(cloudBrain) | |||||
| _, total, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: 1, | |||||
| }, | |||||
| Type: modelarts.DebugType, | |||||
| NeedRepoInfo: false, | |||||
| IsLatestVersion: modelarts.IsLatestVersion, | |||||
| }) | |||||
| if err != nil { | |||||
| log.Warn("Can not get cloud brain info", err) | |||||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.cloudbrain_query_fail")) | |||||
| return | |||||
| } | |||||
| totalPage := getTotalPage(total, pageSize) | |||||
| f := excelize.NewFile() | |||||
| index := f.NewSheet(cloudBrain) | |||||
| f.DeleteSheet("Sheet1") | |||||
| for k, v := range allHeader(ctx) { | |||||
| f.SetCellValue(cloudBrain, k, v) | |||||
| } | |||||
| var row = 2 | |||||
| for i := 0; i < totalPage; i++ { | |||||
| pageRecords, _, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: pageSize, | |||||
| }, | |||||
| Type: modelarts.DebugType, | |||||
| NeedRepoInfo: true, | |||||
| IsLatestVersion: modelarts.IsLatestVersion, | |||||
| }) | |||||
| if err != nil { | |||||
| log.Warn("Can not get cloud brain info", err) | |||||
| continue | |||||
| } | |||||
| for _, record := range pageRecords { | |||||
| for k, v := range allValues(row, record, ctx) { | |||||
| f.SetCellValue(cloudBrain, k, v) | |||||
| } | |||||
| row++ | |||||
| } | |||||
| page++ | |||||
| } | |||||
| f.SetActiveSheet(index) | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName)) | |||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||||
| f.WriteTo(ctx.Resp) | |||||
| } | |||||
| 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.Status, getCellName("C", row): rs.JobType, 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, | |||||
| } | |||||
| } | |||||
| func getRepoPathName(rs *models.CloudbrainInfo) string { | |||||
| if rs.Repo != nil { | |||||
| return rs.Repo.OwnerName + "/" + rs.Repo.Alias | |||||
| } | |||||
| return "" | |||||
| } | |||||
| func getDurationTime(rs *models.CloudbrainInfo) string { | |||||
| if rs.JobType == "TRAIN" || rs.JobType == "INFERENCE" { | |||||
| return rs.TrainJobDuration | |||||
| } else { | |||||
| return "-" | |||||
| } | |||||
| } | |||||
| func getFileName(baseName string) string { | |||||
| return baseName + "_" + time.Now().Format(EXCEL_DATE_FORMAT) + ".xlsx" | |||||
| } | |||||
| func getTotalPage(total int64, pageSize int) int { | |||||
| another := 0 | |||||
| if int(total)%pageSize != 0 { | |||||
| another = 1 | |||||
| } | |||||
| return int(total)/pageSize + another | |||||
| } | |||||
| func allHeader(ctx *context.Context) map[string]string { | |||||
| return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.modelarts.status"), "C1": ctx.Tr("repo.cloudbrain_task_type"), "D1": ctx.Tr("repo.modelarts.createtime"), "E1": ctx.Tr("repo.modelarts.train_job.dura_time"), "F1": ctx.Tr("repo.modelarts.computing_resources"), "G1": ctx.Tr("repo.cloudbrain_creator"), "H1": ctx.Tr("repo.repo_name"), "I1": ctx.Tr("repo.cloudbrain_task_name")} | |||||
| } | |||||
| func getCellName(col string, row int) string { | |||||
| return col + strconv.Itoa(row) | |||||
| } | |||||
| @@ -881,6 +881,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
| m.Get("/:jobid", repo.GetCloudbrainTask) | m.Get("/:jobid", repo.GetCloudbrainTask) | ||||
| m.Get("/:jobid/log", repo.CloudbrainGetLog) | m.Get("/:jobid/log", repo.CloudbrainGetLog) | ||||
| // m.Get("/:jobname", repo.GetCloudbrainTask) | |||||
| // m.Get("/:jobname/log", repo.CloudbrainGetLog) | |||||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | }, reqRepoReader(models.UnitTypeCloudBrain)) | ||||
| m.Group("/modelarts", func() { | m.Group("/modelarts", func() { | ||||
| m.Group("/notebook", func() { | m.Group("/notebook", func() { | ||||
| @@ -6,11 +6,12 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "net/http" | "net/http" | ||||
| "sort" | "sort" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/cloudbrain" | "code.gitea.io/gitea/modules/cloudbrain" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| @@ -48,14 +49,15 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| err error | err error | ||||
| ) | ) | ||||
| // jobName := ctx.Params(":jobname") | |||||
| // job, err := models.GetCloudbrainByName(jobName) | |||||
| jobID := ctx.Params(":jobid") | jobID := ctx.Params(":jobid") | ||||
| repoID := ctx.Repo.Repository.ID | repoID := ctx.Repo.Repository.ID | ||||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | |||||
| return | |||||
| ctx.Data["error"] = err.Error() | |||||
| } | } | ||||
| jobResult, err := cloudbrain.GetJob(jobID) | |||||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| @@ -85,6 +87,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobID": result.Config.JobID, | "JobID": result.Config.JobID, | ||||
| "JobName": result.Config.JobName, | |||||
| "JobStatus": result.JobStatus.State, | "JobStatus": result.JobStatus.State, | ||||
| "SubState": result.JobStatus.SubState, | "SubState": result.JobStatus.SubState, | ||||
| "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), | "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), | ||||
| @@ -94,8 +97,11 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| } | } | ||||
| func CloudbrainGetLog(ctx *context.Context) { | func CloudbrainGetLog(ctx *context.Context) { | ||||
| // jobName := ctx.Params(":jobname") | |||||
| // job, err := models.GetCloudbrainByName(jobName) | |||||
| jobID := ctx.Params(":jobid") | jobID := ctx.Params(":jobid") | ||||
| _, err := models.GetCloudbrainByJobID(jobID) | |||||
| repoID := ctx.Repo.Repository.ID | |||||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobID failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainByJobID failed: %v", err, ctx.Data["MsgID"]) | ||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| @@ -103,8 +109,8 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
| } | } | ||||
| var hits []models.Hits | var hits []models.Hits | ||||
| result, err := cloudbrain.GetJobLog(jobID) | |||||
| if err != nil{ | |||||
| result, err := cloudbrain.GetJobLog(job.JobID) | |||||
| if err != nil { | |||||
| log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"]) | ||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| return | return | ||||
| @@ -115,7 +121,7 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
| if len(result.Hits.Hits) >= cloudbrain.LogPageSize { | if len(result.Hits.Hits) >= cloudbrain.LogPageSize { | ||||
| for { | for { | ||||
| resultNext, err := cloudbrain.GetJobAllLog(result.ScrollID) | resultNext, err := cloudbrain.GetJobAllLog(result.ScrollID) | ||||
| if err != nil{ | |||||
| if err != nil { | |||||
| log.Error("GetJobAllLog failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetJobAllLog failed: %v", err, ctx.Data["MsgID"]) | ||||
| } else { | } else { | ||||
| for _, hit := range resultNext.Hits.Hits { | for _, hit := range resultNext.Hits.Hits { | ||||
| @@ -142,8 +148,8 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobID": jobID, | |||||
| "Content": content, | |||||
| "JobID": jobID, | |||||
| "Content": content, | |||||
| }) | }) | ||||
| return | return | ||||
| @@ -77,6 +77,7 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobID": jobID, | "JobID": jobID, | ||||
| "JobName": job.JobName, | |||||
| "JobStatus": result.Status, | "JobStatus": result.Status, | ||||
| }) | }) | ||||
| @@ -297,7 +297,7 @@ func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | |||||
| } | } | ||||
| func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | 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.Name, getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| 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("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("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), | getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), | ||||
| @@ -317,7 +317,7 @@ func allProjectsOpenIHeader() map[string]string { | |||||
| func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | 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.Name, getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| 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("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), | 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), | ||||
| @@ -466,10 +466,10 @@ func generateCountSql(beginTime time.Time, endTime time.Time, latestDate string, | |||||
| countSql := "SELECT count(*) FROM " + | countSql := "SELECT count(*) FROM " + | ||||
| "(SELECT repo_id FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | "(SELECT repo_id FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | ||||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | ||||
| "(SELECT repo_id,name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| "(SELECT repo_id,name,alias,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| " where A.repo_id=B.repo_id" | " where A.repo_id=B.repo_id" | ||||
| if q != "" { | if q != "" { | ||||
| countSql = countSql + " and LOWER(B.name) like '%" + strings.ToLower(q) + "%'" | |||||
| countSql = countSql + " and LOWER(B.alias) like '%" + strings.ToLower(q) + "%'" | |||||
| } | } | ||||
| return countSql | return countSql | ||||
| } | } | ||||
| @@ -482,22 +482,22 @@ func generateOpenICountSql(latestDate string) string { | |||||
| } | } | ||||
| func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) 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,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,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 " + | "(SELECT repo_id,sum(num_visits) as num_visits " + | ||||
| " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | ||||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | ||||
| "(SELECT repo_id,name,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,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" | " where A.repo_id=B.repo_id" | ||||
| if q != "" { | if q != "" { | ||||
| sql = sql + " and LOWER(name) like '%" + strings.ToLower(q) + "%'" | |||||
| sql = sql + " and LOWER(alias) like '%" + strings.ToLower(q) + "%'" | |||||
| } | } | ||||
| sql = sql + " order by " + orderBy + " desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | sql = sql + " order by " + orderBy + " desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | ||||
| return sql | return sql | ||||
| } | } | ||||
| func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | 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, 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, owner_name FROM " + | |||||
| " public.repo_statistic where date='" + latestDate + "'" | " 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) | sql = sql + " order by radar_total desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | ||||
| @@ -506,14 +506,14 @@ 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 { | 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,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,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 " + | "(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) + | " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | ||||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | ||||
| "(SELECT repo_id,name,owner_name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| "(SELECT repo_id,name,alias,owner_name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| " where A.repo_id=B.repo_id" | " where A.repo_id=B.repo_id" | ||||
| if q != "" { | if q != "" { | ||||
| sql = sql + " and LOWER(B.name) like '%" + strings.ToLower(q) + "%'" | |||||
| sql = sql + " and LOWER(B.alias) like '%" + strings.ToLower(q) + "%'" | |||||
| } | } | ||||
| sql = sql + " order by " + orderBy + " desc,A.repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | sql = sql + " order by " + orderBy + " desc,A.repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | ||||
| return sql | return sql | ||||
| @@ -38,6 +38,7 @@ const ( | |||||
| tplExploreCode base.TplName = "explore/code" | tplExploreCode base.TplName = "explore/code" | ||||
| tplExploreImages base.TplName = "explore/images" | tplExploreImages base.TplName = "explore/images" | ||||
| tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis" | tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis" | ||||
| tplHomeTerm base.TplName = "terms" | |||||
| ) | ) | ||||
| // Home render home page | // Home render home page | ||||
| @@ -596,3 +597,7 @@ func RecommendRepoFromPromote(ctx *context.Context) { | |||||
| ctx.JSON(200, result) | ctx.JSON(200, result) | ||||
| } | } | ||||
| } | } | ||||
| func HomeTerm(ctx *context.Context) { | |||||
| ctx.HTML(200, tplHomeTerm) | |||||
| } | |||||
| @@ -12,6 +12,7 @@ import ( | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| uuid "github.com/satori/go.uuid" | uuid "github.com/satori/go.uuid" | ||||
| @@ -113,7 +114,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes) | models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes) | ||||
| log.Info("save model end.") | log.Info("save model end.") | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -20,11 +20,11 @@ import ( | |||||
| "code.gitea.io/gitea/modules/labelmsg" | "code.gitea.io/gitea/modules/labelmsg" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/minio_ext" | "code.gitea.io/gitea/modules/minio_ext" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| "code.gitea.io/gitea/modules/upload" | "code.gitea.io/gitea/modules/upload" | ||||
| "code.gitea.io/gitea/modules/worker" | "code.gitea.io/gitea/modules/worker" | ||||
| gouuid "github.com/satori/go.uuid" | gouuid "github.com/satori/go.uuid" | ||||
| ) | ) | ||||
| @@ -845,6 +845,9 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err)) | ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err)) | ||||
| return | return | ||||
| } | } | ||||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||||
| repository, _ := models.GetRepositoryByID(dataset.RepoID) | |||||
| notification.NotifyOtherTask(ctx.User, repository, fmt.Sprint(attachment.Type), attachment.Name, models.ActionUploadAttachment) | |||||
| if attachment.DatasetID != 0 { | if attachment.DatasetID != 0 { | ||||
| if isCanDecompress(attachment.Name) { | if isCanDecompress(attachment.Name) { | ||||
| @@ -865,7 +868,6 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| labelmsg.SendDecompressAttachToLabelOBS(string(attachjson)) | labelmsg.SendDecompressAttachToLabelOBS(string(attachjson)) | ||||
| } | } | ||||
| } else { | } else { | ||||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||||
| var labelMap map[string]string | var labelMap map[string]string | ||||
| labelMap = make(map[string]string) | labelMap = make(map[string]string) | ||||
| labelMap["UUID"] = uuid | labelMap["UUID"] = uuid | ||||
| @@ -350,18 +350,15 @@ func CloudBrainShow(ctx *context.Context) { | |||||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| var jobID = ctx.Params(":jobid") | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| var jobName = ctx.Params(":jobname") | |||||
| task, err := models.GetCloudbrainByName(jobName) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| } | } | ||||
| result, err := cloudbrain.GetJob(jobID) | |||||
| result, err := cloudbrain.GetJob(task.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | ||||
| jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | ||||
| @@ -369,6 +366,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| ctx.Data["resource_spec"] = spec | ctx.Data["resource_spec"] = spec | ||||
| taskRoles := jobRes.TaskRoles | taskRoles := jobRes.TaskRoles | ||||
| if jobRes.JobStatus.State != string(models.JobFailed) { | if jobRes.JobStatus.State != string(models.JobFailed) { | ||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | ||||
| ctx.Data["taskRes"] = taskRes | ctx.Data["taskRes"] = taskRes | ||||
| task.Status = taskRes.TaskStatuses[0].State | task.Status = taskRes.TaskStatuses[0].State | ||||
| @@ -422,7 +420,7 @@ 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["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | ||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["jobID"] = jobID | |||||
| // ctx.Data["jobID"] = task.JobID | |||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| version_list_task := make([]*models.Cloudbrain, 0) | version_list_task := make([]*models.Cloudbrain, 0) | ||||
| version_list_task = append(version_list_task, task) | version_list_task = append(version_list_task, task) | ||||
| @@ -582,12 +580,19 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) { | |||||
| } | } | ||||
| func CloudBrainDel(ctx *context.Context) { | func CloudBrainDel(ctx *context.Context) { | ||||
| var listType = ctx.Query("debugListType") | |||||
| if err := deleteCloudbrainJob(ctx); err != nil { | if err := deleteCloudbrainJob(ctx); err != nil { | ||||
| log.Error("deleteCloudbrainJob failed: %v", err, ctx.Data["msgID"]) | log.Error("deleteCloudbrainJob failed: %v", err, ctx.Data["msgID"]) | ||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
| var isAdminPage = ctx.Query("isadminpage") | |||||
| if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | |||||
| ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | |||||
| } else { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=" + listType) | |||||
| } | |||||
| } | } | ||||
| func deleteCloudbrainJob(ctx *context.Context) error { | func deleteCloudbrainJob(ctx *context.Context) error { | ||||
| @@ -1098,6 +1103,9 @@ func GetChildTypes(ctx *context.Context) { | |||||
| } | } | ||||
| func CloudBrainBenchmarkNew(ctx *context.Context) { | func CloudBrainBenchmarkNew(ctx *context.Context) { | ||||
| ctx.Data["description"] = "" | |||||
| ctx.Data["benchmarkTypeID"] = -1 | |||||
| ctx.Data["benchmark_child_types_id_hidden"] = -1 | |||||
| err := cloudBrainNewDataPrepare(ctx) | err := cloudBrainNewDataPrepare(ctx) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("get new cloudbrain info failed", err) | ctx.ServerError("get new cloudbrain info failed", err) | ||||
| @@ -1200,6 +1208,9 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| benchmarkTypeID := form.BenchmarkTypeID | benchmarkTypeID := form.BenchmarkTypeID | ||||
| benchmarkChildTypeID := form.BenchmarkChildTypeID | benchmarkChildTypeID := form.BenchmarkChildTypeID | ||||
| ctx.Data["description"] = form.Description | |||||
| ctx.Data["benchmarkTypeID"] = benchmarkTypeID | |||||
| ctx.Data["benchmark_child_types_id_hidden"] = benchmarkChildTypeID | |||||
| if !jobNamePattern.MatchString(jobName) { | if !jobNamePattern.MatchString(jobName) { | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | ||||
| @@ -1343,5 +1354,11 @@ func BenchmarkDel(ctx *context.Context) { | |||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | |||||
| var isAdminPage = ctx.Query("isadminpage") | |||||
| if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | |||||
| ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | |||||
| } else { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | |||||
| } | |||||
| } | } | ||||
| @@ -103,8 +103,13 @@ func MustEnableModelArts(ctx *context.Context) { | |||||
| } | } | ||||
| func NotebookNew(ctx *context.Context) { | func NotebookNew(ctx *context.Context) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| notebookNewDataPrepare(ctx) | |||||
| ctx.HTML(200, tplModelArtsNotebookNew) | |||||
| } | |||||
| func notebookNewDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | ||||
| ctx.Data["job_name"] = jobName | ctx.Data["job_name"] = jobName | ||||
| @@ -112,26 +117,14 @@ func NotebookNew(ctx *context.Context) { | |||||
| attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetAllUserAttachments failed:", err) | ctx.ServerError("GetAllUserAttachments failed:", err) | ||||
| return | |||||
| return err | |||||
| } | } | ||||
| ctx.Data["attachments"] = attachs | ctx.Data["attachments"] = attachs | ||||
| ctx.Data["dataset_path"] = modelarts.DataSetMountPath | |||||
| ctx.Data["env"] = modelarts.NotebookEnv | |||||
| ctx.Data["notebook_type"] = modelarts.NotebookType | |||||
| if modelarts.FlavorInfos == nil { | |||||
| json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | |||||
| } | |||||
| ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo | |||||
| ctx.HTML(200, tplModelArtsNotebookNew) | |||||
| } | |||||
| 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 | |||||
| if modelarts.ImageInfos == nil { | |||||
| json.Unmarshal([]byte(setting.ImageInfos), &modelarts.ImageInfos) | |||||
| } | |||||
| ctx.Data["images"] = modelarts.ImageInfos.ImageInfo | |||||
| if modelarts.FlavorInfos == nil { | if modelarts.FlavorInfos == nil { | ||||
| json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | ||||
| @@ -191,8 +184,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| flavor := form.Flavor | flavor := form.Flavor | ||||
| flavor = "modelarts.bm.910.arm.public.1" | |||||
| imageId := form.ImageId | |||||
| count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -223,7 +215,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
| } | } | ||||
| } | } | ||||
| err = modelarts.GenerateNotebook2(ctx, jobName, uuid, description, flavor) | |||||
| err = modelarts.GenerateNotebook2(ctx, jobName, uuid, description, flavor, imageId) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | ||||
| notebookNewDataPrepare(ctx) | notebookNewDataPrepare(ctx) | ||||
| @@ -262,12 +254,22 @@ func NotebookShow(ctx *context.Context) { | |||||
| result.CreateTime = time.Unix(int64(result.CreateAt/1000), 0).Format("2006-01-02 15:04:05") | result.CreateTime = time.Unix(int64(result.CreateAt/1000), 0).Format("2006-01-02 15:04:05") | ||||
| result.LatestUpdateTime = time.Unix(int64(result.UpdateAt/1000), 0).Format("2006-01-02 15:04:05") | result.LatestUpdateTime = time.Unix(int64(result.UpdateAt/1000), 0).Format("2006-01-02 15:04:05") | ||||
| //result.QueuingInfo.BeginTime = time.Unix(int64(result.QueuingInfo.BeginTimestamp/1000), 0).Format("2006-01-02 15:04:05") | |||||
| //result.QueuingInfo.EndTime = time.Unix(int64(result.QueuingInfo.EndTimestamp/1000), 0).Format("2006-01-02 15:04:05") | |||||
| } | } | ||||
| datasetDownloadLink := "-" | |||||
| if ctx.IsSigned { | |||||
| if task.Uuid != "" && task.UserID == ctx.User.ID { | |||||
| attachment, err := models.GetAttachmentByUUID(task.Uuid) | |||||
| if err == nil { | |||||
| datasetDownloadLink = attachment.S3DownloadURL() | |||||
| } | |||||
| } | |||||
| } | |||||
| ctx.Data["datasetDownloadLink"] = datasetDownloadLink | |||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["jobID"] = jobID | ctx.Data["jobID"] = jobID | ||||
| ctx.Data["jobName"] = task.JobName | |||||
| ctx.Data["result"] = result | ctx.Data["result"] = result | ||||
| ctx.HTML(200, tplModelArtsNotebookShow) | ctx.HTML(200, tplModelArtsNotebookShow) | ||||
| } | } | ||||
| @@ -417,6 +419,7 @@ func NotebookManage(ctx *context.Context) { | |||||
| func NotebookDel(ctx *context.Context) { | func NotebookDel(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
| var listType = ctx.Query("debugListType") | |||||
| task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
| if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) { | if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) { | ||||
| @@ -442,7 +445,12 @@ func NotebookDel(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
| var isAdminPage = ctx.Query("isadminpage") | |||||
| if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | |||||
| ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | |||||
| } else { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=" + listType) | |||||
| } | |||||
| } | } | ||||
| func TrainJobIndex(ctx *context.Context) { | func TrainJobIndex(ctx *context.Context) { | ||||
| @@ -1451,6 +1459,7 @@ func TrainJobShow(ctx *context.Context) { | |||||
| ctx.Data["jobName"] = VersionListTasks[0].JobName | ctx.Data["jobName"] = VersionListTasks[0].JobName | ||||
| ctx.Data["version_list_task"] = VersionListTasks | ctx.Data["version_list_task"] = VersionListTasks | ||||
| ctx.Data["version_list_count"] = VersionListCount | ctx.Data["version_list_count"] = VersionListCount | ||||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | |||||
| ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow) | ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow) | ||||
| } | } | ||||
| @@ -1547,7 +1556,12 @@ func TrainJobDel(ctx *context.Context) { | |||||
| DeleteJobStorage(VersionListTasks[0].JobName) | DeleteJobStorage(VersionListTasks[0].JobName) | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
| var isAdminPage = ctx.Query("isadminpage") | |||||
| if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | |||||
| ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | |||||
| } else { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
| } | |||||
| } | } | ||||
| func TrainJobStop(ctx *context.Context) { | func TrainJobStop(ctx *context.Context) { | ||||
| @@ -2050,6 +2064,7 @@ func InferenceJobShow(ctx *context.Context) { | |||||
| ctx.Data["jobID"] = jobID | ctx.Data["jobID"] = jobID | ||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||||
| tempUids := []int64{} | tempUids := []int64{} | ||||
| tempUids = append(tempUids, task.UserID) | tempUids = append(tempUids, task.UserID) | ||||
| @@ -107,6 +107,7 @@ func RepoStatisticDaily(date string) { | |||||
| RepoID: repo.ID, | RepoID: repo.ID, | ||||
| Date: date, | Date: date, | ||||
| Name: repo.Name, | Name: repo.Name, | ||||
| Alias: repo.Alias, | |||||
| IsPrivate: repo.IsPrivate, | IsPrivate: repo.IsPrivate, | ||||
| IsMirror: repo.IsMirror, | IsMirror: repo.IsMirror, | ||||
| OwnerName: repo.OwnerName, | OwnerName: repo.OwnerName, | ||||
| @@ -282,7 +283,7 @@ func RepoStatisticDaily(date string) { | |||||
| } | } | ||||
| func getDistinctProjectName(repo *models.Repository) string { | func getDistinctProjectName(repo *models.Repository) string { | ||||
| return repo.OwnerName + "/" + repo.Name | |||||
| return repo.OwnerName + "/" + repo.Alias | |||||
| } | } | ||||
| func getDatasetSize(repo *models.Repository) (int64, error) { | func getDatasetSize(repo *models.Repository) (int64, error) { | ||||
| @@ -63,11 +63,13 @@ func queryUserDataPage(ctx *context.Context, tableName string, queryObj interfac | |||||
| _, count := models.QueryUserStaticDataByTableName(1, 1, tableName, queryObj, userName) | _, count := models.QueryUserStaticDataByTableName(1, 1, tableName, queryObj, userName) | ||||
| var indexTotal int64 | var indexTotal int64 | ||||
| indexTotal = 0 | indexTotal = 0 | ||||
| row := 1 | |||||
| for { | for { | ||||
| re, _ := models.QueryUserStaticDataByTableName(int(indexTotal), PAGE_SIZE, tableName, queryObj, "") | re, _ := models.QueryUserStaticDataByTableName(int(indexTotal), PAGE_SIZE, tableName, queryObj, "") | ||||
| log.Info("return count=" + fmt.Sprint(count)) | log.Info("return count=" + fmt.Sprint(count)) | ||||
| for i, userRecord := range re { | |||||
| rows := fmt.Sprint(i + 2) | |||||
| for _, userRecord := range re { | |||||
| row++ | |||||
| rows := fmt.Sprint(row) | |||||
| xlsx.SetCellValue(sheetName, "A"+rows, userRecord.ID) | xlsx.SetCellValue(sheetName, "A"+rows, userRecord.ID) | ||||
| xlsx.SetCellValue(sheetName, "B"+rows, userRecord.Name) | xlsx.SetCellValue(sheetName, "B"+rows, userRecord.Name) | ||||
| xlsx.SetCellValue(sheetName, "C"+rows, userRecord.CodeMergeCount) | xlsx.SetCellValue(sheetName, "C"+rows, userRecord.CodeMergeCount) | ||||
| @@ -322,6 +322,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/action/notification", routers.ActionNotification) | m.Get("/action/notification", routers.ActionNotification) | ||||
| m.Get("/recommend/org", routers.RecommendOrgFromPromote) | m.Get("/recommend/org", routers.RecommendOrgFromPromote) | ||||
| m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | ||||
| m.Get("/home/term", routers.HomeTerm) | |||||
| m.Group("/explore", func() { | m.Group("/explore", func() { | ||||
| m.Get("", func(ctx *context.Context) { | m.Get("", func(ctx *context.Context) { | ||||
| ctx.Redirect(setting.AppSubURL + "/explore/repos") | ctx.Redirect(setting.AppSubURL + "/explore/repos") | ||||
| @@ -517,6 +518,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("", admin.Datasets) | m.Get("", admin.Datasets) | ||||
| // m.Post("/delete", admin.DeleteDataset) | // m.Post("/delete", admin.DeleteDataset) | ||||
| }) | }) | ||||
| m.Group("/cloudbrains", func() { | |||||
| m.Get("", admin.CloudBrains) | |||||
| m.Get("/download", admin.DownloadCloudBrains) | |||||
| }) | |||||
| m.Group("/^:configType(hooks|system-hooks)$", func() { | m.Group("/^:configType(hooks|system-hooks)$", func() { | ||||
| m.Get("", admin.DefaultOrSystemWebhooks) | m.Get("", admin.DefaultOrSystemWebhooks) | ||||
| @@ -984,9 +989,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
| m.Group("/:jobid", func() { | |||||
| m.Group("/:jobname", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) | ||||
| m.Get("/debug", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) | |||||
| }) | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("/debug", reqWechatBind,cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) | |||||
| m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | ||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | ||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) | m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) | ||||
| @@ -1000,8 +1007,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/benchmark", func() { | m.Group("/benchmark", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) | ||||
| m.Group("/:jobid", func() { | |||||
| m.Group("/:jobname", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | ||||
| }) | |||||
| m.Group("/:jobid", func() { | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | ||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | ||||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | ||||
| @@ -132,7 +132,7 @@ func getNotifications(c *context.Context) { | |||||
| } | } | ||||
| c.Data["Title"] = c.Tr("notifications") | c.Data["Title"] = c.Tr("notifications") | ||||
| c.Data["Keyword"] = keyword | |||||
| //c.Data["Keyword"] = keyword | |||||
| c.Data["Status"] = status | c.Data["Status"] = status | ||||
| c.Data["Notifications"] = notifications | c.Data["Notifications"] = notifications | ||||
| @@ -10,7 +10,7 @@ import ( | |||||
| "github.com/elliotchance/orderedmap" | "github.com/elliotchance/orderedmap" | ||||
| ) | ) | ||||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23} | |||||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30} | |||||
| type ClientsManager struct { | type ClientsManager struct { | ||||
| Clients *orderedmap.OrderedMap | Clients *orderedmap.OrderedMap | ||||
| @@ -0,0 +1,220 @@ | |||||
| {{template "base/head" .}} | |||||
| <!-- 弹窗 --> | |||||
| <div id="mask"> | |||||
| <div id="loadingPage"> | |||||
| <div class="rect1"></div> | |||||
| <div class="rect2"></div> | |||||
| <div class="rect3"></div> | |||||
| <div class="rect4"></div> | |||||
| <div class="rect5"></div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 提示框 --> | |||||
| <div class="alert"></div> | |||||
| <div class="admin user"> | |||||
| {{template "admin/navbar" .}} | |||||
| <div class="ui container" style="width: 80%;"> | |||||
| {{template "base/alert" .}} | |||||
| <div class="ui grid" > | |||||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||||
| {{template "admin/cloudbrain/search" .}} | |||||
| <div class="ui ten wide column right aligned" style="margin: 1rem 0;"> | |||||
| <a class="ui compact blue basic icon button" style="box-shadow: none !important; padding: 0.8em;" href="/admin/cloudbrains/download"><i class="ri-download-line middle aligned icon"></i>{{.i18n.Tr "admin.cloudbrain.download_report"}}</a> | |||||
| </div> | |||||
| <div class="ui sixteen wide column"> | |||||
| <!-- 任务展示 --> | |||||
| <div class="dataset list"> | |||||
| <!-- 表头 --> | |||||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||||
| <div class="row"> | |||||
| <div class="two wide column nowrap"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap"> | |||||
| <span>{{$.i18n.Tr "repository"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap"> | |||||
| <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range .Tasks}} | |||||
| <div class="ui grid stackable item"> | |||||
| <div class="row"> | |||||
| <!-- 任务名 --> | |||||
| <div class="two wide column nowrap"> | |||||
| {{if eq .JobType "DEBUG"}} | |||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</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> | |||||
| {{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> | |||||
| {{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> | |||||
| {{end}} | |||||
| </div> | |||||
| <!-- 任务类型 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| </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> | |||||
| </div> | |||||
| <!-- 任务创建时间 --> | |||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||||
| </div> | |||||
| <!-- 任务运行时间 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- 计算资源 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- 创建者 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| {{if .User.Name}} | |||||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||||
| {{else}} | |||||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||||
| {{end}} | |||||
| </div> | |||||
| <!-- 项目 --> | |||||
| <div class="two wide column text center nowrap"> | |||||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||||
| </div> | |||||
| <!-- 云脑侧名称 --> | |||||
| <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | |||||
| <span class="fitted">{{.JobName}}</span> | |||||
| </div> | |||||
| <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}}"> | |||||
| {{$.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}}/'> | |||||
| {{$.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}}/'> | |||||
| {{$.i18n.Tr "repo.debug_again"}} | |||||
| </a> | |||||
| {{end}} | |||||
| </form> | |||||
| </div> | |||||
| {{end}} | |||||
| <!-- 停止任务 --> | |||||
| <div class="ui compact buttons"> | |||||
| {{if eq .JobType "DEBUG" "BENCHMARK"}} | |||||
| <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}}"> | |||||
| {{$.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}}" > | |||||
| {{$.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"> | |||||
| {{$.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;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | |||||
| </a> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | |||||
| <div id="app" style="margin-top: 2rem;"> | |||||
| <div class="center"> | |||||
| <el-pagination | |||||
| background | |||||
| @current-change="handleCurrentChange" | |||||
| :current-page="page" | |||||
| :page-sizes="[10]" | |||||
| :page-size="10" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="{{.Page.Paginater.Total}}"> | |||||
| </el-pagination> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 确认模态框 --> | |||||
| <div id="deletemodel"> | |||||
| <div class="ui basic modal"> | |||||
| <div class="ui icon header"> | |||||
| <i class="trash icon"></i> 删除任务 | |||||
| </div> | |||||
| <div class="content"> | |||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| </div> | |||||
| <div class="actions"> | |||||
| <div class="ui red basic inverted cancel button"> | |||||
| <i class="remove icon"></i> 取消操作 | |||||
| </div> | |||||
| <div class="ui green basic inverted ok button"> | |||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| function getParams(){ | |||||
| const params = new URLSearchParams(window.location.search) | |||||
| let jobType = !params.get('jobType')? '{{.i18n.Tr "admin.cloudbrain.all_task_types"}}' : params.get('jobType') | |||||
| let listType = !params.get('listType')? '{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}' : params.get('listType') | |||||
| let jobStatus = !params.get('jobStatus')? '{{.i18n.Tr "admin.cloudbrain.all_status"}}' : params.get('jobStatus') | |||||
| const dropdownValueArray = [jobType,listType,jobStatus] | |||||
| $('#adminCloud .default.text ').each(function(index,e){ | |||||
| $(e).text(dropdownValueArray[index]) | |||||
| }) | |||||
| } | |||||
| getParams() | |||||
| console.log({{.Tasks}}) | |||||
| </script> | |||||
| @@ -0,0 +1,47 @@ | |||||
| <div class="ui attached segment"> | |||||
| <form class="ui form ignore-dirty" style="max-width: 90%"> | |||||
| <div class="ui fluid action input"> | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> | |||||
| <button class="ui blue button">{{.i18n.Tr "explore.search"}}</button> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| <div class="ui six wide column" style="margin: 1rem 0;" id="adminCloud"> | |||||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||||
| <div class="default text" style="color: rgba(0,0,0,.87);">{{.i18n.Tr "admin.cloudbrain.all_task_types"}}</div> | |||||
| <i class="dropdown icon"></i> | |||||
| <div class="menu"> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value='{{.i18n.Tr "admin.cloudbrain.all_task_types"}}'>{{.i18n.Tr "admin.cloudbrain.all_task_types"}}</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=DEBUG&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="DEBUG">DEBUG</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=TRAIN&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="TRAIN">TRAIN</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=INFERENCE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="INFERENCE">INFERENCE</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BENCHMARK&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">BENCHMARK</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||||
| <div class="default text" style="color: rgba(0,0,0,.87);">{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}</div> | |||||
| <i class="dropdown icon"></i> | |||||
| <div class="menu"> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=&jobStatus={{$.JobStatus}}" data-value='{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}'>{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=CPU/GPU&jobStatus={{$.JobStatus}}" data-value="CPU/GPU">CPU/GPU</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=NPU&jobStatus={{$.JobStatus}}" data-value="NPU">NPU</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||||
| <div class="default text" style="color: rgba(0,0,0,.87);">{{.i18n.Tr "admin.cloudbrain.all_status"}}</div> | |||||
| <i class="dropdown icon"></i> | |||||
| <div class="menu"> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=" data-value='{{.i18n.Tr "admin.cloudbrain.all_status"}}'>{{.i18n.Tr "admin.cloudbrain.all_status"}}</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STARTING" data-value="CPU/GPU">STARTING</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=RESTARTING" data-value="NPU">RESTARTING </a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=START_FAILED" data-value="all">START_FAILED</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STOPPING" data-value="CPU/GPU">STOPPING</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STOPPED" data-value="NPU">STOPPED</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=WAITING" data-value="all">WAITING</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=COMPLETED" data-value="CPU/GPU">COMPLETED</a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=FAILED" data-value="NPU">FAILED </a> | |||||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=OTHER" data-value="NPU">OTHER</a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| @@ -14,6 +14,9 @@ | |||||
| <a class="{{if .PageIsAdminDatasets}}active{{end}} item" href="{{AppSubUrl}}/admin/datasets"> | <a class="{{if .PageIsAdminDatasets}}active{{end}} item" href="{{AppSubUrl}}/admin/datasets"> | ||||
| {{.i18n.Tr "admin.datasets"}} | {{.i18n.Tr "admin.datasets"}} | ||||
| </a> | </a> | ||||
| <a class="{{if .PageIsAdminCloudBrains}}active{{end}} item" href="{{AppSubUrl}}/admin/cloudbrains"> | |||||
| 云脑任务 | |||||
| </a> | |||||
| <a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | <a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | ||||
| {{.i18n.Tr "admin.hooks"}} | {{.i18n.Tr "admin.hooks"}} | ||||
| </a> | </a> | ||||
| @@ -8,6 +8,8 @@ | |||||
| <a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.council"}}</a> | <a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.council"}}</a> | ||||
| <a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.technical_committee"}}</a> | <a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.technical_committee"}}</a> | ||||
| <a href="https://openi.org.cn/html/Club/2019/0228/17.html" class="item">{{.i18n.Tr "custom.foot.join"}}</a> | <a href="https://openi.org.cn/html/Club/2019/0228/17.html" class="item">{{.i18n.Tr "custom.foot.join"}}</a> | ||||
| <a href="{{AppSubUrl}}/home/term/" class="item">{{.i18n.Tr "custom.foot.agreement"}}</a> | |||||
| </div> | </div> | ||||
| <div class="column ui vertical text menu"> | <div class="column ui vertical text menu"> | ||||
| <div class="header item">{{.i18n.Tr "custom.foot.news"}}</div> | <div class="header item">{{.i18n.Tr "custom.foot.news"}}</div> | ||||
| @@ -226,10 +226,12 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| let isShowNoticeTag = false; | let isShowNoticeTag = false; | ||||
| let notices= {{.notices.Notices}} | let notices= {{.notices.Notices}} | ||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| if(notices != null && notices!=''){ | |||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (isShowNoticeTag){ | if (isShowNoticeTag){ | ||||
| @@ -245,7 +247,9 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| document.getElementById("notic_content").style.display='none' | |||||
| if (document.getElementById("notic_content") != null){ | |||||
| document.getElementById("notic_content").style.display='none' | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -227,10 +227,12 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| let isShowNoticeTag = false; | let isShowNoticeTag = false; | ||||
| let notices= {{.notices.Notices}} | let notices= {{.notices.Notices}} | ||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| if(notices != null && notices!=''){ | |||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (isShowNoticeTag){ | if (isShowNoticeTag){ | ||||
| @@ -246,7 +248,9 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| document.getElementById("notic_content").style.display='none' | |||||
| if (document.getElementById("notic_content") != null){ | |||||
| document.getElementById("notic_content").style.display='none' | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -231,10 +231,12 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| let isShowNoticeTag = false; | let isShowNoticeTag = false; | ||||
| let notices= {{.notices.Notices}} | let notices= {{.notices.Notices}} | ||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| if(notices != null && notices!=''){ | |||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (isShowNoticeTag){ | if (isShowNoticeTag){ | ||||
| @@ -250,7 +252,9 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| document.getElementById("notic_content").style.display='none' | |||||
| if (document.getElementById("notic_content") != null){ | |||||
| document.getElementById("notic_content").style.display='none' | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -228,10 +228,12 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| let isShowNoticeTag = false; | let isShowNoticeTag = false; | ||||
| let notices= {{.notices.Notices}} | let notices= {{.notices.Notices}} | ||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| if(notices != null && notices!=''){ | |||||
| for (i =0;i<notices.length;i++){ | |||||
| if (notices[i].Visible==1){ | |||||
| isShowNoticeTag =true; | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (isShowNoticeTag){ | if (isShowNoticeTag){ | ||||
| @@ -247,7 +249,9 @@ var _hmt = _hmt || []; | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| document.getElementById("notic_content").style.display='none' | |||||
| if (document.getElementById("notic_content") != null){ | |||||
| document.getElementById("notic_content").style.display='none' | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -20,7 +20,7 @@ | |||||
| <div id="homenews" class="ui container"> | <div id="homenews" class="ui container"> | ||||
| <p>* {{.page_only_dynamic}}</p> | <p>* {{.page_only_dynamic}}</p> | ||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="twelve wide tablet ten wide computer column homenews"> | |||||
| <div class="sixteen wide mobile twelve wide tablet ten wide computer column homenews"> | |||||
| <div class="newslist"> | <div class="newslist"> | ||||
| <div class="ui mini aligned list swiper-wrapper" id="newmessage"> | <div class="ui mini aligned list swiper-wrapper" id="newmessage"> | ||||
| @@ -42,7 +42,11 @@ | |||||
| <a href="{{AppSubUrl}}/explore/organizations" class="circular ui primary basic button">{{.page_recommend_org_more}} <i class="arrow circle right icon"></i></a> | <a href="{{AppSubUrl}}/explore/organizations" class="circular ui primary basic button">{{.page_recommend_org_more}} <i class="arrow circle right icon"></i></a> | ||||
| </div> | </div> | ||||
| <div class="sixteen wide tablet twelve wide computer column"> | <div class="sixteen wide tablet twelve wide computer column"> | ||||
| <div class="ui stackable three column grid homeorg-list" id="recommendorg"> | |||||
| <div class="homeorg-list"> | |||||
| <div class="swiper-wrapper" id="recommendorg"> | |||||
| </div> | |||||
| <div class="swiper-pagination"></div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -78,7 +82,7 @@ | |||||
| <h2>{{.page_dev_env}}</h2> | <h2>{{.page_dev_env}}</h2> | ||||
| <p><span class="ui text grey">{{.page_dev_env_desc}}</p> | <p><span class="ui text grey">{{.page_dev_env_desc}}</p> | ||||
| </div> | </div> | ||||
| <div class="ui four stackable cards"> | |||||
| <div class="ui four doubling cards"> | |||||
| <div class="card"> | <div class="card"> | ||||
| <div class="image"> | <div class="image"> | ||||
| <img src="/img/i-pic-01.svg"> | <img src="/img/i-pic-01.svg"> | ||||
| @@ -158,4 +162,4 @@ | |||||
| <script src="/home/home.js?v={{MD5 AppVer}}" type="text/javascript"></script> | <script src="/home/home.js?v={{MD5 AppVer}}" type="text/javascript"></script> | ||||
| {{template "base/footer" .}} | |||||
| {{template "base/footer" .}} | |||||
| @@ -67,8 +67,20 @@ | |||||
| <div class="item"> | <div class="item"> | ||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | ||||
| <p class="text grey"> | <p class="text grey"> | ||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.NumMembers}}</strong> {{$.i18n.Tr "org.lower_members"}}</a> · | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}/repositories"><strong>{{.NumRepos}}</strong> {{$.i18n.Tr "org.lower_repositories"}}</a> | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.NumMembers}}</strong> | |||||
| {{if le .NumMembers 1}} | |||||
| {{$.i18n.Tr "org.lower_member"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_members"}} | |||||
| {{end}} | |||||
| </a> · | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}/repositories"><strong>{{.NumRepos}}</strong> | |||||
| {{if le .NumRepos 1}} | |||||
| {{$.i18n.Tr "org.lower_repository"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_repositories"}} | |||||
| {{end}} | |||||
| </a> | |||||
| </p> | </p> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -221,8 +221,20 @@ | |||||
| <div style="margin-top: 10px;"> | <div style="margin-top: 10px;"> | ||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | ||||
| <p class="text grey"> | <p class="text grey"> | ||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.NumMembers}}</strong> {{$.i18n.Tr "org.lower_members"}}</a> · | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}/repositories"><strong>{{.NumRepos}}</strong> {{$.i18n.Tr "org.lower_repositories"}}</a> | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.NumMembers}}</strong> | |||||
| {{if le .NumMembers 1}} | |||||
| {{$.i18n.Tr "org.lower_member"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_members"}} | |||||
| {{end}} | |||||
| </a> · | |||||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}/repositories"><strong>{{.NumRepos}}</strong> | |||||
| {{if le .NumRepos 1}} | |||||
| {{$.i18n.Tr "org.lower_repository"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_repositories"}} | |||||
| {{end}} | |||||
| </a> | |||||
| </p> | </p> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -120,7 +120,6 @@ | |||||
| <script> | <script> | ||||
| function show_bt(bt_id){ | function show_bt(bt_id){ | ||||
| console.log(bt_id) | |||||
| document.getElementById(""+bt_id).getElementsByClassName("button_leaveOrg")[0].style.display="inline-block"; | document.getElementById(""+bt_id).getElementsByClassName("button_leaveOrg")[0].style.display="inline-block"; | ||||
| } | } | ||||
| @@ -70,11 +70,11 @@ | |||||
| <div style="width: 100%;margin:15px 0;"> | <div style="width: 100%;margin:15px 0;"> | ||||
| {{if .tags}} | {{if .tags}} | ||||
| <span class="header"> | <span class="header"> | ||||
| 精选项目 | |||||
| {{.i18n.Tr "org.selected_project"}} | |||||
| </span> | </span> | ||||
| <!-- {{.IsOrganizationOwner}} --> | <!-- {{.IsOrganizationOwner}} --> | ||||
| {{if .IsOrganizationOwner}} | {{if .IsOrganizationOwner}} | ||||
| <a class="text-right" id="model" onclick="showcreate()" >{{svg "octicon-gear" 16}}自定义</a> | |||||
| <a class="text-right" id="model" onclick="showcreate()" >{{svg "octicon-gear" 16}}{{.i18n.Tr "org.customize"}}</a> | |||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| @@ -137,10 +137,10 @@ | |||||
| <div class="ui modal"> | <div class="ui modal"> | ||||
| <div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | <div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | ||||
| <h4 id="model_header">自定义精选项目</h4> | |||||
| <h4 id="model_header">{{.i18n.Tr "org.custom_select_projects"}}</h4> | |||||
| </div> | </div> | ||||
| <div class="content content-padding" style="color: black;"> | <div class="content content-padding" style="color: black;"> | ||||
| <p>最多可选9个公开项目</p> | |||||
| <p>{{.i18n.Tr "org.max_selectedPro"}}</p> | |||||
| <div class="ui search" > | <div class="ui search" > | ||||
| <div class="ui input" style="width: 100%;"> | <div class="ui input" style="width: 100%;"> | ||||
| <input type="text" id = 'search_selectPro' placeholder="Search ..." value = '' oninput="search()"> | <input type="text" id = 'search_selectPro' placeholder="Search ..." value = '' oninput="search()"> | ||||
| @@ -223,12 +223,12 @@ | |||||
| function saveSeletedPro(typeTag){ | function saveSeletedPro(typeTag){ | ||||
| var saveData=[]; | var saveData=[]; | ||||
| $('input[name="select_pro_name"]:checked').each(function(){ | $('input[name="select_pro_name"]:checked').each(function(){ | ||||
| console.log('值',this.dataset.repoid) | |||||
| // console.log('值',this.dataset.repoid) | |||||
| saveData.push(parseInt(this.dataset.repoid)); | saveData.push(parseInt(this.dataset.repoid)); | ||||
| }) | }) | ||||
| if(saveData.length>9){ | if(saveData.length>9){ | ||||
| alert("最多可选9个,保存失败") | |||||
| alert("{{.i18n.Tr "org.save_fail_tips"}}") | |||||
| return | return | ||||
| } | } | ||||
| // saveData = getSelecteDataID(); | // saveData = getSelecteDataID(); | ||||
| @@ -242,7 +242,7 @@ | |||||
| data:JSON.stringify({'repoList':saveData | data:JSON.stringify({'repoList':saveData | ||||
| }), | }), | ||||
| success:function(res){ | success:function(res){ | ||||
| console.log('保存成功'); | |||||
| // console.log('保存成功'); | |||||
| location.reload() | location.reload() | ||||
| } | } | ||||
| @@ -270,15 +270,15 @@ | |||||
| filterData.push(data[i]) | filterData.push(data[i]) | ||||
| } | } | ||||
| } | } | ||||
| console.log("选中的值:",selectedData) | |||||
| console.log("筛选包括选中的值:",filterData) | |||||
| // console.log("选中的值:",selectedData) | |||||
| // console.log("筛选包括选中的值:",filterData) | |||||
| var showData=[]; | var showData=[]; | ||||
| for(i=0;i<selectedData.length;i++){ | for(i=0;i<selectedData.length;i++){ | ||||
| filterData =filterData.filter((item)=>{ | filterData =filterData.filter((item)=>{ | ||||
| return item.RepoID!=selectedData[i].RepoID | return item.RepoID!=selectedData[i].RepoID | ||||
| }); | }); | ||||
| } | } | ||||
| console.log("筛选后不包括选中的值:",filterData) | |||||
| // console.log("筛选后不包括选中的值:",filterData) | |||||
| $("#org_list").empty() | $("#org_list").empty() | ||||
| if(searchValue!=""){ | if(searchValue!=""){ | ||||
| if (filterData.length!=0){ | if (filterData.length!=0){ | ||||
| @@ -307,7 +307,7 @@ | |||||
| num++ | num++ | ||||
| if(num>9){ | if(num>9){ | ||||
| document.getElementById(id).checked=false | document.getElementById(id).checked=false | ||||
| alert("选择超过9个,请重新选择!") | |||||
| alert("{{.i18n.Tr "org.select_again"}}") | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| @@ -315,7 +315,8 @@ | |||||
| } | } | ||||
| var show_num = 9-num; | var show_num = 9-num; | ||||
| document.getElementById("recommend").innerHTML="还能推荐"+show_num+"个" | |||||
| let rec = "{{.i18n.Tr "org.recommend_remain_pro"}}" | |||||
| document.getElementById("recommend").innerHTML=rec +" : "+ show_num | |||||
| } | } | ||||
| @@ -44,7 +44,19 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui bottom attached header"> | <div class="ui bottom attached header"> | ||||
| <p class="team-meta">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p> | |||||
| <p class="team-meta">{{.NumMembers}} | |||||
| {{if le .NumMembers 1}} | |||||
| {{$.i18n.Tr "org.lower_member"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_members"}} | |||||
| {{end}} | |||||
| · {{.NumRepos}} | |||||
| {{if le .NumRepos 1}} | |||||
| {{$.i18n.Tr "org.lower_repository"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_repositories"}} | |||||
| {{end}} | |||||
| </p> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -36,7 +36,19 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui bottom attached header"> | <div class="ui bottom attached header"> | ||||
| <p class="team-meta">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p> | |||||
| <p class="team-meta">{{.NumMembers}} | |||||
| {{if le .NumMembers 1}} | |||||
| {{$.i18n.Tr "org.lower_member"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_members"}} | |||||
| {{end}} | |||||
| · {{.NumRepos}} | |||||
| {{if le .NumRepos 1}} | |||||
| {{$.i18n.Tr "org.lower_repository"}} | |||||
| {{else}} | |||||
| {{$.i18n.Tr "org.lower_repositories"}} | |||||
| {{end}} | |||||
| </p> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -99,14 +99,13 @@ | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="{{$.Link}}/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <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><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> | </span> | ||||
| </div> | </div> | ||||
| @@ -137,10 +136,9 @@ | |||||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/cloudbrain/benchmark/{{.JobID}}/stop")'> | |||||
| {{$.i18n.Tr "repo.stop"}} | |||||
| </a> | |||||
| <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}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | |||||
| </a> | |||||
| {{else}} | {{else}} | ||||
| <a class="ui basic disabled button"> | <a class="ui basic disabled button"> | ||||
| @@ -148,26 +146,21 @@ | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | </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/{{.JobID}}/rate" target="_blank"> | ||||
| 评分 | 评分 | ||||
| </a> | </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-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | ||||
| <input type="hidden" name="debugListType" value="all"> | <input type="hidden" name="debugListType" value="all"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="model-delete-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||||
| <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;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui basic button disabled" onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||||
| <a class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| @@ -221,167 +214,3 @@ | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| console.log({{.Tasks}}) | |||||
| // 调试和评分新开窗口 | |||||
| function stop(obj) { | |||||
| if (obj.style.color != "rgb(204, 204, 204)") { | |||||
| obj.target = '_blank' | |||||
| } else { | |||||
| return | |||||
| } | |||||
| } | |||||
| // 删除时用户确认 | |||||
| function assertDelete(obj) { | |||||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||||
| return | |||||
| } else { | |||||
| var delId = obj.parentNode.id | |||||
| flag = 1; | |||||
| $('.ui.basic.modal') | |||||
| .modal({ | |||||
| onDeny: function() { | |||||
| flag = false | |||||
| }, | |||||
| onApprove: function() { | |||||
| document.getElementById(delId).submit() | |||||
| flag = true | |||||
| }, | |||||
| onHidden: function() { | |||||
| if (flag == false) { | |||||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| } | |||||
| function runtime(time){ | |||||
| if(time){ | |||||
| let hours = time/3600000<10 ? "0"+parseInt(time/3600000):parseInt(time/3600000) | |||||
| let miuns = time%3600000/60000<10 ? "0"+parseInt(time%3600000/60000):parseInt(time%3600000/60000) | |||||
| let seconds = time%60000/1000<10 ? "0"+parseInt(time%60000/1000):parseInt(time%60000/1000) | |||||
| return hours + ":" + miuns + ":" + seconds | |||||
| }else{ | |||||
| return "00:00:00" | |||||
| } | |||||
| } | |||||
| // 加载任务状态 | |||||
| var timeid = window.setInterval(loadJobStatus, 15000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadJobStatus() { | |||||
| $(".job-status").each((index, job) => { | |||||
| const jobID = job.dataset.jobid; | |||||
| const repoPath = job.dataset.repopath; | |||||
| const computeResource = job.dataset.resource | |||||
| const initArray = ['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'] | |||||
| if (initArray.includes(job.textContent.trim())) { | |||||
| return | |||||
| } | |||||
| const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||||
| $.get(`/api/v1/repos/${repoPath}/${diffResource}/${jobID}`, (data) => { | |||||
| const jobID = data.JobID | |||||
| const status = data.JobStatus | |||||
| if (status != job.textContent.trim()) { | |||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| } | |||||
| if(status==="RUNNING"){ | |||||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| if(status!=="RUNNING"){ | |||||
| // $('#model-debug-'+jobID).removeClass('blue') | |||||
| // $('#model-debug-'+jobID).addClass('disabled') | |||||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||||
| $('#model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||||
| } | |||||
| if(["RUNNING","WAITING"].includes(status)){ | |||||
| $('#stop-model-debug-'+jobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||||
| $('#stop-model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ | |||||
| $('#model-delete-'+jobID).removeClass('disabled').addClass('blue') | |||||
| }else{ | |||||
| $('#model-delete-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| // 获取弹窗 | |||||
| var modal = document.getElementById('imageModal'); | |||||
| // 打开弹窗的按钮对象 | |||||
| var btns = document.getElementsByClassName("imageBtn"); | |||||
| // 获取 <span> 元素,用于关闭弹窗 | |||||
| var spans = document.getElementsByClassName('close'); | |||||
| // 点击按钮打开弹窗 | |||||
| for (i = 0; i < btns.length; i++) { | |||||
| btns[i].onclick = function() { | |||||
| modal.style.display = "block"; | |||||
| } | |||||
| } | |||||
| // 点击 <span> (x), 关闭弹窗 | |||||
| for (i = 0; i < spans.length; i++) { | |||||
| spans[i].onclick = function() { | |||||
| modal.style.display = "none"; | |||||
| } | |||||
| } | |||||
| // 在用户点击其他地方时,关闭弹窗 | |||||
| window.onclick = function(event) { | |||||
| if (event.target == modal) { | |||||
| modal.style.display = "none"; | |||||
| } | |||||
| } | |||||
| function stopDebug(JobID,stopUrl){ | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:stopUrl, | |||||
| data:$('#stopForm-'+JobID).serialize(), | |||||
| success:function(res){ | |||||
| if(res.result_code==="0"){ | |||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-text').text(res.status) | |||||
| if(res.status==="STOPPED"){ | |||||
| $('#model-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||||
| $('#model-image-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#model-delete-'+JobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| else{ | |||||
| $('#model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }else{ | |||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||||
| } | |||||
| }, | |||||
| error :function(res){ | |||||
| console.log(res) | |||||
| } | |||||
| }) | |||||
| } | |||||
| </script> | |||||
| @@ -83,7 +83,7 @@ | |||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | ||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| @@ -102,11 +102,16 @@ | |||||
| <span> </span> | <span> </span> | ||||
| <select class="ui fluid selection search dropdown" id="benchmark_types_id" name="benchmark_types_id" > | <select class="ui fluid selection search dropdown" id="benchmark_types_id" name="benchmark_types_id" > | ||||
| {{range .benchmark_types}} | {{range .benchmark_types}} | ||||
| <option value="{{.Id}}">{{.First}}</option> | |||||
| {{if eq .Id $.benchmarkTypeID}} | |||||
| <option value="{{.Id}}" selected="true">{{.First}}</option> | |||||
| {{else}} | |||||
| <option value="{{.Id}}">{{.First}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="eight wide field" id="engine_name"> | <div class="eight wide field" id="engine_name"> | ||||
| <input type="hidden" id="benchmark_child_types_id_hidden" name="benchmark_child_types_id_hidden" value="{{.benchmark_child_types_id_hidden}}"> | |||||
| <label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}}</label> | <label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}}</label> | ||||
| <select class="ui fluid selection dropdown nowrap" id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id"> | <select class="ui fluid selection dropdown nowrap" id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id"> | ||||
| </select> | </select> | ||||
| @@ -182,12 +187,16 @@ | |||||
| function setChildType(){ | function setChildType(){ | ||||
| let type_id = $('#benchmark_types_id').val(); | let type_id = $('#benchmark_types_id').val(); | ||||
| let child_selected_id = $('#benchmark_child_types_id_hidden').val(); | |||||
| $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => { | $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => { | ||||
| console.log(JSON.stringify(data)) | |||||
| const n_length = data['child_types'].length | const n_length = data['child_types'].length | ||||
| let html='' | let html='' | ||||
| for (let i=0;i<n_length;i++){ | for (let i=0;i<n_length;i++){ | ||||
| html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`; | |||||
| if(child_selected_id == data['child_types'][i].id){ | |||||
| html += `<option value="${data['child_types'][i].id}" selected="true">${data['child_types'][i].value}</option>`; | |||||
| }else{ | |||||
| html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`; | |||||
| } | |||||
| } | } | ||||
| document.getElementById("benchmark_child_types_id").innerHTML=html; | document.getElementById("benchmark_child_types_id").innerHTML=html; | ||||
| }) | }) | ||||
| @@ -188,6 +188,7 @@ td, th { | |||||
| </h4> | </h4> | ||||
| {{range $k ,$v := .version_list_task}} | {{range $k ,$v := .version_list_task}} | ||||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | <div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | ||||
| <input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||||
| <div class="{{if eq $k 0}}active{{end}} title padding0"> | <div class="{{if eq $k 0}}active{{end}} title padding0"> | ||||
| <div class="according-panel-heading"> | <div class="according-panel-heading"> | ||||
| <div class="accordion-panel-title"> | <div class="accordion-panel-title"> | ||||
| @@ -432,19 +433,18 @@ td, th { | |||||
| let userName | let userName | ||||
| let repoPath | let repoPath | ||||
| let jobID | |||||
| let jobName | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| let url = window.location.href; | let url = window.location.href; | ||||
| let urlArr = url.split('/') | let urlArr = url.split('/') | ||||
| userName = urlArr.slice(-5)[0] | userName = urlArr.slice(-5)[0] | ||||
| repoPath = urlArr.slice(-4)[0] | repoPath = urlArr.slice(-4)[0] | ||||
| jobID = urlArr.slice(-1)[0] | |||||
| jobName = urlArr.slice(-1)[0] | |||||
| }) | }) | ||||
| function loadLog(version_name){ | function loadLog(version_name){ | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${jobID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${jobName}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||||
| $('input[name=end_line]').val(data.EndLine) | $('input[name=end_line]').val(data.EndLine) | ||||
| $('input[name=start_line]').val(data.StartLine) | $('input[name=start_line]').val(data.StartLine) | ||||
| $(`#log_file${version_name}`).text(data.Content) | $(`#log_file${version_name}`).text(data.Content) | ||||
| @@ -121,8 +121,8 @@ | |||||
| </div> | </div> | ||||
| <a style="margin-left: 0.5rem;" id="manage_topic"> | <a style="margin-left: 0.5rem;" id="manage_topic"> | ||||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i style="cursor: pointer;" class="plus square outline icon"></i>{{end}} | |||||
| {{.i18n.Tr "repo.issues.new.add_labels_title"}} | |||||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i style="cursor: pointer;" class="plus square outline icon"></i>{{.i18n.Tr "repo.issues.new.add_labels_title"}}{{end}} | |||||
| </a> | </a> | ||||
| <div id="topic_edit" class="vue_menu" style="display:none;"> | <div id="topic_edit" class="vue_menu" style="display:none;"> | ||||
| @@ -94,7 +94,6 @@ $(document).ready(function(){ | |||||
| $('#course_label_item').empty() | $('#course_label_item').empty() | ||||
| }else{ | }else{ | ||||
| $.get(`/api/v1/topics/search?q=${query}`,(data)=>{ | $.get(`/api/v1/topics/search?q=${query}`,(data)=>{ | ||||
| console.log(data) | |||||
| if(data.topics.length!==0){ | if(data.topics.length!==0){ | ||||
| let html='' | let html='' | ||||
| $('#course_label_item').empty() | $('#course_label_item').empty() | ||||
| @@ -107,5 +106,4 @@ $(document).ready(function(){ | |||||
| } | } | ||||
| }); | }); | ||||
| }) | }) | ||||
| console.log() | |||||
| </script> | </script> | ||||
| @@ -7,14 +7,14 @@ | |||||
| <div class="row"> | <div class="row"> | ||||
| <div class="eight wide column" data-tooltip="{{.Name}}"> | <div class="eight wide column" data-tooltip="{{.Name}}"> | ||||
| <span class="ui right">{{.Size | FileSize}}</span> | <span class="ui right">{{.Size | FileSize}}</span> | ||||
| <a class="title" href="{{.DownloadURL}}?type={{$.Type}}"> | |||||
| <a class="title" href="{{.DownloadURL}}"> | |||||
| {{svg "octicon-cloud-download" 16}} {{.Name}} | {{svg "octicon-cloud-download" 16}} {{.Name}} | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <div class="eight wide column right aligned"> | <div class="eight wide column right aligned"> | ||||
| <div class="ui left mini icon buttons"> | <div class="ui left mini icon buttons"> | ||||
| <span class="ui basic button text left" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right" style="width: 60px; padding-left: 0;">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span> | <span class="ui basic button text left" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right" style="width: 60px; padding-left: 0;">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span> | ||||
| <span class="ui basic basic button clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy"{{if ne $.Type 0}} style="display:none;"{{end}}>{{svg "octicon-file" 16}}</span> | |||||
| <span class="ui basic basic button clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy">{{svg "octicon-file" 16}}</span> | |||||
| <span class="ui basic basic button clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span> | <span class="ui basic basic button clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span> | ||||
| </div> | </div> | ||||
| {{if eq .DecompressState 1}} | {{if eq .DecompressState 1}} | ||||
| @@ -11,9 +11,8 @@ | |||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <script> | <script> | ||||
| $(document).ready(function() { | $(document).ready(function() { | ||||
| url = window.location.href | |||||
| type = url.split('?type=')[1] | |||||
| if (type == 0){ | |||||
| const params = new URLSearchParams(window.location.search); | |||||
| if (params.get('type') == 0){ | |||||
| $('.contorl_component').attr("id", 'minioUploader') | $('.contorl_component').attr("id", 'minioUploader') | ||||
| }else{ | }else{ | ||||
| $('.contorl_component').attr("id", 'obsUploader') | $('.contorl_component').attr("id", 'obsUploader') | ||||
| @@ -287,13 +287,13 @@ | |||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="four wide column"> | <div class="four wide column"> | ||||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}' title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.JobName}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.JobID}}{{end}}' title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center"> | <div class="two wide column text center"> | ||||
| <!--任务状态 --> | <!--任务状态 --> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-resource="{{.ComputeResource}}"> | |||||
| <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><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> | </span> | ||||
| </div> | </div> | ||||
| @@ -324,11 +324,11 @@ | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDebug}} | {{if .CanDebug}} | ||||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | ||||
| <a style="margin: 0 1rem;" id="model-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/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='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/' data-linkpath='{{$.Link}}'> | |||||
| {{$.i18n.Tr "repo.debug"}} | {{$.i18n.Tr "repo.debug"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a id="model-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/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='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||||
| {{$.i18n.Tr "repo.debug_again"}} | {{$.i18n.Tr "repo.debug_again"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -349,15 +349,9 @@ | |||||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| {{if eq .ComputeResource "CPU/GPU" }} | |||||
| <a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/cloudbrain/{{.JobID}}/stop")'> | |||||
| {{$.i18n.Tr "repo.stop"}} | |||||
| </a> | |||||
| {{else}} | |||||
| <a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/modelarts/notebook/{{.JobID}}/stop")'> | |||||
| {{$.i18n.Tr "repo.stop"}} | |||||
| </a> | |||||
| {{end}} | |||||
| <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}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | |||||
| </a> | |||||
| {{else}} | {{else}} | ||||
| <a class="ui basic disabled button"> | <a class="ui basic disabled button"> | ||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| @@ -366,22 +360,19 @@ | |||||
| </form> | </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-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | ||||
| <input type="hidden" name="debugListType" value="all"> | |||||
| <input type="hidden" name="debugListType" value="{{$.ListType}}"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="model-delete-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||||
| <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;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui basic button disabled" onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | |||||
| <a class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| </div> | |||||
| <!-- 删除任务 --> | |||||
| </div> | |||||
| <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | <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="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | ||||
| <div class="text">更多</div> | <div class="text">更多</div> | ||||
| @@ -411,7 +402,6 @@ | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -487,15 +477,14 @@ | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | <script> | ||||
| // 调试和评分新开窗口 | // 调试和评分新开窗口 | ||||
| console.log({{.Tasks}}) | |||||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | ||||
| let url={{.RepoLink}} | let url={{.RepoLink}} | ||||
| let redirect_to = {{$.Link}} | let redirect_to = {{$.Link}} | ||||
| let getParam=getQueryVariable('debugListType') | let getParam=getQueryVariable('debugListType') | ||||
| let dropdownValue = getParam==='all'||getParam==='' ? '全部' : getParam | |||||
| let dropdownValue = ['all','',false].includes(getParam)? '全部' : getParam | |||||
| localStorage.setItem('all',location.href) | localStorage.setItem('all',location.href) | ||||
| function getQueryVariable(variable) | function getQueryVariable(variable) | ||||
| { | { | ||||
| @@ -507,156 +496,6 @@ | |||||
| } | } | ||||
| return(false); | return(false); | ||||
| } | } | ||||
| function stop(obj) { | |||||
| if (obj.style.color != "rgb(204, 204, 204)") { | |||||
| obj.target = '_blank' | |||||
| } else { | |||||
| return | |||||
| } | |||||
| } | |||||
| // 删除时用户确认 | |||||
| function assertDelete(obj) { | |||||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||||
| return | |||||
| } else { | |||||
| var delId = obj.parentNode.id | |||||
| flag = 1; | |||||
| $('.ui.basic.modal') | |||||
| .modal({ | |||||
| onDeny: function() { | |||||
| flag = false | |||||
| }, | |||||
| onApprove: function() { | |||||
| document.getElementById(delId).submit() | |||||
| flag = true | |||||
| $('.alert').html('操作成功!').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut(); | |||||
| }, | |||||
| onHidden: function() { | |||||
| if (flag == false) { | |||||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| } | |||||
| function debugAgain(JobID,debugUrl){ | |||||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||||
| window.open(debugUrl+'debug') | |||||
| }else{ | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:debugUrl+'restart?redirect_to='+redirect_to, | |||||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||||
| success:function(res){ | |||||
| if(res['WechatRedirectUrl']){ | |||||
| window.location.href=res['WechatRedirectUrl'] | |||||
| } | |||||
| else if(res.result_code==="0"){ | |||||
| if(res.job_id!==JobID){ | |||||
| location.reload() | |||||
| }else{ | |||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-text').text(res.status) | |||||
| $('#model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#model-delete-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#model-debug-'+JobID).text("调试").css("margin","0 1rem") | |||||
| } | |||||
| }else{ | |||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||||
| } | |||||
| }, | |||||
| error :function(res){ | |||||
| console.log(res) | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| function stopDebug(JobID,stopUrl){ | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:stopUrl, | |||||
| data:$('#stopForm-'+JobID).serialize(), | |||||
| success:function(res){ | |||||
| if(res.result_code==="0"){ | |||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-text').text(res.status) | |||||
| if(res.status==="STOPPED"){ | |||||
| $('#model-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||||
| $('#model-image-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#model-delete-'+JobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| else{ | |||||
| $('#model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }else{ | |||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||||
| } | |||||
| }, | |||||
| error :function(res){ | |||||
| console.log(res) | |||||
| } | |||||
| }) | |||||
| } | |||||
| // 加载任务状态 | |||||
| var timeid = window.setInterval(loadJobStatus, 15000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadJobStatus() { | |||||
| $(".job-status").each((index, job) => { | |||||
| const jobID = job.dataset.jobid; | |||||
| const repoPath = job.dataset.repopath; | |||||
| const computeResource = job.dataset.resource | |||||
| const initArray = ['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED','UNAVAILABLE','DELETED','RESIZE_FAILED'] | |||||
| if (initArray.includes(job.textContent.trim())) { | |||||
| return | |||||
| } | |||||
| const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||||
| $.get(`/api/v1/repos/${repoPath}/${diffResource}/${jobID}`, (data) => { | |||||
| const jobID = data.JobID | |||||
| const status = data.JobStatus | |||||
| if (status != job.textContent.trim()) { | |||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| } | |||||
| if(status==="RUNNING"){ | |||||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| if(status!=="RUNNING"){ | |||||
| // $('#model-debug-'+jobID).removeClass('blue') | |||||
| // $('#model-debug-'+jobID).addClass('disabled') | |||||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||||
| $('#model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||||
| } | |||||
| if(["RUNNING","WAITING"].includes(status)){ | |||||
| $('#stop-model-debug-'+jobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||||
| $('#stop-model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ | |||||
| $('#model-delete-'+jobID).removeClass('disabled').addClass('blue') | |||||
| }else{ | |||||
| $('#model-delete-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| dropdownValue = dropdownValue==="CPU%2FGPU"? 'CPU/GPU' : dropdownValue | dropdownValue = dropdownValue==="CPU%2FGPU"? 'CPU/GPU' : dropdownValue | ||||
| $('.default.text').text(dropdownValue) | $('.default.text').text(dropdownValue) | ||||
| @@ -676,9 +515,6 @@ | |||||
| .transition('fade') | .transition('fade') | ||||
| }) | }) | ||||
| }) | }) | ||||
| // 获取弹窗 | // 获取弹窗 | ||||
| var modal = document.getElementById('imageModal'); | var modal = document.getElementById('imageModal'); | ||||
| @@ -708,7 +544,6 @@ | |||||
| modal.style.display = "none"; | modal.style.display = "none"; | ||||
| } | } | ||||
| } | } | ||||
| // 显示弹窗,弹出相应的信息 | // 显示弹窗,弹出相应的信息 | ||||
| function showmask() { | function showmask() { | ||||
| var image_tag = !$('#image_tag').val() | var image_tag = !$('#image_tag').val() | ||||
| @@ -132,7 +132,7 @@ | |||||
| {{end}} --> | {{end}} --> | ||||
| {{if and .Repository.CanEnablePulls (.Permission.CanRead $.UnitTypePullRequests)}} | {{if and .Repository.CanEnablePulls (.Permission.CanRead $.UnitTypePullRequests)}} | ||||
| <a class="{{if .PageIsPullList}}active{{end}} item" href="{{.RepoLink}}/pulls"> | |||||
| <a class="{{if or .PageIsComparePull .PageIsPullList}}active{{end}} item" href="{{.RepoLink}}/pulls"> | |||||
| {{svg "octicon-git-pull-request" 16}} {{.i18n.Tr "repo.pulls"}} <span class="ui {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span> | {{svg "octicon-git-pull-request" 16}} {{.i18n.Tr "repo.pulls"}} <span class="ui {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span> | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -255,9 +255,9 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui six wide tablet four wide computer column"> | <div class="ui six wide tablet four wide computer column"> | ||||
| <div id="repo-desc"> | |||||
| <h4 id="about-desc" class="ui header">简介</h4> | |||||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||||
| <div id="repo-desc" data-IsAdmin= "{{.Permission.IsAdmin}}" data-IsArchived="{{.Repository.IsArchived}}" > | |||||
| <h4 id="about-desc" class="ui header">简介</h4> | |||||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||||
| <p> | <p> | ||||
| {{if .Repository.DescriptionHTML}} | {{if .Repository.DescriptionHTML}} | ||||
| <span class="description" style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | <span class="description" style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | ||||
| @@ -113,11 +113,11 @@ | |||||
| <!-- 模型版本 --> | <!-- 模型版本 --> | ||||
| <!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | <!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | ||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <a id="{{.JobName}}" href="javascript:void(0);" data-variation="inverted" data-position="top center" data-content="{{$.i18n.Tr "repo.modelarts.infer_job.tooltip"}}" onclick="getModelInfo({{.ModelName}},{{.ModelVersion}},{{.JobName}})">{{.ModelName}} </a> <span style="font-size: 12px;">{{.ModelVersion}} </span> | |||||
| <a id="{{.JobName}}" class="goto_modelmanage" href="javascript:void(0);" data-variation="inverted" data-position="top center" data-content="{{$.i18n.Tr "repo.modelarts.infer_job.tooltip"}}" data-jobname={{.JobName}} data-modelname={{.ModelName}} data-version={{.ModelVersion}} data-repopath="{{$.RepoLink}}">{{.ModelName}} </a> <span style="font-size: 12px;">{{.ModelVersion}}</span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center padding0" > | <div class="two wide column text center padding0" > | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job" 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><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> | </span> | ||||
| </div> | </div> | ||||
| @@ -147,11 +147,11 @@ | |||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;" id="{{.JobID}}-stop" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" onclick="stopVersion({{.VersionName}},{{.JobID}})"> | |||||
| <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="{{$.RepoRelPath}}/modelarts/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a style="padding: 0.5rem 1rem;" id="{{.JobID}}-stop" class="ui basic disabled button"> | |||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -174,7 +174,7 @@ | |||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic blue button" onclick="assertDelete(this,{{.VersionName}},{{.JobID}})" style="border-radius: .28571429rem;"> | |||||
| <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;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -221,118 +221,6 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| // 加载任务状态 | |||||
| var timeid = window.setInterval(loadJobStatus, 15000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadJobStatus() { | |||||
| $(".job-status").each((index, job) => { | |||||
| const jobID = job.dataset.jobid | |||||
| const repoPath = job.dataset.repopath | |||||
| const versionname = job.dataset.version | |||||
| const status_text = $(`#${jobID}-text`).text() | |||||
| const finalState = ['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 | |||||
| } | |||||
| $.get(`/api/v1/repos/${repoPath}/modelarts/inference-job/${jobID}?version_name=${versionname}`, (data) => { | |||||
| const jobID = data.JobID | |||||
| const status = data.JobStatus | |||||
| const duration = data.JobDuration | |||||
| $('#duration-'+jobID).text(duration) | |||||
| if (status != job.textContent.trim()) { | |||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| finalState.includes(status) && $('#' + jobID + '-stop').removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| function getModelInfo(ID,version,JobName){ | |||||
| $.get("{{$.RepoLink}}/modelmanage/show_model_info_api?name="+ID,(data)=>{ | |||||
| if(data.length===0){ | |||||
| $(`#${JobName}`).popup('toggle') | |||||
| }else{ | |||||
| let versionData = data.filter((item)=>{ | |||||
| return item.Version === version | |||||
| }) | |||||
| if(versionData.length==0){ | |||||
| $(`#${JobName}`).popup('toggle') | |||||
| } | |||||
| else{ | |||||
| location.href = "{{$.RepoLink}}/modelmanage/show_model_info?name="+ID | |||||
| } | |||||
| } | |||||
| }) | |||||
| } | |||||
| function deleteVersion(version_name,jobID){ | |||||
| const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/inference-job/'+jobID+'/del_version' | |||||
| $.post(url,{version_name:version_name},(data)=>{ | |||||
| if(data.StatusOK===0){ | |||||
| location.reload() | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| function stopVersion(version_name,jobID){ | |||||
| const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/inference-job/'+jobID+'/stop_version' | |||||
| $.post(url,{version_name:version_name},(data)=>{ | |||||
| if(data.StatusOK===0){ | |||||
| $('#'+version_name+'-stop').removeClass('blue') | |||||
| $('#'+version_name+'-stop').addClass('disabled') | |||||
| refreshStatus(version_name,jobID) | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| function refreshStatus(version_name,jobID){ | |||||
| const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/inference-job/'+jobID+'?version_name='+version_name | |||||
| $.get(url,(data)=>{ | |||||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||||
| // detail status and duration | |||||
| $(`#${jobID}-text`).text(data.JobStatus) | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| function assertDelete(obj,version_name,jobID) { | |||||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||||
| return | |||||
| } else { | |||||
| // var delId = obj.parentNode.id | |||||
| flag = 1; | |||||
| $('.ui.basic.modal') | |||||
| .modal({ | |||||
| onDeny: function() { | |||||
| flag = false | |||||
| }, | |||||
| onApprove: function() { | |||||
| // document.getElementById(delId).submit() | |||||
| deleteVersion(version_name,jobID) | |||||
| flag = true | |||||
| }, | |||||
| onHidden: function() { | |||||
| if (flag == false) { | |||||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| } | |||||
| </script> | |||||
| @@ -469,13 +469,13 @@ td, th { | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | <script> | ||||
| console.log({{.task}}) | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| $('.secondary.menu .item').tab(); | $('.secondary.menu .item').tab(); | ||||
| }); | }); | ||||
| let userName | let userName | ||||
| let repoPath | let repoPath | ||||
| let jobID | let jobID | ||||
| let downlaodFlag = {{$.canDownload }} | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| let url = window.location.href; | let url = window.location.href; | ||||
| let urlArr = url.split('/') | let urlArr = url.split('/') | ||||
| @@ -621,7 +621,12 @@ function renderDir(data,version_name){ | |||||
| html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | ||||
| html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | ||||
| }else{ | }else{ | ||||
| html += `<a href="${location.href}/result_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||||
| if(downlaodFlag){ | |||||
| html += `<a href="${location.href}/result_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||||
| } | |||||
| else{ | |||||
| html += `<a class="disabled">` | |||||
| } | |||||
| html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | ||||
| } | } | ||||
| html += '</a>' | html += '</a>' | ||||
| @@ -19,7 +19,7 @@ | |||||
| <div class="repository new repo ui middle very relaxed page grid"> | <div class="repository new repo ui middle very relaxed page grid"> | ||||
| <div class="column"> | <div class="column"> | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="ui positive message" id="messageInfo"> | |||||
| <div class="ui negative message" id="messageInfo"> | |||||
| <p></p> | <p></p> | ||||
| </div> | </div> | ||||
| <form class="ui form" id="form_id" action="{{.Link}}" method="post"> | <form class="ui form" id="form_id" action="{{.Link}}" method="post"> | ||||
| @@ -51,7 +51,16 @@ | |||||
| <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="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | ||||
| </div> | </div> | ||||
| <!-- <div class="inline field"> | |||||
| <div class="inline required field"> | |||||
| <label>镜像</label> | |||||
| <select id="cloudbrain_image" class="ui search dropdown" placeholder="选择镜像" style='width:385px' name="image_id"> | |||||
| {{range .images}} | |||||
| <option name="image_id" value="{{.Id}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="inline field"> | |||||
| <label>数据集</label> | <label>数据集</label> | ||||
| <input type="text" list="cloudbrain_dataset" placeholder="选择数据集" name="" id="answerInput" autofocus maxlength="36"> | <input type="text" list="cloudbrain_dataset" placeholder="选择数据集" name="" id="answerInput" autofocus maxlength="36"> | ||||
| <datalist id="cloudbrain_dataset" class="ui search" style='width:385px' name="attachment"> | <datalist id="cloudbrain_dataset" class="ui search" style='width:385px' name="attachment"> | ||||
| @@ -62,7 +71,7 @@ | |||||
| <input type="hidden" name="attachment" id="answerInput-hidden"> | <input type="hidden" name="attachment" id="answerInput-hidden"> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | |||||
| <!--<div class="inline required field"> | |||||
| <label>工作环境</label> | <label>工作环境</label> | ||||
| <input name="de" id="cloudbrain_de" value="{{.env}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="de" id="cloudbrain_de" value="{{.env}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| @@ -27,7 +27,7 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui green segment"> | <div class="ui green segment"> | ||||
| <p>任务结果:</p> | |||||
| <p>任务详情:</p> | |||||
| {{with .result}} | {{with .result}} | ||||
| <table class="ui celled striped table"> | <table class="ui celled striped table"> | ||||
| <tbody> | <tbody> | ||||
| @@ -35,6 +35,18 @@ | |||||
| <td class="four wide"> 状态 </td> | <td class="four wide"> 状态 </td> | ||||
| <td> {{.Status}} </td> | <td> {{.Status}} </td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td> 描述 </td> | |||||
| <td style="max-width: 480px; word-wrap:break-word">{{$.task.Description}}</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td> 镜像名称 </td> | |||||
| <td>{{$.task.Image}}</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td> 数据集下载地址 </td> | |||||
| <td style="max-width: 480px; word-wrap:break-word">{{$.datasetDownloadLink}}</td> | |||||
| </tr> | |||||
| <tr> | <tr> | ||||
| <td> 开始时间 </td> | <td> 开始时间 </td> | ||||
| <td>{{.CreateTime}}</td> | <td>{{.CreateTime}}</td> | ||||
| @@ -113,7 +113,7 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}/modelarts/train-job" 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><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> | </span> | ||||
| </div> | </div> | ||||
| @@ -143,11 +143,11 @@ | |||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;" id="{{.JobID}}-stop" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" onclick="stopVersion({{.VersionName}},{{.JobID}})"> | |||||
| <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="{{$.RepoRelPath}}/modelarts/train-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a style="padding: 0.5rem 1rem;" id="{{.JobID}}-stop" class="ui basic disabled button"> | |||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -157,7 +157,7 @@ | |||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic blue button" onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||||
| <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;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -204,162 +204,5 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| console.log({{.Tasks}}) | |||||
| // 调试和评分新开窗口 | |||||
| function stop(obj) { | |||||
| if (obj.style.color != "rgb(204, 204, 204)") { | |||||
| obj.target = '_blank' | |||||
| } else { | |||||
| return | |||||
| } | |||||
| } | |||||
| // 删除时用户确认 | |||||
| function assertDelete(obj) { | |||||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||||
| return | |||||
| } else { | |||||
| var delId = obj.parentNode.id | |||||
| flag = 1; | |||||
| $('.ui.basic.modal') | |||||
| .modal({ | |||||
| onDeny: function() { | |||||
| flag = false | |||||
| }, | |||||
| onApprove: function() { | |||||
| document.getElementById(delId).submit() | |||||
| flag = true | |||||
| }, | |||||
| onHidden: function() { | |||||
| if (flag == false) { | |||||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| } | |||||
| function runtime(time){ | |||||
| if(time){ | |||||
| let hours = time/3600000<10 ? "0"+parseInt(time/3600000):parseInt(time/3600000) | |||||
| let miuns = time%3600000/60000<10 ? "0"+parseInt(time%3600000/60000):parseInt(time%3600000/60000) | |||||
| let seconds = time%60000/1000<10 ? "0"+parseInt(time%60000/1000):parseInt(time%60000/1000) | |||||
| return hours + ":" + miuns + ":" + seconds | |||||
| }else{ | |||||
| return "00:00:00" | |||||
| } | |||||
| } | |||||
| // 加载任务状态 | |||||
| var timeid = window.setInterval(loadJobStatus, 15000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadJobStatus() { | |||||
| $(".job-status").each((index, job) => { | |||||
| const jobID = job.dataset.jobid | |||||
| const repoPath = job.dataset.repopath | |||||
| const versionname = job.dataset.version | |||||
| const status_text = $(`#${jobID}-text`).text() | |||||
| const finalState = ['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 | |||||
| } | |||||
| $.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => { | |||||
| const jobID = data.JobID | |||||
| const status = data.JobStatus | |||||
| const duration = data.JobDuration | |||||
| $('#duration-'+jobID).text(duration) | |||||
| if (status != job.textContent.trim()) { | |||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| finalState.includes(status) && $('#' + jobID + '-stop').removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| // 获取弹窗 | |||||
| var modal = document.getElementById('imageModal'); | |||||
| // 打开弹窗的按钮对象 | |||||
| var btns = document.getElementsByClassName("imageBtn"); | |||||
| // 获取 <span> 元素,用于关闭弹窗 | |||||
| var spans = document.getElementsByClassName('close'); | |||||
| // 点击按钮打开弹窗 | |||||
| for (i = 0; i < btns.length; i++) { | |||||
| btns[i].onclick = function() { | |||||
| modal.style.display = "block"; | |||||
| } | |||||
| } | |||||
| // 点击 <span> (x), 关闭弹窗 | |||||
| for (i = 0; i < spans.length; i++) { | |||||
| spans[i].onclick = function() { | |||||
| modal.style.display = "none"; | |||||
| } | |||||
| } | |||||
| // 在用户点击其他地方时,关闭弹窗 | |||||
| window.onclick = function(event) { | |||||
| if (event.target == modal) { | |||||
| modal.style.display = "none"; | |||||
| } | |||||
| } | |||||
| function stopVersion(version_name,jobID){ | |||||
| const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/train-job/'+jobID+'/stop_version' | |||||
| $.post(url,{version_name:version_name},(data)=>{ | |||||
| if(data.StatusOK===0){ | |||||
| $('#'+version_name+'-stop').removeClass('blue') | |||||
| $('#'+version_name+'-stop').addClass('disabled') | |||||
| refreshStatus(version_name,jobID) | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| function refreshStatus(version_name,jobID){ | |||||
| const url = '/api/v1/repos/{{$.RepoRelPath}}/modelarts/train-job/'+jobID+'?version_name='+version_name | |||||
| $.get(url,(data)=>{ | |||||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||||
| // detail status and duration | |||||
| $(`#${jobID}-text`).text(data.JobStatus) | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| // 显示弹窗,弹出相应的信息 | |||||
| function showmask() { | |||||
| $('#imageModal').css('display', 'none') | |||||
| $('#mask').css('display', 'block') | |||||
| $("iframe[name=iframeContent]").on("load", function() { | |||||
| var responseText = $("iframe")[0].contentDocument.body.getElementsByTagName("pre")[0].innerHTML; | |||||
| var json1 = JSON.parse(responseText) | |||||
| $('#mask').css('display', 'none') | |||||
| parent.location.href | |||||
| if (json1.result_code === "0") { | |||||
| $('.alert').html('操作成功!').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut(); | |||||
| } else { | |||||
| $('.alert').html(json1.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(5000).fadeOut(); | |||||
| } | |||||
| }) | |||||
| } | |||||
| </script> | |||||
| {{template "base/footer" .}} | |||||
| @@ -518,6 +518,7 @@ td, th { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | <script> | ||||
| @@ -532,6 +533,7 @@ td, th { | |||||
| let userName | let userName | ||||
| let repoPath | let repoPath | ||||
| let jobID | let jobID | ||||
| let downlaodFlag = {{$.canDownload }} | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| let url = window.location.href; | let url = window.location.href; | ||||
| let urlArr = url.split('/') | let urlArr = url.split('/') | ||||
| @@ -784,7 +786,12 @@ td, th { | |||||
| html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | ||||
| html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | ||||
| }else{ | }else{ | ||||
| html += `<a href="${location.href}/model_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||||
| if(downlaodFlag){ | |||||
| html += `<a href="${location.href}/model_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||||
| } | |||||
| else{ | |||||
| html += `<a class="disabled">` | |||||
| } | |||||
| html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | ||||
| } | } | ||||
| html += '</a>' | html += '</a>' | ||||
| @@ -186,7 +186,6 @@ | |||||
| <div class='ui breadcrumb model_file_bread' id='file_breadcrumb'> | <div class='ui breadcrumb model_file_bread' id='file_breadcrumb'> | ||||
| <div class="active section"></div> | <div class="active section"></div> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| </div> | </div> | ||||
| <div id="dir_list"> | <div id="dir_list"> | ||||
| @@ -52,6 +52,4 @@ | |||||
| </div> | </div> | ||||
| <script> | |||||
| console.log({{$.Err_Alias}}) | |||||
| </script> | |||||
| @@ -0,0 +1,70 @@ | |||||
| {{template "base/head_home" .}} | |||||
| <div class="ui container"> | |||||
| <h1 class="ui center am-pt-30 am-pb-20">OpenI启智社区AI协作平台使用协议</h1> | |||||
| <div class="ui divider am-pb-10"></div> | |||||
| <p> | |||||
| OpenI启智社区AI协作平台作为新一代人工智能领域开源开放开发协作平台,不仅为用户提供代码托管与数据集管理等服务,同时提供开发者所需的计算算力资源,一个良好的开发环境对用户、组织和项目都尤为重要。 | |||||
| </p> | |||||
| <p> | |||||
| 为了保障用户权益,维护平台正常秩序,实现平台规范化运营,给开发者提供一个良好的开发环境,您不得在本平台进行恶意攻击、挖矿等任何违法或扰乱平台秩序的行为。<strong>一经发现,平台有权变更、暂停或终止您对平台服务的使用而无须事先声明,包括但不限于限制您使用平台服务的次数与资源、账号永久封闭等。</strong> | |||||
| </p> | |||||
| <h2> | |||||
| AI协作平台使用协议及违规处罚 | |||||
| </h2> | |||||
| <p> | |||||
| 1. 您需保证对平台服务的使用不违反国家各项法律法规的规定,且不侵害任何第三方权益,如因此造成任何后果及损失,由您自行承担全部责任。 | |||||
| </p> | |||||
| <p> | |||||
| <strong>2. 禁止行为</strong> | |||||
| </p> | |||||
| <p> | |||||
| 您充分理解并同意,您在使用平台服务时,应当遵守所有中华人民共和国的法律、法规、规章制度、规范、政策、行政命令、强制标准及行业标准等(统称为“法律法规”)。除非法律法规允许且启智社区事先书面许可,您不得从事以下活动,也不得同意、授权或指示任何第三人从事包括但不限于以下内容的活动: | |||||
| <br> | |||||
| (1) 对平台服务进行挖矿、逆向工程、反编辑等恶意行为损坏平台服务相关内容与数据,或不正当手段获取原始数据和其他数据等;<br> | |||||
| (2) 对平台服务或者平台服务运行过程中释放出的任何数据或其他数据及平台服务运行过程中的交互数据进行复制、更改、修改等操作,包括但不限于使用插件、外挂或非经授权的第三方工具或服务接入平台服务和相关系统; | |||||
| <br> | |||||
| (3) 宣扬或提供关于非法行为的说明信息、宣扬针对任何团体或个人的人身伤害或传播任何病毒、蠕虫、缺陷、特洛伊木马或其他具有破坏性的内容等;<br> | |||||
| (4) 删除本平台服务中包含的任何版权声明、商标声明或其他所有权声明;包括但不限于任何有损本平台一切相关知识产权的行为;<br> | |||||
| (5) 创造任何网站或应用程序以重现或复制平台服务或本平台。 | |||||
| </p> | |||||
| <p> | |||||
| <strong>3. 遵守法律规范</strong> | |||||
| </p> | |||||
| <p> | |||||
| 您不得利用平台服务上传、上载、发布、发表、传播任何违法内容,包括但不限于您制作、复制、发布、传播下列信息: | |||||
| </p> | |||||
| <p> | |||||
| (1)煽动抗拒、破坏宪法和法律、行政法规实施<br> | |||||
| (2)煽动颠覆国家政权,推翻社会主义制度<br> | |||||
| (3)煽动分裂国家、破坏国家统一<br> | |||||
| (4)煽动民族仇恨、民族歧视、破坏民族团结<br> | |||||
| (5)捏造或者歪曲事实、散布谣言,扰乱社会秩序<br> | |||||
| (6)宣扬封建迷信、淫秽、色情、赌博、暴力、教唆犯罪<br> | |||||
| (7)公然侮辱他人或者捏造事实诽谤他人<br> | |||||
| (8)损害国家机关信誉或有损国家领导人荣誉<br> | |||||
| (9)其他违反宪法和法律、行政法规<br> | |||||
| (10)含有虚假、有害、胁迫、侵害他人隐私、骚扰、侵害、中伤、粗俗、猥亵或其他道德上令人反感的内容<br> | |||||
| (11)含有中国法律、法规、规章、条例以及任何具有法律效力之规范所限制或禁止的其他内容 | |||||
| </p> | |||||
| <p> | |||||
| 一经发现,平台将按照国家有关规定,及时删除网站中含有上述内容的地址、目录,并保留原始记录,在二十四小时之内向公安机关报告。 | |||||
| </p> | |||||
| <p> | |||||
| <strong>4. 保障网络信息安全</strong> | |||||
| </p> | |||||
| <p> | |||||
| 您不得利用平台服务从事以下危害计算机网络信息安全的活动:<br> | |||||
| (1) 未经允许,进入计算机信息网络或者使用计算机信息网络资源的;<br> | |||||
| (2) 未经允许,对计算机信息网络功能进行删除、修改或者增加的;<br> | |||||
| (3) 未经允许,对进入计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加的;<br> | |||||
| (4) 故意制作、传播计算机病毒等破坏性程序的;<br> | |||||
| (5) 其他危害计算机信息网络安全的行为。 | |||||
| </p> | |||||
| <p> | |||||
| 5. 您充分理解并同意,您对自己使用平台服务的一切行为及由此产生的一切结果负责,包括但不限于您所发表的任何内容、提供的任何服务以及由此产生的任何后果。您应对平台服务的内容应自行判断并决定是否使用,并承担因使用平台服务及其相关内容而引起的所有风险,包括因对平台服务及其内容的真实性、完整性、准确性、及时性及实用性的依赖而产生的风险。平台不对此提供任何担保和保证,不对因前述风险而导致的任何后果或损失对您承担责任。 | |||||
| </p> | |||||
| <p> | |||||
| <strong>如果您违反了法律法规或本协议,OpenI启智社区有权依据合理判断对违反法律法规或本协议的行为作出处理,并保留对该违反行为采取法律所能提供的所有补救手段的权利。OpenI启智社区有权对违反法律法规及本协议的任何用户调查并采取适当的法律行动,包括但不限于民事诉讼等。OpenI启智社区有权根据违法违规行为的严重程度,将上述违法违规行为的线索和您的个人信息报告司法机关或其他执法机关,并配合司法机关或其他执法机关进行的调查、听证、起诉等。您应当自行承担由此产生的任何法律责任。</strong> | |||||
| </p> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -69,7 +69,21 @@ | |||||
| {{$.i18n.Tr "action.reject_pull_request" .GetRepoLink $index .ShortRepoFullDisplayName | Str2html}} | {{$.i18n.Tr "action.reject_pull_request" .GetRepoLink $index .ShortRepoFullDisplayName | Str2html}} | ||||
| {{else if eq .GetOpType 23}} | {{else if eq .GetOpType 23}} | ||||
| {{ $index := index .GetIssueInfos 0}} | {{ $index := index .GetIssueInfos 0}} | ||||
| {{$.i18n.Tr "action.comment_pull" .GetRepoLink $index .ShortRepoFullDisplayName | Str2html}} | |||||
| {{$.i18n.Tr "action.comment_pull" .GetRepoLink $index .ShortRepoPath | Str2html}} | |||||
| {{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}} | |||||
| {{else if eq .GetOpType 26}} | |||||
| {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{else if eq .GetOpType 27}} | |||||
| {{$.i18n.Tr "action.task_trainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{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}} | |||||
| {{else if eq .GetOpType 30}} | |||||
| {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | |||||
| {{end}} | {{end}} | ||||
| </p> | </p> | ||||
| {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | ||||
| @@ -101,7 +115,23 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui two wide right aligned column"> | <div class="ui two wide right aligned column"> | ||||
| <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | |||||
| {{if eq .GetOpType 24}} | |||||
| <span class="text grey"><i class="ri-uninstall-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 25}} | |||||
| <span class="text grey"><i class="ri-voice-recognition-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 26}} | |||||
| <span class="text grey"><i class="ri-voice-recognition-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 27}} | |||||
| <span class="text grey"><i class="ri-character-recognition-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 28}} | |||||
| <span class="text grey"><i class="ri-haze-2-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 29}} | |||||
| <span class="text grey"><i class="ri-vip-crown-line icon big"></i></span> | |||||
| {{else if eq .GetOpType 30}} | |||||
| <span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | |||||
| {{else}} | |||||
| <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -208,6 +208,3 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| console.log({{.Issues}}) | |||||
| </script> | |||||
| @@ -117,6 +117,3 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| console.log({{.Milestones}}) | |||||
| </script> | |||||
| @@ -141,6 +141,7 @@ | |||||
| {{if eq .TabName "activity"}} | {{if eq .TabName "activity"}} | ||||
| {{if .EnableHeatmap}} | {{if .EnableHeatmap}} | ||||
| <div id="user-heatmap" style="padding-right: 40px"> | <div id="user-heatmap" style="padding-right: 40px"> | ||||
| <activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser"> | <activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser"> | ||||
| <div slot="loading"> | <div slot="loading"> | ||||
| @@ -1,7 +1,7 @@ | |||||
| <template> | <template> | ||||
| <div> | <div> | ||||
| <h4 id="about-desc" class="ui header desc-home">简介 | <h4 id="about-desc" class="ui header desc-home">简介 | ||||
| <a class="edit-icon" href="javascript:void(0)" @click="editClick"> | |||||
| <a class="edit-icon" v-if="IsPermit" id ="editBtn" href="javascript:void(0)" @click="editClick" > | |||||
| <i class="gray edit outline icon" style="margin-right: 0;"></i> | <i class="gray edit outline icon" style="margin-right: 0;"></i> | ||||
| </a> | </a> | ||||
| </h4> | </h4> | ||||
| @@ -52,7 +52,8 @@ export default { | |||||
| desc: '', | desc: '', | ||||
| index_web: '', | index_web: '', | ||||
| repo_name_name: '', | repo_name_name: '', | ||||
| alias:'' | |||||
| alias:'', | |||||
| IsPermit:false | |||||
| }, | }, | ||||
| // rule1:[{min:3,max:5,message:'1',trigger:"blur"}], | // rule1:[{min:3,max:5,message:'1',trigger:"blur"}], | ||||
| rule: { | rule: { | ||||
| @@ -63,8 +64,18 @@ export default { | |||||
| }; | }; | ||||
| }, | }, | ||||
| methods: { | methods: { | ||||
| getIsSigned(){ | |||||
| var isadmin= document.getElementById("repo-desc").dataset.isadmin; | |||||
| var isarchived=document.getElementById("repo-desc").dataset.isarchived; | |||||
| // console.log("IsSigned:",this.IsSigned) | |||||
| if ((isadmin==true || isadmin=="true")&& (isarchived==false || isarchived=="false")){ | |||||
| this.IsPermit=true; | |||||
| } | |||||
| }, | |||||
| editClick() { | editClick() { | ||||
| this.editDataDialog = true; | |||||
| if (this.IsPermit){ | |||||
| this.editDataDialog = true; | |||||
| } | |||||
| }, | }, | ||||
| getDesc() { | getDesc() { | ||||
| const el = $('span.description').text(); | const el = $('span.description').text(); | ||||
| @@ -121,6 +132,7 @@ export default { | |||||
| } | } | ||||
| }, | }, | ||||
| mounted() { | mounted() { | ||||
| this.getIsSigned(); | |||||
| this.getUrl(); | this.getUrl(); | ||||
| this.getRepoName(); | this.getRepoName(); | ||||
| this.getDesc(); | this.getDesc(); | ||||
| @@ -135,7 +147,7 @@ export default { | |||||
| } | } | ||||
| }, | }, | ||||
| created() { | created() { | ||||
| this.getIsSigned(); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -310,7 +310,6 @@ export default { | |||||
| }, | }, | ||||
| handleCurrentChange(val){ | handleCurrentChange(val){ | ||||
| console.log(val) | |||||
| this.params.page = val | this.params.page = val | ||||
| this.getImageList() | this.getImageList() | ||||
| @@ -350,7 +349,6 @@ export default { | |||||
| }) | }) | ||||
| }, | }, | ||||
| copyUrl(url){ | copyUrl(url){ | ||||
| console.log(url) | |||||
| const cInput = document.createElement('input') | const cInput = document.createElement('input') | ||||
| cInput.value = url | cInput.value = url | ||||
| document.body.appendChild(cInput) | document.body.appendChild(cInput) | ||||
| @@ -380,16 +378,13 @@ export default { | |||||
| clearP(value){ | clearP(value){ | ||||
| console.log("sorce value",value) | |||||
| if(!value) return '' | if(!value) return '' | ||||
| const reg = /\<\/?p\>/g; | const reg = /\<\/?p\>/g; | ||||
| value = value.replace(reg,'') | value = value.replace(reg,'') | ||||
| console.log("repalace:",value) | |||||
| return value | return value | ||||
| }, | }, | ||||
| transformTimestamp(timestamp){ | transformTimestamp(timestamp){ | ||||
| console.log("timestamp",timestamp) | |||||
| let a = new Date(timestamp).getTime(); | let a = new Date(timestamp).getTime(); | ||||
| const date = new Date(a); | const date = new Date(a); | ||||
| const Y = date.getFullYear() + '-'; | const Y = date.getFullYear() + '-'; | ||||
| @@ -81,7 +81,7 @@ export default { | |||||
| dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'), | dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'), | ||||
| dictFileTooBig: this.dropzoneParams.data('file-too-big'), | dictFileTooBig: this.dropzoneParams.data('file-too-big'), | ||||
| dictRemoveFile: this.dropzoneParams.data('remove-file'), | dictRemoveFile: this.dropzoneParams.data('remove-file'), | ||||
| previewTemplate | |||||
| // previewTemplate | |||||
| }); | }); | ||||
| dropzoneUploader.on('addedfile', (file) => { | dropzoneUploader.on('addedfile', (file) => { | ||||
| setTimeout(() => { | setTimeout(() => { | ||||
| @@ -82,7 +82,7 @@ export default { | |||||
| dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'), | dictInvalidFileType: this.dropzoneParams.data('invalid-input-type'), | ||||
| dictFileTooBig: this.dropzoneParams.data('file-too-big'), | dictFileTooBig: this.dropzoneParams.data('file-too-big'), | ||||
| dictRemoveFile: this.dropzoneParams.data('remove-file'), | dictRemoveFile: this.dropzoneParams.data('remove-file'), | ||||
| previewTemplate | |||||
| // previewTemplate | |||||
| }); | }); | ||||
| dropzoneUploader.on('addedfile', (file) => { | dropzoneUploader.on('addedfile', (file) => { | ||||
| setTimeout(() => { | setTimeout(() => { | ||||
| @@ -58,15 +58,22 @@ | |||||
| stripe | stripe | ||||
| > | > | ||||
| </el-table-column> | </el-table-column> | ||||
| <el-table-column | |||||
| label="项目名称中文" | |||||
| align="left" | |||||
| prop="name" | |||||
| v-if='0' | |||||
| > | |||||
| </el-table-column> | |||||
| <el-table-column | <el-table-column | ||||
| label="项目名称" | label="项目名称" | ||||
| width="125px" | width="125px" | ||||
| align="left" | align="left" | ||||
| prop="name" | |||||
| prop="alias" | |||||
| style="color:#0366D6;font-family: Roboto" | style="color:#0366D6;font-family: Roboto" | ||||
| > | > | ||||
| <template slot-scope="scope"> | <template slot-scope="scope"> | ||||
| <a @click=goToDetailPage(scope.row.repo_id,scope.row.name,scope.row.ownerName)>{{scope.row.name}} </a> | |||||
| <a @click=goToDetailPage(scope.row.repo_id,scope.row.name,scope.row.ownerName,scope.row.alias)>{{scope.row.alias}} </a> | |||||
| </template> | </template> | ||||
| </el-table-column> | </el-table-column> | ||||
| <el-table-column | <el-table-column | ||||
| @@ -160,7 +167,7 @@ | |||||
| </div> | </div> | ||||
| <div id ="pro_detail" style="display:none;width: 100%;"> | <div id ="pro_detail" style="display:none;width: 100%;"> | ||||
| <div style="margin-top: 10px;"> | <div style="margin-top: 10px;"> | ||||
| <a class="pro_item" :href="'../../../'+this.ownerName+'/'+this.pro_name">{{this.ownerName}} / {{this.pro_name}}</a> <span class="update_time">数据更新时间:</span><span style="font-size: 12px;">{{tableDataIDTotal.lastUpdatedTime}} / 从{{tableDataIDTotal.recordBeginTime}}开始统计</span> | |||||
| <a class="pro_item" :href="'../../../'+this.ownerName+'/'+this.pro_name">{{this.ownerName}} / {{this.alias}}</a> <span class="update_time">数据更新时间:</span><span style="font-size: 12px;">{{tableDataIDTotal.lastUpdatedTime}} / 从{{tableDataIDTotal.recordBeginTime}}开始统计</span> | |||||
| </div> | </div> | ||||
| <div style="margin-top: 10px;"> | <div style="margin-top: 10px;"> | ||||
| 项目描述:{{tableDataIDTotal.description | discriptionFun}} | 项目描述:{{tableDataIDTotal.description | discriptionFun}} | ||||
| @@ -388,6 +395,7 @@ | |||||
| create_time_pro: '', | create_time_pro: '', | ||||
| dynamic_pro:7, | dynamic_pro:7, | ||||
| pro_name:'', | pro_name:'', | ||||
| alias:'', | |||||
| pro_id:'', | pro_id:'', | ||||
| ownerName:'', | ownerName:'', | ||||
| radarOpenI:'', | radarOpenI:'', | ||||
| @@ -445,7 +453,7 @@ | |||||
| startDate = this.comparedate(tmp,this.recordBeginTime) | startDate = this.comparedate(tmp,this.recordBeginTime) | ||||
| console.log("comparedate:"+startDate) | console.log("comparedate:"+startDate) | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+endDate | |||||
| }else{ | }else{ | ||||
| switch(this.paramsID.type){ | switch(this.paramsID.type){ | ||||
| case "yesterday":{ | case "yesterday":{ | ||||
| @@ -453,7 +461,7 @@ | |||||
| startDate = this.comparedate(yesterday_tmp,this.recordBeginTime) | startDate = this.comparedate(yesterday_tmp,this.recordBeginTime) | ||||
| endDate = startDate | endDate = startDate | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "current_week":{ | case "current_week":{ | ||||
| @@ -465,7 +473,7 @@ | |||||
| endDate = yesterday | endDate = yesterday | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "current_month":{ | case "current_month":{ | ||||
| @@ -475,7 +483,7 @@ | |||||
| endDate = yesterday | endDate = yesterday | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "last_month":{ | case "last_month":{ | ||||
| @@ -495,7 +503,7 @@ | |||||
| var days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24) | var days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24) | ||||
| endDate=this.saveFormatDate(lastYear, lastMonth+1, days); //月份从0开始,所以+1保存月份 | endDate=this.saveFormatDate(lastYear, lastMonth+1, days); //月份从0开始,所以+1保存月份 | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "monthly":{ | case "monthly":{ | ||||
| @@ -504,7 +512,7 @@ | |||||
| startDate = this.comparedate(startDate,this.recordBeginTime) | startDate = this.comparedate(startDate,this.recordBeginTime) | ||||
| endDate = yesterday | endDate = yesterday | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "current_year":{ | case "current_year":{ | ||||
| @@ -512,14 +520,14 @@ | |||||
| startDate = this.comparedate(startDate,this.recordBeginTime) | startDate = this.comparedate(startDate,this.recordBeginTime) | ||||
| endDate = yesterday | endDate = yesterday | ||||
| saveFileName = this.pro_name+"_"+startDate+'_'+ endDate | |||||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||||
| break | break | ||||
| } | } | ||||
| case "all":{ | case "all":{ | ||||
| console.log("e:"+today) | console.log("e:"+today) | ||||
| startDate = 'all' | startDate = 'all' | ||||
| endDate = yesterday | endDate = yesterday | ||||
| saveFileName = this.pro_name+'_所有' | |||||
| saveFileName = this.alias+'_所有' | |||||
| break | break | ||||
| } | } | ||||
| } | } | ||||
| @@ -641,7 +649,7 @@ | |||||
| this.tableData = res.data.pageRecords | this.tableData = res.data.pageRecords | ||||
| this.totalPage=res.data.totalPage | this.totalPage=res.data.totalPage | ||||
| this.totalNum = res.data.totalCount//this.totalPage*this.params.pagesize | this.totalNum = res.data.totalCount//this.totalPage*this.params.pagesize | ||||
| console.log("this.totalPage:"+this.totalPage) | |||||
| // console.log("this.totalPage:"+this.totalPage) | |||||
| }) | }) | ||||
| }, | }, | ||||
| @@ -652,13 +660,14 @@ | |||||
| this.getAllProList(this.params.type, this.dynamic) | this.getAllProList(this.params.type, this.dynamic) | ||||
| }, | }, | ||||
| goToDetailPage(pro_id,pro_name,ownerName){ | |||||
| goToDetailPage(pro_id,pro_name,ownerName,alias){ | |||||
| this.currentPage=1 | this.currentPage=1 | ||||
| document.getElementById("pro_main").style.display="none"; | document.getElementById("pro_main").style.display="none"; | ||||
| document.getElementById("pro_detail").style.display="block"; | document.getElementById("pro_detail").style.display="block"; | ||||
| console.log(pro_id) | |||||
| console.log(pro_name) | |||||
| // console.log(pro_id) | |||||
| // console.log(pro_name) | |||||
| this.pro_name=pro_name; | this.pro_name=pro_name; | ||||
| this.alias=alias; | |||||
| this.pro_id=pro_id; | this.pro_id=pro_id; | ||||
| this.ownerName=ownerName | this.ownerName=ownerName | ||||
| this.getOneProData(pro_id); | this.getOneProData(pro_id); | ||||
| @@ -200,7 +200,6 @@ | |||||
| var saveFileName='' | var saveFileName='' | ||||
| var Date=(this.params.startDate).split('-') | var Date=(this.params.startDate).split('-') | ||||
| var startDate=Date[0]+''+Date[1]+''+Date[2] | var startDate=Date[0]+''+Date[1]+''+Date[2] | ||||
| console.log(startDate) | |||||
| Date=(this.params.endDate).split('-') | Date=(this.params.endDate).split('-') | ||||
| var endDate=Date[0]+Date[1]+Date[2] | var endDate=Date[0]+Date[1]+Date[2] | ||||
| saveFileName = '用户分析_'+this.search+''+startDate+'_'+endDate | saveFileName = '用户分析_'+this.search+''+startDate+'_'+endDate | ||||
| @@ -258,7 +257,6 @@ | |||||
| getUserList(type_val,index){ | getUserList(type_val,index){ | ||||
| this.type_val = type_val | this.type_val = type_val | ||||
| this.dynamic = index; | this.dynamic = index; | ||||
| console.log("dj:"+type_val) | |||||
| var now = new Date(); // 当前日期 | var now = new Date(); // 当前日期 | ||||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | ||||
| var nowDay = now.getDate(); // 当前日 | var nowDay = now.getDate(); // 当前日 | ||||
| @@ -324,7 +322,6 @@ | |||||
| // console.log("res.data:"+res.data.data) | // console.log("res.data:"+res.data.data) | ||||
| this.totalNum = res.data.count | this.totalNum = res.data.count | ||||
| console.log("res.count:"+res.data.count) | |||||
| }) | }) | ||||
| @@ -354,9 +351,7 @@ | |||||
| }, | }, | ||||
| filters:{ | filters:{ | ||||
| transformTimestamp(timestamp){ | transformTimestamp(timestamp){ | ||||
| console.log("timestamp",timestamp) | |||||
| let a = new Date(timestamp*1000); | let a = new Date(timestamp*1000); | ||||
| const date = new Date(a); | const date = new Date(a); | ||||
| const Y = date.getFullYear() + '/'; | const Y = date.getFullYear() + '/'; | ||||
| @@ -366,7 +361,6 @@ | |||||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes());// + ':' ; | const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes());// + ':' ; | ||||
| // const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | // const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | ||||
| const dateString = Y + M + D + h + m ;//+ s; | const dateString = Y + M + D + h + m ;//+ s; | ||||
| console.log('dateString', dateString); // > dateString 2021-07-06 14:23 | |||||
| return dateString; | return dateString; | ||||
| }, | }, | ||||
| }, | }, | ||||
| @@ -100,7 +100,6 @@ export function export_table_to_excel(id) { | |||||
| /* original data */ | /* original data */ | ||||
| var data = oo[0]; | var data = oo[0]; | ||||
| var ws_name = "SheetJS"; | var ws_name = "SheetJS"; | ||||
| console.log(data); | |||||
| var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); | var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); | ||||
| @@ -118,7 +117,7 @@ export function export_table_to_excel(id) { | |||||
| } | } | ||||
| function formatJson(jsonData) { | function formatJson(jsonData) { | ||||
| console.log(jsonData) | |||||
| } | } | ||||
| export function export_json_to_excel(th, jsonData, defaultTitle) { | export function export_json_to_excel(th, jsonData, defaultTitle) { | ||||
| @@ -3,7 +3,6 @@ export function export2Excel(columns,list,filename){ | |||||
| const { export_json_to_excel } = require('./Export2Excel'); | const { export_json_to_excel } = require('./Export2Excel'); | ||||
| let tHeader = [] | let tHeader = [] | ||||
| let filterVal = [] | let filterVal = [] | ||||
| console.log(columns) | |||||
| if(!columns){ | if(!columns){ | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -0,0 +1,238 @@ | |||||
| export default async function initCloudrain() { | |||||
| let timeid = window.setInterval(loadJobStatus, 15000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadJobStatus() { | |||||
| $(".job-status").each((index, job) => { | |||||
| const jobID = 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 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 | |||||
| const status = data.JobStatus | |||||
| const duration = data.JobDuration | |||||
| $('#duration-'+jobID).text(duration) | |||||
| if (status != status_text) { | |||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| finalState.includes(status) && $('#' + jobID + '-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') | |||||
| } | |||||
| if(status!=="RUNNING"){ | |||||
| // $('#model-debug-'+jobID).removeClass('blue') | |||||
| // $('#model-debug-'+jobID).addClass('disabled') | |||||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||||
| $('#ai-debug-'+jobID).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") | |||||
| } | |||||
| if(["RUNNING","WAITING"].includes(status)){ | |||||
| $('#ai-stop-'+jobID).removeClass('disabled').addClass('blue') | |||||
| } | |||||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||||
| $('#ai-stop-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(status)){ | |||||
| $('#ai-delete-'+jobID).removeClass('disabled').addClass('blue') | |||||
| }else{ | |||||
| $('#ai-delete-'+jobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| function assertDelete(obj,versionName,repoPath) { | |||||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||||
| return | |||||
| } else { | |||||
| const delId = obj.parentNode.id | |||||
| let flag = 1; | |||||
| $('.ui.basic.modal') | |||||
| .modal({ | |||||
| onDeny: function() { | |||||
| flag = false | |||||
| }, | |||||
| onApprove: function() { | |||||
| if(!versionName){ | |||||
| document.getElementById(delId).submit() | |||||
| } | |||||
| else{ | |||||
| deleteVersion(versionName,repoPath) | |||||
| } | |||||
| flag = true | |||||
| }, | |||||
| onHidden: function() { | |||||
| if (flag == false) { | |||||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| } | |||||
| function deleteVersion(versionName,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}` | |||||
| $.post(url,{version_name:versionName},(data)=>{ | |||||
| if(data.StatusOK===0){ | |||||
| location.reload() | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| $('.ui.basic.ai_delete').click(function() { | |||||
| const repoPath = this.dataset.repopath | |||||
| const versionName = this.dataset.version | |||||
| if(repoPath && versionName){ | |||||
| assertDelete(this,versionName,repoPath) | |||||
| } | |||||
| else{ | |||||
| assertDelete(this) | |||||
| } | |||||
| }) | |||||
| function stopDebug(JobID,stopUrl){ | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:stopUrl, | |||||
| data:$('#stopForm-'+JobID).serialize(), | |||||
| success:function(res){ | |||||
| if(res.result_code==="0"){ | |||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-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') | |||||
| } | |||||
| else{ | |||||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||||
| } | |||||
| }else{ | |||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||||
| } | |||||
| }, | |||||
| error :function(res){ | |||||
| console.log(res) | |||||
| } | |||||
| }) | |||||
| } | |||||
| $('.ui.basic.ai_stop').click(function() { | |||||
| const jobID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | |||||
| stopDebug(jobID,repoPath) | |||||
| }) | |||||
| function stopVersion(version_name,jobID,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}/${jobID}/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) | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| function refreshStatus(version_name,jobID,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}/${jobID}/?version_name${version_name}` | |||||
| $.get(url,(data)=>{ | |||||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||||
| // detail status and duration | |||||
| $(`#${jobID}-text`).text(data.JobStatus) | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| } | |||||
| $('.ui.basic.ai_stop_version').click(function() { | |||||
| const jobID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | |||||
| const versionName = this.dataset.version | |||||
| stopVersion(versionName,jobID,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') | |||||
| }else{ | |||||
| let versionData = data.filter((item)=>{ | |||||
| return item.Version === versionName | |||||
| }) | |||||
| if(versionData.length==0){ | |||||
| $(`#${jobName}`).popup('toggle') | |||||
| } | |||||
| else{ | |||||
| location.href = `${repoPath}/modelmanage/show_model_info?name=${modelName}` | |||||
| } | |||||
| } | |||||
| }) | |||||
| } | |||||
| $('.goto_modelmanage').click(function() { | |||||
| const repoPath = this.dataset.repopath | |||||
| const modelName = this.dataset.modelname | |||||
| const versionName = this.dataset.version | |||||
| const jobName = this.dataset.jobname | |||||
| getModelInfo(repoPath,modelName,versionName,jobName) | |||||
| }) | |||||
| function debugAgain(JobID,debugUrl,redirect_to){ | |||||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||||
| window.open(debugUrl+'debug') | |||||
| }else{ | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:debugUrl+'restart?redirect_to='+redirect_to, | |||||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||||
| success:function(res){ | |||||
| if(res['WechatRedirectUrl']){ | |||||
| window.location.href=res['WechatRedirectUrl'] | |||||
| } | |||||
| if(res.result_code==="0"){ | |||||
| if(res.job_id!==JobID){ | |||||
| 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") | |||||
| } | |||||
| }else{ | |||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||||
| } | |||||
| }, | |||||
| error :function(res){ | |||||
| console.log(res) | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| $('.ui.basic.ai_debug').click(function() { | |||||
| const jobID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | |||||
| const redirect_to = this.dataset.linkpath | |||||
| debugAgain(jobID,repoPath,redirect_to) | |||||
| }) | |||||
| } | |||||
| @@ -42,6 +42,7 @@ import DataAnalysis from './components/DataAnalysis.vue' | |||||
| import Contributors from './components/Contributors.vue' | import Contributors from './components/Contributors.vue' | ||||
| import Model from './components/Model.vue'; | import Model from './components/Model.vue'; | ||||
| import WxAutorize from './components/WxAutorize.vue' | import WxAutorize from './components/WxAutorize.vue' | ||||
| import initCloudrain from './features/cloudrbanin.js' | |||||
| Vue.use(ElementUI); | Vue.use(ElementUI); | ||||
| @@ -2941,6 +2942,7 @@ $(document).ready(async () => { | |||||
| initNotificationCount(); | initNotificationCount(); | ||||
| initTribute(); | initTribute(); | ||||
| initDropDown(); | initDropDown(); | ||||
| initCloudrain(); | |||||
| // Repo clone url. | // Repo clone url. | ||||
| if ($('#repo-clone-url').length > 0) { | if ($('#repo-clone-url').length > 0) { | ||||
| @@ -3589,22 +3591,43 @@ function initVueApp() { | |||||
| } | } | ||||
| initVueComponents(); | initVueComponents(); | ||||
| new Vue({ | new Vue({ | ||||
| delimiters: ['${', '}'], | delimiters: ['${', '}'], | ||||
| el, | el, | ||||
| data: { | data: { | ||||
| page:parseInt(new URLSearchParams(window.location.search).get('page')), | |||||
| searchLimit: Number( | searchLimit: Number( | ||||
| (document.querySelector('meta[name=_search_limit]') || {}).content | (document.querySelector('meta[name=_search_limit]') || {}).content | ||||
| ), | ), | ||||
| page:1, | |||||
| suburl: AppSubUrl, | suburl: AppSubUrl, | ||||
| uid: Number( | uid: Number( | ||||
| (document.querySelector('meta[name=_context_uid]') || {}).content | (document.querySelector('meta[name=_context_uid]') || {}).content | ||||
| ), | ), | ||||
| activityTopAuthors: window.ActivityTopAuthors || [] | |||||
| activityTopAuthors: window.ActivityTopAuthors || [], | |||||
| localHref:'' | |||||
| }, | }, | ||||
| components: { | components: { | ||||
| ActivityTopAuthors | ActivityTopAuthors | ||||
| }, | |||||
| mounted(){ | |||||
| this.page = parseInt(new URLSearchParams(window.location.search).get('page')) | |||||
| this.localHref = location.href | |||||
| }, | |||||
| methods:{ | |||||
| handleCurrentChange:function (val) { | |||||
| const searchParams = new URLSearchParams(window.location.search) | |||||
| if (!window.location.search) { | |||||
| window.location.href = this.localHref + '?page='+val | |||||
| } else if (searchParams.has('page')) { | |||||
| window.location.href = this.localHref.replace(/page=[0-9]/g,'page='+val) | |||||
| } else { | |||||
| window.location.href=location.href+'&page='+val | |||||
| } | |||||
| this.page = val | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -3693,8 +3716,6 @@ function initVueModel() { | |||||
| } | } | ||||
| function initVueDataAnalysis() { | function initVueDataAnalysis() { | ||||
| const el = document.getElementById('data_analysis'); | const el = document.getElementById('data_analysis'); | ||||
| console.log("el",el) | |||||
| if (!el) { | if (!el) { | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -3770,7 +3791,6 @@ function initFilterBranchTagDropdown(selector) { | |||||
| }); | }); | ||||
| }); | }); | ||||
| $data.remove(); | $data.remove(); | ||||
| console.log("-this",this) | |||||
| new Vue({ | new Vue({ | ||||
| delimiters: ['${', '}'], | delimiters: ['${', '}'], | ||||
| el: this, | el: this, | ||||
| @@ -1,6 +1,11 @@ | |||||
| a { | a { | ||||
| color: #0366d6; | color: #0366d6; | ||||
| } | } | ||||
| .nowrap{ | |||||
| white-space: nowrap; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| } | |||||
| .ui .text.yellow a { | .ui .text.yellow a { | ||||
| color: #fbbd08!important | color: #fbbd08!important | ||||
| } | } | ||||
| @@ -720,4 +725,13 @@ display: block; | |||||
| .markdown:not(code).file-view{ | .markdown:not(code).file-view{ | ||||
| padding: 2em 0!important; | padding: 2em 0!important; | ||||
| } | } | ||||
| } | |||||
| } | |||||
| //elemet-ui | |||||
| .el-pagination.is-background .el-pager li:not(.disabled).active { | |||||
| background-color: #5bb973 !important; | |||||
| color: #FFF !important; | |||||
| } | |||||
| .el-pagination.is-background .el-pager li:hover { | |||||
| color: #5bb973 !important; | |||||
| } | |||||
| @@ -115,6 +115,15 @@ module.exports = { | |||||
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| { | |||||
| test: /\.ts$/, | |||||
| use: [ | |||||
| { | |||||
| loader: "ts-loader", | |||||
| } | |||||
| ], | |||||
| exclude: /node_modules/ | |||||
| }, | |||||
| { | { | ||||
| test: /\.js$/, | test: /\.js$/, | ||||
| exclude: /node_modules/, | exclude: /node_modules/, | ||||
| @@ -252,6 +261,7 @@ module.exports = { | |||||
| alias: { | alias: { | ||||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | ||||
| }, | }, | ||||
| extensions: ['.tsx', '.ts', '.js'] | |||||
| }, | }, | ||||
| watchOptions: { | watchOptions: { | ||||
| ignored: [ | ignored: [ | ||||