| @@ -49,6 +49,14 @@ const ( | |||
| ActionApprovePullRequest // 21 | |||
| ActionRejectPullRequest // 22 | |||
| 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 | |||
| @@ -103,7 +103,7 @@ type Cloudbrain struct { | |||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | |||
| Duration int64 | |||
| TrainJobDuration string | |||
| Image string //GPU镜像名称 | |||
| Image string //镜像名称 | |||
| GpuQueue string //GPU类型即GPU队列 | |||
| ResourceSpecId int //GPU规格id | |||
| DeletedAt time.Time `xorm:"deleted"` | |||
| @@ -220,17 +220,20 @@ type GetImagesPayload struct { | |||
| type CloudbrainsOptions struct { | |||
| 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 | |||
| JobTypes []string | |||
| VersionName string | |||
| IsLatestVersion string | |||
| JobTypeNot bool | |||
| NeedRepoInfo bool | |||
| } | |||
| type TaskPod struct { | |||
| @@ -450,6 +453,16 @@ type FlavorInfo struct { | |||
| 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 { | |||
| PoolInfo []*PoolInfo `json:"pool_info"` | |||
| } | |||
| @@ -1073,16 +1086,39 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||
| } | |||
| 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 { | |||
| 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 { | |||
| return nil, 0, fmt.Errorf("Count: %v", err) | |||
| } | |||
| @@ -1100,11 +1136,25 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||
| sess.OrderBy("cloudbrain.created_unix DESC") | |||
| cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | |||
| if err := sess.Table(&Cloudbrain{}).Where(cond). | |||
| Join("left", "`user`", "cloudbrain.user_id = `user`.id"). | |||
| Join("left", "`user`", condition). | |||
| Find(&cloudbrains); err != nil { | |||
| 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 | |||
| } | |||
| @@ -19,7 +19,8 @@ type CreateModelArtsNotebookForm struct { | |||
| JobName string `form:"job_name" binding:"Required"` | |||
| Attachment string `form:"attachment"` | |||
| 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 { | |||
| @@ -1,16 +1,17 @@ | |||
| package cloudbrain | |||
| import ( | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "encoding/json" | |||
| "errors" | |||
| "strconv" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/notification" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| ) | |||
| const ( | |||
| @@ -221,13 +222,19 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||
| ComputeResource: models.GPUResource, | |||
| BenchmarkTypeID: benchmarkTypeID, | |||
| BenchmarkChildTypeID: benchmarkChildTypeID, | |||
| Description: description, | |||
| Description: description, | |||
| }) | |||
| if err != nil { | |||
| 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 | |||
| } | |||
| @@ -2,6 +2,7 @@ package modelarts | |||
| import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "path" | |||
| "strconv" | |||
| @@ -9,6 +10,7 @@ import ( | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/notification" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| ) | |||
| @@ -63,6 +65,7 @@ const ( | |||
| var ( | |||
| poolInfos *models.PoolInfos | |||
| FlavorInfos *models.FlavorInfos | |||
| ImageInfos *models.ImageInfosModelArts | |||
| ) | |||
| type GenerateTrainJobReq struct { | |||
| @@ -260,24 +263,31 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||
| if err != nil { | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||
| 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 { | |||
| 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{ | |||
| JobName: jobName, | |||
| Description: description, | |||
| Flavor: flavor, | |||
| Duration: autoStopDurationMs, | |||
| ImageID: "59a6e9f5-93c0-44dd-85b0-82f390c5d53a", | |||
| ImageID: imageId, | |||
| PoolID: poolInfos.PoolInfo[0].PoolId, | |||
| Feature: models.NotebookFeature, | |||
| Volume: models.VolumeReq{ | |||
| Capacity: 100, | |||
| Capacity: setting.Capacity, | |||
| Category: models.EVSCategory, | |||
| Ownership: models.ManagedOwnership, | |||
| }, | |||
| @@ -288,7 +298,7 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor | |||
| return err | |||
| } | |||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | |||
| Status: string(models.JobWaiting), | |||
| Status: jobResult.Status, | |||
| UserID: ctx.User.ID, | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobResult.ID, | |||
| @@ -297,12 +307,14 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor | |||
| Type: models.TypeCloudBrainTwo, | |||
| Uuid: uuid, | |||
| ComputeResource: models.NPUResource, | |||
| Image: imageName, | |||
| Description: description, | |||
| }) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||
| return nil | |||
| } | |||
| @@ -336,12 +348,12 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | |||
| return err | |||
| } | |||
| jobId := strconv.FormatInt(jobResult.JobID, 10) | |||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | |||
| Status: TransTrainJobStatus(jobResult.Status), | |||
| UserID: ctx.User.ID, | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | |||
| JobID: jobId, | |||
| JobName: req.JobName, | |||
| DisplayJobName: req.DisplayJobName, | |||
| JobType: string(models.JobTypeTrain), | |||
| @@ -373,7 +385,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.JobName, models.ActionCreateTrainTask) | |||
| return nil | |||
| } | |||
| @@ -558,12 +570,12 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | |||
| return err | |||
| } | |||
| jobID := strconv.FormatInt(jobResult.JobID, 10) | |||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | |||
| Status: TransTrainJobStatus(jobResult.Status), | |||
| UserID: ctx.User.ID, | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | |||
| JobID: jobID, | |||
| JobName: req.JobName, | |||
| JobType: string(models.JobTypeInference), | |||
| Type: models.TypeCloudBrainTwo, | |||
| @@ -586,6 +598,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| EngineName: req.EngineName, | |||
| LabelName: req.LabelName, | |||
| IsLatestVersion: req.IsLatestVersion, | |||
| ComputeResource: models.NPUResource, | |||
| VersionCount: req.VersionCount, | |||
| TotalVersionCount: req.TotalVersionCount, | |||
| ModelName: req.ModelName, | |||
| @@ -598,6 +611,29 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.JobName, models.ActionCreateInferenceTask) | |||
| 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) | |||
| } | |||
| } | |||
| 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) | |||
| NotifySyncCreateRef(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 | |||
| 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()) | |||
| } | |||
| // 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 | |||
| func NotifyCreateIssueComment(doer *models.User, repo *models.Repository, | |||
| issue *models.Issue, comment *models.Comment) { | |||
| @@ -513,6 +513,8 @@ var ( | |||
| PoolInfos string | |||
| Flavor string | |||
| DebugHost string | |||
| ImageInfos string | |||
| Capacity int | |||
| //train-job | |||
| ResourcePools string | |||
| Engines string | |||
| @@ -1326,7 +1328,8 @@ func NewContext() { | |||
| ProfileID = sec.Key("PROFILE_ID").MustString("") | |||
| PoolInfos = sec.Key("POOL_INFOS").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("") | |||
| Engines = sec.Key("Engines").MustString("") | |||
| EngineVersions = sec.Key("Engine_Versions").MustString("") | |||
| @@ -864,9 +864,13 @@ confirm_choice = confirm | |||
| cloudbran1_tips = Only data in zip format can create cloudbrain tasks | |||
| cloudbrain_creator=Creator | |||
| cloudbrain_task = Task Name | |||
| cloudbrain_task_type = Task Type | |||
| cloudbrain_task_name=Cloud Brain Task Name | |||
| cloudbrain_operate = Operate | |||
| cloudbrain_status_createtime = Status/Createtime | |||
| cloudbrain_status_runtime = Running Time | |||
| cloudbrain_jobname_err=Name must start with a lowercase letter or number,can include lowercase letter,number,_ and -,can not end with _, and can be up to 36 characters long. | |||
| cloudbrain_query_fail=Failed to query cloudbrain information. | |||
| record_begintime_get_err=Can not get the record begin time. | |||
| parameter_is_wrong=The input parameter is wrong. | |||
| @@ -2344,6 +2348,12 @@ datasets.owner=Owner | |||
| datasets.name=name | |||
| 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.add_webhook = Add Default Webhook | |||
| hooks.update_webhook = Update Default Webhook | |||
| @@ -2683,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 | |||
| 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>` | |||
| 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] | |||
| ago = %s ago | |||
| @@ -2757,6 +2774,7 @@ head.dataset = Datasets | |||
| foot.council = Council | |||
| foot.technical_committee = Technical Committee | |||
| foot.join = Join OpenI | |||
| foot.agreement=Use agreement | |||
| foot.news = News | |||
| foot.community_news = Community News | |||
| foot.member_news = Member news | |||
| @@ -868,10 +868,13 @@ confirm_choice=确定 | |||
| cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 | |||
| cloudbrain_creator=创建者 | |||
| cloudbrain_task=任务名称 | |||
| cloudbrain_task_type=任务类型 | |||
| cloudbrain_task_name=云脑侧任务名称 | |||
| cloudbrain_operate=操作 | |||
| cloudbrain_status_createtime=状态/创建时间 | |||
| cloudbrain_status_runtime = 运行时长 | |||
| cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | |||
| cloudbrain_query_fail=查询云脑任务失败。 | |||
| record_begintime_get_err=无法获取统计开始时间。 | |||
| parameter_is_wrong=输入参数错误,请检查输入参数。 | |||
| @@ -2354,6 +2357,12 @@ datasets.owner=所有者 | |||
| datasets.name=名称 | |||
| 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.add_webhook=新增默认Web钩子 | |||
| hooks.update_webhook=更新默认Web钩子 | |||
| @@ -2420,7 +2429,7 @@ auths.sspi_auto_activate_users_helper=允许 SSPI 认证自动激活新用户 | |||
| auths.sspi_strip_domain_names=从用户名中删除域名部分 | |||
| auths.sspi_strip_domain_names_helper=如果选中此项,域名将从登录名中删除(例如,"DOMAIN\user"和"user@example.org",两者都将变成只是“用户”)。 | |||
| 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_helper=SSPI 认证方法为用户自动创建的默认语言。如果您想要自动检测到语言,请留空。 | |||
| auths.tips=帮助提示 | |||
| @@ -2693,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> | |||
| approve_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] | |||
| ago=%s前 | |||
| @@ -2767,6 +2783,7 @@ head.dataset=数据集 | |||
| foot.council=理事会 | |||
| foot.technical_committee=技术委员会 | |||
| foot.join=加入启智 | |||
| foot.agreement=使用协议 | |||
| foot.news=动态 | |||
| foot.community_news=社区动态 | |||
| foot.member_news=成员动态 | |||
| @@ -13869,6 +13869,130 @@ | |||
| "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", | |||
| "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": { | |||
| "version": "1.13.0", | |||
| "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", | |||
| @@ -13928,6 +14052,12 @@ | |||
| "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": { | |||
| "version": "0.7.21", | |||
| "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", | |||
| @@ -69,6 +69,8 @@ | |||
| "script-loader": "0.7.2", | |||
| "stylelint": "13.3.3", | |||
| "stylelint-config-standard": "20.0.0", | |||
| "ts-loader": "4.0.0", | |||
| "typescript": "4.5.5", | |||
| "updates": "10.2.11" | |||
| }, | |||
| "browserslist": [ | |||
| @@ -126,11 +126,14 @@ socket.onmessage = function (e) { | |||
| actionName = actionName.replace("{oldRepoName}",record.Content); | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | |||
| } | |||
| else if(record.OpType == "24" || record.OpType == "25" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "29" || record.OpType == "30"){ | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| } | |||
| else{ | |||
| continue; | |||
| } | |||
| if(record.Repo != null){ | |||
| var time = getTime(record.CreatedUnix,currentTime); | |||
| html += " " + time; | |||
| @@ -138,13 +141,32 @@ socket.onmessage = function (e) { | |||
| html += "</div>"; | |||
| html += "</div>"; | |||
| } | |||
| } | |||
| output.innerHTML = html; | |||
| swiperNewMessage.updateSlides(); | |||
| 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){ | |||
| var html =""; | |||
| html += "<div class=\"swiper-slide item\">"; | |||
| @@ -276,7 +298,14 @@ var actionNameZH={ | |||
| "15":"重新开启了合并请求", | |||
| "17":"从 {repoName} 删除分支 {deleteBranchName}", | |||
| "22":"建议变更", | |||
| "23":"评论了合并请求" | |||
| "23":"评论了合并请求", | |||
| "24":"上传了数据集文件", | |||
| "25":"创建了CPU/GPU类型调试任务", | |||
| "26":"创建了NPU类型调试任务", | |||
| "27":"创建了训练任务", | |||
| "28":"创建了推理任务", | |||
| "29":"创建了评测任务", | |||
| "30":"导入了新模型" | |||
| }; | |||
| var actionNameEN={ | |||
| @@ -294,7 +323,14 @@ var actionNameEN={ | |||
| "15":" reopened pull request", | |||
| "17":" deleted branch {deleteBranchName} from {repoName}", | |||
| "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={ | |||
| @@ -0,0 +1,217 @@ | |||
| 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, | |||
| }) | |||
| 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): rs.Repo.OwnerName + "/" + rs.Repo.Alias, getCellName("I", row): rs.JobName, | |||
| } | |||
| } | |||
| 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) | |||
| } | |||
| @@ -38,6 +38,7 @@ const ( | |||
| tplExploreCode base.TplName = "explore/code" | |||
| tplExploreImages base.TplName = "explore/images" | |||
| tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis" | |||
| tplHomeTerm base.TplName = "terms" | |||
| ) | |||
| // Home render home page | |||
| @@ -596,3 +597,7 @@ func RecommendRepoFromPromote(ctx *context.Context) { | |||
| 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/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/notification" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| 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) | |||
| log.Info("save model end.") | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask) | |||
| return nil | |||
| } | |||
| @@ -20,11 +20,11 @@ import ( | |||
| "code.gitea.io/gitea/modules/labelmsg" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/minio_ext" | |||
| "code.gitea.io/gitea/modules/notification" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "code.gitea.io/gitea/modules/upload" | |||
| "code.gitea.io/gitea/modules/worker" | |||
| gouuid "github.com/satori/go.uuid" | |||
| ) | |||
| @@ -845,6 +845,9 @@ func CompleteMultipart(ctx *context.Context) { | |||
| ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err)) | |||
| 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 isCanDecompress(attachment.Name) { | |||
| @@ -865,7 +868,6 @@ func CompleteMultipart(ctx *context.Context) { | |||
| labelmsg.SendDecompressAttachToLabelOBS(string(attachjson)) | |||
| } | |||
| } else { | |||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||
| var labelMap map[string]string | |||
| labelMap = make(map[string]string) | |||
| labelMap["UUID"] = uuid | |||
| @@ -350,18 +350,15 @@ func CloudBrainShow(ctx *context.Context) { | |||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| var jobName = ctx.Params(":jobname") | |||
| task, err := models.GetCloudbrainByName(jobName) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| } | |||
| result, err := cloudbrain.GetJob(task.JobID) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| } | |||
| if result != nil { | |||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||
| 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 | |||
| taskRoles := jobRes.TaskRoles | |||
| if jobRes.JobStatus.State != string(models.JobFailed) { | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| ctx.Data["taskRes"] = taskRes | |||
| task.Status = taskRes.TaskStatuses[0].State | |||
| @@ -588,7 +586,13 @@ func CloudBrainDel(ctx *context.Context) { | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=" + listType) | |||
| 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 { | |||
| @@ -1099,6 +1103,9 @@ func GetChildTypes(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) | |||
| if err != nil { | |||
| ctx.ServerError("get new cloudbrain info failed", err) | |||
| @@ -1201,6 +1208,9 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| benchmarkTypeID := form.BenchmarkTypeID | |||
| benchmarkChildTypeID := form.BenchmarkChildTypeID | |||
| ctx.Data["description"] = form.Description | |||
| ctx.Data["benchmarkTypeID"] = benchmarkTypeID | |||
| ctx.Data["benchmark_child_types_id_hidden"] = benchmarkChildTypeID | |||
| if !jobNamePattern.MatchString(jobName) { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | |||
| @@ -1344,5 +1354,11 @@ func BenchmarkDel(ctx *context.Context) { | |||
| ctx.ServerError(err.Error(), err) | |||
| 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") | |||
| } | |||
| } | |||
| @@ -120,8 +120,13 @@ func MustEnableModelArts(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() | |||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
| ctx.Data["job_name"] = jobName | |||
| @@ -129,26 +134,14 @@ func NotebookNew(ctx *context.Context) { | |||
| attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | |||
| if err != nil { | |||
| ctx.ServerError("GetAllUserAttachments failed:", err) | |||
| return | |||
| return err | |||
| } | |||
| 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 { | |||
| json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | |||
| @@ -208,8 +201,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| flavor := form.Flavor | |||
| flavor = "modelarts.bm.910.arm.public.1" | |||
| imageId := form.ImageId | |||
| count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| @@ -240,7 +232,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 { | |||
| log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | |||
| notebookNewDataPrepare(ctx) | |||
| @@ -279,10 +271,19 @@ func NotebookShow(ctx *context.Context) { | |||
| 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.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["jobID"] = jobID | |||
| ctx.Data["jobName"] = task.JobName | |||
| @@ -461,7 +462,12 @@ func NotebookDel(ctx *context.Context) { | |||
| return | |||
| } | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=" + listType) | |||
| 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) { | |||
| @@ -1473,6 +1479,7 @@ func TrainJobShow(ctx *context.Context) { | |||
| ctx.Data["displayJobName"] = VersionListTasks[0].DisplayJobName | |||
| ctx.Data["version_list_task"] = VersionListTasks | |||
| ctx.Data["version_list_count"] = VersionListCount | |||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | |||
| ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow) | |||
| } | |||
| @@ -1569,7 +1576,12 @@ func TrainJobDel(ctx *context.Context) { | |||
| 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) { | |||
| @@ -2072,6 +2084,7 @@ func InferenceJobShow(ctx *context.Context) { | |||
| ctx.Data["jobID"] = jobID | |||
| ctx.Data["jobName"] = task.JobName | |||
| ctx.Data["task"] = task | |||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||
| tempUids := []int64{} | |||
| tempUids = append(tempUids, task.UserID) | |||
| @@ -319,6 +319,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/action/notification", routers.ActionNotification) | |||
| m.Get("/recommend/org", routers.RecommendOrgFromPromote) | |||
| m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | |||
| m.Get("/home/term", routers.HomeTerm) | |||
| m.Group("/explore", func() { | |||
| m.Get("", func(ctx *context.Context) { | |||
| ctx.Redirect(setting.AppSubURL + "/explore/repos") | |||
| @@ -507,6 +508,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("", admin.Datasets) | |||
| // 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.Get("", admin.DefaultOrSystemWebhooks) | |||
| @@ -996,7 +1001,6 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | |||
| }) | |||
| m.Group("/:jobid", func() { | |||
| // m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | |||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | |||
| @@ -10,7 +10,7 @@ import ( | |||
| "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 { | |||
| Clients *orderedmap.OrderedMap | |||
| @@ -0,0 +1,219 @@ | |||
| {{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 padding0"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repository"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" 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 padding0"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/cloudbrain/{{.JobID}}" 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.Alias}}/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.Alias}}/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.Alias}}/cloudbrain/benchmark/{{.JobID}}" 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 padding0"> | |||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center padding0" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Alias}}{{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 padding0" style="width: 10% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center padding0"> | |||
| {{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 padding0"> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}" title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| </div> | |||
| <!-- 云脑侧名称 --> | |||
| <div class="two wide column text center padding0" style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <span class="fitted">{{.JobName}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" 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.Alias}}{{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.Alias}}{{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.Alias}}{{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.Alias}}/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.Alias}}{{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.Alias}}/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() | |||
| </script> | |||
| @@ -0,0 +1,46 @@ | |||
| <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> | |||
| </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"> | |||
| {{.i18n.Tr "admin.datasets"}} | |||
| </a> | |||
| <a class="{{if .PageIsAdminCloudBrains}}active{{end}} item" href="{{AppSubUrl}}/admin/cloudbrains"> | |||
| 云脑任务 | |||
| </a> | |||
| <a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | |||
| {{.i18n.Tr "admin.hooks"}} | |||
| </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.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="{{AppSubUrl}}/home/term/" class="item">{{.i18n.Tr "custom.foot.agreement"}}</a> | |||
| </div> | |||
| <div class="column ui vertical text menu"> | |||
| <div class="header item">{{.i18n.Tr "custom.foot.news"}}</div> | |||
| @@ -78,7 +78,7 @@ | |||
| {{if le .NumRepos 1}} | |||
| {{$.i18n.Tr "org.lower_repository"}} | |||
| {{else}} | |||
| {{$.i18n.Tr "org.lower_repository"}} | |||
| {{$.i18n.Tr "org.lower_repositories"}} | |||
| {{end}} | |||
| </a> | |||
| </p> | |||
| @@ -232,7 +232,7 @@ | |||
| {{if le .NumRepos 1}} | |||
| {{$.i18n.Tr "org.lower_repository"}} | |||
| {{else}} | |||
| {{$.i18n.Tr "org.lower_repository"}} | |||
| {{$.i18n.Tr "org.lower_repositories"}} | |||
| {{end}} | |||
| </a> | |||
| </p> | |||
| @@ -120,7 +120,6 @@ | |||
| <script> | |||
| function show_bt(bt_id){ | |||
| console.log(bt_id) | |||
| document.getElementById(""+bt_id).getElementsByClassName("button_leaveOrg")[0].style.display="inline-block"; | |||
| } | |||
| @@ -44,7 +44,19 @@ | |||
| {{end}} | |||
| </div> | |||
| <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> | |||
| {{end}} | |||
| @@ -36,7 +36,19 @@ | |||
| {{end}} | |||
| </div> | |||
| <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> | |||
| {{end}} | |||
| @@ -100,13 +100,12 @@ | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0"> | |||
| <a class="title" href="{{$.Link}}/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| </a> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <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}}" data-jobname="{{.JobName}}"> | |||
| <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> | |||
| </div> | |||
| @@ -137,10 +136,9 @@ | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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}} | |||
| <a class="ui basic disabled button"> | |||
| @@ -148,26 +146,21 @@ | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/rate" target="_blank"> | |||
| 评分 | |||
| </a> | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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"}} | |||
| </a> | |||
| {{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"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| @@ -221,169 +214,3 @@ | |||
| </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 jobName = job.dataset.jobname; | |||
| 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' | |||
| const diffApi = computeResource == "NPU" ? jobID : jobName | |||
| $.get(`/api/v1/repos/${repoPath}/${diffResource}/${diffApi}`, (data) => { | |||
| const jobID = data.JobID | |||
| const jobName = data.JobName | |||
| const status = data.JobStatus | |||
| if (status != job.textContent.trim()) { | |||
| $('#' + jobName+'-icon').removeClass().addClass(status) | |||
| $('#' + jobName+ '-text').text(status) | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#model-debug-'+jobName).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+jobName).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| // $('#model-debug-'+jobID).removeClass('blue') | |||
| // $('#model-debug-'+jobID).addClass('disabled') | |||
| $('#model-image-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#model-debug-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#model-debug-'+jobName).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#stop-model-debug-'+jobName).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||
| $('#stop-model-debug-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ | |||
| $('#model-delete-'+jobName).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#model-delete-'+jobName).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 class="unite min_title inline field"> | |||
| <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 class="required unite min_title inline field"> | |||
| @@ -102,11 +102,16 @@ | |||
| <span> </span> | |||
| <select class="ui fluid selection search dropdown" id="benchmark_types_id" name="benchmark_types_id" > | |||
| {{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}} | |||
| </select> | |||
| </div> | |||
| <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> | |||
| <select class="ui fluid selection dropdown nowrap" id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id"> | |||
| </select> | |||
| @@ -182,12 +187,16 @@ | |||
| function setChildType(){ | |||
| 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) => { | |||
| console.log(JSON.stringify(data)) | |||
| const n_length = data['child_types'].length | |||
| let html='' | |||
| 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; | |||
| }) | |||
| @@ -188,6 +188,7 @@ td, th { | |||
| </h4> | |||
| {{range $k ,$v := .version_list_task}} | |||
| <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="according-panel-heading"> | |||
| <div class="accordion-panel-title"> | |||
| @@ -441,7 +442,6 @@ td, th { | |||
| jobName = urlArr.slice(-1)[0] | |||
| }) | |||
| function loadLog(version_name){ | |||
| document.getElementById("mask").style.display = "block" | |||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${jobName}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||
| @@ -94,7 +94,6 @@ $(document).ready(function(){ | |||
| $('#course_label_item').empty() | |||
| }else{ | |||
| $.get(`/api/v1/topics/search?q=${query}`,(data)=>{ | |||
| console.log(data) | |||
| if(data.topics.length!==0){ | |||
| let html='' | |||
| $('#course_label_item').empty() | |||
| @@ -107,5 +106,4 @@ $(document).ready(function(){ | |||
| } | |||
| }); | |||
| }) | |||
| console.log() | |||
| </script> | |||
| @@ -11,9 +11,8 @@ | |||
| {{template "repo/header" .}} | |||
| <script> | |||
| $(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') | |||
| }else{ | |||
| $('.contorl_component').attr("id", 'obsUploader') | |||
| @@ -293,7 +293,7 @@ | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <!--任务状态 --> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-resource="{{.ComputeResource}}" data-jobname="{{.JobName}}"> | |||
| <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> | |||
| </div> | |||
| @@ -324,11 +324,11 @@ | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDebug}} | |||
| {{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}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{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"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -349,15 +349,9 @@ | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| @@ -369,19 +363,16 @@ | |||
| <input type="hidden" name="debugListType" value="{{$.ListType}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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"}} | |||
| </a> | |||
| {{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> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| </div> | |||
| <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | |||
| <div class="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | |||
| <div class="text">更多</div> | |||
| @@ -411,7 +402,6 @@ | |||
| </a> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -487,14 +477,13 @@ | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| // 调试和评分新开窗口 | |||
| console.log({{.Tasks}}) | |||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | |||
| let url={{.RepoLink}} | |||
| let getParam=getQueryVariable('debugListType') | |||
| let dropdownValue = getParam==='all'||getParam==='' ? '全部' : getParam | |||
| let dropdownValue = ['all','',false].includes(getParam)? '全部' : getParam | |||
| localStorage.setItem('all',location.href) | |||
| function getQueryVariable(variable) | |||
| { | |||
| @@ -506,155 +495,6 @@ | |||
| } | |||
| 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', | |||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||
| success:function(res){ | |||
| 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 jobName = job.dataset.jobname; | |||
| 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' | |||
| const diffApi = computeResource == "NPU" ? jobID : jobName | |||
| $.get(`/api/v1/repos/${repoPath}/${diffResource}/${diffApi}`, (data) => { | |||
| const jobName = data.JobName | |||
| const status = data.JobStatus | |||
| if (status != job.textContent.trim()) { | |||
| $('#' + jobName+'-icon').removeClass().addClass(status) | |||
| $('#' + jobName+ '-text').text(status) | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#model-debug-'+jobName).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+jobName).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| // $('#model-debug-'+jobID).removeClass('blue') | |||
| // $('#model-debug-'+jobID).addClass('disabled') | |||
| $('#model-image-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#model-debug-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#model-debug-'+jobName).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#stop-model-debug-'+jobName).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||
| $('#stop-model-debug-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ | |||
| $('#model-delete-'+jobName).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#model-delete-'+jobName).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| }); | |||
| }; | |||
| $(document).ready(function(){ | |||
| dropdownValue = dropdownValue==="CPU%2FGPU"? 'CPU/GPU' : dropdownValue | |||
| $('.default.text').text(dropdownValue) | |||
| @@ -674,9 +514,6 @@ | |||
| .transition('fade') | |||
| }) | |||
| }) | |||
| // 获取弹窗 | |||
| var modal = document.getElementById('imageModal'); | |||
| @@ -706,7 +543,6 @@ | |||
| modal.style.display = "none"; | |||
| } | |||
| } | |||
| // 显示弹窗,弹出相应的信息 | |||
| function showmask() { | |||
| var image_tag = !$('#image_tag').val() | |||
| @@ -113,11 +113,11 @@ | |||
| <!-- 模型版本 --> | |||
| <!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | |||
| <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 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> | |||
| </div> | |||
| @@ -147,11 +147,11 @@ | |||
| <div class="ui compact buttons"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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"}} | |||
| </a> | |||
| {{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"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -174,7 +174,7 @@ | |||
| <div class="ui compact buttons"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic 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"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -221,118 +221,6 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{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> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.task}}) | |||
| $(document).ready(function(){ | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| let userName | |||
| let repoPath | |||
| let jobID | |||
| let downlaodFlag = {{$.canDownload }} | |||
| $(document).ready(function(){ | |||
| let url = window.location.href; | |||
| 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 += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||
| }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 += '</a>' | |||
| @@ -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,'')"> | |||
| </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> | |||
| <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"> | |||
| @@ -62,7 +71,7 @@ | |||
| <input type="hidden" name="attachment" id="answerInput-hidden"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <!--<div class="inline required field"> | |||
| <label>工作环境</label> | |||
| <input name="de" id="cloudbrain_de" value="{{.env}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| @@ -27,7 +27,7 @@ | |||
| {{end}} | |||
| </div> | |||
| <div class="ui green segment"> | |||
| <p>任务结果:</p> | |||
| <p>任务详情:</p> | |||
| {{with .result}} | |||
| <table class="ui celled striped table"> | |||
| <tbody> | |||
| @@ -35,6 +35,18 @@ | |||
| <td class="four wide"> 状态 </td> | |||
| <td> {{.Status}} </td> | |||
| </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> | |||
| <td> 开始时间 </td> | |||
| <td>{{.CreateTime}}</td> | |||
| @@ -113,7 +113,7 @@ | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <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> | |||
| </div> | |||
| @@ -143,11 +143,11 @@ | |||
| <div class="ui compact buttons"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{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"}} | |||
| </a> | |||
| {{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"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -157,7 +157,7 @@ | |||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic 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"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -204,162 +204,5 @@ | |||
| </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> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| @@ -532,6 +533,7 @@ td, th { | |||
| let userName | |||
| let repoPath | |||
| let jobID | |||
| let downlaodFlag = {{$.canDownload }} | |||
| $(document).ready(function(){ | |||
| let url = window.location.href; | |||
| let urlArr = url.split('/') | |||
| @@ -787,7 +789,12 @@ td, th { | |||
| 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>" | |||
| }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 += '</a>' | |||
| @@ -186,7 +186,6 @@ | |||
| <div class='ui breadcrumb model_file_bread' id='file_breadcrumb'> | |||
| <div class="active section"></div> | |||
| <div class="divider"> / </div> | |||
| </div> | |||
| <div id="dir_list"> | |||
| @@ -52,6 +52,4 @@ | |||
| </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}} | |||
| {{else if eq .GetOpType 23}} | |||
| {{ $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}} | |||
| </p> | |||
| {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | |||
| @@ -101,7 +115,23 @@ | |||
| </div> | |||
| </div> | |||
| <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 class="ui divider"></div> | |||
| @@ -208,6 +208,3 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Issues}}) | |||
| </script> | |||
| @@ -117,6 +117,3 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Milestones}}) | |||
| </script> | |||
| @@ -141,6 +141,7 @@ | |||
| {{if eq .TabName "activity"}} | |||
| {{if .EnableHeatmap}} | |||
| <div id="user-heatmap" style="padding-right: 40px"> | |||
| <activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser"> | |||
| <div slot="loading"> | |||
| @@ -310,7 +310,6 @@ export default { | |||
| }, | |||
| handleCurrentChange(val){ | |||
| console.log(val) | |||
| this.params.page = val | |||
| this.getImageList() | |||
| @@ -350,7 +349,6 @@ export default { | |||
| }) | |||
| }, | |||
| copyUrl(url){ | |||
| console.log(url) | |||
| const cInput = document.createElement('input') | |||
| cInput.value = url | |||
| document.body.appendChild(cInput) | |||
| @@ -380,16 +378,13 @@ export default { | |||
| clearP(value){ | |||
| console.log("sorce value",value) | |||
| if(!value) return '' | |||
| const reg = /\<\/?p\>/g; | |||
| value = value.replace(reg,'') | |||
| console.log("repalace:",value) | |||
| return value | |||
| }, | |||
| transformTimestamp(timestamp){ | |||
| console.log("timestamp",timestamp) | |||
| let a = new Date(timestamp).getTime(); | |||
| const date = new Date(a); | |||
| const Y = date.getFullYear() + '-'; | |||
| @@ -200,7 +200,6 @@ | |||
| var saveFileName='' | |||
| var Date=(this.params.startDate).split('-') | |||
| var startDate=Date[0]+''+Date[1]+''+Date[2] | |||
| console.log(startDate) | |||
| Date=(this.params.endDate).split('-') | |||
| var endDate=Date[0]+Date[1]+Date[2] | |||
| saveFileName = '用户分析_'+this.search+''+startDate+'_'+endDate | |||
| @@ -258,7 +257,6 @@ | |||
| getUserList(type_val,index){ | |||
| this.type_val = type_val | |||
| this.dynamic = index; | |||
| console.log("dj:"+type_val) | |||
| var now = new Date(); // 当前日期 | |||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | |||
| var nowDay = now.getDate(); // 当前日 | |||
| @@ -324,7 +322,6 @@ | |||
| // console.log("res.data:"+res.data.data) | |||
| this.totalNum = res.data.count | |||
| console.log("res.count:"+res.data.count) | |||
| }) | |||
| @@ -354,9 +351,7 @@ | |||
| }, | |||
| filters:{ | |||
| transformTimestamp(timestamp){ | |||
| console.log("timestamp",timestamp) | |||
| let a = new Date(timestamp*1000); | |||
| const date = new Date(a); | |||
| const Y = date.getFullYear() + '/'; | |||
| @@ -366,7 +361,6 @@ | |||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes());// + ':' ; | |||
| // const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | |||
| const dateString = Y + M + D + h + m ;//+ s; | |||
| console.log('dateString', dateString); // > dateString 2021-07-06 14:23 | |||
| return dateString; | |||
| }, | |||
| }, | |||
| @@ -100,7 +100,6 @@ export function export_table_to_excel(id) { | |||
| /* original data */ | |||
| var data = oo[0]; | |||
| var ws_name = "SheetJS"; | |||
| console.log(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) { | |||
| console.log(jsonData) | |||
| } | |||
| 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'); | |||
| let tHeader = [] | |||
| let filterVal = [] | |||
| console.log(columns) | |||
| if(!columns){ | |||
| return; | |||
| } | |||
| @@ -0,0 +1,236 @@ | |||
| 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() | |||
| console.log(versionname) | |||
| 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){ | |||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||
| window.open(debugUrl+'debug') | |||
| }else{ | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:debugUrl+'restart', | |||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||
| success:function(res){ | |||
| 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 | |||
| debugAgain(jobID,repoPath) | |||
| }) | |||
| } | |||
| @@ -40,6 +40,8 @@ import EditTopics from './components/EditTopics.vue'; | |||
| import DataAnalysis from './components/DataAnalysis.vue' | |||
| import Contributors from './components/Contributors.vue' | |||
| import Model from './components/Model.vue'; | |||
| import initCloudrain from './features/cloudrbanin.js' | |||
| Vue.use(ElementUI); | |||
| Vue.prototype.$axios = axios; | |||
| @@ -2936,6 +2938,7 @@ $(document).ready(async () => { | |||
| initNotificationCount(); | |||
| initTribute(); | |||
| initDropDown(); | |||
| initCloudrain(); | |||
| // Repo clone url. | |||
| if ($('#repo-clone-url').length > 0) { | |||
| @@ -3584,14 +3587,16 @@ function initVueApp() { | |||
| } | |||
| initVueComponents(); | |||
| new Vue({ | |||
| delimiters: ['${', '}'], | |||
| el, | |||
| data: { | |||
| page:parseInt(new URLSearchParams(window.location.search).get('page')), | |||
| searchLimit: Number( | |||
| (document.querySelector('meta[name=_search_limit]') || {}).content | |||
| ), | |||
| page:1, | |||
| suburl: AppSubUrl, | |||
| uid: Number( | |||
| (document.querySelector('meta[name=_context_uid]') || {}).content | |||
| @@ -3600,6 +3605,15 @@ function initVueApp() { | |||
| }, | |||
| components: { | |||
| ActivityTopAuthors | |||
| }, | |||
| mounted(){ | |||
| this.page = parseInt(new URLSearchParams(window.location.search).get('page')) | |||
| }, | |||
| methods:{ | |||
| handleCurrentChange:function (val) { | |||
| window.location.href='/admin/cloudbrains?page='+val | |||
| this.page = val | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| @@ -3688,8 +3702,6 @@ function initVueModel() { | |||
| } | |||
| function initVueDataAnalysis() { | |||
| const el = document.getElementById('data_analysis'); | |||
| console.log("el",el) | |||
| if (!el) { | |||
| return; | |||
| } | |||
| @@ -3756,7 +3768,6 @@ function initFilterBranchTagDropdown(selector) { | |||
| }); | |||
| }); | |||
| $data.remove(); | |||
| console.log("-this",this) | |||
| new Vue({ | |||
| delimiters: ['${', '}'], | |||
| el: this, | |||
| @@ -720,4 +720,13 @@ display: block; | |||
| .markdown:not(code).file-view{ | |||
| 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$/, | |||
| exclude: /node_modules/, | |||
| @@ -252,6 +261,7 @@ module.exports = { | |||
| alias: { | |||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | |||
| }, | |||
| extensions: ['.tsx', '.ts', '.js'] | |||
| }, | |||
| watchOptions: { | |||
| ignored: [ | |||