Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/1810tags/v1.22.3.2
| @@ -41,6 +41,7 @@ | |||||
| ## 授权许可 | ## 授权许可 | ||||
| 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://git.openi.org.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。 | 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://git.openi.org.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。 | ||||
| ## 需要帮助? | ## 需要帮助? | ||||
| 如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询: | 如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询: | ||||
| - 点击[这里](https://git.openi.org.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**) | - 点击[这里](https://git.openi.org.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**) | ||||
| @@ -49,3 +50,8 @@ | |||||
| ## 启智社区小白训练营: | ## 启智社区小白训练营: | ||||
| - 结合案例给大家详细讲解如何使用社区平台,帮助无技术背景的小白成长为启智社区达人 (https://git.openi.org.cn/zeizei/OpenI_Learning) | - 结合案例给大家详细讲解如何使用社区平台,帮助无技术背景的小白成长为启智社区达人 (https://git.openi.org.cn/zeizei/OpenI_Learning) | ||||
| ## 平台引用 | |||||
| 如果本平台对您的科研工作提供了帮助,可在论文致谢中加入: | |||||
| 英文版:```Thanks for the support provided by OpenI Community (https://git.openi.org.cn).``` | |||||
| 中文版:```感谢启智社区提供的技术支持(https://git.openi.org.cn)。``` | |||||
| @@ -44,12 +44,6 @@ | |||||
| -webkit-line-clamp: 2; | -webkit-line-clamp: 2; | ||||
| -webkit-box-orient: vertical; | -webkit-box-orient: vertical; | ||||
| } | } | ||||
| .ui.label{ | |||||
| font-weight: normal; | |||||
| } | |||||
| .active { | |||||
| color: #0366D6 !important; | |||||
| } | |||||
| .opacity5{ opacity:0.5;} | .opacity5{ opacity:0.5;} | ||||
| .radius15{ border-radius:1.5rem !important; } | .radius15{ border-radius:1.5rem !important; } | ||||
| @@ -287,70 +281,6 @@ | |||||
| position: relative; | position: relative; | ||||
| } | } | ||||
| /**seach**/ | |||||
| /**搜索导航条适配窄屏**/ | |||||
| .seachnav{ | |||||
| overflow-x: auto; | |||||
| overflow-y: hidden; | |||||
| scrollbar-width: none; /* firefox */ | |||||
| -ms-overflow-style: none; /* IE 10+ */ | |||||
| } | |||||
| .seachnav::-webkit-scrollbar { | |||||
| display: none; /* Chrome Safari */ | |||||
| } | |||||
| .ui.green.button, .ui.green.buttons .button{ | |||||
| background-color: #5BB973; | |||||
| } | |||||
| .seach .repos--seach{ | |||||
| padding-bottom: 0; | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu{ | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .item > i{ | |||||
| margin-right: 5px; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .active.item{ | |||||
| border-bottom-width: 2px; | |||||
| margin: 0 0 -1px; | |||||
| } | |||||
| .seach .ui.menu .active.item>.label { | |||||
| background: #1684FC; | |||||
| color: #FFF; | |||||
| } | |||||
| .seach .ui.menu .item>.label:not(.active.item>.label) { | |||||
| background: #e8e8e8; | |||||
| color: rgba(0,0,0,.6); | |||||
| } | |||||
| .highlight{ | |||||
| color: red; | |||||
| } | |||||
| .ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||||
| width: calc(100% - 3.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| .seach .ui.list .list>.item .header, .seach .ui.list>.item .header{ | |||||
| margin-bottom: 0.5em; | |||||
| font-size: 1.4rem !important; | |||||
| font-weight: normal; | |||||
| } | |||||
| .seach .time, .seach .time a{ | |||||
| font-size: 12px; | |||||
| color: grey; | |||||
| } | |||||
| .seach .list .item.members .ui.avatar.image { | |||||
| width: 3.2em; | |||||
| height: 3.2em; | |||||
| } | |||||
| .ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content { | |||||
| width: calc(100% - 4.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| @media only screen and (max-width: 767px) { | @media only screen and (max-width: 767px) { | ||||
| .am-mt-30{ margin-top: 1.5rem !important;} | .am-mt-30{ margin-top: 1.5rem !important;} | ||||
| .ui.secondary.hometop.segment{ | .ui.secondary.hometop.segment{ | ||||
| @@ -57,6 +57,7 @@ const ( | |||||
| ActionCreateInferenceTask // 28 | ActionCreateInferenceTask // 28 | ||||
| ActionCreateBenchMarkTask //29 | ActionCreateBenchMarkTask //29 | ||||
| ActionCreateNewModelTask //30 | ActionCreateNewModelTask //30 | ||||
| ActionCreateGPUTrainTask //31 | |||||
| ) | ) | ||||
| // Action represents user operation type and other information to | // Action represents user operation type and other information to | ||||
| @@ -9,6 +9,7 @@ import ( | |||||
| "fmt" | "fmt" | ||||
| "io" | "io" | ||||
| "path" | "path" | ||||
| "strings" | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/obs" | "code.gitea.io/gitea/modules/obs" | ||||
| @@ -18,6 +19,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| gouuid "github.com/satori/go.uuid" | gouuid "github.com/satori/go.uuid" | ||||
| "xorm.io/builder" | |||||
| "xorm.io/xorm" | "xorm.io/xorm" | ||||
| ) | ) | ||||
| @@ -38,6 +40,7 @@ type Attachment struct { | |||||
| UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added | UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added | ||||
| CommentID int64 | CommentID int64 | ||||
| Name string | Name string | ||||
| Description string `xorm:"TEXT"` | |||||
| DownloadCount int64 `xorm:"DEFAULT 0"` | DownloadCount int64 `xorm:"DEFAULT 0"` | ||||
| Size int64 `xorm:"DEFAULT 0"` | Size int64 `xorm:"DEFAULT 0"` | ||||
| IsPrivate bool `xorm:"DEFAULT false"` | IsPrivate bool `xorm:"DEFAULT false"` | ||||
| @@ -47,6 +50,7 @@ type Attachment struct { | |||||
| FileChunk *FileChunk `xorm:"-"` | FileChunk *FileChunk `xorm:"-"` | ||||
| CanDel bool `xorm:"-"` | CanDel bool `xorm:"-"` | ||||
| Uploader *User `xorm:"-"` | |||||
| } | } | ||||
| type AttachmentUsername struct { | type AttachmentUsername struct { | ||||
| @@ -54,6 +58,27 @@ type AttachmentUsername struct { | |||||
| Name string | Name string | ||||
| } | } | ||||
| type AttachmentInfo struct { | |||||
| Attachment `xorm:"extends"` | |||||
| Repo *Repository `xorm:"extends"` | |||||
| RelAvatarLink string `xorm:"extends"` | |||||
| UserName string `xorm:"extends"` | |||||
| } | |||||
| type AttachmentsOptions struct { | |||||
| ListOptions | |||||
| DatasetIDs []int64 | |||||
| DecompressState int | |||||
| Type int | |||||
| UploaderID int64 | |||||
| NeedDatasetIDs bool | |||||
| NeedIsPrivate bool | |||||
| IsPrivate bool | |||||
| JustNeedZipFile bool | |||||
| NeedRepoInfo bool | |||||
| Keyword string | |||||
| } | |||||
| func (a *Attachment) AfterUpdate() { | func (a *Attachment) AfterUpdate() { | ||||
| if a.DatasetID > 0 { | if a.DatasetID > 0 { | ||||
| datasetIsPublicCount, err := x.Where("dataset_id = ? AND is_private = ?", a.DatasetID, false).Count(new(Attachment)) | datasetIsPublicCount, err := x.Where("dataset_id = ? AND is_private = ?", a.DatasetID, false).Count(new(Attachment)) | ||||
| @@ -326,6 +351,18 @@ func DeleteAttachmentsByComment(commentID int64, remove bool) (int, error) { | |||||
| func UpdateAttachment(atta *Attachment) error { | func UpdateAttachment(atta *Attachment) error { | ||||
| return updateAttachment(x, atta) | return updateAttachment(x, atta) | ||||
| } | } | ||||
| func UpdateAttachmentDescription(atta *Attachment) error { | |||||
| return updateAttachmentDescription(x, atta) | |||||
| } | |||||
| func updateAttachmentDescription(e Engine, atta *Attachment) error { | |||||
| var sess *xorm.Session | |||||
| sess = e.ID(atta.ID) | |||||
| _, err := sess.Cols("description").Update(atta) | |||||
| return err | |||||
| } | |||||
| func updateAttachment(e Engine, atta *Attachment) error { | func updateAttachment(e Engine, atta *Attachment) error { | ||||
| var sess *xorm.Session | var sess *xorm.Session | ||||
| @@ -503,3 +540,98 @@ func GetAttachmentSizeByDatasetID(datasetID int64) (int64, error) { | |||||
| func GetAllAttachmentSize() (int64, error) { | func GetAllAttachmentSize() (int64, error) { | ||||
| return x.SumInt(&Attachment{}, "size") | return x.SumInt(&Attachment{}, "size") | ||||
| } | } | ||||
| func Attachments(opts *AttachmentsOptions) ([]*AttachmentInfo, int64, error) { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| var cond = builder.NewCond() | |||||
| if opts.NeedDatasetIDs { | |||||
| cond = cond.And( | |||||
| builder.In("attachment.dataset_id", opts.DatasetIDs), | |||||
| ) | |||||
| } | |||||
| if opts.UploaderID > 0 { | |||||
| cond = cond.And( | |||||
| builder.Eq{"attachment.uploader_id": opts.UploaderID}, | |||||
| ) | |||||
| } | |||||
| if (opts.Type) >= 0 { | |||||
| cond = cond.And( | |||||
| builder.Eq{"attachment.type": opts.Type}, | |||||
| ) | |||||
| } | |||||
| if opts.NeedIsPrivate { | |||||
| cond = cond.And( | |||||
| builder.Eq{"attachment.is_private": opts.IsPrivate}, | |||||
| ) | |||||
| } | |||||
| if opts.JustNeedZipFile { | |||||
| var DecompressState []int32 | |||||
| DecompressState = append(DecompressState, DecompressStateDone, DecompressStateIng, DecompressStateFailed) | |||||
| cond = cond.And( | |||||
| builder.In("attachment.decompress_state", DecompressState), | |||||
| ) | |||||
| } | |||||
| var count int64 | |||||
| var err error | |||||
| if len(opts.Keyword) == 0 { | |||||
| count, err = sess.Where(cond).Count(new(Attachment)) | |||||
| } else { | |||||
| lowerKeyWord := strings.ToLower(opts.Keyword) | |||||
| cond = cond.And(builder.Or(builder.Like{"LOWER(attachment.name)", lowerKeyWord}, builder.Like{"LOWER(attachment.description)", lowerKeyWord})) | |||||
| count, err = sess.Table(&Attachment{}).Where(cond).Count(new(AttachmentInfo)) | |||||
| } | |||||
| if err != nil { | |||||
| return nil, 0, fmt.Errorf("Count: %v", err) | |||||
| } | |||||
| if opts.Page >= 0 && opts.PageSize > 0 { | |||||
| var start int | |||||
| if opts.Page == 0 { | |||||
| start = 0 | |||||
| } else { | |||||
| start = (opts.Page - 1) * opts.PageSize | |||||
| } | |||||
| sess.Limit(opts.PageSize, start) | |||||
| } | |||||
| sess.OrderBy("attachment.created_unix DESC") | |||||
| attachments := make([]*AttachmentInfo, 0, setting.UI.DatasetPagingNum) | |||||
| if err := sess.Table(&Attachment{}).Where(cond). | |||||
| Find(&attachments); err != nil { | |||||
| return nil, 0, fmt.Errorf("Find: %v", err) | |||||
| } | |||||
| if opts.NeedRepoInfo { | |||||
| for _, attachment := range attachments { | |||||
| dataset, err := GetDatasetByID(attachment.DatasetID) | |||||
| if err != nil { | |||||
| return nil, 0, fmt.Errorf("GetDatasetByID failed error: %v", err) | |||||
| } | |||||
| repo, err := GetRepositoryByID(dataset.RepoID) | |||||
| if err == nil { | |||||
| attachment.Repo = repo | |||||
| } else { | |||||
| return nil, 0, fmt.Errorf("GetRepositoryByID failed error: %v", err) | |||||
| } | |||||
| user, err := GetUserByID(attachment.UploaderID) | |||||
| if err == nil { | |||||
| attachment.RelAvatarLink = user.RelAvatarLink() | |||||
| attachment.UserName = user.Name | |||||
| } else { | |||||
| return nil, 0, fmt.Errorf("GetUserByID failed error: %v", err) | |||||
| } | |||||
| } | |||||
| } | |||||
| return attachments, count, nil | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| package models | |||||
| type BaseMessage struct { | |||||
| Code int | |||||
| Message string | |||||
| } | |||||
| var BaseOKMessage = BaseMessage{ | |||||
| 0, "", | |||||
| } | |||||
| func BaseErrorMessage(message string) BaseMessage { | |||||
| return BaseMessage{ | |||||
| 1, message, | |||||
| } | |||||
| } | |||||
| @@ -1,6 +1,7 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/util" | |||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "strconv" | "strconv" | ||||
| @@ -19,9 +20,17 @@ type CloudbrainStatus string | |||||
| type JobType string | type JobType string | ||||
| type ModelArtsJobStatus string | type ModelArtsJobStatus string | ||||
| const ( | |||||
| TypeCloudBrainOne int = iota | |||||
| TypeCloudBrainTwo | |||||
| TypeCloudBrainAll = -1 | |||||
| ) | |||||
| const ( | const ( | ||||
| NPUResource = "NPU" | NPUResource = "NPU" | ||||
| GPUResource = "CPU/GPU" | GPUResource = "CPU/GPU" | ||||
| AllResource = "all" | |||||
| //notebook storage category | //notebook storage category | ||||
| EVSCategory = "EVS" | EVSCategory = "EVS" | ||||
| @@ -86,6 +95,8 @@ const ( | |||||
| ModelArtsTrainJobCheckRunning ModelArtsJobStatus = "CHECK_RUNNING" //审核作业正在运行中 | ModelArtsTrainJobCheckRunning ModelArtsJobStatus = "CHECK_RUNNING" //审核作业正在运行中 | ||||
| ModelArtsTrainJobCheckRunningCompleted ModelArtsJobStatus = "CHECK_RUNNING_COMPLETED" //审核作业已经完成 | ModelArtsTrainJobCheckRunningCompleted ModelArtsJobStatus = "CHECK_RUNNING_COMPLETED" //审核作业已经完成 | ||||
| ModelArtsTrainJobCheckFailed ModelArtsJobStatus = "CHECK_FAILED" //审核作业失败 | ModelArtsTrainJobCheckFailed ModelArtsJobStatus = "CHECK_FAILED" //审核作业失败 | ||||
| DURATION_STR_ZERO = "00:00:00" | |||||
| ) | ) | ||||
| type Cloudbrain struct { | type Cloudbrain struct { | ||||
| @@ -102,15 +113,15 @@ type Cloudbrain struct { | |||||
| ContainerIp string | ContainerIp string | ||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| Duration int64 | |||||
| TrainJobDuration string | |||||
| Image string //镜像名称 | |||||
| GpuQueue string //GPU类型即GPU队列 | |||||
| ResourceSpecId int //GPU规格id | |||||
| DeletedAt time.Time `xorm:"deleted"` | |||||
| CanDebug bool `xorm:"-"` | |||||
| CanDel bool `xorm:"-"` | |||||
| CanModify bool `xorm:"-"` | |||||
| Duration int64 `xorm:"DEFAULT 0"` //运行时长 单位秒 | |||||
| TrainJobDuration string `xorm:"DEFAULT '00:00:00'"` | |||||
| Image string //镜像名称 | |||||
| GpuQueue string //GPU类型即GPU队列 | |||||
| ResourceSpecId int //GPU规格id | |||||
| DeletedAt time.Time `xorm:"deleted"` | |||||
| CanDebug bool `xorm:"-"` | |||||
| CanDel bool `xorm:"-"` | |||||
| CanModify bool `xorm:"-"` | |||||
| Type int | Type int | ||||
| BenchmarkTypeID int | BenchmarkTypeID int | ||||
| BenchmarkChildTypeID int | BenchmarkChildTypeID int | ||||
| @@ -150,6 +161,64 @@ type Cloudbrain struct { | |||||
| Repo *Repository `xorm:"-"` | Repo *Repository `xorm:"-"` | ||||
| BenchmarkTypeName string `xorm:"-"` | BenchmarkTypeName string `xorm:"-"` | ||||
| BenchmarkTypeRankLink string `xorm:"-"` | BenchmarkTypeRankLink string `xorm:"-"` | ||||
| StartTime timeutil.TimeStamp | |||||
| EndTime timeutil.TimeStamp | |||||
| } | |||||
| func (task *Cloudbrain) ComputeAndSetDuration() { | |||||
| var d int64 | |||||
| if task.StartTime == 0 { | |||||
| d = 0 | |||||
| } else if task.EndTime == 0 { | |||||
| if !task.IsTerminal() { | |||||
| d = time.Now().Unix() - task.StartTime.AsTime().Unix() | |||||
| } | |||||
| } else { | |||||
| d = task.EndTime.AsTime().Unix() - task.StartTime.AsTime().Unix() | |||||
| } | |||||
| if d < 0 { | |||||
| d = 0 | |||||
| } | |||||
| task.Duration = d | |||||
| task.TrainJobDuration = ConvertDurationToStr(d) | |||||
| } | |||||
| func (task *Cloudbrain) IsTerminal() bool { | |||||
| status := task.Status | |||||
| return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) || status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded) | |||||
| } | |||||
| func ConvertDurationToStr(duration int64) string { | |||||
| if duration == 0 { | |||||
| return DURATION_STR_ZERO | |||||
| } | |||||
| return util.AddZero(duration/3600) + ":" + util.AddZero(duration%3600/60) + ":" + util.AddZero(duration%60) | |||||
| } | |||||
| func IsTrainJobTerminal(status string) bool { | |||||
| return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) | |||||
| } | |||||
| func IsModelArtsDebugJobTerminal(status string) bool { | |||||
| return status == string(ModelArtsStopped) | |||||
| } | |||||
| func IsCloudBrainOneDebugJobTerminal(status string) bool { | |||||
| return status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded) | |||||
| } | |||||
| func ParseAndSetDurationFromCloudBrainOne(result JobResultPayload, task *Cloudbrain) { | |||||
| isActivated := result.JobStatus.CreatedTime > 0 | |||||
| if task.StartTime == 0 && isActivated { | |||||
| task.StartTime = timeutil.TimeStamp(result.JobStatus.CreatedTime / 1000) | |||||
| } | |||||
| if task.EndTime == 0 && IsCloudBrainOneDebugJobTerminal(task.Status) && isActivated { | |||||
| if result.JobStatus.CompletedTime > 0 { | |||||
| task.EndTime = timeutil.TimeStamp(result.JobStatus.CompletedTime / 1000) | |||||
| } | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| } | } | ||||
| type CloudbrainInfo struct { | type CloudbrainInfo struct { | ||||
| @@ -319,7 +388,7 @@ type JobResultPayload struct { | |||||
| AppProgress string `json:"appProgress"` | AppProgress string `json:"appProgress"` | ||||
| AppTrackingURL string `json:"appTrackingUrl"` | AppTrackingURL string `json:"appTrackingUrl"` | ||||
| AppLaunchedTime int64 `json:"appLaunchedTime"` | AppLaunchedTime int64 `json:"appLaunchedTime"` | ||||
| AppCompletedTime interface{} `json:"appCompletedTime"` | |||||
| AppCompletedTime int64 `json:"appCompletedTime"` | |||||
| AppExitCode int `json:"appExitCode"` | AppExitCode int `json:"appExitCode"` | ||||
| AppExitDiagnostics string `json:"appExitDiagnostics"` | AppExitDiagnostics string `json:"appExitDiagnostics"` | ||||
| AppExitType interface{} `json:"appExitType"` | AppExitType interface{} `json:"appExitType"` | ||||
| @@ -1019,6 +1088,7 @@ type GetTrainJobResult struct { | |||||
| NasShareAddr string `json:"nas_share_addr"` | NasShareAddr string `json:"nas_share_addr"` | ||||
| DatasetName string | DatasetName string | ||||
| ModelMetricList string `json:"model_metric_list"` //列表里包含f1_score,recall,precision,accuracy,若有的话 | ModelMetricList string `json:"model_metric_list"` //列表里包含f1_score,recall,precision,accuracy,若有的话 | ||||
| StartTime int64 `json:"start_time"` //训练作业开始时间。 | |||||
| } | } | ||||
| type GetTrainJobLogResult struct { | type GetTrainJobLogResult struct { | ||||
| @@ -1117,7 +1187,7 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| } else { | } else { | ||||
| lowerKeyWord := strings.ToLower(opts.Keyword) | lowerKeyWord := strings.ToLower(opts.Keyword) | ||||
| cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) | |||||
| cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, builder.Like{"LOWER(cloudbrain.display_job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) | |||||
| count, err = sess.Table(&Cloudbrain{}).Where(cond). | count, err = sess.Table(&Cloudbrain{}).Where(cond). | ||||
| Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | ||||
| @@ -1283,6 +1353,7 @@ func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int, e | |||||
| } | } | ||||
| func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) { | func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) { | ||||
| cloudbrain.TrainJobDuration = DURATION_STR_ZERO | |||||
| if _, err = x.Insert(cloudbrain); err != nil { | if _, err = x.Insert(cloudbrain); err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -1327,13 +1398,13 @@ func GetCloudbrainByJobIDAndIsLatestVersion(jobID string, isLatestVersion string | |||||
| func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) { | func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) { | ||||
| cloudBrains := make([]*Cloudbrain, 0) | cloudBrains := make([]*Cloudbrain, 0) | ||||
| err := x.Cols("job_id", "status", "type", "job_type", "version_id").Where("user_id=? AND status !=?", userID, string(JobStopped)).Find(&cloudBrains) | |||||
| err := x.Cols("job_id", "status", "type", "job_type", "version_id", "start_time").Where("user_id=? AND status !=?", userID, string(JobStopped)).Find(&cloudBrains) | |||||
| return cloudBrains, err | return cloudBrains, err | ||||
| } | } | ||||
| func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | ||||
| cloudBrains := make([]*Cloudbrain, 0) | cloudBrains := make([]*Cloudbrain, 0) | ||||
| err := x.Cols("job_id", "status", "type", "job_type", "version_id").Where("repo_id=? AND status !=?", repoID, string(JobStopped)).Find(&cloudBrains) | |||||
| err := x.Cols("job_id", "status", "type", "job_type", "version_id", "start_time").Where("repo_id=? AND status !=?", repoID, string(JobStopped)).Find(&cloudBrains) | |||||
| return cloudBrains, err | return cloudBrains, err | ||||
| } | } | ||||
| @@ -1377,7 +1448,7 @@ func UpdateTrainJobVersion(job *Cloudbrain) error { | |||||
| func updateJobTrainVersion(e Engine, job *Cloudbrain) error { | func updateJobTrainVersion(e Engine, job *Cloudbrain) error { | ||||
| var sess *xorm.Session | var sess *xorm.Session | ||||
| sess = e.Where("job_id = ? AND version_name=?", job.JobID, job.VersionName) | sess = e.Where("job_id = ? AND version_name=?", job.JobID, job.VersionName) | ||||
| _, err := sess.Cols("status", "train_job_duration").Update(job) | |||||
| _, err := sess.Cols("status", "train_job_duration", "duration", "start_time", "end_time").Update(job) | |||||
| return err | return err | ||||
| } | } | ||||
| @@ -1427,6 +1498,15 @@ func GetCloudBrainUnStoppedJob() ([]*Cloudbrain, error) { | |||||
| Find(&cloudbrains) | Find(&cloudbrains) | ||||
| } | } | ||||
| func GetStoppedJobWithNoDurationJob() ([]*Cloudbrain, error) { | |||||
| cloudbrains := make([]*Cloudbrain, 0) | |||||
| return cloudbrains, x. | |||||
| In("status", ModelArtsTrainJobCompleted, ModelArtsTrainJobFailed, ModelArtsTrainJobKilled, ModelArtsStopped, JobStopped, JobFailed, JobSucceeded). | |||||
| Where("train_job_duration is null or train_job_duration = '' "). | |||||
| Limit(100). | |||||
| Find(&cloudbrains) | |||||
| } | |||||
| func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { | func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { | ||||
| count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | ||||
| return int(count), err | return int(count), err | ||||
| @@ -1457,7 +1537,7 @@ func UpdateInferenceJob(job *Cloudbrain) error { | |||||
| func updateInferenceJob(e Engine, job *Cloudbrain) error { | func updateInferenceJob(e Engine, job *Cloudbrain) error { | ||||
| var sess *xorm.Session | var sess *xorm.Session | ||||
| sess = e.Where("job_id = ?", job.JobID) | sess = e.Where("job_id = ?", job.JobID) | ||||
| _, err := sess.Cols("status", "train_job_duration").Update(job) | |||||
| _, err := sess.Cols("status", "train_job_duration", "duration", "start_time", "end_time").Update(job) | |||||
| return err | return err | ||||
| } | } | ||||
| func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) { | func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) { | ||||
| @@ -22,6 +22,7 @@ type Dataset struct { | |||||
| Category string | Category string | ||||
| Description string `xorm:"TEXT"` | Description string `xorm:"TEXT"` | ||||
| DownloadTimes int64 | DownloadTimes int64 | ||||
| NumStars int `xorm:"INDEX NOT NULL DEFAULT 0"` | |||||
| License string | License string | ||||
| Task string | Task string | ||||
| ReleaseID int64 `xorm:"INDEX"` | ReleaseID int64 `xorm:"INDEX"` | ||||
| @@ -35,6 +36,11 @@ type Dataset struct { | |||||
| Attachments []*Attachment `xorm:"-"` | Attachments []*Attachment `xorm:"-"` | ||||
| } | } | ||||
| type DatasetWithStar struct { | |||||
| Dataset | |||||
| IsStaring bool | |||||
| } | |||||
| func (d *Dataset) IsPrivate() bool { | func (d *Dataset) IsPrivate() bool { | ||||
| switch d.Status { | switch d.Status { | ||||
| case DatasetStatusPrivate: | case DatasetStatusPrivate: | ||||
| @@ -91,33 +97,37 @@ type SearchDatasetOptions struct { | |||||
| OwnerID int64 | OwnerID int64 | ||||
| RepoID int64 | RepoID int64 | ||||
| IncludePublic bool | IncludePublic bool | ||||
| Category string | |||||
| Task string | |||||
| License string | |||||
| ListOptions | ListOptions | ||||
| SearchOrderBy | SearchOrderBy | ||||
| IsOwner bool | IsOwner bool | ||||
| } | } | ||||
| func CreateDataset(dataset *Dataset) (err error) { | func CreateDataset(dataset *Dataset) (err error) { | ||||
| if _, err = x.Insert(dataset); err != nil { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err := sess.Begin(); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| return nil | |||||
| } | |||||
| func CreateDefaultDatasetToRepo(repo *Repository) (err error) { | |||||
| dataset := &Dataset{RepoID: repo.ID} | |||||
| has, err := x.Get(dataset) | |||||
| datasetByRepoId := &Dataset{RepoID: dataset.RepoID} | |||||
| has, err := sess.Get(datasetByRepoId) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| if !has { | |||||
| dataset.Status = DatasetStatusPrivate | |||||
| dataset.Title = repo.Name | |||||
| if err = CreateDataset(dataset); err != nil { | |||||
| return err | |||||
| } | |||||
| if has { | |||||
| return fmt.Errorf("The dataset already exists.") | |||||
| } | } | ||||
| return nil | |||||
| if _, err = sess.Insert(dataset); err != nil { | |||||
| return err | |||||
| } | |||||
| return sess.Commit() | |||||
| } | } | ||||
| func SearchDataset(opts *SearchDatasetOptions) (DatasetList, int64, error) { | func SearchDataset(opts *SearchDatasetOptions) (DatasetList, int64, error) { | ||||
| @@ -130,7 +140,18 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||||
| cond = cond.And(builder.Neq{"dataset.status": DatasetStatusDeleted}) | cond = cond.And(builder.Neq{"dataset.status": DatasetStatusDeleted}) | ||||
| if len(opts.Keyword) > 0 { | if len(opts.Keyword) > 0 { | ||||
| cond = cond.And(builder.Like{"dataset.title", opts.Keyword}) | |||||
| cond = cond.And(builder.Or(builder.Like{"dataset.title", opts.Keyword}, builder.Like{"dataset.description", opts.Keyword})) | |||||
| } | |||||
| if len(opts.Category) > 0 { | |||||
| cond = cond.And(builder.Eq{"dataset.category": opts.Category}) | |||||
| } | |||||
| if len(opts.Task) > 0 { | |||||
| cond = cond.And(builder.Eq{"dataset.task": opts.Task}) | |||||
| } | |||||
| if len(opts.License) > 0 { | |||||
| cond = cond.And(builder.Eq{"dataset.license": opts.License}) | |||||
| } | } | ||||
| if opts.RepoID > 0 { | if opts.RepoID > 0 { | ||||
| @@ -139,12 +160,13 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||||
| if opts.IncludePublic { | if opts.IncludePublic { | ||||
| cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) | cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) | ||||
| cond = cond.And(builder.Eq{"attachment.is_private": false}) | |||||
| if opts.OwnerID > 0 { | if opts.OwnerID > 0 { | ||||
| if len(opts.Keyword) == 0 { | if len(opts.Keyword) == 0 { | ||||
| cond = cond.Or(builder.Eq{"repository.owner_id": opts.OwnerID}) | cond = cond.Or(builder.Eq{"repository.owner_id": opts.OwnerID}) | ||||
| } else { | } else { | ||||
| subCon := builder.NewCond() | subCon := builder.NewCond() | ||||
| subCon = subCon.And(builder.Eq{"repository.owner_id": opts.OwnerID}, builder.Like{"dataset.title", opts.Keyword}) | |||||
| subCon = subCon.And(builder.Eq{"repository.owner_id": opts.OwnerID}, builder.Or(builder.Like{"dataset.title", opts.Keyword}, builder.Like{"dataset.description", opts.Keyword})) | |||||
| cond = cond.Or(subCon) | cond = cond.Or(subCon) | ||||
| } | } | ||||
| @@ -153,6 +175,7 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||||
| cond = cond.And(builder.Eq{"repository.owner_id": opts.OwnerID}) | cond = cond.And(builder.Eq{"repository.owner_id": opts.OwnerID}) | ||||
| if !opts.IsOwner { | if !opts.IsOwner { | ||||
| cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) | cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) | ||||
| cond = cond.And(builder.Eq{"attachment.is_private": false}) | |||||
| } | } | ||||
| } | } | ||||
| @@ -169,14 +192,20 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da | |||||
| defer sess.Close() | defer sess.Close() | ||||
| datasets := make(DatasetList, 0, opts.PageSize) | datasets := make(DatasetList, 0, opts.PageSize) | ||||
| selectColumnsSql := "distinct dataset.id,dataset.title, dataset.status, dataset.category, dataset.description, dataset.download_times, dataset.license, dataset.task, dataset.release_id, dataset.user_id, dataset.repo_id, dataset.created_unix,dataset.updated_unix,dataset.num_stars" | |||||
| count, err := sess.Join("INNER", "repository", "repository.id = dataset.repo_id").Where(cond).Count(new(Dataset)) | |||||
| count, err := sess.Distinct("dataset.id").Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||||
| Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). | |||||
| Where(cond).Count(new(Dataset)) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, 0, fmt.Errorf("Count: %v", err) | return nil, 0, fmt.Errorf("Count: %v", err) | ||||
| } | } | ||||
| sess.Select("dataset.*").Join("INNER", "repository", "repository.id = dataset.repo_id").Where(cond).OrderBy(opts.SearchOrderBy.String()) | |||||
| sess.Select(selectColumnsSql).Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||||
| Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). | |||||
| Where(cond).OrderBy(opts.SearchOrderBy.String()) | |||||
| if opts.PageSize > 0 { | if opts.PageSize > 0 { | ||||
| sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | ||||
| } | } | ||||
| @@ -231,13 +260,23 @@ func getDatasetAttachments(e Engine, typeCloudBrain int, isSigned bool, user *Us | |||||
| sort.Sort(sortedRels) | sort.Sort(sortedRels) | ||||
| // Select attachments | // Select attachments | ||||
| err = e. | |||||
| Asc("dataset_id"). | |||||
| In("dataset_id", sortedRels.ID). | |||||
| And("type = ?", typeCloudBrain). | |||||
| Find(&attachments, Attachment{}) | |||||
| if err != nil { | |||||
| return err | |||||
| if typeCloudBrain == -1 { | |||||
| err = e. | |||||
| Asc("dataset_id"). | |||||
| In("dataset_id", sortedRels.ID). | |||||
| Find(&attachments, Attachment{}) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| } else { | |||||
| err = e. | |||||
| Asc("dataset_id"). | |||||
| In("dataset_id", sortedRels.ID). | |||||
| And("type = ?", typeCloudBrain). | |||||
| Find(&attachments, Attachment{}) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| } | } | ||||
| // merge join | // merge join | ||||
| @@ -301,9 +340,6 @@ func GetDatasetByID(id int64) (*Dataset, error) { | |||||
| } | } | ||||
| func GetDatasetByRepo(repo *Repository) (*Dataset, error) { | func GetDatasetByRepo(repo *Repository) (*Dataset, error) { | ||||
| if err := CreateDefaultDatasetToRepo(repo); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| dataset := &Dataset{RepoID: repo.ID} | dataset := &Dataset{RepoID: repo.ID} | ||||
| has, err := x.Get(dataset) | has, err := x.Get(dataset) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -316,6 +352,12 @@ func GetDatasetByRepo(repo *Repository) (*Dataset, error) { | |||||
| } | } | ||||
| } | } | ||||
| func GetDatasetStarByUser(user *User) ([]*DatasetStar, error) { | |||||
| datasetStars := make([]*DatasetStar, 0) | |||||
| err := x.Cols("id", "uid", "dataset_id", "created_unix").Where("uid=?", user.ID).Find(&datasetStars) | |||||
| return datasetStars, err | |||||
| } | |||||
| func DeleteDataset(datasetID int64, uid int64) error { | func DeleteDataset(datasetID int64, uid int64) error { | ||||
| var err error | var err error | ||||
| sess := x.NewSession() | sess := x.NewSession() | ||||
| @@ -0,0 +1,70 @@ | |||||
| package models | |||||
| import "code.gitea.io/gitea/modules/timeutil" | |||||
| type DatasetStar struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| UID int64 `xorm:"UNIQUE(s)"` | |||||
| DatasetID int64 `xorm:"UNIQUE(s)"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| } | |||||
| // StarRepo or unstar repository. | |||||
| func StarDataset(userID, datasetID int64, star bool) error { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err := sess.Begin(); err != nil { | |||||
| return err | |||||
| } | |||||
| if star { | |||||
| if isDatasetStaring(sess, userID, datasetID) { | |||||
| return nil | |||||
| } | |||||
| if _, err := sess.Insert(&DatasetStar{UID: userID, DatasetID: datasetID}); err != nil { | |||||
| return err | |||||
| } | |||||
| if _, err := sess.Exec("UPDATE `dataset` SET num_stars = num_stars + 1 WHERE id = ?", datasetID); err != nil { | |||||
| return err | |||||
| } | |||||
| if _, err := sess.Exec("UPDATE `user` SET num_dataset_stars = num_dataset_stars + 1 WHERE id = ?", userID); err != nil { | |||||
| return err | |||||
| } | |||||
| } else { | |||||
| if !isDatasetStaring(sess, userID, datasetID) { | |||||
| return nil | |||||
| } | |||||
| if _, err := sess.Delete(&DatasetStar{0, userID, datasetID, 0}); err != nil { | |||||
| return err | |||||
| } | |||||
| if _, err := sess.Exec("UPDATE `dataset` SET num_stars = num_stars - 1 WHERE id = ?", datasetID); err != nil { | |||||
| return err | |||||
| } | |||||
| if _, err := sess.Exec("UPDATE `user` SET num_dataset_stars = num_dataset_stars - 1 WHERE id = ?", userID); err != nil { | |||||
| return err | |||||
| } | |||||
| } | |||||
| return sess.Commit() | |||||
| } | |||||
| func IsDatasetStaringByRepoId(userID, repoID int64) bool { | |||||
| dataset, _ := GetDatasetByRepo(&Repository{ID: repoID}) | |||||
| if dataset == nil { | |||||
| return false | |||||
| } | |||||
| return isDatasetStaring(x, userID, dataset.ID) | |||||
| } | |||||
| func IsDatasetStaring(userID, datasetID int64) bool { | |||||
| return isDatasetStaring(x, userID, datasetID) | |||||
| } | |||||
| func isDatasetStaring(e Engine, userID, datasetID int64) bool { | |||||
| has, _ := e.Get(&DatasetStar{0, userID, datasetID, 0}) | |||||
| return has | |||||
| } | |||||
| @@ -0,0 +1,186 @@ | |||||
| DROP FOREIGN TABLE public.dataset_es; | |||||
| CREATE FOREIGN TABLE public.dataset_es | |||||
| ( | |||||
| id bigint NOT NULL, | |||||
| title character varying(255), | |||||
| status integer, | |||||
| category character varying(255), | |||||
| description text, | |||||
| download_times bigint, | |||||
| license character varying(255), | |||||
| task character varying(255), | |||||
| release_id bigint, | |||||
| user_id bigint, | |||||
| repo_id bigint, | |||||
| created_unix bigint, | |||||
| updated_unix bigint, | |||||
| file_name text, | |||||
| file_desc text | |||||
| )SERVER multicorn_es | |||||
| OPTIONS | |||||
| ( | |||||
| host '192.168.207.94', | |||||
| port '9200', | |||||
| index 'dataset-es-index', | |||||
| rowid_column 'id', | |||||
| default_sort '_id' | |||||
| ) | |||||
| ; | |||||
| DELETE FROM public.dataset_es; | |||||
| INSERT INTO public.dataset_es( | |||||
| id, | |||||
| title, | |||||
| status, | |||||
| category, | |||||
| description, | |||||
| download_times, | |||||
| license, task, | |||||
| release_id, | |||||
| user_id, | |||||
| repo_id, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| file_name, | |||||
| file_desc | |||||
| ) | |||||
| SELECT | |||||
| b.id, | |||||
| b.title, | |||||
| b.status, | |||||
| b.category, | |||||
| b.description, | |||||
| b.download_times, | |||||
| b.license, | |||||
| b.task, | |||||
| b.release_id, | |||||
| b.user_id, | |||||
| b.repo_id, | |||||
| b.created_unix, | |||||
| b.updated_unix, | |||||
| (select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false), | |||||
| (select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false) | |||||
| FROM public.dataset b,public.repository c where b.repo_id=c.id and c.is_private=false; | |||||
| DROP TRIGGER IF EXISTS es_insert_dataset on public.dataset; | |||||
| CREATE OR REPLACE FUNCTION public.insert_dataset_data() RETURNS trigger AS | |||||
| $def$ | |||||
| DECLARE | |||||
| privateValue boolean=false; | |||||
| BEGIN | |||||
| select into privateValue is_private from public.repository where id=NEW.repo_id; | |||||
| if not privateValue then | |||||
| INSERT INTO public.dataset_es( | |||||
| id, | |||||
| title, | |||||
| status, | |||||
| category, | |||||
| description, | |||||
| download_times, | |||||
| license, | |||||
| task, | |||||
| release_id, | |||||
| user_id, | |||||
| repo_id, | |||||
| created_unix, | |||||
| updated_unix) | |||||
| VALUES ( | |||||
| NEW.id, | |||||
| NEW.title, | |||||
| NEW.status, | |||||
| NEW.category, | |||||
| NEW.description, | |||||
| NEW.download_times, | |||||
| NEW.license, | |||||
| NEW.task, | |||||
| NEW.release_id, | |||||
| NEW.user_id, | |||||
| NEW.repo_id, | |||||
| NEW.created_unix, | |||||
| NEW.updated_unix | |||||
| ); | |||||
| end if; | |||||
| RETURN NEW; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_insert_dataset | |||||
| AFTER INSERT ON public.dataset | |||||
| FOR EACH ROW EXECUTE PROCEDURE insert_dataset_data(); | |||||
| ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_insert_dataset; | |||||
| DROP TRIGGER IF EXISTS es_udpate_dataset_file_name on public.attachment; | |||||
| CREATE OR REPLACE FUNCTION public.udpate_dataset_file_name() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| if (TG_OP = 'UPDATE') then | |||||
| update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id; | |||||
| elsif (TG_OP = 'INSERT') then | |||||
| update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id; | |||||
| elsif (TG_OP = 'DELETE') then | |||||
| update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id; | |||||
| update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id; | |||||
| end if; | |||||
| return NEW; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_udpate_dataset_file_name | |||||
| AFTER INSERT OR UPDATE OR DELETE ON public.attachment | |||||
| FOR EACH ROW EXECUTE PROCEDURE udpate_dataset_file_name(); | |||||
| ALTER TABLE public.attachment ENABLE ALWAYS TRIGGER es_udpate_dataset_file_name; | |||||
| DROP TRIGGER IF EXISTS es_update_dataset on public.dataset; | |||||
| CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| UPDATE public.dataset_es | |||||
| SET description=NEW.description, | |||||
| title=NEW.title, | |||||
| category=NEW.category, | |||||
| task=NEW.task, | |||||
| download_times=NEW.download_times, | |||||
| updated_unix=NEW.updated_unix, | |||||
| file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false), | |||||
| file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false) | |||||
| where id=NEW.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_update_dataset | |||||
| AFTER UPDATE ON public.dataset | |||||
| FOR EACH ROW EXECUTE PROCEDURE update_dataset(); | |||||
| ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_update_dataset; | |||||
| DROP TRIGGER IF EXISTS es_delete_dataset on public.dataset; | |||||
| CREATE OR REPLACE FUNCTION public.delete_dataset() RETURNS trigger AS | |||||
| $def$ | |||||
| declare | |||||
| BEGIN | |||||
| DELETE FROM public.dataset_es where id=OLD.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_delete_dataset | |||||
| AFTER DELETE ON public.dataset | |||||
| FOR EACH ROW EXECUTE PROCEDURE delete_dataset(); | |||||
| ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_delete_dataset; | |||||
| @@ -0,0 +1,215 @@ | |||||
| DROP FOREIGN TABLE public.issue_es; | |||||
| CREATE FOREIGN TABLE public.issue_es | |||||
| ( | |||||
| id bigint NOT NULL, | |||||
| repo_id bigint, | |||||
| index bigint, | |||||
| poster_id bigint, | |||||
| original_author character varying(255), | |||||
| original_author_id bigint, | |||||
| name character varying(255) , | |||||
| content text, | |||||
| comment text, | |||||
| milestone_id bigint, | |||||
| priority integer, | |||||
| is_closed boolean, | |||||
| is_pull boolean, | |||||
| pr_id bigint, | |||||
| num_comments integer, | |||||
| ref character varying(255), | |||||
| deadline_unix bigint, | |||||
| created_unix bigint, | |||||
| updated_unix bigint, | |||||
| closed_unix bigint, | |||||
| is_locked boolean NOT NULL, | |||||
| amount bigint, | |||||
| is_transformed boolean NOT NULL | |||||
| )SERVER multicorn_es | |||||
| OPTIONS | |||||
| ( | |||||
| host '192.168.207.94', | |||||
| port '9200', | |||||
| index 'issue-es-index', | |||||
| rowid_column 'id', | |||||
| default_sort '_id' | |||||
| ) | |||||
| ; | |||||
| delete from public.issue_es; | |||||
| INSERT INTO public.issue_es( | |||||
| id, | |||||
| repo_id, | |||||
| index, | |||||
| poster_id, | |||||
| original_author, | |||||
| original_author_id, | |||||
| name, | |||||
| content, | |||||
| milestone_id, | |||||
| priority, | |||||
| is_closed, | |||||
| is_pull, | |||||
| num_comments, | |||||
| ref, | |||||
| deadline_unix, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| closed_unix, | |||||
| is_locked, | |||||
| amount, | |||||
| is_transformed,comment,pr_id) | |||||
| SELECT | |||||
| b.id, | |||||
| b.repo_id, | |||||
| b.index, | |||||
| b.poster_id, | |||||
| b.original_author, | |||||
| b.original_author_id, | |||||
| b.name, | |||||
| b.content, | |||||
| b.milestone_id, | |||||
| b.priority, | |||||
| b.is_closed, | |||||
| b.is_pull, | |||||
| b.num_comments, | |||||
| b.ref, | |||||
| b.deadline_unix, | |||||
| b.created_unix, | |||||
| b.updated_unix, | |||||
| b.closed_unix, | |||||
| b.is_locked, | |||||
| b.amount, | |||||
| b.is_transformed, | |||||
| (select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id), | |||||
| (select id from public.pull_request d where b.id=d.issue_id and b.is_pull=true) | |||||
| FROM public.issue b,public.repository c where b.repo_id=c.id and c.is_private=false; | |||||
| CREATE OR REPLACE FUNCTION public.insert_issue_data() RETURNS trigger AS | |||||
| $def$ | |||||
| DECLARE | |||||
| privateValue boolean=false; | |||||
| BEGIN | |||||
| select into privateValue is_private from public.repository where id=NEW.repo_id; | |||||
| if not privateValue then | |||||
| INSERT INTO public.issue_es( | |||||
| id, | |||||
| repo_id, | |||||
| index, | |||||
| poster_id, | |||||
| original_author, | |||||
| original_author_id, | |||||
| name, | |||||
| content, | |||||
| milestone_id, | |||||
| priority, | |||||
| is_closed, | |||||
| is_pull, | |||||
| num_comments, | |||||
| ref, | |||||
| deadline_unix, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| closed_unix, | |||||
| is_locked, | |||||
| amount, | |||||
| is_transformed) | |||||
| VALUES ( | |||||
| NEW.id, | |||||
| NEW.repo_id, | |||||
| NEW.index, | |||||
| NEW.poster_id, | |||||
| NEW.original_author, | |||||
| NEW.original_author_id, | |||||
| NEW.name, | |||||
| NEW.content, | |||||
| NEW.milestone_id, | |||||
| NEW.priority, | |||||
| NEW.is_closed, | |||||
| NEW.is_pull, | |||||
| NEW.num_comments, | |||||
| NEW.ref, | |||||
| NEW.deadline_unix, | |||||
| NEW.created_unix, | |||||
| NEW.updated_unix, | |||||
| NEW.closed_unix, | |||||
| NEW.is_locked, | |||||
| NEW.amount, | |||||
| NEW.is_transformed | |||||
| ); | |||||
| end if; | |||||
| RETURN NEW; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| DROP TRIGGER IF EXISTS es_insert_issue on public.issue; | |||||
| CREATE TRIGGER es_insert_issue | |||||
| AFTER INSERT ON public.issue | |||||
| FOR EACH ROW EXECUTE PROCEDURE insert_issue_data(); | |||||
| ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_insert_issue; | |||||
| CREATE OR REPLACE FUNCTION public.udpate_issue_comment() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| if (TG_OP = 'DELETE') then | |||||
| update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=OLD.issue_id) where id=OLD.issue_id; | |||||
| elsif (TG_OP = 'UPDATE') then | |||||
| update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.issue_id) where id=NEW.issue_id; | |||||
| end if; | |||||
| return null; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| DROP TRIGGER IF EXISTS es_udpate_issue_comment on public.comment; | |||||
| CREATE TRIGGER es_udpate_issue_comment | |||||
| AFTER DELETE OR UPDATE ON public.comment | |||||
| FOR EACH ROW EXECUTE PROCEDURE udpate_issue_comment(); | |||||
| ALTER TABLE public.comment ENABLE ALWAYS TRIGGER es_udpate_issue_comment; | |||||
| CREATE OR REPLACE FUNCTION public.update_issue() RETURNS trigger AS | |||||
| $def$ | |||||
| declare | |||||
| BEGIN | |||||
| UPDATE public.issue_es | |||||
| SET content=NEW.content, | |||||
| name=NEW.name, | |||||
| is_closed=NEW.is_closed, | |||||
| num_comments=NEW.num_comments, | |||||
| comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.id) | |||||
| where id=NEW.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| DROP TRIGGER IF EXISTS es_update_issue on public.issue; | |||||
| CREATE TRIGGER es_update_issue | |||||
| AFTER UPDATE ON public.issue | |||||
| FOR EACH ROW EXECUTE PROCEDURE update_issue(); | |||||
| ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_update_issue; | |||||
| CREATE OR REPLACE FUNCTION public.delete_issue() RETURNS trigger AS | |||||
| $def$ | |||||
| declare | |||||
| BEGIN | |||||
| DELETE FROM public.issue_es where id=OLD.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| DROP TRIGGER IF EXISTS es_delete_issue on public.issue; | |||||
| CREATE TRIGGER es_delete_issue | |||||
| AFTER DELETE ON public.issue | |||||
| FOR EACH ROW EXECUTE PROCEDURE delete_issue(); | |||||
| ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_delete_issue; | |||||
| @@ -0,0 +1,532 @@ | |||||
| -- 要处理项目从私有变为公有,并且从公有变成私有的情况 | |||||
| DROP FOREIGN table if exists public.repository_es; | |||||
| CREATE FOREIGN TABLE public.repository_es ( | |||||
| id bigint NOT NULL, | |||||
| owner_id bigint, | |||||
| owner_name character varying(255), | |||||
| lower_name character varying(255) NOT NULL, | |||||
| name character varying(255) NOT NULL, | |||||
| description text, | |||||
| website character varying(2048), | |||||
| original_service_type integer, | |||||
| original_url character varying(2048), | |||||
| default_branch character varying(255), | |||||
| num_watches integer, | |||||
| num_stars integer, | |||||
| num_forks integer, | |||||
| num_issues integer, | |||||
| num_closed_issues integer, | |||||
| num_pulls integer, | |||||
| num_closed_pulls integer, | |||||
| num_milestones integer DEFAULT 0 NOT NULL, | |||||
| num_closed_milestones integer DEFAULT 0 NOT NULL, | |||||
| is_private boolean, | |||||
| is_empty boolean, | |||||
| is_archived boolean, | |||||
| is_mirror boolean, | |||||
| status integer DEFAULT 0 NOT NULL, | |||||
| is_fork boolean DEFAULT false NOT NULL, | |||||
| fork_id bigint, | |||||
| is_template boolean DEFAULT false NOT NULL, | |||||
| template_id bigint, | |||||
| size bigint DEFAULT 0 NOT NULL, | |||||
| is_fsck_enabled boolean DEFAULT true NOT NULL, | |||||
| close_issues_via_commit_in_any_branch boolean DEFAULT false NOT NULL, | |||||
| topics text, | |||||
| avatar character varying(64), | |||||
| created_unix bigint, | |||||
| updated_unix bigint, | |||||
| contract_address character varying(255), | |||||
| block_chain_status integer DEFAULT 0 NOT NULL, | |||||
| balance character varying(255) DEFAULT '0'::character varying NOT NULL, | |||||
| clone_cnt bigint DEFAULT 0 NOT NULL, | |||||
| license character varying(100), | |||||
| download_cnt bigint DEFAULT 0 NOT NULL, | |||||
| num_commit bigint DEFAULT 0 NOT NULL, | |||||
| git_clone_cnt bigint DEFAULT 0 NOT NULL, | |||||
| creator_id bigint NOT NULL DEFAULT 0, | |||||
| repo_type integer NOT NULL DEFAULT 0, | |||||
| lang character varying(2048), | |||||
| alias character varying(255), | |||||
| lower_alias character varying(255) | |||||
| ) SERVER multicorn_es | |||||
| OPTIONS | |||||
| ( | |||||
| host '192.168.207.94', | |||||
| port '9200', | |||||
| index 'repository-es-index', | |||||
| rowid_column 'id', | |||||
| default_sort '_id' | |||||
| ) | |||||
| ; | |||||
| delete from public.repository_es; | |||||
| INSERT INTO public.repository_es (id, | |||||
| owner_id, | |||||
| owner_name, | |||||
| lower_name, | |||||
| name, | |||||
| description, | |||||
| website, | |||||
| original_service_type, | |||||
| original_url, | |||||
| default_branch, | |||||
| num_watches, | |||||
| num_stars, | |||||
| num_forks, | |||||
| num_issues, | |||||
| num_closed_issues, | |||||
| num_pulls, | |||||
| num_closed_pulls, | |||||
| num_milestones, | |||||
| num_closed_milestones, | |||||
| is_private, | |||||
| is_empty, | |||||
| is_archived, | |||||
| is_mirror, | |||||
| status, | |||||
| is_fork, | |||||
| fork_id, | |||||
| is_template, | |||||
| template_id, | |||||
| size, | |||||
| is_fsck_enabled, | |||||
| close_issues_via_commit_in_any_branch, | |||||
| topics, | |||||
| avatar, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| contract_address, | |||||
| block_chain_status, | |||||
| balance, | |||||
| clone_cnt, | |||||
| num_commit, | |||||
| git_clone_cnt, | |||||
| creator_id, | |||||
| repo_type, | |||||
| lang, | |||||
| alias, | |||||
| lower_alias | |||||
| ) | |||||
| SELECT | |||||
| id, | |||||
| owner_id, | |||||
| owner_name, | |||||
| lower_name, | |||||
| name, | |||||
| description, | |||||
| website, | |||||
| original_service_type, | |||||
| original_url, | |||||
| default_branch, | |||||
| num_watches, | |||||
| num_stars, | |||||
| num_forks, | |||||
| num_issues, | |||||
| num_closed_issues, | |||||
| num_pulls, | |||||
| num_closed_pulls, | |||||
| num_milestones, | |||||
| num_closed_milestones, | |||||
| is_private, | |||||
| is_empty, | |||||
| is_archived, | |||||
| is_mirror, | |||||
| status, | |||||
| is_fork, | |||||
| fork_id, | |||||
| is_template, | |||||
| template_id, | |||||
| size, | |||||
| is_fsck_enabled, | |||||
| close_issues_via_commit_in_any_branch, | |||||
| topics, | |||||
| avatar, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| contract_address, | |||||
| block_chain_status, | |||||
| balance, | |||||
| clone_cnt, | |||||
| num_commit, | |||||
| git_clone_cnt, | |||||
| creator_id, | |||||
| repo_type, | |||||
| (select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id), | |||||
| alias, | |||||
| lower_alias | |||||
| FROM public.repository b where b.is_private=false; | |||||
| DROP TRIGGER IF EXISTS es_insert_repository on public.repository; | |||||
| CREATE OR REPLACE FUNCTION public.insert_repository_data() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| if not NEW.is_private then | |||||
| INSERT INTO public.repository_es (id, | |||||
| owner_id, | |||||
| owner_name, | |||||
| lower_name, | |||||
| name, | |||||
| description, | |||||
| website, | |||||
| original_service_type, | |||||
| original_url, | |||||
| default_branch, | |||||
| num_watches, | |||||
| num_stars, | |||||
| num_forks, | |||||
| num_issues, | |||||
| num_closed_issues, | |||||
| num_pulls, | |||||
| num_closed_pulls, | |||||
| num_milestones, | |||||
| num_closed_milestones, | |||||
| is_private, | |||||
| is_empty, | |||||
| is_archived, | |||||
| is_mirror, | |||||
| status, | |||||
| is_fork, | |||||
| fork_id, | |||||
| is_template, | |||||
| template_id, | |||||
| size, | |||||
| is_fsck_enabled, | |||||
| close_issues_via_commit_in_any_branch, | |||||
| topics, | |||||
| avatar, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| contract_address, | |||||
| block_chain_status, | |||||
| balance, | |||||
| clone_cnt, | |||||
| num_commit, | |||||
| git_clone_cnt, | |||||
| creator_id, | |||||
| repo_type, | |||||
| alias, | |||||
| lower_alias) VALUES | |||||
| (NEW.id, | |||||
| NEW.owner_id, | |||||
| NEW.owner_name, | |||||
| NEW.lower_name, | |||||
| NEW.name, | |||||
| NEW.description, | |||||
| NEW.website, | |||||
| NEW.original_service_type, | |||||
| NEW.original_url, | |||||
| NEW.default_branch, | |||||
| NEW.num_watches, | |||||
| NEW.num_stars, | |||||
| NEW.num_forks, | |||||
| NEW.num_issues, | |||||
| NEW.num_closed_issues, | |||||
| NEW.num_pulls, | |||||
| NEW.num_closed_pulls, | |||||
| NEW.num_milestones, | |||||
| NEW.num_closed_milestones, | |||||
| NEW.is_private, | |||||
| NEW.is_empty, | |||||
| NEW.is_archived, | |||||
| NEW.is_mirror, | |||||
| NEW.status, | |||||
| NEW.is_fork, | |||||
| NEW.fork_id, | |||||
| NEW.is_template, | |||||
| NEW.template_id, | |||||
| NEW.size, | |||||
| NEW.is_fsck_enabled, | |||||
| NEW.close_issues_via_commit_in_any_branch, | |||||
| NEW.topics, | |||||
| NEW.avatar, | |||||
| NEW.created_unix, | |||||
| NEW.updated_unix, | |||||
| NEW.contract_address, | |||||
| NEW.block_chain_status, | |||||
| NEW.balance, | |||||
| NEW.clone_cnt, | |||||
| NEW.num_commit, | |||||
| NEW.git_clone_cnt, | |||||
| NEW.creator_id, | |||||
| NEW.repo_type, | |||||
| NEW.alias, | |||||
| NEW.lower_alias); | |||||
| end if; | |||||
| RETURN NEW; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_insert_repository | |||||
| AFTER INSERT ON public.repository | |||||
| FOR EACH ROW EXECUTE PROCEDURE insert_repository_data(); | |||||
| ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_insert_repository; | |||||
| DROP TRIGGER IF EXISTS es_update_repository on public.repository; | |||||
| CREATE OR REPLACE FUNCTION public.update_repository() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| if OLD.is_private != NEW.is_private then | |||||
| if OLD.is_private and not NEW.is_private then | |||||
| --insert | |||||
| INSERT INTO public.repository_es (id, | |||||
| owner_id, | |||||
| owner_name, | |||||
| lower_name, | |||||
| name, | |||||
| description, | |||||
| website, | |||||
| original_service_type, | |||||
| original_url, | |||||
| default_branch, | |||||
| num_watches, | |||||
| num_stars, | |||||
| num_forks, | |||||
| num_issues, | |||||
| num_closed_issues, | |||||
| num_pulls, | |||||
| num_closed_pulls, | |||||
| num_milestones, | |||||
| num_closed_milestones, | |||||
| is_private, | |||||
| is_empty, | |||||
| is_archived, | |||||
| is_mirror, | |||||
| status, | |||||
| is_fork, | |||||
| fork_id, | |||||
| is_template, | |||||
| template_id, | |||||
| size, | |||||
| is_fsck_enabled, | |||||
| close_issues_via_commit_in_any_branch, | |||||
| topics, | |||||
| avatar, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| contract_address, | |||||
| block_chain_status, | |||||
| balance, | |||||
| clone_cnt, | |||||
| num_commit, | |||||
| git_clone_cnt, | |||||
| creator_id, | |||||
| repo_type, | |||||
| lang, | |||||
| alias, | |||||
| lower_alias) | |||||
| SELECT | |||||
| id, | |||||
| owner_id, | |||||
| owner_name, | |||||
| lower_name, | |||||
| name, | |||||
| description, | |||||
| website, | |||||
| original_service_type, | |||||
| original_url, | |||||
| default_branch, | |||||
| num_watches, | |||||
| num_stars, | |||||
| num_forks, | |||||
| num_issues, | |||||
| num_closed_issues, | |||||
| num_pulls, | |||||
| num_closed_pulls, | |||||
| num_milestones, | |||||
| num_closed_milestones, | |||||
| is_private, | |||||
| is_empty, | |||||
| is_archived, | |||||
| is_mirror, | |||||
| status, | |||||
| is_fork, | |||||
| fork_id, | |||||
| is_template, | |||||
| template_id, | |||||
| size, | |||||
| is_fsck_enabled, | |||||
| close_issues_via_commit_in_any_branch, | |||||
| topics, | |||||
| avatar, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| contract_address, | |||||
| block_chain_status, | |||||
| balance, | |||||
| clone_cnt, | |||||
| num_commit, | |||||
| git_clone_cnt, | |||||
| creator_id, | |||||
| repo_type, | |||||
| (select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id), | |||||
| alias, | |||||
| lower_alias | |||||
| FROM public.repository b where b.id=NEW.id; | |||||
| INSERT INTO public.dataset_es( | |||||
| id, | |||||
| title, | |||||
| status, | |||||
| category, | |||||
| description, | |||||
| download_times, | |||||
| license, task, | |||||
| release_id, | |||||
| user_id, | |||||
| repo_id, | |||||
| created_unix, | |||||
| updated_unix,file_name) | |||||
| SELECT | |||||
| b.id, | |||||
| b.title, | |||||
| b.status, | |||||
| b.category, | |||||
| b.description, | |||||
| b.download_times, | |||||
| b.license, | |||||
| b.task, | |||||
| b.release_id, | |||||
| b.user_id, | |||||
| b.repo_id, | |||||
| b.created_unix, | |||||
| b.updated_unix,(select array_to_string(array_agg(name order by created_unix desc),',') from public.attachment a where a.dataset_id=b.id and a.is_private=false) | |||||
| FROM public.dataset b where b.repo_id=NEW.id; | |||||
| INSERT INTO public.issue_es( | |||||
| id, | |||||
| repo_id, | |||||
| index, | |||||
| poster_id, | |||||
| original_author, | |||||
| original_author_id, | |||||
| name, | |||||
| content, | |||||
| milestone_id, | |||||
| priority, | |||||
| is_closed, | |||||
| is_pull, | |||||
| num_comments, | |||||
| ref, | |||||
| deadline_unix, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| closed_unix, | |||||
| is_locked, | |||||
| amount, | |||||
| is_transformed,comment,pr_id) | |||||
| SELECT | |||||
| b.id, | |||||
| b.repo_id, | |||||
| b.index, | |||||
| b.poster_id, | |||||
| b.original_author, | |||||
| b.original_author_id, | |||||
| b.name, | |||||
| b.content, | |||||
| b.milestone_id, | |||||
| b.priority, | |||||
| b.is_closed, | |||||
| b.is_pull, | |||||
| b.num_comments, | |||||
| b.ref, | |||||
| b.deadline_unix, | |||||
| b.created_unix, | |||||
| b.updated_unix, | |||||
| b.closed_unix, | |||||
| b.is_locked, | |||||
| b.amount, | |||||
| b.is_transformed, | |||||
| (select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id), | |||||
| (select id from public.pull_request d where d.issue_id=b.id) | |||||
| FROM public.issue b where b.repo_id=NEW.id; | |||||
| end if; | |||||
| if not OLD.is_private and NEW.is_private then | |||||
| delete from public.issue_es where repo_id=NEW.id; | |||||
| delete from public.dataset_es where repo_id=NEW.id; | |||||
| delete from public.repository_es where id=NEW.id; | |||||
| end if; | |||||
| end if; | |||||
| if not NEW.is_private then | |||||
| raise notice 'update repo,the updated_unix is %',NEW.updated_unix; | |||||
| update public.repository_es SET description=NEW.description, | |||||
| name=NEW.name, | |||||
| lower_name=NEW.lower_name, | |||||
| owner_name=NEW.owner_name, | |||||
| website=NEW.website, | |||||
| updated_unix=NEW.updated_unix, | |||||
| num_watches=NEW.num_watches, | |||||
| num_stars=NEW.num_stars, | |||||
| num_forks=NEW.num_forks, | |||||
| topics=NEW.topics, | |||||
| alias = NEW.alias, | |||||
| lower_alias = NEW.lower_alias, | |||||
| avatar=NEW.avatar | |||||
| where id=NEW.id; | |||||
| end if; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_update_repository | |||||
| AFTER UPDATE ON public.repository | |||||
| FOR EACH ROW EXECUTE PROCEDURE update_repository(); | |||||
| ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_update_repository; | |||||
| DROP TRIGGER IF EXISTS es_delete_repository on public.repository; | |||||
| CREATE OR REPLACE FUNCTION public.delete_repository() RETURNS trigger AS | |||||
| $def$ | |||||
| declare | |||||
| BEGIN | |||||
| delete from public.issue_es where repo_id=OLD.id; | |||||
| delete from public.dataset_es where repo_id=OLD.id; | |||||
| DELETE FROM public.repository_es where id=OLD.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_delete_repository | |||||
| AFTER DELETE ON public.repository | |||||
| FOR EACH ROW EXECUTE PROCEDURE delete_repository(); | |||||
| ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_delete_repository; | |||||
| DROP TRIGGER IF EXISTS es_udpate_repository_lang on public.language_stat; | |||||
| CREATE OR REPLACE FUNCTION public.udpate_repository_lang() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| if (TG_OP = 'UPDATE') then | |||||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||||
| elsif (TG_OP = 'INSERT') then | |||||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||||
| elsif (TG_OP = 'DELETE') then | |||||
| if exists(select 1 from public.repository where id=OLD.repo_id) then | |||||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id; | |||||
| end if; | |||||
| end if; | |||||
| return null; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_udpate_repository_lang | |||||
| AFTER INSERT OR UPDATE OR DELETE ON public.language_stat | |||||
| FOR EACH ROW EXECUTE PROCEDURE udpate_repository_lang(); | |||||
| ALTER TABLE public.language_stat ENABLE ALWAYS TRIGGER es_udpate_repository_lang; | |||||
| @@ -0,0 +1,308 @@ | |||||
| DROP FOREIGN table if exists public.user_es; | |||||
| CREATE FOREIGN TABLE public.user_es | |||||
| ( | |||||
| id bigint NOT NULL , | |||||
| lower_name character varying(255) NULL, | |||||
| name character varying(255) NULL, | |||||
| full_name character varying(255), | |||||
| email character varying(255), | |||||
| keep_email_private boolean, | |||||
| email_notifications_preference character varying(20) , | |||||
| passwd character varying(255) , | |||||
| passwd_hash_algo character varying(255) , | |||||
| must_change_password boolean NOT NULL DEFAULT false, | |||||
| login_type integer, | |||||
| login_source bigint NOT NULL DEFAULT 0, | |||||
| login_name character varying(255) , | |||||
| type integer, | |||||
| location character varying(255), | |||||
| website character varying(255), | |||||
| rands character varying(10), | |||||
| salt character varying(10), | |||||
| language character varying(5), | |||||
| description character varying(255), | |||||
| created_unix bigint, | |||||
| updated_unix bigint, | |||||
| last_login_unix bigint, | |||||
| last_repo_visibility boolean, | |||||
| max_repo_creation integer, | |||||
| is_active boolean, | |||||
| is_admin boolean, | |||||
| is_restricted boolean NOT NULL DEFAULT false, | |||||
| allow_git_hook boolean, | |||||
| allow_import_local boolean, | |||||
| allow_create_organization boolean DEFAULT true, | |||||
| prohibit_login boolean NOT NULL DEFAULT false, | |||||
| avatar character varying(2048) , | |||||
| avatar_email character varying(255), | |||||
| use_custom_avatar boolean, | |||||
| num_followers integer, | |||||
| num_following integer NOT NULL DEFAULT 0, | |||||
| num_stars integer, | |||||
| num_repos integer, | |||||
| num_teams integer, | |||||
| num_members integer, | |||||
| visibility integer NOT NULL DEFAULT 0, | |||||
| repo_admin_change_team_access boolean NOT NULL DEFAULT false, | |||||
| diff_view_style character varying(255), | |||||
| theme character varying(255), | |||||
| token character varying(1024) , | |||||
| public_key character varying(255), | |||||
| private_key character varying(255), | |||||
| is_operator boolean NOT NULL DEFAULT false, | |||||
| num_dataset_stars integer NOT NULL DEFAULT 0 | |||||
| ) SERVER multicorn_es | |||||
| OPTIONS | |||||
| ( | |||||
| host '192.168.207.94', | |||||
| port '9200', | |||||
| index 'user-es-index', | |||||
| rowid_column 'id', | |||||
| default_sort '_id' | |||||
| ) | |||||
| ; | |||||
| delete from public.user_es; | |||||
| INSERT INTO public.user_es( | |||||
| id, | |||||
| lower_name, | |||||
| name, | |||||
| full_name, | |||||
| email, | |||||
| keep_email_private, | |||||
| email_notifications_preference, | |||||
| must_change_password, | |||||
| login_type, | |||||
| login_source, | |||||
| login_name, | |||||
| type, | |||||
| location, | |||||
| website, | |||||
| rands, | |||||
| language, | |||||
| description, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| last_login_unix, | |||||
| last_repo_visibility, | |||||
| max_repo_creation, | |||||
| is_active, | |||||
| is_restricted, | |||||
| allow_git_hook, | |||||
| allow_import_local, | |||||
| allow_create_organization, | |||||
| prohibit_login, | |||||
| avatar, | |||||
| avatar_email, | |||||
| use_custom_avatar, | |||||
| num_followers, | |||||
| num_following, | |||||
| num_stars, | |||||
| num_repos, | |||||
| num_teams, | |||||
| num_members, | |||||
| visibility, | |||||
| repo_admin_change_team_access, | |||||
| diff_view_style, | |||||
| theme, | |||||
| is_operator, | |||||
| num_dataset_stars) | |||||
| SELECT | |||||
| id, | |||||
| lower_name, | |||||
| name, | |||||
| full_name, | |||||
| email, | |||||
| keep_email_private, | |||||
| email_notifications_preference, | |||||
| must_change_password, | |||||
| login_type, | |||||
| login_source, | |||||
| login_name, | |||||
| type, | |||||
| location, | |||||
| website, | |||||
| rands, | |||||
| language, | |||||
| description, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| last_login_unix, | |||||
| last_repo_visibility, | |||||
| max_repo_creation, | |||||
| is_active, | |||||
| is_restricted, | |||||
| allow_git_hook, | |||||
| allow_import_local, | |||||
| allow_create_organization, | |||||
| prohibit_login, | |||||
| avatar, | |||||
| avatar_email, | |||||
| use_custom_avatar, | |||||
| num_followers, | |||||
| num_following, | |||||
| num_stars, | |||||
| num_repos, | |||||
| num_teams, | |||||
| num_members, | |||||
| visibility, | |||||
| repo_admin_change_team_access, | |||||
| diff_view_style, | |||||
| theme, | |||||
| is_operator, | |||||
| num_dataset_stars | |||||
| FROM public.user; | |||||
| DROP TRIGGER IF EXISTS es_insert_user on public.user; | |||||
| CREATE OR REPLACE FUNCTION public.insert_user_data() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| INSERT INTO public."user_es"( | |||||
| id, | |||||
| lower_name, | |||||
| name, | |||||
| full_name, | |||||
| email, | |||||
| keep_email_private, | |||||
| email_notifications_preference, | |||||
| must_change_password, | |||||
| login_type, | |||||
| login_source, | |||||
| login_name, | |||||
| type, | |||||
| location, | |||||
| website, | |||||
| rands, | |||||
| language, | |||||
| description, | |||||
| created_unix, | |||||
| updated_unix, | |||||
| last_login_unix, | |||||
| last_repo_visibility, | |||||
| max_repo_creation, | |||||
| is_active, | |||||
| is_restricted, | |||||
| allow_git_hook, | |||||
| allow_import_local, | |||||
| allow_create_organization, | |||||
| prohibit_login, | |||||
| avatar, | |||||
| avatar_email, | |||||
| use_custom_avatar, | |||||
| num_followers, | |||||
| num_following, | |||||
| num_stars, | |||||
| num_repos, | |||||
| num_teams, | |||||
| num_members, | |||||
| visibility, | |||||
| repo_admin_change_team_access, | |||||
| diff_view_style, | |||||
| theme, | |||||
| is_operator, | |||||
| num_dataset_stars) | |||||
| VALUES ( | |||||
| NEW.id, | |||||
| NEW.lower_name, | |||||
| NEW.name, | |||||
| NEW.full_name, | |||||
| NEW.email, | |||||
| NEW.keep_email_private, | |||||
| NEW.email_notifications_preference, | |||||
| NEW.must_change_password, | |||||
| NEW.login_type, | |||||
| NEW.login_source, | |||||
| NEW.login_name, | |||||
| NEW.type, | |||||
| NEW.location, | |||||
| NEW.website, | |||||
| NEW.rands, | |||||
| NEW.language, | |||||
| NEW.description, | |||||
| NEW.created_unix, | |||||
| NEW.updated_unix, | |||||
| NEW.last_login_unix, | |||||
| NEW.last_repo_visibility, | |||||
| NEW.max_repo_creation, | |||||
| NEW.is_active, | |||||
| NEW.is_restricted, | |||||
| NEW.allow_git_hook, | |||||
| NEW.allow_import_local, | |||||
| NEW.allow_create_organization, | |||||
| NEW.prohibit_login, | |||||
| NEW.avatar, | |||||
| NEW.avatar_email, | |||||
| NEW.use_custom_avatar, | |||||
| NEW.num_followers, | |||||
| NEW.num_following, | |||||
| NEW.num_stars, | |||||
| NEW.num_repos, | |||||
| NEW.num_teams, | |||||
| NEW.num_members, | |||||
| NEW.visibility, | |||||
| NEW.repo_admin_change_team_access, | |||||
| NEW.diff_view_style, | |||||
| NEW.theme, | |||||
| NEW.is_operator, | |||||
| NEW.num_dataset_stars | |||||
| ); | |||||
| RETURN NEW; | |||||
| END; | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_insert_user | |||||
| AFTER INSERT ON public.user | |||||
| FOR EACH ROW EXECUTE PROCEDURE insert_user_data(); | |||||
| ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_insert_user; | |||||
| DROP TRIGGER IF EXISTS es_update_user on public.user; | |||||
| CREATE OR REPLACE FUNCTION public.update_user() RETURNS trigger AS | |||||
| $def$ | |||||
| BEGIN | |||||
| UPDATE public.user_es | |||||
| SET description=NEW.description, | |||||
| name=NEW.name, | |||||
| full_name=NEW.full_name, | |||||
| location=NEW.location, | |||||
| website=NEW.website, | |||||
| email=NEW.email, | |||||
| num_dataset_stars=NEW.num_dataset_stars, | |||||
| updated_unix=NEW.updated_unix | |||||
| where id=NEW.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_update_user | |||||
| AFTER UPDATE ON public.user | |||||
| FOR EACH ROW EXECUTE PROCEDURE update_user(); | |||||
| ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_update_user; | |||||
| DROP TRIGGER IF EXISTS es_delete_user on public.user; | |||||
| CREATE OR REPLACE FUNCTION public.delete_user() RETURNS trigger AS | |||||
| $def$ | |||||
| declare | |||||
| BEGIN | |||||
| DELETE FROM public.user_es where id=OLD.id; | |||||
| return new; | |||||
| END | |||||
| $def$ | |||||
| LANGUAGE plpgsql; | |||||
| CREATE TRIGGER es_delete_user | |||||
| AFTER DELETE ON public.user | |||||
| FOR EACH ROW EXECUTE PROCEDURE delete_user(); | |||||
| ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_delete_user; | |||||
| @@ -13,11 +13,6 @@ const ( | |||||
| FileUploaded | FileUploaded | ||||
| ) | ) | ||||
| const ( | |||||
| TypeCloudBrainOne int = iota | |||||
| TypeCloudBrainTwo | |||||
| ) | |||||
| type FileChunk struct { | type FileChunk struct { | ||||
| ID int64 `xorm:"pk autoincr"` | ID int64 `xorm:"pk autoincr"` | ||||
| UUID string `xorm:"uuid UNIQUE"` | UUID string `xorm:"uuid UNIQUE"` | ||||
| @@ -129,6 +129,7 @@ func init() { | |||||
| new(LanguageStat), | new(LanguageStat), | ||||
| new(EmailHash), | new(EmailHash), | ||||
| new(Dataset), | new(Dataset), | ||||
| new(DatasetStar), | |||||
| new(Cloudbrain), | new(Cloudbrain), | ||||
| new(FileChunk), | new(FileChunk), | ||||
| new(BlockChain), | new(BlockChain), | ||||
| @@ -137,6 +138,7 @@ func init() { | |||||
| new(OfficialTag), | new(OfficialTag), | ||||
| new(OfficialTagRepos), | new(OfficialTagRepos), | ||||
| new(WechatBindLog), | new(WechatBindLog), | ||||
| new(SearchRecord), | |||||
| ) | ) | ||||
| tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
| @@ -6,13 +6,14 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/git" | |||||
| "context" | "context" | ||||
| "crypto/md5" | "crypto/md5" | ||||
| "errors" | "errors" | ||||
| "fmt" | "fmt" | ||||
| "html/template" | "html/template" | ||||
| "math/rand" | "math/rand" | ||||
| "code.gitea.io/gitea/modules/git" | |||||
| "xorm.io/xorm" | "xorm.io/xorm" | ||||
| "code.gitea.io/gitea/modules/blockchain" | "code.gitea.io/gitea/modules/blockchain" | ||||
| @@ -1280,10 +1281,6 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...Cr | |||||
| return fmt.Errorf("copyDefaultWebhooksToRepo: %v", err) | return fmt.Errorf("copyDefaultWebhooksToRepo: %v", err) | ||||
| } | } | ||||
| if err = CreateDefaultDatasetToRepo(repo); err != nil { | |||||
| return fmt.Errorf("models.CreateDefaultDatasetToRepo: %v", err) | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -1547,6 +1544,21 @@ func GetAllRepositoriesCount() (int64, error) { | |||||
| return x.Count(repo) | return x.Count(repo) | ||||
| } | } | ||||
| func GetAllPublicRepositoriesCount() (int64, error) { | |||||
| repo := new(Repository) | |||||
| return x.Where("is_private = ?", false).Count(repo) | |||||
| } | |||||
| func GetAllMirrorRepositoriesCount() (int64, error) { | |||||
| repo := new(Repository) | |||||
| return x.Where("is_mirror = ?", true).Count(repo) | |||||
| } | |||||
| func GetAllForkRepositoriesCount() (int64, error) { | |||||
| repo := new(Repository) | |||||
| return x.Where("is_fork = ?", true).Count(repo) | |||||
| } | |||||
| func GetAllRepositoriesSize() (int64, error) { | func GetAllRepositoriesSize() (int64, error) { | ||||
| return x.SumInt(&Repository{}, "size") | return x.SumInt(&Repository{}, "size") | ||||
| } | } | ||||
| @@ -1586,6 +1598,34 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| //If repo has become private, we need set dataset and dataset_file to private | |||||
| _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ | |||||
| Status: 0, | |||||
| }) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| dataset, err := GetDatasetByRepo(repo) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| _, err = e.Where("dataset_id = ?", dataset.ID).Cols("is_private").Update(&Attachment{ | |||||
| IsPrivate: true, | |||||
| }) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| } else { | |||||
| //If repo has become public, we need set dataset to public | |||||
| _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ | |||||
| Status: 1, | |||||
| }) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| } | } | ||||
| // Create/Remove git-daemon-export-ok for git-daemon... | // Create/Remove git-daemon-export-ok for git-daemon... | ||||
| @@ -2676,7 +2716,7 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi | |||||
| log.Error("ReadLatestFileInRepo error when OpenRepository,error=%v", err) | log.Error("ReadLatestFileInRepo error when OpenRepository,error=%v", err) | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| commitID, err := gitRepo.GetBranchCommitID(refName) | |||||
| _, err = gitRepo.GetBranchCommitID(refName) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("ReadLatestFileInRepo error when GetBranchCommitID,error=%v", err) | log.Error("ReadLatestFileInRepo error when GetBranchCommitID,error=%v", err) | ||||
| return nil, err | return nil, err | ||||
| @@ -2708,5 +2748,9 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi | |||||
| if n >= 0 { | if n >= 0 { | ||||
| buf = buf[:n] | buf = buf[:n] | ||||
| } | } | ||||
| return &RepoFile{CommitId: commitID, Content: buf}, nil | |||||
| commitId := "" | |||||
| if blob != nil { | |||||
| commitId = fmt.Sprint(blob.ID) | |||||
| } | |||||
| return &RepoFile{CommitId: commitId, Content: buf}, nil | |||||
| } | } | ||||
| @@ -190,7 +190,8 @@ type SearchRepoOptions struct { | |||||
| // None -> include all repos | // None -> include all repos | ||||
| // True -> include just courses | // True -> include just courses | ||||
| // False -> include just no courses | // False -> include just no courses | ||||
| Course util.OptionalBool | |||||
| Course util.OptionalBool | |||||
| OnlySearchPrivate bool | |||||
| } | } | ||||
| //SearchOrderBy is used to sort the result | //SearchOrderBy is used to sort the result | ||||
| @@ -219,12 +220,15 @@ const ( | |||||
| SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" | ||||
| SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" | ||||
| SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" | ||||
| SearchOrderByWatches SearchOrderBy = "num_watches DESC" | |||||
| ) | ) | ||||
| // SearchRepositoryCondition creates a query condition according search repository options | // SearchRepositoryCondition creates a query condition according search repository options | ||||
| func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | ||||
| var cond = builder.NewCond() | var cond = builder.NewCond() | ||||
| if opts.OnlySearchPrivate { | |||||
| cond = cond.And(builder.Eq{"is_private": true}) | |||||
| } | |||||
| if opts.Private { | if opts.Private { | ||||
| if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID { | if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID { | ||||
| // OK we're in the context of a User | // OK we're in the context of a User | ||||
| @@ -337,7 +341,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | |||||
| if !opts.TopicOnly { | if !opts.TopicOnly { | ||||
| var likes = builder.NewCond() | var likes = builder.NewCond() | ||||
| for _, v := range strings.Split(opts.Keyword, ",") { | for _, v := range strings.Split(opts.Keyword, ",") { | ||||
| likes = likes.Or(builder.Like{"lower_name", strings.ToLower(v)}) | |||||
| likes = likes.Or(builder.Like{"lower_alias", strings.ToLower(v)}) | |||||
| likes = likes.Or(builder.Like{"alias", v}) | likes = likes.Or(builder.Like{"alias", v}) | ||||
| if opts.IncludeDescription { | if opts.IncludeDescription { | ||||
| likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)}) | likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)}) | ||||
| @@ -9,43 +9,45 @@ import ( | |||||
| // RepoStatistic statistic info of all repository | // RepoStatistic statistic info of all repository | ||||
| type RepoStatistic struct { | type RepoStatistic struct { | ||||
| ID int64 `xorm:"pk autoincr" json:"-"` | |||||
| RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | |||||
| Name string `xorm:"INDEX" json:"name"` | |||||
| Alias string `xorm:"INDEX" json:"alias"` | |||||
| OwnerName string `json:"ownerName"` | |||||
| IsPrivate bool `json:"isPrivate"` | |||||
| IsMirror bool `json:"isMirror"` | |||||
| Date string `xorm:"unique(s) NOT NULL" json:"date"` | |||||
| NumWatches int64 `xorm:"NOT NULL DEFAULT 0" json:"watch"` | |||||
| NumWatchesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumStars int64 `xorm:"NOT NULL DEFAULT 0" json:"star"` | |||||
| NumStarsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumForks int64 `xorm:"NOT NULL DEFAULT 0" json:"fork"` | |||||
| NumForksAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumDownloads int64 `xorm:"NOT NULL DEFAULT 0" json:"download"` | |||||
| NumDownloadsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumComments int64 `xorm:"NOT NULL DEFAULT 0" json:"comment"` | |||||
| NumCommentsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumVisits int64 `xorm:"NOT NULL DEFAULT 0" json:"view"` | |||||
| NumClosedIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issueClosed"` | |||||
| NumClosedIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumVersions int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"` | |||||
| NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issue"` | |||||
| NumIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumPulls int64 `xorm:"NOT NULL DEFAULT 0" json:"pr"` | |||||
| NumPullsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| IssueFixedRate float32 `xorm:"NOT NULL" json:"issueClosedRatio"` | |||||
| NumContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"contributor"` | |||||
| NumContributorAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumKeyContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| ID int64 `xorm:"pk autoincr" json:"-"` | |||||
| RepoID int64 `xorm:"unique(s) NOT NULL" json:"repo_id"` | |||||
| Name string `xorm:"INDEX" json:"name"` | |||||
| Alias string `xorm:"INDEX" json:"alias"` | |||||
| OwnerName string `json:"ownerName"` | |||||
| IsPrivate bool `json:"isPrivate"` | |||||
| IsMirror bool `json:"isMirror"` | |||||
| IsFork bool `json:"isFork"` | |||||
| RepoCreatedUnix timeutil.TimeStamp `xorm:"NOT NULL DEFAULT 0" json:"createUnix"` | |||||
| Date string `xorm:"unique(s) NOT NULL" json:"date"` | |||||
| NumWatches int64 `xorm:"NOT NULL DEFAULT 0" json:"watch"` | |||||
| NumWatchesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumStars int64 `xorm:"NOT NULL DEFAULT 0" json:"star"` | |||||
| NumStarsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumForks int64 `xorm:"NOT NULL DEFAULT 0" json:"fork"` | |||||
| NumForksAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumDownloads int64 `xorm:"NOT NULL DEFAULT 0" json:"download"` | |||||
| NumDownloadsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumComments int64 `xorm:"NOT NULL DEFAULT 0" json:"comment"` | |||||
| NumCommentsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumVisits int64 `xorm:"NOT NULL DEFAULT 0" json:"view"` | |||||
| NumClosedIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issueClosed"` | |||||
| NumClosedIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumVersions int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"` | |||||
| NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumIssues int64 `xorm:"NOT NULL DEFAULT 0" json:"issue"` | |||||
| NumIssuesAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumPulls int64 `xorm:"NOT NULL DEFAULT 0" json:"pr"` | |||||
| NumPullsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| IssueFixedRate float32 `xorm:"NOT NULL" json:"issueClosedRatio"` | |||||
| NumContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"contributor"` | |||||
| NumContributorAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumKeyContributor int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | |||||
| NumContributorsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | NumContributorsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | ||||
| NumCommitsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | NumCommitsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"` | ||||
| @@ -0,0 +1,83 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "xorm.io/xorm" | |||||
| ) | |||||
| type SearchRecord struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| //user | |||||
| Keyword string `xorm:"NOT NULL"` | |||||
| // | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||||
| } | |||||
| func SaveSearchKeywordToDb(keyword string) error { | |||||
| record := &SearchRecord{ | |||||
| Keyword: keyword, | |||||
| } | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| _, err := sess.Insert(record) | |||||
| if err != nil { | |||||
| log.Info("insert error." + err.Error()) | |||||
| return err | |||||
| } | |||||
| return nil | |||||
| } | |||||
| func setIssueQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId int64) { | |||||
| sess.And("issue.poster_id=?", userId) | |||||
| sess.And("issue.is_pull=?", isPull) | |||||
| sess.And("(issue.name like '%" + Keyword + "%' or issue.content like '%" + Keyword + "%')") | |||||
| sess.Join("INNER", "repository", "issue.repo_id = repository.id").And("repository.is_private = ?", true) | |||||
| } | |||||
| func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool, userId int64) ([]*Issue, int64, error) { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| setIssueQueryCondition(sess, Keyword, isPull, userId) | |||||
| count, err := sess.Count(new(Issue)) | |||||
| if err != nil { | |||||
| return nil, 0, err | |||||
| } | |||||
| setIssueQueryCondition(sess, Keyword, isPull, userId) | |||||
| sess.Desc("issue.created_unix") | |||||
| sess.Limit(PageSize, (Page-1)*PageSize) | |||||
| issues := make([]*Issue, 0) | |||||
| if err := sess.Find(&issues); err != nil { | |||||
| return nil, 0, err | |||||
| } else { | |||||
| return issues, count, nil | |||||
| } | |||||
| } | |||||
| func setDataSetQueryCondition(sess *xorm.Session, Keyword string, userId int64) { | |||||
| sess.And("dataset.user_id=?", userId) | |||||
| sess.And("(dataset.title like '%" + Keyword + "%' or dataset.description like '%" + Keyword + "%')") | |||||
| sess.Join("INNER", "repository", "dataset.repo_id = repository.id").And("repository.is_private = ?", true) | |||||
| } | |||||
| func SearchDatasetBySQL(Page int, PageSize int, Keyword string, userId int64) ([]*Dataset, int64, error) { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| setDataSetQueryCondition(sess, Keyword, userId) | |||||
| count, err := sess.Count(new(Dataset)) | |||||
| if err != nil { | |||||
| return nil, 0, err | |||||
| } | |||||
| setDataSetQueryCondition(sess, Keyword, userId) | |||||
| sess.Desc("dataset.created_unix") | |||||
| sess.Limit(PageSize, (Page-1)*PageSize) | |||||
| datasets := make([]*Dataset, 0) | |||||
| if err := sess.Find(&datasets); err != nil { | |||||
| return nil, 0, err | |||||
| } else { | |||||
| return datasets, count, nil | |||||
| } | |||||
| } | |||||
| @@ -40,6 +40,11 @@ type SummaryStatistic struct { | |||||
| NumRepoLeagueLearn int `xorm:"NOT NULL DEFAULT 0"` | NumRepoLeagueLearn int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NumRepoDataMining int `xorm:"NOT NULL DEFAULT 0"` | NumRepoDataMining int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NumRepoRISC int `xorm:"NOT NULL DEFAULT 0"` | NumRepoRISC int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NumRepoPublic int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumRepoPrivate int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumRepoFork int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumRepoMirror int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumRepoSelf int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| } | } | ||||
| @@ -153,10 +153,11 @@ type User struct { | |||||
| UseCustomAvatar bool | UseCustomAvatar bool | ||||
| // Counters | // Counters | ||||
| NumFollowers int | |||||
| NumFollowing int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumStars int | |||||
| NumRepos int | |||||
| NumFollowers int | |||||
| NumFollowing int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumStars int | |||||
| NumDatasetStars int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumRepos int | |||||
| // For organization | // For organization | ||||
| NumTeams int | NumTeams int | ||||
| @@ -20,6 +20,9 @@ type CreateCloudBrainForm struct { | |||||
| ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | ||||
| BenchmarkTypeID int `form:"benchmark_types_id"` | BenchmarkTypeID int `form:"benchmark_types_id"` | ||||
| BenchmarkChildTypeID int `form:"benchmark_child_types_id"` | BenchmarkChildTypeID int `form:"benchmark_child_types_id"` | ||||
| BootFile string `form:"boot_file"` | |||||
| Params string `form:"run_para_list"` | |||||
| BranchName string `form:"branch_name"` | |||||
| } | } | ||||
| type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
| @@ -9,11 +9,10 @@ import ( | |||||
| type CreateDatasetForm struct { | type CreateDatasetForm struct { | ||||
| Title string `binding:"Required"` | Title string `binding:"Required"` | ||||
| Category string `binding:"Required"` | Category string `binding:"Required"` | ||||
| Description string `binding:"Required;MaxSize(254)"` | |||||
| Description string `binding:"Required"` | |||||
| License string `binding:"Required;MaxSize(64)"` | License string `binding:"Required;MaxSize(64)"` | ||||
| Task string `binding:"Required;MaxSize(64)"` | Task string `binding:"Required;MaxSize(64)"` | ||||
| ReleaseID int64 `xorm:"INDEX"` | ReleaseID int64 `xorm:"INDEX"` | ||||
| Private bool | |||||
| Files []string | Files []string | ||||
| } | } | ||||
| @@ -25,11 +24,23 @@ type EditDatasetForm struct { | |||||
| ID int64 `binding:"Required"` | ID int64 `binding:"Required"` | ||||
| Title string `binding:"Required"` | Title string `binding:"Required"` | ||||
| Category string `binding:"Required"` | Category string `binding:"Required"` | ||||
| Description string `binding:"Required;MaxSize(254)"` | |||||
| Description string `binding:"Required"` | |||||
| License string `binding:"Required;MaxSize(64)"` | License string `binding:"Required;MaxSize(64)"` | ||||
| Task string `binding:"Required;MaxSize(64)"` | Task string `binding:"Required;MaxSize(64)"` | ||||
| Private bool | |||||
| ReleaseID int64 `xorm:"INDEX"` | |||||
| ReleaseID int64 `xorm:"INDEX"` | |||||
| Files []string | Files []string | ||||
| Type string `binding:"Required"` | |||||
| Type string `binding:"Required"` | |||||
| } | |||||
| func (f *EditDatasetForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||||
| return validate(errs, ctx.Data, f, ctx.Locale) | |||||
| } | |||||
| type EditAttachmentForm struct { | |||||
| ID int64 `binding:"Required"` | |||||
| Description string | |||||
| } | |||||
| func (f *EditAttachmentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||||
| return validate(errs, ctx.Data, f, ctx.Locale) | |||||
| } | } | ||||
| @@ -15,14 +15,13 @@ import ( | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple; | |||||
| service ssh stop; | |||||
| jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | |||||
| Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | |||||
| //CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | //CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | ||||
| CommandBenchmark = `echo "start benchmark";cd /benchmark && bash run_bk.sh;echo "end benchmark"` | CommandBenchmark = `echo "start benchmark";cd /benchmark && bash run_bk.sh;echo "end benchmark"` | ||||
| CodeMountPath = "/code" | CodeMountPath = "/code" | ||||
| DataSetMountPath = "/dataset" | DataSetMountPath = "/dataset" | ||||
| ModelMountPath = "/model" | ModelMountPath = "/model" | ||||
| LogFile = "log.txt" | |||||
| BenchMarkMountPath = "/benchmark" | BenchMarkMountPath = "/benchmark" | ||||
| BenchMarkResourceID = 1 | BenchMarkResourceID = 1 | ||||
| Snn4imagenetMountPath = "/snn4imagenet" | Snn4imagenetMountPath = "/snn4imagenet" | ||||
| @@ -32,10 +31,13 @@ const ( | |||||
| SubTaskName = "task1" | SubTaskName = "task1" | ||||
| Success = "S000" | Success = "S000" | ||||
| DefaultBranchName = "master" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| ResourceSpecs *models.ResourceSpecs | |||||
| ResourceSpecs *models.ResourceSpecs | |||||
| TrainResourceSpecs *models.ResourceSpecs | |||||
| ) | ) | ||||
| func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool { | func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool { | ||||
| @@ -147,7 +149,7 @@ func AdminOrJobCreaterRightForTrain(ctx *context.Context) { | |||||
| } | } | ||||
| func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
| func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description, branchName, bootFile, params string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
| dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
| setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
| setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
| @@ -155,13 +157,27 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
| uuid | uuid | ||||
| var resourceSpec *models.ResourceSpec | var resourceSpec *models.ResourceSpec | ||||
| if ResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||||
| } | |||||
| for _, spec := range ResourceSpecs.ResourceSpec { | |||||
| if resourceSpecId == spec.Id { | |||||
| resourceSpec = spec | |||||
| var versionCount int | |||||
| if jobType == string(models.JobTypeTrain) { | |||||
| versionCount = 1 | |||||
| if TrainResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs) | |||||
| } | |||||
| for _, spec := range TrainResourceSpecs.ResourceSpec { | |||||
| if resourceSpecId == spec.Id { | |||||
| resourceSpec = spec | |||||
| } | |||||
| } | |||||
| } else { | |||||
| if ResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||||
| } | |||||
| for _, spec := range ResourceSpecs.ResourceSpec { | |||||
| if resourceSpecId == spec.Id { | |||||
| resourceSpec = spec | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if resourceSpec == nil { | if resourceSpec == nil { | ||||
| @@ -169,6 +185,15 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
| return errors.New("no such resourceSpec") | return errors.New("no such resourceSpec") | ||||
| } | } | ||||
| var datasetName string | |||||
| attach, err := models.GetAttachmentByUUID(uuid) | |||||
| if err != nil { | |||||
| //for benchmark, do not return error | |||||
| log.Error("GetAttachmentByUUID failed:%v", err) | |||||
| } else { | |||||
| datasetName = attach.Name | |||||
| } | |||||
| jobResult, err := CreateJob(jobName, models.CreateJobParams{ | jobResult, err := CreateJob(jobName, models.CreateJobParams{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| RetryCount: 1, | RetryCount: 1, | ||||
| @@ -263,13 +288,19 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
| BenchmarkTypeID: benchmarkTypeID, | BenchmarkTypeID: benchmarkTypeID, | ||||
| BenchmarkChildTypeID: benchmarkChildTypeID, | BenchmarkChildTypeID: benchmarkChildTypeID, | ||||
| Description: description, | Description: description, | ||||
| IsLatestVersion: "1", | |||||
| VersionCount: versionCount, | |||||
| BranchName: branchName, | |||||
| BootFile: bootFile, | |||||
| DatasetName: datasetName, | |||||
| Parameters: params, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| task, err := models.GetCloudbrainByName(jobName) | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByName failed: %v", err.Error()) | log.Error("GetCloudbrainByName failed: %v", err.Error()) | ||||
| return err | return err | ||||
| @@ -278,6 +309,8 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||||
| if string(models.JobTypeBenchmark) == jobType { | if string(models.JobTypeBenchmark) == jobType { | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | ||||
| } else if string(models.JobTypeTrain) == jobType { | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, displayJobName, models.ActionCreateGPUTrainTask) | |||||
| } else { | } else { | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | ||||
| } | } | ||||
| @@ -407,8 +440,10 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||||
| return err | return err | ||||
| } | } | ||||
| idString := strconv.FormatInt(newTask.ID, 10) | |||||
| *newID = idString | |||||
| stringId := strconv.FormatInt(newTask.ID, 10) | |||||
| *newID = stringId | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, task.DisplayJobName, models.ActionCreateDebugGPUTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -475,6 +475,8 @@ func RepoAssignment() macaron.Handler { | |||||
| if ctx.IsSigned { | if ctx.IsSigned { | ||||
| ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ||||
| ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ||||
| ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | |||||
| } | } | ||||
| if repo.IsFork { | if repo.IsFork { | ||||
| @@ -0,0 +1,17 @@ | |||||
| package dataset | |||||
| func GetResourceType(cloudbrainType int) string { | |||||
| if cloudbrainType == 0 { | |||||
| return "CPU/GPU" | |||||
| } else { | |||||
| return "NPU" | |||||
| } | |||||
| } | |||||
| func GetStatusText(isPrivate bool) string { | |||||
| if isPrivate { | |||||
| return "dataset.private" | |||||
| } else { | |||||
| return "dataset.public" | |||||
| } | |||||
| } | |||||
| @@ -51,10 +51,11 @@ const ( | |||||
| DataUrl = "data_url" | DataUrl = "data_url" | ||||
| ResultUrl = "result_url" | ResultUrl = "result_url" | ||||
| CkptUrl = "ckpt_url" | CkptUrl = "ckpt_url" | ||||
| DeviceTarget = "device_target" | |||||
| Ascend = "Ascend" | |||||
| PerPage = 10 | PerPage = 10 | ||||
| IsLatestVersion = "1" | IsLatestVersion = "1" | ||||
| NotLatestVersion = "0" | NotLatestVersion = "0" | ||||
| DebugType = -1 | |||||
| VersionCount = 1 | VersionCount = 1 | ||||
| SortByCreateTime = "create_time" | SortByCreateTime = "create_time" | ||||
| @@ -165,6 +165,7 @@ var ( | |||||
| ExplorePagingNum int | ExplorePagingNum int | ||||
| ContributorPagingNum int | ContributorPagingNum int | ||||
| IssuePagingNum int | IssuePagingNum int | ||||
| DatasetPagingNum int | |||||
| RepoSearchPagingNum int | RepoSearchPagingNum int | ||||
| MembersPagingNum int | MembersPagingNum int | ||||
| FeedMaxCommitNum int | FeedMaxCommitNum int | ||||
| @@ -207,6 +208,7 @@ var ( | |||||
| ExplorePagingNum: 20, | ExplorePagingNum: 20, | ||||
| ContributorPagingNum: 50, | ContributorPagingNum: 50, | ||||
| IssuePagingNum: 10, | IssuePagingNum: 10, | ||||
| DatasetPagingNum: 5, | |||||
| RepoSearchPagingNum: 10, | RepoSearchPagingNum: 10, | ||||
| MembersPagingNum: 20, | MembersPagingNum: 20, | ||||
| FeedMaxCommitNum: 5, | FeedMaxCommitNum: 5, | ||||
| @@ -435,7 +437,7 @@ var ( | |||||
| //home page | //home page | ||||
| RecommentRepoAddr string | RecommentRepoAddr string | ||||
| ESSearchURL string | |||||
| //notice config | //notice config | ||||
| UserNameOfNoticeRepo string | UserNameOfNoticeRepo string | ||||
| RepoNameOfNoticeRepo string | RepoNameOfNoticeRepo string | ||||
| @@ -450,16 +452,18 @@ var ( | |||||
| DecompressOBSTaskName string | DecompressOBSTaskName string | ||||
| //cloudbrain config | //cloudbrain config | ||||
| CBAuthUser string | |||||
| CBAuthPassword string | |||||
| RestServerHost string | |||||
| JobPath string | |||||
| CBCodePathPrefix string | |||||
| JobType string | |||||
| GpuTypes string | |||||
| DebugServerHost string | |||||
| ResourceSpecs string | |||||
| MaxDuration int64 | |||||
| CBAuthUser string | |||||
| CBAuthPassword string | |||||
| RestServerHost string | |||||
| JobPath string | |||||
| CBCodePathPrefix string | |||||
| JobType string | |||||
| GpuTypes string | |||||
| DebugServerHost string | |||||
| ResourceSpecs string | |||||
| MaxDuration int64 | |||||
| TrainGpuTypes string | |||||
| TrainResourceSpecs string | |||||
| //benchmark config | //benchmark config | ||||
| IsBenchmarkEnabled bool | IsBenchmarkEnabled bool | ||||
| @@ -512,9 +516,9 @@ var ( | |||||
| ProfileID string | ProfileID string | ||||
| PoolInfos string | PoolInfos string | ||||
| Flavor string | Flavor string | ||||
| DebugHost string | |||||
| ImageInfos string | |||||
| Capacity int | |||||
| DebugHost string | |||||
| ImageInfos string | |||||
| Capacity int | |||||
| //train-job | //train-job | ||||
| ResourcePools string | ResourcePools string | ||||
| Engines string | Engines string | ||||
| @@ -1263,6 +1267,7 @@ func NewContext() { | |||||
| sec = Cfg.Section("homepage") | sec = Cfg.Section("homepage") | ||||
| RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/") | RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/") | ||||
| ESSearchURL = sec.Key("ESSearchURL").MustString("http://192.168.207.94:9200") | |||||
| sec = Cfg.Section("notice") | sec = Cfg.Section("notice") | ||||
| UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG") | UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG") | ||||
| @@ -1283,6 +1288,8 @@ func NewContext() { | |||||
| GpuTypes = sec.Key("GPU_TYPES").MustString("") | GpuTypes = sec.Key("GPU_TYPES").MustString("") | ||||
| ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("") | ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("") | ||||
| MaxDuration = sec.Key("MAX_DURATION").MustInt64(14400) | MaxDuration = sec.Key("MAX_DURATION").MustInt64(14400) | ||||
| TrainGpuTypes = sec.Key("TRAIN_GPU_TYPES").MustString("") | |||||
| TrainResourceSpecs = sec.Key("TRAIN_RESOURCE_SPECS").MustString("") | |||||
| sec = Cfg.Section("benchmark") | sec = Cfg.Section("benchmark") | ||||
| IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | ||||
| @@ -23,6 +23,8 @@ import ( | |||||
| "time" | "time" | ||||
| "unicode" | "unicode" | ||||
| "code.gitea.io/gitea/modules/dataset" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| "code.gitea.io/gitea/modules/emoji" | "code.gitea.io/gitea/modules/emoji" | ||||
| @@ -86,20 +88,22 @@ func NewFuncMap() []template.FuncMap { | |||||
| "AllowedReactions": func() []string { | "AllowedReactions": func() []string { | ||||
| return setting.UI.Reactions | return setting.UI.Reactions | ||||
| }, | }, | ||||
| "AvatarLink": models.AvatarLink, | |||||
| "Safe": Safe, | |||||
| "SafeJS": SafeJS, | |||||
| "Str2html": Str2html, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "FileSize": base.FileSize, | |||||
| "PrettyNumber": base.PrettyNumber, | |||||
| "Subtract": base.Subtract, | |||||
| "EntryIcon": base.EntryIcon, | |||||
| "MigrationIcon": MigrationIcon, | |||||
| "AvatarLink": models.AvatarLink, | |||||
| "Safe": Safe, | |||||
| "SafeJS": SafeJS, | |||||
| "Str2html": Str2html, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "FileSize": base.FileSize, | |||||
| "PrettyNumber": base.PrettyNumber, | |||||
| "Subtract": base.Subtract, | |||||
| "EntryIcon": base.EntryIcon, | |||||
| "MigrationIcon": MigrationIcon, | |||||
| "Add": func(a, b int) int { | "Add": func(a, b int) int { | ||||
| return a + b | return a + b | ||||
| }, | }, | ||||
| @@ -340,11 +344,13 @@ func NewTextFuncMap() []texttmpl.FuncMap { | |||||
| "AppDomain": func() string { | "AppDomain": func() string { | ||||
| return setting.Domain | return setting.Domain | ||||
| }, | }, | ||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "DateFmtLong": func(t time.Time) string { | "DateFmtLong": func(t time.Time) string { | ||||
| return t.Format(time.RFC1123Z) | return t.Format(time.RFC1123Z) | ||||
| }, | }, | ||||
| @@ -746,5 +752,5 @@ func licenses() []string { | |||||
| // Dataset tasks | // Dataset tasks | ||||
| func tasks() []string { | func tasks() []string { | ||||
| return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_recognition", "speech_synthesis"} | |||||
| return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_synthesis"} | |||||
| } | } | ||||
| @@ -254,6 +254,18 @@ page_dev_yunlao_desc3=Developers can freely choose the corresponding computing r | |||||
| page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately. | page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately. | ||||
| page_dev_yunlao_apply=Apply Separately | page_dev_yunlao_apply=Apply Separately | ||||
| search=Search | |||||
| search_repo=Repository | |||||
| search_dataset=DataSet | |||||
| search_issue=Issue | |||||
| search_pr=Pull Request | |||||
| search_user=User | |||||
| search_org=Organization | |||||
| search_finded=Find | |||||
| search_related=related | |||||
| search_maybe=maybe | |||||
| search_ge= | |||||
| [explore] | [explore] | ||||
| repos = Repositories | repos = Repositories | ||||
| select_repos = Select the project | select_repos = Select the project | ||||
| @@ -273,6 +285,20 @@ code_search_results = Search results for '%s' | |||||
| code_last_indexed_at = Last indexed %s | code_last_indexed_at = Last indexed %s | ||||
| save=Save | save=Save | ||||
| cancel=Cancel | cancel=Cancel | ||||
| hot_repo=Hot Repositories | |||||
| active_repo=Active Repositories | |||||
| all_fields = All fields | |||||
| large_model = Large model | |||||
| ai_development_tools = AI tools | |||||
| computer_version = Computer version | |||||
| natural_language_processing = NLP | |||||
| machine_learning = Machine learning | |||||
| neural_networks = Neural networks | |||||
| autopilot = Autopilot | |||||
| robot = Robot | |||||
| federated_learning = Federated learning | |||||
| data_mining = Data mining | |||||
| RISC-V_development = RISC-V development | |||||
| [auth] | [auth] | ||||
| create_new_account = Register Account | create_new_account = Register Account | ||||
| @@ -709,8 +735,13 @@ alert = To initiate a cloud brain task, please upload the dataset in zip format. | |||||
| dataset = Dataset | dataset = Dataset | ||||
| dataset_setting= Dataset Setting | dataset_setting= Dataset Setting | ||||
| title = Name | title = Name | ||||
| title_format_err=Name can only contain number,letter,'-','_' or '.', and can be up to 100 characters long. | |||||
| description = Description | description = Description | ||||
| description_format_err=Description's length can be up to 1024 characters long. | |||||
| create_dataset = Create Dataset | create_dataset = Create Dataset | ||||
| create_dataset_fail=Failed to create dataset. | |||||
| query_dataset_fail=Failed to query dataset. | |||||
| edit_attachment_fail=Failed to update description. | |||||
| show_dataset= Dataset | show_dataset= Dataset | ||||
| edit_dataset= Edit Dataset | edit_dataset= Edit Dataset | ||||
| update_dataset= Update Dataset | update_dataset= Update Dataset | ||||
| @@ -729,7 +760,8 @@ private = private | |||||
| public = public | public = public | ||||
| dir = directory | dir = directory | ||||
| back = back | back = back | ||||
| copy_url=copy download url | |||||
| copy_url=Copy Download Url | |||||
| copy_md5 = Copy MD5 | |||||
| directory=preview of the datasets | directory=preview of the datasets | ||||
| create_label_task=create label task | create_label_task=create label task | ||||
| visibility = visibility | visibility = visibility | ||||
| @@ -780,12 +812,49 @@ category.computer_vision= computer vision | |||||
| category.natural_language_processing= natural language processing | category.natural_language_processing= natural language processing | ||||
| category.speech_processing= speech processing | category.speech_processing= speech processing | ||||
| category.computer_vision_natural_language_processing= computer vision and natural language processing | category.computer_vision_natural_language_processing= computer vision and natural language processing | ||||
| attachment.delete= delete this version of dataset | |||||
| attachment.delete= Delete this version of dataset | |||||
| attachment.delete_desc= Are you sure you will delete this version of dataset, once deleted can not be recovery | attachment.delete_desc= Are you sure you will delete this version of dataset, once deleted can not be recovery | ||||
| public= public | public= public | ||||
| private= private | private= private | ||||
| delete= delete | |||||
| delete= Delete | |||||
| select_dataset=Select Dataset | |||||
| current_project=Current Project | |||||
| owner_dataset=Owner Dataset | |||||
| public_dataset=Public Dataset | |||||
| I_liked = I Liked | |||||
| use = Use | |||||
| create_new_dataset = Create New Dataset | |||||
| dataset_name = Dataset Name | |||||
| dataset_description = Dataset Description | |||||
| select_category = Select Category | |||||
| select_task = Select Research Direction/Application Area | |||||
| dataset_name_tooltips = Please enter letters, numbers, _ and - up to 100 characters. | |||||
| dataset_no_create = No dataset has been created yet | |||||
| dataset_explain = Dataset: CloudBrain I provides CPU/GPU resources, Cloudbrain II provides Ascend NPU resources, and the data set used for debugging also needs to be uploaded to the corresponding environment; | |||||
| dataset_instructions_for_use = Instructions for use: You can refer to Qizhi AI Collaboration Platform | |||||
| dataset_camp_course = Newcomer Training Camp Course; | |||||
| dataset_upload = Upload | |||||
| dataset_file_name = File Name | |||||
| dataset_available_clusters = Available Clusters | |||||
| dataset_upload_time = Upload Time | |||||
| download = Download | |||||
| modify_description = Modify Description | |||||
| set_public = Set Public | |||||
| set_private = Set Private | |||||
| annotation = Annotation | |||||
| upload_dataset_file = Upload Dataset File | |||||
| file_description = File Description | |||||
| data_upload = Dataset Upload | |||||
| illustrate = Illustrate | |||||
| illustrate.only = Only Datasets In | |||||
| illustrate.zip = zip/tar.gz Format | |||||
| illustrate.fisrt_end = Can Initiate Cloudbrain Tasks | |||||
| modify_dataset = Modify Dataset | |||||
| modify_dataset_description = Modify Dataset Description | |||||
| search_dataset = Search Dataset Files | |||||
| unzip_tooltips = If it has not been decompressed for a long time, please check whether the compressed package has encrypted files or file errors | |||||
| zip_failed = Decompression failed, please check whether the compressed package is encrypted or contact technical support | |||||
| dataset_desc = The description should not exceed 1024 characters | |||||
| [repo] | [repo] | ||||
| owner = Owner | owner = Owner | ||||
| repo_name = Repository Name | repo_name = Repository Name | ||||
| @@ -815,7 +884,7 @@ repo_label_helpe = Press Enter to complete | |||||
| issue_labels = Issue Labels | issue_labels = Issue Labels | ||||
| issue_labels_helper = Select an issue label set. | issue_labels_helper = Select an issue label set. | ||||
| license = License | license = License | ||||
| license_helper = Select a license file. | |||||
| license_helper = Select a license file | |||||
| readme = README | readme = README | ||||
| readme_helper = Select a README file template. | readme_helper = Select a README file template. | ||||
| auto_init = Initialize Repository (Adds .gitignore, License and README) | auto_init = Initialize Repository (Adds .gitignore, License and README) | ||||
| @@ -848,6 +917,7 @@ model_noright=No right | |||||
| model_rename=Duplicate model name, please modify model name. | model_rename=Duplicate model name, please modify model name. | ||||
| debug=Debug | debug=Debug | ||||
| debug_again=Restart | |||||
| stop=Stop | stop=Stop | ||||
| delete=Delete | delete=Delete | ||||
| more=More | more=More | ||||
| @@ -855,7 +925,7 @@ gpu_type_all=All | |||||
| model_download=Model Download | model_download=Model Download | ||||
| submit_image=Submit Image | submit_image=Submit Image | ||||
| download=Download | download=Download | ||||
| score=Score | |||||
| cloudbrain=Cloudbrain | cloudbrain=Cloudbrain | ||||
| cloudbrain.new=New cloudbrain | cloudbrain.new=New cloudbrain | ||||
| @@ -870,7 +940,7 @@ cloudbrain1 = cloudbrain1 | |||||
| cloudbrain2 = cloudbrain2 | cloudbrain2 = cloudbrain2 | ||||
| cloudbrain_selection = select cloudbrain | cloudbrain_selection = select cloudbrain | ||||
| cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | ||||
| confirm_choice = confirm | |||||
| confirm_choice = Confirm | |||||
| cloudbran1_tips = Only data in zip format can create cloudbrain tasks | cloudbran1_tips = Only data in zip format can create cloudbrain tasks | ||||
| cloudbrain_creator=Creator | cloudbrain_creator=Creator | ||||
| cloudbrain_task = Task Name | cloudbrain_task = Task Name | ||||
| @@ -952,7 +1022,8 @@ modelarts.train_job.parameter_value=Parameter Value | |||||
| modelarts.train_job.resource_setting=resource_setting | modelarts.train_job.resource_setting=resource_setting | ||||
| modelarts.train_job.resource_setting_info=resource_setting_info | modelarts.train_job.resource_setting_info=resource_setting_info | ||||
| modelarts.train_job.resource_pool=resource_pool | modelarts.train_job.resource_pool=resource_pool | ||||
| modelarts.train_job.resource_type=resource_type | |||||
| modelarts.train_job.resource_type=Resource Type | |||||
| modelarts.train_job.train_dataset=Train Dataset | |||||
| modelarts.train_job.standard=Standard | modelarts.train_job.standard=Standard | ||||
| modelarts.train_job.NAS_address=NAS Address | modelarts.train_job.NAS_address=NAS Address | ||||
| modelarts.train_job.NAS_mount_path=NAS Mount Path | modelarts.train_job.NAS_mount_path=NAS Mount Path | ||||
| @@ -977,13 +1048,28 @@ cloudbrain.benchmark.evaluate_child_type=Child Type | |||||
| cloudbrain.benchmark.evaluate_mirror=Mirror | cloudbrain.benchmark.evaluate_mirror=Mirror | ||||
| cloudbrain.benchmark.evaluate_train=Train Script | cloudbrain.benchmark.evaluate_train=Train Script | ||||
| cloudbrain.benchmark.evaluate_test=Test Script | cloudbrain.benchmark.evaluate_test=Test Script | ||||
| cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"Target detection","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"Target re-identification","second":[{"id":1,"value":"Vehicle re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"Image-based person re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"Multi-target tracking","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]} | |||||
| modelarts.infer_job_model = Model | modelarts.infer_job_model = Model | ||||
| modelarts.infer_job_model_file = Model File | modelarts.infer_job_model_file = Model File | ||||
| modelarts.infer_job = Inference Job | modelarts.infer_job = Inference Job | ||||
| modelarts.infer_job.model_version = Model/Version | modelarts.infer_job.model_version = Model/Version | ||||
| modelarts.infer_job.select_model = Select Model | modelarts.infer_job.select_model = Select Model | ||||
| modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference. Py, case/main.py. | |||||
| modelarts.infer_job.tooltip = The model has been deleted and cannot be viewed. | modelarts.infer_job.tooltip = The model has been deleted and cannot be viewed. | ||||
| debug_task_not_created = Debug task has not been created | |||||
| train_task_not_created = Train task has not been created | |||||
| inference_job_not_created = Inference job has not been created | |||||
| model_Evaluation_not_created = Model evaluation has not been created | |||||
| repo_not_initialized = Code version: You have not initialized the code repository, please <a href="%s"> initialized </a> first ; | |||||
| debug_task_running_limit =Running time: no more than 4 hours, it will automatically stop if it exceeds 4 hours; | |||||
| dataset_desc = Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU.And dataset also needs to be uploaded to the corresponding environment; | |||||
| platform_instructions = Instructions for use: You can refer to the <a href="https://git.openi.org.cn/zeizei/OpenI_Learning">Xiaobai training camp </a> course of Qizhi AI collaboration platform. | |||||
| model_not_exist = Model file: You do not have a model file yet, please generate and <a href="%s/modelmanage/show_model">export the model</a> through the <a href="%s/modelarts/train-job">training task</a> first ; | |||||
| benchmark_leaderboards = Benchmark leaderboards | |||||
| model.manage.import_new_model=Import New Model | model.manage.import_new_model=Import New Model | ||||
| model.manage.create_error=Equal Name and Version has existed. | model.manage.create_error=Equal Name and Version has existed. | ||||
| model.manage.model_name = Model Name | model.manage.model_name = Model Name | ||||
| @@ -1065,6 +1151,7 @@ unstar = Unstar | |||||
| star = Star | star = Star | ||||
| fork = Fork | fork = Fork | ||||
| download_archive = Download Repository | download_archive = Download Repository | ||||
| star_fail=Failed to %s the dataset. | |||||
| no_desc = No Description | no_desc = No Description | ||||
| no_label = No labels | no_label = No labels | ||||
| @@ -2348,6 +2435,9 @@ repos.size = Size | |||||
| repos.id=ID | repos.id=ID | ||||
| repos.projectName=Project Name | repos.projectName=Project Name | ||||
| repos.isPrivate=Private | repos.isPrivate=Private | ||||
| repos.create=Project Create Time | |||||
| repos.isFork=Fork | |||||
| repos.isMirror=Mirror | |||||
| repos.openi=OpenI | repos.openi=OpenI | ||||
| repos.visit=Visit | repos.visit=Visit | ||||
| repos.download=Code Download | repos.download=Code Download | ||||
| @@ -2713,10 +2803,11 @@ 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>` | 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_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_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_nputrainjob=`created NPU 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_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_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>` | task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
| task_gputrainjob=`created CPU/GPU training task<a href="%s/cloudbrain/train-job/%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago = %s ago | ago = %s ago | ||||
| @@ -2816,4 +2907,24 @@ benchmark_path = Benchmark script path | |||||
| snn4imagenet_path = Snn4imagenet script path | snn4imagenet_path = Snn4imagenet script path | ||||
| brainscore_path = Brainscore script path | brainscore_path = Brainscore script path | ||||
| start_command = Start command | start_command = Start command | ||||
| choose_mirror = select mirror | |||||
| choose_mirror = select mirror or enter mirror path | |||||
| select_dataset = select dataset | |||||
| specification = specification | |||||
| select_specification = select specification | |||||
| description = description | |||||
| job_name_rule = Please enter letters, numbers, _ and - up to 64 characters and cannot end with a dash (-). | |||||
| dataset_path_rule = The dataset location is stored in the environment variable data_url, and the training output path is stored in the environment variable train_url. | |||||
| view_sample = View sample | |||||
| inference_output_path_rule = The inference output path is stored in the environment variable result_url. | |||||
| model_file_path_rule=The model file location is stored in the environment variable ckpt_url | |||||
| delete_task = Delete task | |||||
| task_delete_confirm = Are you sure you want to delete this task? Once this task is deleted, it cannot be recovered. | |||||
| operate_confirm = confirm | |||||
| operate_cancel = cancel | |||||
| gpu_num = GPU | |||||
| cpu_num = CPU | |||||
| memory = Memory | |||||
| shared_memory = Shared Memory | |||||
| @@ -256,6 +256,18 @@ page_dev_yunlao_desc3=开发者可以根据使用需求,自由选择相应计 | |||||
| page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请 | page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请 | ||||
| page_dev_yunlao_apply=单独申请 | page_dev_yunlao_apply=单独申请 | ||||
| search=搜索 | |||||
| search_repo=项目 | |||||
| search_dataset=数据集 | |||||
| search_issue=任务 | |||||
| search_pr=合并请求 | |||||
| search_user=用户 | |||||
| search_org=组织 | |||||
| search_finded=找到 | |||||
| search_related=相关 | |||||
| search_maybe=约为 | |||||
| search_ge=个 | |||||
| [explore] | [explore] | ||||
| repos=项目 | repos=项目 | ||||
| select_repos=精选项目 | select_repos=精选项目 | ||||
| @@ -275,6 +287,20 @@ code_search_results=“%s” 的搜索结果是 | |||||
| code_last_indexed_at=最后索引于 %s | code_last_indexed_at=最后索引于 %s | ||||
| save=保存 | save=保存 | ||||
| cancel=取消 | cancel=取消 | ||||
| hot_repo=热门项目 | |||||
| active_repo=活跃项目 | |||||
| all_fields = 全部领域 | |||||
| large_model = 大模型 | |||||
| ai_development_tools = AI开发工具 | |||||
| computer_version = 计算机视觉 | |||||
| natural_language_processing = 自然语言处理 | |||||
| machine_learning = 机器学习 | |||||
| neural_networks = 神经网络 | |||||
| autopilot = 自动驾驶 | |||||
| robot = 机器人 | |||||
| federated_learning = 联邦学习 | |||||
| data_mining = 数据挖掘 | |||||
| RISC-V_development = RISC-V开发 | |||||
| [auth] | [auth] | ||||
| create_new_account=注册帐号 | create_new_account=注册帐号 | ||||
| @@ -712,8 +738,14 @@ alert=如果要发起云脑任务,请上传zip格式的数据集 | |||||
| dataset=数据集 | dataset=数据集 | ||||
| dataset_setting=数据集设置 | dataset_setting=数据集设置 | ||||
| title=名称 | title=名称 | ||||
| title_format_err=名称最多允许输入100个字符,只允许字母,数字,中划线 (‘-’),下划线 (‘_’) 和点 (‘.’) 。 | |||||
| description=描述 | description=描述 | ||||
| description_format_err=描述最多允许输入1024个字符。 | |||||
| create_dataset=创建数据集 | create_dataset=创建数据集 | ||||
| create_dataset_fail=创建数据集失败。 | |||||
| query_dataset_fail=查询数据集失败。 | |||||
| edit_attachment_fail=修改描述失败。 | |||||
| show_dataset=数据集 | show_dataset=数据集 | ||||
| edit_dataset=编辑数据集 | edit_dataset=编辑数据集 | ||||
| update_dataset=更新数据集 | update_dataset=更新数据集 | ||||
| @@ -789,6 +821,44 @@ attachment.delete_desc= 你确定要删除该版本的数据集么?一旦删 | |||||
| public=公有 | public=公有 | ||||
| private=私有 | private=私有 | ||||
| delete=删除 | delete=删除 | ||||
| select_dataset=选择数据集 | |||||
| current_project=当前项目 | |||||
| owner_dataset=我的数据集 | |||||
| public_dataset=公开数据集 | |||||
| I_liked=我收藏的 | |||||
| use=使用 | |||||
| create_new_dataset = 新建数据集 | |||||
| dataset_name=数据集名称 | |||||
| dataset_description = 数据集描述 | |||||
| select_category = 选择分类 | |||||
| select_task = 选择研究方向/应用领域 | |||||
| dataset_name_tooltips = 请输入字母、数字、_和-,最长100个字符。 | |||||
| dataset_no_create = 还未创建过数据集 | |||||
| dataset_explain = 数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境; | |||||
| dataset_instructions_for_use = 使用说明:可以参考启智AI协作平台 | |||||
| dataset_camp_course = 小白训练营课程 | |||||
| dataset_upload = 上传 | |||||
| dataset_file_name = 文件名称 | |||||
| dataset_available_clusters = 可用集群 | |||||
| dataset_upload_time = 上传时间 | |||||
| download = 下载 | |||||
| modify_description = 修改描述 | |||||
| set_public = 设为公开 | |||||
| set_private = 设为私有 | |||||
| annotation = 标注 | |||||
| upload_dataset_file = 上传数据集文件 | |||||
| file_description = 文件描述 | |||||
| data_upload = 数据上传 | |||||
| illustrate = 说明 | |||||
| illustrate.only = 只有 | |||||
| illustrate.zip = zip/tar.gz格式 | |||||
| illustrate.fisrt_end = 的数据集才能发起云脑任务 | |||||
| modify_dataset = 修改数据集 | |||||
| modify_dataset_description = 修改数据集文件描述 | |||||
| search_dataset = 搜索数据集文件 | |||||
| unzip_tooltips = 如果长时间未解压,请检查压缩包是否有加密文件或者文件错误 | |||||
| zip_failed = 解压失败,请检查压缩包是否有加密或者联系技术支持人员。 | |||||
| dataset_desc = 描述字数不超过1024个字符 | |||||
| [repo] | [repo] | ||||
| owner=拥有者 | owner=拥有者 | ||||
| @@ -819,7 +889,7 @@ repo_label_helpe=输入完成后回车键完成标签确定。 | |||||
| issue_labels=任务标签 | issue_labels=任务标签 | ||||
| issue_labels_helper=选择一个任务标签集 | issue_labels_helper=选择一个任务标签集 | ||||
| license=授权许可 | license=授权许可 | ||||
| license_helper=选择授权许可文件。 | |||||
| license_helper=选择授权许可文件 | |||||
| readme=自述 | readme=自述 | ||||
| readme_helper=选择自述文件模板。 | readme_helper=选择自述文件模板。 | ||||
| auto_init=初始化存储库 (添加. gitignore、许可证和自述文件) | auto_init=初始化存储库 (添加. gitignore、许可证和自述文件) | ||||
| @@ -860,6 +930,7 @@ gpu_type_all=全部 | |||||
| model_download=结果下载 | model_download=结果下载 | ||||
| submit_image=提交镜像 | submit_image=提交镜像 | ||||
| download=模型下载 | download=模型下载 | ||||
| score=评分 | |||||
| cloudbrain=云脑 | cloudbrain=云脑 | ||||
| cloudbrain.new=新建任务 | cloudbrain.new=新建任务 | ||||
| @@ -983,7 +1054,7 @@ cloudbrain.benchmark.evaluate_child_type=子类型 | |||||
| cloudbrain.benchmark.evaluate_mirror=镜像 | cloudbrain.benchmark.evaluate_mirror=镜像 | ||||
| cloudbrain.benchmark.evaluate_train=训练程序 | cloudbrain.benchmark.evaluate_train=训练程序 | ||||
| cloudbrain.benchmark.evaluate_test=测试程序 | cloudbrain.benchmark.evaluate_test=测试程序 | ||||
| cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]} | |||||
| modelarts.infer_job_model = 模型名称 | modelarts.infer_job_model = 模型名称 | ||||
| modelarts.infer_job_model_file = 模型文件 | modelarts.infer_job_model_file = 模型文件 | ||||
| @@ -993,6 +1064,18 @@ modelarts.infer_job.select_model = 选择模型 | |||||
| modelarts.infer_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。比如inference.py、main.py、example/inference.py、case/main.py。 | modelarts.infer_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。比如inference.py、main.py、example/inference.py、case/main.py。 | ||||
| modelarts.infer_job.tooltip = 该模型已删除,无法查看。 | modelarts.infer_job.tooltip = 该模型已删除,无法查看。 | ||||
| debug_task_not_created = 未创建过调试任务 | |||||
| train_task_not_created = 未创建过训练任务 | |||||
| inference_job_not_created = 未创建过推理任务 | |||||
| model_Evaluation_not_created = 未创建过评测任务 | |||||
| repo_not_initialized = 代码版本:您还没有初始化代码仓库,请先<a href=%s>创建代码版本</a>; | |||||
| debug_task_running_limit = 运行时长:最长不超过4个小时,超过4个小时将自动停止; | |||||
| dataset_desc = 数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境; | |||||
| platform_instructions = 使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程</a>。 | |||||
| model_not_exist = 模型文件:您还没有模型文件,请先通过<a href="%s/modelarts/train-job">训练任务</a>产生并 <a href="%s/modelmanage/show_model">导出模型</a> ; | |||||
| benchmark_leaderboards = 基准测试排行榜 | |||||
| model.manage.import_new_model=导入新模型 | model.manage.import_new_model=导入新模型 | ||||
| model.manage.create_error=相同的名称和版本的模型已经存在。 | model.manage.create_error=相同的名称和版本的模型已经存在。 | ||||
| model.manage.model_name = 模型名称 | model.manage.model_name = 模型名称 | ||||
| @@ -1074,6 +1157,8 @@ unstar=取消点赞 | |||||
| star=点赞 | star=点赞 | ||||
| fork=派生 | fork=派生 | ||||
| download_archive=下载此项目 | download_archive=下载此项目 | ||||
| star_fail=%s失败。 | |||||
| no_desc=暂无描述 | no_desc=暂无描述 | ||||
| no_label = 暂无标签 | no_label = 暂无标签 | ||||
| @@ -2356,6 +2441,9 @@ repos.size=大小 | |||||
| repos.id=ID | repos.id=ID | ||||
| repos.projectName=项目名称 | repos.projectName=项目名称 | ||||
| repos.isPrivate=私有 | repos.isPrivate=私有 | ||||
| repos.create=项目创建时间 | |||||
| repos.isFork=派生 | |||||
| repos.isMirror=镜像 | |||||
| repos.openi=OpenI指数 | repos.openi=OpenI指数 | ||||
| repos.visit=浏览量 | repos.visit=浏览量 | ||||
| repos.download=代码下载量 | repos.download=代码下载量 | ||||
| @@ -2721,10 +2809,11 @@ reject_pull_request=`建议变更 <a href="%s/pulls/%s">%s#%[2]s</a>` | |||||
| upload_dataset=`上传了数据集文件 <a href="%s/datasets?type=%s">%s</a>` | upload_dataset=`上传了数据集文件 <a href="%s/datasets?type=%s">%s</a>` | ||||
| task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%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_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>` | ||||
| task_trainjob=`创建了训练任务 <a href="%s/modelarts/train-job/%s">%s</a>` | |||||
| task_nputrainjob=`创建了NPU类型训练任务 <a href="%s/modelarts/train-job/%s">%s</a>` | |||||
| task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-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_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | ||||
| task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
| task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago=%s前 | ago=%s前 | ||||
| @@ -2825,3 +2914,24 @@ snn4imagenet_path = snn4imagenet脚本存放路径 | |||||
| brainscore_path = brainscore脚本存放路径 | brainscore_path = brainscore脚本存放路径 | ||||
| start_command = 启动命令 | start_command = 启动命令 | ||||
| choose_mirror = 选择镜像或输入镜像地址 | choose_mirror = 选择镜像或输入镜像地址 | ||||
| select_dataset = 选择数据集 | |||||
| specification = 规格 | |||||
| select_specification = 选择资源规格 | |||||
| description = 描述 | |||||
| job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | |||||
| dataset_path_rule = 数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。 | |||||
| view_sample = 查看样例 | |||||
| inference_output_path_rule = 推理输出路径存储在环境变量result_url中。 | |||||
| model_file_path_rule = 模型文件位置存储在环境变量ckpt_url中。 | |||||
| delete_task = 删除任务 | |||||
| task_delete_confirm = 你确认删除该任务么?此任务一旦删除不可恢复。 | |||||
| operate_confirm = 确定操作 | |||||
| operate_cancel = 取消操作 | |||||
| gpu_num = GPU数 | |||||
| cpu_num = CPU数 | |||||
| memory = 内存 | |||||
| shared_memory = 共享内存 | |||||
| @@ -135,7 +135,7 @@ socket.onmessage = function (e) { | |||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | ||||
| } | } | ||||
| else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"){ | |||||
| else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30" || record.OpType == "31"){ | |||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | ||||
| } | } | ||||
| @@ -175,6 +175,8 @@ function getTaskLink(record){ | |||||
| re = re + "/cloudbrain/benchmark/" + record.Content; | re = re + "/cloudbrain/benchmark/" + record.Content; | ||||
| }else if(record.OpType == 30){ | }else if(record.OpType == 30){ | ||||
| re = re + "/modelmanage/show_model_info?name=" + record.RefName; | re = re + "/modelmanage/show_model_info?name=" + record.RefName; | ||||
| }else if(record.OpType == 31){ | |||||
| re = re + "/cloudbrain/train-job/" + record.Content; | |||||
| } | } | ||||
| re = encodeURI(re); | re = encodeURI(re); | ||||
| return re; | return re; | ||||
| @@ -321,10 +323,11 @@ var actionNameZH={ | |||||
| "24":"上传了数据集文件", | "24":"上传了数据集文件", | ||||
| "25":"创建了CPU/GPU类型调试任务", | "25":"创建了CPU/GPU类型调试任务", | ||||
| "26":"创建了NPU类型调试任务", | "26":"创建了NPU类型调试任务", | ||||
| "27":"创建了训练任务", | |||||
| "27":"创建了NPU类型训练任务", | |||||
| "28":"创建了推理任务", | "28":"创建了推理任务", | ||||
| "29":"创建了评测任务", | "29":"创建了评测任务", | ||||
| "30":"导入了新模型" | |||||
| "30":"导入了新模型", | |||||
| "31":"创建了CPU/GPU类型训练任务" | |||||
| }; | }; | ||||
| var actionNameEN={ | var actionNameEN={ | ||||
| @@ -346,10 +349,11 @@ var actionNameEN={ | |||||
| "24":" upload dataset ", | "24":" upload dataset ", | ||||
| "25":" created CPU/GPU type debugging task ", | "25":" created CPU/GPU type debugging task ", | ||||
| "26":" created NPU type debugging task ", | "26":" created NPU type debugging task ", | ||||
| "27":" created training task", | |||||
| "27":" created NPU type training task", | |||||
| "28":" created reasoning task", | "28":" created reasoning task", | ||||
| "29":" created profiling task", | "29":" created profiling task", | ||||
| "30":" created new model" | |||||
| "30":" created new model", | |||||
| "31":" created CPU/GPU type training task", | |||||
| }; | }; | ||||
| var repoAndOrgZH={ | var repoAndOrgZH={ | ||||
| @@ -620,10 +620,10 @@ function showfilelist(){ | |||||
| for (var i=0;i<labeltastresult.length;i++){ | for (var i=0;i<labeltastresult.length;i++){ | ||||
| var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | ||||
| console.log(labeltastresult[i]) | |||||
| //console.log(labeltastresult[i]) | |||||
| if(labeltastresult[i].pic_image_field.length > 70){ | if(labeltastresult[i].pic_image_field.length > 70){ | ||||
| var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | ||||
| console.log(tmpIndex) | |||||
| //console.log(tmpIndex) | |||||
| if(tmpIndex != -1){ | if(tmpIndex != -1){ | ||||
| fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | ||||
| fname = fname.substring(fname.indexOf('/')+1); | fname = fname.substring(fname.indexOf('/')+1); | ||||
| @@ -679,7 +679,7 @@ function breadFiles(){ | |||||
| fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | ||||
| } | } | ||||
| var fname_path = fname_full_path.split('/') | var fname_path = fname_full_path.split('/') | ||||
| console.log(fname_path) | |||||
| //console.log(fname_path) | |||||
| // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | ||||
| var html_breadFile = '' | var html_breadFile = '' | ||||
| // var source_name = filename_title+'.zip' | // var source_name = filename_title+'.zip' | ||||
| @@ -41,7 +41,7 @@ func CloudBrains(ctx *context.Context) { | |||||
| if page <= 0 { | if page <= 0 { | ||||
| page = 1 | page = 1 | ||||
| } | } | ||||
| debugType := modelarts.DebugType | |||||
| debugType := models.TypeCloudBrainAll | |||||
| if listType == models.GPUResource { | if listType == models.GPUResource { | ||||
| debugType = models.TypeCloudBrainOne | debugType = models.TypeCloudBrainOne | ||||
| } else if listType == models.NPUResource { | } else if listType == models.NPUResource { | ||||
| @@ -121,7 +121,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||||
| Page: page, | Page: page, | ||||
| PageSize: 1, | PageSize: 1, | ||||
| }, | }, | ||||
| Type: modelarts.DebugType, | |||||
| Type: models.TypeCloudBrainAll, | |||||
| NeedRepoInfo: false, | NeedRepoInfo: false, | ||||
| IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
| }) | }) | ||||
| @@ -151,7 +151,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||||
| Page: page, | Page: page, | ||||
| PageSize: pageSize, | PageSize: pageSize, | ||||
| }, | }, | ||||
| Type: modelarts.DebugType, | |||||
| Type: models.TypeCloudBrainAll, | |||||
| NeedRepoInfo: true, | NeedRepoInfo: true, | ||||
| IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
| }) | }) | ||||
| @@ -62,10 +62,10 @@ import ( | |||||
| "net/http" | "net/http" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/routers/authentication" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/cloudbrain" | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| @@ -77,6 +77,7 @@ import ( | |||||
| "code.gitea.io/gitea/routers/api/v1/repo" | "code.gitea.io/gitea/routers/api/v1/repo" | ||||
| _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation | _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation | ||||
| "code.gitea.io/gitea/routers/api/v1/user" | "code.gitea.io/gitea/routers/api/v1/user" | ||||
| "code.gitea.io/gitea/routers/authentication" | |||||
| repo_ext "code.gitea.io/gitea/routers/repo" | repo_ext "code.gitea.io/gitea/routers/repo" | ||||
| "gitea.com/macaron/binding" | "gitea.com/macaron/binding" | ||||
| @@ -882,6 +883,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
| m.Get("/:id", repo.GetCloudbrainTask) | m.Get("/:id", repo.GetCloudbrainTask) | ||||
| m.Get("/:id/log", repo.CloudbrainGetLog) | m.Get("/:id/log", repo.CloudbrainGetLog) | ||||
| m.Group("/train-job", func() { | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", repo.GetModelArtsTrainJobVersion) | |||||
| m.Get("/model_list", repo.CloudBrainModelList) | |||||
| m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | |||||
| }) | |||||
| }) | |||||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | }, reqRepoReader(models.UnitTypeCloudBrain)) | ||||
| m.Group("/modelarts", func() { | m.Group("/modelarts", func() { | ||||
| m.Group("/notebook", func() { | m.Group("/notebook", func() { | ||||
| @@ -6,15 +6,18 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "encoding/json" | |||||
| "net/http" | "net/http" | ||||
| "sort" | "sort" | ||||
| "strings" | |||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/cloudbrain" | "code.gitea.io/gitea/modules/cloudbrain" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/storage" | |||||
| routerRepo "code.gitea.io/gitea/routers/repo" | |||||
| ) | ) | ||||
| // cloudbrain get job task by jobid | // cloudbrain get job task by jobid | ||||
| @@ -62,7 +65,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| log.Error("GetJob failed:", err) | log.Error("GetJob failed:", err) | ||||
| return | return | ||||
| } | } | ||||
| result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||||
| result, _ := models.ConvertToJobResultPayload(jobResult.Payload) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| log.Error("ConvertToJobResultPayload failed:", err) | log.Error("ConvertToJobResultPayload failed:", err) | ||||
| @@ -70,16 +73,16 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| } | } | ||||
| job.Status = result.JobStatus.State | job.Status = result.JobStatus.State | ||||
| taskRoles := result.TaskRoles | |||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | ||||
| taskRoles := result.TaskRoles | |||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||||
| job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | ||||
| job.ContainerID = taskRes.TaskStatuses[0].ContainerID | job.ContainerID = taskRes.TaskStatuses[0].ContainerID | ||||
| job.Status = taskRes.TaskStatuses[0].State | job.Status = taskRes.TaskStatuses[0].State | ||||
| } | } | ||||
| if result.JobStatus.State != string(models.JobWaiting) { | if result.JobStatus.State != string(models.JobWaiting) { | ||||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -152,3 +155,55 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| func CloudBrainModelList(ctx *context.APIContext) { | |||||
| var ( | |||||
| err error | |||||
| ) | |||||
| var jobID = ctx.Params(":jobid") | |||||
| var versionName = ctx.Query("version_name") | |||||
| parentDir := ctx.Query("parentDir") | |||||
| dirArray := strings.Split(parentDir, "/") | |||||
| task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error()) | |||||
| return | |||||
| } | |||||
| //get dirs | |||||
| dirs, err := routerRepo.GetModelDirs(task.JobName, parentDir) | |||||
| if err != nil { | |||||
| log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"]) | |||||
| ctx.ServerError("GetModelDirs failed:", err) | |||||
| return | |||||
| } | |||||
| var fileInfos []storage.FileInfo | |||||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||||
| if err != nil { | |||||
| log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return | |||||
| } | |||||
| for i, fileInfo := range fileInfos { | |||||
| temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime) | |||||
| fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05") | |||||
| } | |||||
| sort.Slice(fileInfos, func(i, j int) bool { | |||||
| return fileInfos[i].ModTime > fileInfos[j].ModTime | |||||
| }) | |||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||||
| "JobID": jobID, | |||||
| "VersionName": versionName, | |||||
| "StatusOK": 0, | |||||
| "Path": dirArray, | |||||
| "Dirs": fileInfos, | |||||
| "task": task, | |||||
| "PageIsCloudBrain": true, | |||||
| }) | |||||
| } | |||||
| @@ -10,13 +10,13 @@ import ( | |||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/modules/util" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/cloudbrain" | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| routerRepo "code.gitea.io/gitea/routers/repo" | routerRepo "code.gitea.io/gitea/routers/repo" | ||||
| ) | ) | ||||
| @@ -67,8 +67,14 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| if job.StartTime == 0 && result.Lease.UpdateTime > 0 { | |||||
| job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | |||||
| } | |||||
| job.Status = result.Status | job.Status = result.Status | ||||
| if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { | |||||
| job.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| job.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -128,26 +134,61 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10)) | |||||
| if err != nil { | |||||
| ctx.NotFound(err) | |||||
| return | |||||
| } | |||||
| job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | |||||
| job.Duration = result.Duration | |||||
| job.TrainJobDuration = result.TrainJobDuration | |||||
| if job.Type == models.TypeCloudBrainOne { | |||||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||||
| if err != nil { | |||||
| ctx.NotFound(err) | |||||
| log.Error("GetJob failed:", err) | |||||
| return | |||||
| } | |||||
| result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||||
| if err != nil { | |||||
| ctx.NotFound(err) | |||||
| log.Error("ConvertToJobResultPayload failed:", err) | |||||
| return | |||||
| } | |||||
| if result.Duration != 0 { | |||||
| job.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000) | |||||
| job.Status = result.JobStatus.State | |||||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||||
| taskRoles := result.TaskRoles | |||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||||
| job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||||
| job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||||
| job.Status = taskRes.TaskStatuses[0].State | |||||
| } | |||||
| if result.JobStatus.State != string(models.JobWaiting) { | |||||
| err = models.UpdateJob(job) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob failed:", err) | |||||
| } | |||||
| } | |||||
| } else { | } else { | ||||
| job.TrainJobDuration = "00:00:00" | |||||
| } | |||||
| result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10)) | |||||
| if err != nil { | |||||
| ctx.NotFound(err) | |||||
| return | |||||
| } | |||||
| err = models.UpdateTrainJobVersion(job) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob failed:", err) | |||||
| if job.StartTime == 0 && result.StartTime > 0 { | |||||
| job.StartTime = timeutil.TimeStamp(result.StartTime / 1000) | |||||
| } | |||||
| job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | |||||
| job.Duration = result.Duration / 1000 | |||||
| job.TrainJobDuration = result.TrainJobDuration | |||||
| job.TrainJobDuration = models.ConvertDurationToStr(job.Duration) | |||||
| if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 { | |||||
| job.EndTime = job.StartTime.Add(job.Duration) | |||||
| } | |||||
| err = models.UpdateTrainJobVersion(job) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob failed:", err) | |||||
| } | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| @@ -366,16 +407,15 @@ func GetModelArtsInferenceJob(ctx *context.APIContext) { | |||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| if job.StartTime == 0 && result.StartTime > 0 { | |||||
| job.StartTime = timeutil.TimeStamp(result.StartTime / 1000) | |||||
| } | |||||
| job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | ||||
| job.Duration = result.Duration | |||||
| job.TrainJobDuration = result.TrainJobDuration | |||||
| job.Duration = result.Duration / 1000 | |||||
| job.TrainJobDuration = models.ConvertDurationToStr(job.Duration) | |||||
| if result.Duration != 0 { | |||||
| job.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000) | |||||
| } else { | |||||
| job.TrainJobDuration = "00:00:00" | |||||
| if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 { | |||||
| job.EndTime = job.StartTime.Add(job.Duration) | |||||
| } | } | ||||
| err = models.UpdateInferenceJob(job) | err = models.UpdateInferenceJob(job) | ||||
| @@ -21,6 +21,7 @@ import ( | |||||
| const DEFAULT_PAGE_SIZE = 10 | const DEFAULT_PAGE_SIZE = 10 | ||||
| const DATE_FORMAT = "2006-01-02" | const DATE_FORMAT = "2006-01-02" | ||||
| const EXCEL_DATE_FORMAT = "20060102" | const EXCEL_DATE_FORMAT = "20060102" | ||||
| const CREATE_TIME_FORMAT = "2006/01/02 15:04:05" | |||||
| type ProjectsPeriodData struct { | type ProjectsPeriodData struct { | ||||
| RecordBeginTime string `json:"recordBeginTime"` | RecordBeginTime string `json:"recordBeginTime"` | ||||
| @@ -292,32 +293,32 @@ func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, p | |||||
| func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | ||||
| return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"), | return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"), | ||||
| "J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor")} | |||||
| "J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor"), "P1": ctx.Tr("admin.repos.isFork"), "Q1": ctx.Tr("admin.repos.isMirror"), "R1": ctx.Tr("admin.repos.create")} | |||||
| } | } | ||||
| func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | ||||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10), | getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10), | ||||
| getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10), | getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10), | ||||
| getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), | |||||
| getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("P", row): getBoolDisplay(rs.IsFork, ctx), getCellName("Q", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("R", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT), | |||||
| } | } | ||||
| } | } | ||||
| func allProjectsOpenIHeader() map[string]string { | func allProjectsOpenIHeader() map[string]string { | ||||
| return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "是否私有", "E1": "OpenI指数", | |||||
| return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "私有", "E1": "OpenI指数", | |||||
| "F1": "影响力", "G1": "成熟度", "H1": "活跃度", "I1": "项目健康度", "J1": "团队健康度", "K1": "项目发展趋势", | "F1": "影响力", "G1": "成熟度", "H1": "活跃度", "I1": "项目健康度", "J1": "团队健康度", "K1": "项目发展趋势", | ||||
| "L1": "关注数", "M1": "点赞数", "N1": "派生数", "O1": "代码下载量", "P1": "评论数", "Q1": "浏览量", "R1": "已解决任务数", "S1": "版本发布数量", "T1": "有效开发年龄", | "L1": "关注数", "M1": "点赞数", "N1": "派生数", "O1": "代码下载量", "P1": "评论数", "Q1": "浏览量", "R1": "已解决任务数", "S1": "版本发布数量", "T1": "有效开发年龄", | ||||
| "U1": "数据集", "V1": "模型数", "W1": "百科页面数量", "X1": "提交数", "Y1": "任务数", "Z1": "PR数", "AA1": "版本发布数量", "AB1": "任务完成比例", "AC1": "贡献者数", "AD1": "关键贡献者数", | "U1": "数据集", "V1": "模型数", "W1": "百科页面数量", "X1": "提交数", "Y1": "任务数", "Z1": "PR数", "AA1": "版本发布数量", "AB1": "任务完成比例", "AC1": "贡献者数", "AD1": "关键贡献者数", | ||||
| "AE1": "新人增长量", "AF1": "代码规模增长量", "AG1": "任务增长量", "AH1": "新人增长量", "AI1": "提交增长量", "AJ1": "评论增长量", | |||||
| "AE1": "新人增长量", "AF1": "代码规模增长量", "AG1": "任务增长量", "AH1": "新人增长量", "AI1": "提交增长量", "AJ1": "评论增长量", "AK1": "迁移", "AL1": "镜像", "AM1": "项目创建时间", | |||||
| } | } | ||||
| } | } | ||||
| func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | ||||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||||
| getCellName("F", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("G", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("H", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64), | getCellName("F", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("G", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("H", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64), | ||||
| getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumDownloads, 10), | getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumDownloads, 10), | ||||
| @@ -325,7 +326,7 @@ func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Cont | |||||
| getCellName("T", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("U", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("V", row): strconv.FormatInt(rs.NumModels, 10), getCellName("W", row): strconv.FormatInt(rs.NumWikiViews, 10), | getCellName("T", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("U", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("V", row): strconv.FormatInt(rs.NumModels, 10), getCellName("W", row): strconv.FormatInt(rs.NumWikiViews, 10), | ||||
| getCellName("X", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("Y", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("Z", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AA", row): strconv.FormatInt(rs.NumVersions, 10), | getCellName("X", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("Y", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("Z", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AA", row): strconv.FormatInt(rs.NumVersions, 10), | ||||
| getCellName("AB", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AC", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AD", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AE", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), | getCellName("AB", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AC", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AD", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AE", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), | ||||
| getCellName("AF", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AG", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AH", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), | |||||
| getCellName("AF", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AG", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AH", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), getCellName("AK", row): getBoolDisplay(rs.IsFork, ctx), getCellName("AL", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("AM", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT), | |||||
| } | } | ||||
| } | } | ||||
| @@ -334,8 +335,8 @@ func getCellName(col string, row int) string { | |||||
| return col + strconv.Itoa(row) | return col + strconv.Itoa(row) | ||||
| } | } | ||||
| func getIsPrivateDisplay(private bool, ctx *context.Context) string { | |||||
| if private { | |||||
| func getBoolDisplay(value bool, ctx *context.Context) string { | |||||
| if value { | |||||
| return ctx.Tr("admin.repos.yes") | return ctx.Tr("admin.repos.yes") | ||||
| } else { | } else { | ||||
| return ctx.Tr("admin.repos.no") | return ctx.Tr("admin.repos.no") | ||||
| @@ -482,11 +483,11 @@ func generateOpenICountSql(latestDate string) string { | |||||
| } | } | ||||
| func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | ||||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||||
| "(SELECT repo_id,sum(num_visits) as num_visits " + | "(SELECT repo_id,sum(num_visits) as num_visits " + | ||||
| " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | ||||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | ||||
| "(SELECT repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| "(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| " where A.repo_id=B.repo_id" | " where A.repo_id=B.repo_id" | ||||
| if q != "" { | if q != "" { | ||||
| @@ -497,7 +498,7 @@ func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate strin | |||||
| } | } | ||||
| func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | ||||
| sql := "SELECT id, repo_id, date, num_watches, num_stars, num_forks, num_downloads, num_comments, num_visits, num_closed_issues, num_versions, num_dev_months, repo_size, dataset_size, num_models, num_wiki_views, num_commits, num_issues, num_pulls, issue_fixed_rate, num_contributor, num_key_contributor, num_contributors_growth, num_commits_growth, num_commit_lines_growth, num_issues_growth, num_comments_growth, impact, completeness, liveness, project_health, team_health, growth, radar_total, name,alias, is_private, owner_name FROM " + | |||||
| sql := "SELECT id, repo_id, date, num_watches, num_stars, num_forks, num_downloads, num_comments, num_visits, num_closed_issues, num_versions, num_dev_months, repo_size, dataset_size, num_models, num_wiki_views, num_commits, num_issues, num_pulls, issue_fixed_rate, num_contributor, num_key_contributor, num_contributors_growth, num_commits_growth, num_commit_lines_growth, num_issues_growth, num_comments_growth, impact, completeness, liveness, project_health, team_health, growth, radar_total, name,alias, is_private,is_mirror,is_fork,repo_created_unix, owner_name FROM " + | |||||
| " public.repo_statistic where date='" + latestDate + "'" | " public.repo_statistic where date='" + latestDate + "'" | ||||
| sql = sql + " order by radar_total desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | sql = sql + " order by radar_total desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize) | ||||
| @@ -506,11 +507,11 @@ func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string { | |||||
| func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string { | ||||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||||
| sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " + | |||||
| "(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " + | "(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " + | ||||
| " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + | ||||
| " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," + | ||||
| "(SELECT repo_id,name,alias,owner_name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| "(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total from public.repo_statistic where date='" + latestDate + "') B" + | |||||
| " where A.repo_id=B.repo_id" | " where A.repo_id=B.repo_id" | ||||
| if q != "" { | if q != "" { | ||||
| sql = sql + " and LOWER(B.alias) like '%" + strings.ToLower(q) + "%'" | sql = sql + " and LOWER(B.alias) like '%" + strings.ToLower(q) + "%'" | ||||
| @@ -274,10 +274,11 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | ||||
| var ( | var ( | ||||
| datasets []*models.Dataset | |||||
| count int64 | |||||
| err error | |||||
| orderBy models.SearchOrderBy | |||||
| datasets []*models.Dataset | |||||
| datasetsWithStar []*models.DatasetWithStar | |||||
| count int64 | |||||
| err error | |||||
| orderBy models.SearchOrderBy | |||||
| ) | ) | ||||
| page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
| if page <= 0 { | if page <= 0 { | ||||
| @@ -301,6 +302,10 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| orderBy = models.SearchOrderBySizeReverse | orderBy = models.SearchOrderBySizeReverse | ||||
| case "downloadtimes": | case "downloadtimes": | ||||
| orderBy = models.SearchOrderByDownloadTimes | orderBy = models.SearchOrderByDownloadTimes | ||||
| case "moststars": | |||||
| orderBy = models.SearchOrderByStarsReverse | |||||
| case "feweststars": | |||||
| orderBy = models.SearchOrderByStars | |||||
| default: | default: | ||||
| ctx.Data["SortType"] = "recentupdate" | ctx.Data["SortType"] = "recentupdate" | ||||
| orderBy = models.SearchOrderByRecentUpdated | orderBy = models.SearchOrderByRecentUpdated | ||||
| @@ -308,6 +313,9 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | keyword := strings.Trim(ctx.Query("q"), " ") | ||||
| category := ctx.Query("category") | |||||
| task := ctx.Query("task") | |||||
| license := ctx.Query("license") | |||||
| var ownerID int64 | var ownerID int64 | ||||
| if ctx.User != nil && !ctx.User.IsAdmin { | if ctx.User != nil && !ctx.User.IsAdmin { | ||||
| ownerID = ctx.User.ID | ownerID = ctx.User.ID | ||||
| @@ -316,25 +324,40 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| Keyword: keyword, | Keyword: keyword, | ||||
| IncludePublic: true, | IncludePublic: true, | ||||
| SearchOrderBy: orderBy, | SearchOrderBy: orderBy, | ||||
| Category: category, | |||||
| Task: task, | |||||
| License: license, | |||||
| OwnerID: ownerID, | OwnerID: ownerID, | ||||
| ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: setting.UI.ExplorePagingNum, | |||||
| PageSize: 30, | |||||
| }, | }, | ||||
| } | } | ||||
| datasets, count, err = models.SearchDataset(opts) | datasets, count, err = models.SearchDataset(opts) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("SearchDatasets", err) | ctx.ServerError("SearchDatasets", err) | ||||
| return | return | ||||
| } | } | ||||
| for _, dataset := range datasets { | |||||
| if !ctx.IsSigned { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false}) | |||||
| } else { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)}) | |||||
| } | |||||
| } | |||||
| pager := context.NewPagination(int(count), opts.PageSize, page, 5) | pager := context.NewPagination(int(count), opts.PageSize, page, 5) | ||||
| ctx.Data["Keyword"] = opts.Keyword | ctx.Data["Keyword"] = opts.Keyword | ||||
| ctx.Data["Category"] = category | |||||
| ctx.Data["Task"] = task | |||||
| ctx.Data["License"] = license | |||||
| pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| ctx.Data["Datasets"] = datasets | |||||
| ctx.Data["Datasets"] = datasetsWithStar | |||||
| ctx.Data["Total"] = count | ctx.Data["Total"] = count | ||||
| ctx.Data["PageIsDatasets"] = true | ctx.Data["PageIsDatasets"] = true | ||||
| ctx.HTML(200, tplExploreDataset) | ctx.HTML(200, tplExploreDataset) | ||||
| @@ -71,6 +71,8 @@ func NewServices() { | |||||
| log.Info("decompression.NewContext() succeed.") | log.Info("decompression.NewContext() succeed.") | ||||
| labelmsg.Init() | labelmsg.Init() | ||||
| log.Info("labelmsg.Init() succeed.") | log.Info("labelmsg.Init() succeed.") | ||||
| InitESClient() | |||||
| log.Info("ES Client succeed.") | |||||
| } | } | ||||
| // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | ||||
| @@ -6,6 +6,7 @@ | |||||
| package private | package private | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/routers/repo" | |||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| @@ -45,6 +46,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/tool/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt) | m.Post("/tool/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt) | ||||
| m.Post("/tool/repo_stat/:date", RepoStatisticManually) | m.Post("/tool/repo_stat/:date", RepoStatisticManually) | ||||
| m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | ||||
| m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration) | |||||
| }, CheckInternalToken) | }, CheckInternalToken) | ||||
| } | } | ||||
| @@ -15,6 +15,10 @@ import ( | |||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/modules/auth" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/labelmsg" | "code.gitea.io/gitea/modules/labelmsg" | ||||
| @@ -30,8 +34,10 @@ import ( | |||||
| const ( | const ( | ||||
| //result of decompress | //result of decompress | ||||
| DecompressSuccess = "0" | |||||
| DecompressFailed = "1" | |||||
| DecompressSuccess = "0" | |||||
| DecompressFailed = "1" | |||||
| tplAttachmentUpload base.TplName = "repo/attachment/upload" | |||||
| tplAttachmentEdit base.TplName = "repo/attachment/edit" | |||||
| ) | ) | ||||
| type CloudBrainDataset struct { | type CloudBrainDataset struct { | ||||
| @@ -63,6 +69,40 @@ func renderAttachmentSettings(ctx *context.Context) { | |||||
| ctx.Data["AttachmentMaxFiles"] = setting.Attachment.MaxFiles | ctx.Data["AttachmentMaxFiles"] = setting.Attachment.MaxFiles | ||||
| } | } | ||||
| func UploadAttachmentUI(ctx *context.Context) { | |||||
| ctx.Data["datasetId"] = ctx.Query("datasetId") | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| ctx.HTML(200, tplAttachmentUpload) | |||||
| } | |||||
| func EditAttachmentUI(ctx *context.Context) { | |||||
| id, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64) | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| attachment, _ := models.GetAttachmentByID(id) | |||||
| if attachment == nil { | |||||
| ctx.Error(404, "The attachment does not exits.") | |||||
| } | |||||
| ctx.Data["Attachment"] = attachment | |||||
| ctx.HTML(200, tplAttachmentEdit) | |||||
| } | |||||
| func EditAttachment(ctx *context.Context, form auth.EditAttachmentForm) { | |||||
| err := models.UpdateAttachmentDescription(&models.Attachment{ | |||||
| ID: form.ID, | |||||
| Description: form.Description, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.edit_attachment_fail"))) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | |||||
| // UploadAttachment response for uploading issue's attachment | // UploadAttachment response for uploading issue's attachment | ||||
| func UploadAttachment(ctx *context.Context) { | func UploadAttachment(ctx *context.Context) { | ||||
| if !setting.Attachment.Enabled { | if !setting.Attachment.Enabled { | ||||
| @@ -241,14 +281,20 @@ func GetAttachment(ctx *context.Context) { | |||||
| } | } | ||||
| if dataSet != nil { | if dataSet != nil { | ||||
| isPermit, err := models.GetUserDataSetPermission(dataSet, ctx.User) | |||||
| if err != nil { | |||||
| ctx.Error(http.StatusInternalServerError, "GetUserDataSetPermission", err.Error()) | |||||
| return | |||||
| } | |||||
| if !isPermit { | |||||
| ctx.Error(http.StatusNotFound) | |||||
| if !ctx.IsSigned { | |||||
| ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | |||||
| ctx.Redirect(setting.AppSubURL + "/user/login") | |||||
| return | return | ||||
| } else { | |||||
| isPermit, err := models.GetUserDataSetPermission(dataSet, ctx.User) | |||||
| if err != nil { | |||||
| ctx.Error(http.StatusInternalServerError, "GetUserDataSetPermission", err.Error()) | |||||
| return | |||||
| } | |||||
| if !isPermit { | |||||
| ctx.Error(http.StatusNotFound) | |||||
| return | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -387,11 +433,17 @@ func AddAttachment(ctx *context.Context) { | |||||
| ctx.Error(404, "attachment has not been uploaded") | ctx.Error(404, "attachment has not been uploaded") | ||||
| return | return | ||||
| } | } | ||||
| datasetId := ctx.QueryInt64("dataset_id") | |||||
| dataset, err := models.GetDatasetByID(datasetId) | |||||
| if err != nil { | |||||
| ctx.Error(404, "dataset does not exist.") | |||||
| return | |||||
| } | |||||
| attachment, err := models.InsertAttachment(&models.Attachment{ | attachment, err := models.InsertAttachment(&models.Attachment{ | ||||
| UUID: uuid, | UUID: uuid, | ||||
| UploaderID: ctx.User.ID, | UploaderID: ctx.User.ID, | ||||
| IsPrivate: true, | |||||
| IsPrivate: dataset.IsPrivate(), | |||||
| Name: fileName, | Name: fileName, | ||||
| Size: ctx.QueryInt64("size"), | Size: ctx.QueryInt64("size"), | ||||
| DatasetID: ctx.QueryInt64("dataset_id"), | DatasetID: ctx.QueryInt64("dataset_id"), | ||||
| @@ -798,6 +850,9 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| typeCloudBrain := ctx.QueryInt("type") | typeCloudBrain := ctx.QueryInt("type") | ||||
| fileName := ctx.Query("file_name") | fileName := ctx.Query("file_name") | ||||
| log.Warn("uuid:" + uuid) | |||||
| log.Warn("typeCloudBrain:" + strconv.Itoa(typeCloudBrain)) | |||||
| err := checkTypeCloudBrain(typeCloudBrain) | err := checkTypeCloudBrain(typeCloudBrain) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("checkTypeCloudBrain failed", err) | ctx.ServerError("checkTypeCloudBrain failed", err) | ||||
| @@ -835,22 +890,24 @@ func CompleteMultipart(ctx *context.Context) { | |||||
| ctx.Error(500, fmt.Sprintf("UpdateFileChunk: %v", err)) | ctx.Error(500, fmt.Sprintf("UpdateFileChunk: %v", err)) | ||||
| return | return | ||||
| } | } | ||||
| dataset, _ := models.GetDatasetByID(ctx.QueryInt64("dataset_id")) | |||||
| log.Warn("insert attachment to datasetId:" + strconv.FormatInt(dataset.ID, 10)) | |||||
| attachment, err := models.InsertAttachment(&models.Attachment{ | attachment, err := models.InsertAttachment(&models.Attachment{ | ||||
| UUID: uuid, | |||||
| UploaderID: ctx.User.ID, | |||||
| IsPrivate: true, | |||||
| Name: fileName, | |||||
| Size: ctx.QueryInt64("size"), | |||||
| DatasetID: ctx.QueryInt64("dataset_id"), | |||||
| Type: typeCloudBrain, | |||||
| UUID: uuid, | |||||
| UploaderID: ctx.User.ID, | |||||
| IsPrivate: dataset.IsPrivate(), | |||||
| Name: fileName, | |||||
| Size: ctx.QueryInt64("size"), | |||||
| DatasetID: ctx.QueryInt64("dataset_id"), | |||||
| Description: ctx.Query("description"), | |||||
| Type: typeCloudBrain, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err)) | ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err)) | ||||
| return | return | ||||
| } | } | ||||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||||
| repository, _ := models.GetRepositoryByID(dataset.RepoID) | repository, _ := models.GetRepositoryByID(dataset.RepoID) | ||||
| notification.NotifyOtherTask(ctx.User, repository, fmt.Sprint(attachment.Type), attachment.Name, models.ActionUploadAttachment) | notification.NotifyOtherTask(ctx.User, repository, fmt.Sprint(attachment.Type), attachment.Name, models.ActionUploadAttachment) | ||||
| @@ -2,9 +2,11 @@ package repo | |||||
| import ( | import ( | ||||
| "bufio" | "bufio" | ||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "fmt" | "fmt" | ||||
| "github.com/unknwon/i18n" | |||||
| "io" | "io" | ||||
| "net/http" | "net/http" | ||||
| "os" | "os" | ||||
| @@ -35,6 +37,9 @@ const ( | |||||
| tplCloudBrainBenchmarkIndex base.TplName = "repo/cloudbrain/benchmark/index" | tplCloudBrainBenchmarkIndex base.TplName = "repo/cloudbrain/benchmark/index" | ||||
| tplCloudBrainBenchmarkNew base.TplName = "repo/cloudbrain/benchmark/new" | tplCloudBrainBenchmarkNew base.TplName = "repo/cloudbrain/benchmark/new" | ||||
| tplCloudBrainBenchmarkShow base.TplName = "repo/cloudbrain/benchmark/show" | tplCloudBrainBenchmarkShow base.TplName = "repo/cloudbrain/benchmark/show" | ||||
| tplCloudBrainTrainJobNew base.TplName = "repo/cloudbrain/trainjob/new" | |||||
| tplCloudBrainTrainJobShow base.TplName = "repo/cloudbrain/trainjob/show" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| @@ -43,8 +48,13 @@ var ( | |||||
| benchmarkTypes *models.BenchmarkTypes | benchmarkTypes *models.BenchmarkTypes | ||||
| benchmarkGpuInfos *models.GpuInfos | benchmarkGpuInfos *models.GpuInfos | ||||
| benchmarkResourceSpecs *models.ResourceSpecs | benchmarkResourceSpecs *models.ResourceSpecs | ||||
| trainGpuInfos *models.GpuInfos | |||||
| ) | ) | ||||
| const BENCHMARK_TYPE_CODE = "repo.cloudbrain.benchmark.types" | |||||
| var benchmarkTypesMap = make(map[string]*models.BenchmarkTypes, 0) | |||||
| var jobNamePattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$`) | var jobNamePattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$`) | ||||
| // MustEnableDataset check if repository enable internal cb | // MustEnableDataset check if repository enable internal cb | ||||
| @@ -130,18 +140,18 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
| } | } | ||||
| ctx.Data["benchmark_categories"] = categories.Category | ctx.Data["benchmark_categories"] = categories.Category | ||||
| if benchmarkTypes == nil { | |||||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", setting.BenchmarkTypes, err, ctx.Data["MsgID"]) | |||||
| } | |||||
| } | |||||
| ctx.Data["benchmark_types"] = benchmarkTypes.BenchmarkType | |||||
| ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType | |||||
| if gpuInfos == nil { | if gpuInfos == nil { | ||||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | ||||
| } | } | ||||
| ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ctx.Data["gpu_types"] = gpuInfos.GpuInfo | ||||
| if trainGpuInfos == nil { | |||||
| json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
| } | |||||
| ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||||
| if benchmarkGpuInfos == nil { | if benchmarkGpuInfos == nil { | ||||
| json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | ||||
| } | } | ||||
| @@ -156,12 +166,22 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | ||||
| } | } | ||||
| ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | ||||
| if cloudbrain.TrainResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||||
| } | |||||
| ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||||
| ctx.Data["params"] = "" | |||||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
| ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | ||||
| ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | ||||
| ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath | ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath | ||||
| ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled | ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled | ||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -181,38 +201,52 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| image := form.Image | image := form.Image | ||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| jobType := form.JobType | jobType := form.JobType | ||||
| command := cloudbrain.Command | |||||
| gpuQueue := form.GpuType | gpuQueue := form.GpuType | ||||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
| resourceSpecId := form.ResourceSpecId | resourceSpecId := form.ResourceSpecId | ||||
| branchName := form.BranchName | |||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||||
| tpl := tplCloudBrainNew | |||||
| command := cloudbrain.Command | |||||
| if jobType == string(models.JobTypeTrain) { | |||||
| tpl = tplCloudBrainTrainJobNew | |||||
| commandTrain, err := getTrainJobCommand(form) | |||||
| if err != nil { | |||||
| log.Error("getTrainJobCommand failed: %v", err) | |||||
| ctx.RenderWithErr(err.Error(), tpl, &form) | |||||
| return | |||||
| } | |||||
| command = commandTrain | |||||
| } | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) | |||||
| if err == nil { | if err == nil { | ||||
| if len(tasks) != 0 { | if len(tasks) != 0 { | ||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | log.Error("the job name did already exist", ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr("the job name did already exist", tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| } else { | } else { | ||||
| if !models.IsErrJobNotExist(err) { | if !models.IsErrJobNotExist(err) { | ||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | log.Error("system error, %v", err, ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr("system error", tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| if !jobNamePattern.MatchString(displayJobName) { | if !jobNamePattern.MatchString(displayJobName) { | ||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) { | |||||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) && jobType != string(models.JobTypeTrain) { | |||||
| log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr("jobtype error", tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -220,18 +254,21 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr("system error", tpl, &form) | |||||
| return | return | ||||
| } else { | } else { | ||||
| if count >= 1 { | if count >= 1 { | ||||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| downloadCode(repo, codePath) | |||||
| if branchName == "" { | |||||
| branchName = cloudbrain.DefaultBranchName | |||||
| } | |||||
| downloadCode(repo, codePath, branchName) | |||||
| uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | ||||
| modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" | modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" | ||||
| @@ -265,15 +302,19 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, | |||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, branchName, form.BootFile, form.Params, | |||||
| 0, 0, resourceSpecId) | 0, 0, resourceSpecId) | ||||
| if err != nil { | if err != nil { | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | |||||
| ctx.RenderWithErr(err.Error(), tpl, &form) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
| if jobType == string(models.JobTypeTrain) { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=all") | |||||
| } else { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||||
| } | |||||
| } | } | ||||
| func CloudBrainRestart(ctx *context.Context) { | func CloudBrainRestart(ctx *context.Context) { | ||||
| @@ -339,25 +380,29 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
| } | } | ||||
| func CloudBrainBenchMarkShow(ctx *context.Context) { | func CloudBrainBenchMarkShow(ctx *context.Context) { | ||||
| if benchmarkTypes == nil { | |||||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", setting.BenchmarkTypes, err, ctx.Data["MsgID"]) | |||||
| ctx.ServerError(err.Error(), err) | |||||
| return | |||||
| } | |||||
| } | |||||
| cloudBrainShow(ctx, tplCloudBrainBenchmarkShow) | |||||
| cloudBrainShow(ctx, tplCloudBrainBenchmarkShow, models.JobTypeBenchmark) | |||||
| } | } | ||||
| func CloudBrainShow(ctx *context.Context) { | func CloudBrainShow(ctx *context.Context) { | ||||
| cloudBrainShow(ctx, tplCloudBrainShow) | |||||
| cloudBrainShow(ctx, tplCloudBrainShow, models.JobTypeDebug) | |||||
| } | } | ||||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| func CloudBrainTrainJobShow(ctx *context.Context) { | |||||
| cloudBrainShow(ctx, tplCloudBrainTrainJobShow, models.JobTypeTrain) | |||||
| } | |||||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.JobType) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| var ID = ctx.Params(":id") | |||||
| debugListType := ctx.Query("debugListType") | debugListType := ctx.Query("debugListType") | ||||
| task, err := models.GetCloudbrainByID(ID) | |||||
| var task *models.Cloudbrain | |||||
| var err error | |||||
| if jobType == models.JobTypeTrain { | |||||
| task, err = models.GetCloudbrainByJobID(ctx.Params(":jobid")) | |||||
| } else { | |||||
| task, err = models.GetCloudbrainByID(ctx.Params(":id")) | |||||
| } | |||||
| if err != nil { | if err != nil { | ||||
| log.Info("error:" + err.Error()) | log.Info("error:" + err.Error()) | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| @@ -372,6 +417,16 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | ||||
| spec := "GPU数:" + strconv.Itoa(jobRes.Resource.NvidiaComGpu) + ",CPU数:" + strconv.Itoa(jobRes.Resource.CPU) + ",内存(MB):" + jobRes.Resource.Memory | spec := "GPU数:" + strconv.Itoa(jobRes.Resource.NvidiaComGpu) + ",CPU数:" + strconv.Itoa(jobRes.Resource.CPU) + ",内存(MB):" + jobRes.Resource.Memory | ||||
| ctx.Data["resource_spec"] = spec | ctx.Data["resource_spec"] = spec | ||||
| if task.JobType == string(models.JobTypeTrain) { | |||||
| if trainGpuInfos == nil { | |||||
| json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
| } | |||||
| for _, resourceType := range trainGpuInfos.GpuInfo { | |||||
| if resourceType.Queue == jobRes.Config.GpuType { | |||||
| ctx.Data["resource_type"] = resourceType.Value | |||||
| } | |||||
| } | |||||
| } | |||||
| taskRoles := jobRes.TaskRoles | taskRoles := jobRes.TaskRoles | ||||
| if jobRes.JobStatus.State != string(models.JobFailed) { | if jobRes.JobStatus.State != string(models.JobFailed) { | ||||
| @@ -380,6 +435,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| task.Status = taskRes.TaskStatuses[0].State | task.Status = taskRes.TaskStatuses[0].State | ||||
| task.ContainerID = taskRes.TaskStatuses[0].ContainerID | task.ContainerID = taskRes.TaskStatuses[0].ContainerID | ||||
| task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | ||||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| @@ -405,14 +461,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| task.User = user | task.User = user | ||||
| } | } | ||||
| var duration int64 | |||||
| if task.Status == string(models.JobRunning) { | |||||
| duration = time.Now().Unix() - int64(task.CreatedUnix) | |||||
| } else { | |||||
| duration = int64(task.UpdatedUnix) - int64(task.CreatedUnix) | |||||
| } | |||||
| if task.BenchmarkTypeID > 0 { | if task.BenchmarkTypeID > 0 { | ||||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||||
| if task.BenchmarkTypeID == benchmarkType.Id { | if task.BenchmarkTypeID == benchmarkType.Id { | ||||
| ctx.Data["BenchmarkTypeName"] = benchmarkType.First | ctx.Data["BenchmarkTypeName"] = benchmarkType.First | ||||
| for _, benchmarkChildType := range benchmarkType.Second { | for _, benchmarkChildType := range benchmarkType.Second { | ||||
| @@ -425,8 +475,42 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if task.TrainJobDuration == "" { | |||||
| if task.Duration == 0 { | |||||
| var duration int64 | |||||
| if task.Status == string(models.JobRunning) { | |||||
| duration = time.Now().Unix() - int64(task.CreatedUnix) | |||||
| } else { | |||||
| duration = int64(task.UpdatedUnix) - int64(task.CreatedUnix) | |||||
| } | |||||
| task.Duration = duration | |||||
| } | |||||
| task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | |||||
| } | |||||
| ctx.Data["duration"] = task.TrainJobDuration | |||||
| if len(task.Parameters) > 0 { | |||||
| var parameters models.Parameters | |||||
| err := json.Unmarshal([]byte(task.Parameters), ¶meters) | |||||
| if err != nil { | |||||
| log.Error("Failed to Unmarshal Parameters: %s (%v)", task.Parameters, err) | |||||
| task.Parameters = "" | |||||
| } else { | |||||
| if len(parameters.Parameter) > 0 { | |||||
| paramTemp := "" | |||||
| for _, Parameter := range parameters.Parameter { | |||||
| param := Parameter.Label + " = " + Parameter.Value + "; " | |||||
| paramTemp = paramTemp + param | |||||
| } | |||||
| task.Parameters = paramTemp[:len(paramTemp)-2] | |||||
| } else { | |||||
| task.Parameters = "" | |||||
| } | |||||
| } | |||||
| } | |||||
| ctx.Data["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | |||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| ctx.Data["displayJobName"] = task.DisplayJobName | ctx.Data["displayJobName"] = task.DisplayJobName | ||||
| @@ -434,6 +518,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| version_list_task = append(version_list_task, task) | version_list_task = append(version_list_task, task) | ||||
| ctx.Data["version_list_task"] = version_list_task | ctx.Data["version_list_task"] = version_list_task | ||||
| ctx.Data["debugListType"] = debugListType | ctx.Data["debugListType"] = debugListType | ||||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||||
| ctx.HTML(200, tpName) | ctx.HTML(200, tpName) | ||||
| } | } | ||||
| @@ -489,6 +574,10 @@ func CloudBrainStop(ctx *context.Context) { | |||||
| } | } | ||||
| task.Status = string(models.JobStopped) | task.Status = string(models.JobStopped) | ||||
| if task.EndTime == 0 { | |||||
| task.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | ||||
| @@ -501,11 +590,12 @@ func CloudBrainStop(ctx *context.Context) { | |||||
| break | break | ||||
| } | } | ||||
| ctx.JSON(200, map[string]string{ | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "result_code": resultCode, | "result_code": resultCode, | ||||
| "error_msg": errorMsg, | "error_msg": errorMsg, | ||||
| "status": status, | "status": status, | ||||
| "id": ID, | "id": ID, | ||||
| "StatusOK": 0, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -582,6 +672,10 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) { | |||||
| log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err) | log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err) | ||||
| } else { | } else { | ||||
| taskInfo.Status = string(models.JobStopped) | taskInfo.Status = string(models.JobStopped) | ||||
| if taskInfo.EndTime == 0 { | |||||
| taskInfo.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| taskInfo.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(taskInfo) | err = models.UpdateJob(taskInfo) | ||||
| if err != nil { | if err != nil { | ||||
| log.Warn("UpdateJob failed", err) | log.Warn("UpdateJob failed", err) | ||||
| @@ -753,8 +847,8 @@ func GetRate(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| func downloadCode(repo *models.Repository, codePath string) error { | |||||
| if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{}); err != nil { | |||||
| func downloadCode(repo *models.Repository, codePath, branchName string) error { | |||||
| if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{Branch: branchName}); err != nil { | |||||
| log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -952,7 +1046,7 @@ func SyncCloudbrainStatus() { | |||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | ||||
| task.Status = taskRes.TaskStatuses[0].State | task.Status = taskRes.TaskStatuses[0].State | ||||
| if task.Status != string(models.JobWaiting) { | if task.Status != string(models.JobWaiting) { | ||||
| task.Duration = time.Now().Unix() - taskRes.TaskStatuses[0].StartAt.Unix() | |||||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -973,6 +1067,10 @@ func SyncCloudbrainStatus() { | |||||
| continue | continue | ||||
| } | } | ||||
| task.Status = string(models.JobStopped) | task.Status = string(models.JobStopped) | ||||
| if task.EndTime == 0 { | |||||
| task.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -991,14 +1089,20 @@ func SyncCloudbrainStatus() { | |||||
| if result != nil { | if result != nil { | ||||
| task.Status = result.Status | task.Status = result.Status | ||||
| if task.StartTime == 0 && result.Lease.UpdateTime > 0 { | |||||
| task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | |||||
| } | |||||
| if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | |||||
| task.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| continue | continue | ||||
| } | } | ||||
| } | } | ||||
| } else if task.JobType == string(models.JobTypeTrain) { | |||||
| } else if task.JobType == string(models.JobTypeTrain) || task.JobType == string(models.JobTypeInference) { | |||||
| result, err := modelarts.GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | result, err := modelarts.GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetTrainJob(%s) failed:%v", task.JobName, err) | log.Error("GetTrainJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -1007,16 +1111,160 @@ func SyncCloudbrainStatus() { | |||||
| if result != nil { | if result != nil { | ||||
| task.Status = modelarts.TransTrainJobStatus(result.IntStatus) | task.Status = modelarts.TransTrainJobStatus(result.IntStatus) | ||||
| task.Duration = result.Duration | |||||
| task.Duration = result.Duration / 1000 | |||||
| task.TrainJobDuration = result.TrainJobDuration | task.TrainJobDuration = result.TrainJobDuration | ||||
| if result.Duration != 0 { | |||||
| task.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000) | |||||
| if task.StartTime == 0 && result.StartTime > 0 { | |||||
| task.StartTime = timeutil.TimeStamp(result.StartTime / 1000) | |||||
| } | |||||
| task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | |||||
| if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 { | |||||
| task.EndTime = task.StartTime.Add(task.Duration) | |||||
| } | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | |||||
| continue | |||||
| } | |||||
| } | |||||
| } else { | |||||
| log.Error("task.JobType(%s) is error:%s", task.JobName, task.JobType) | |||||
| } | |||||
| } else { | |||||
| log.Error("task.Type(%s) is error:%d", task.JobName, task.Type) | |||||
| } | |||||
| } | |||||
| return | |||||
| } | |||||
| func HandleTaskWithNoDuration(ctx *context.Context) { | |||||
| log.Info("HandleTaskWithNoDuration start") | |||||
| count := 0 | |||||
| start := time.Now().Unix() | |||||
| for { | |||||
| cloudBrains, err := models.GetStoppedJobWithNoDurationJob() | |||||
| if err != nil { | |||||
| log.Error("HandleTaskWithNoTrainJobDuration failed:", err.Error()) | |||||
| break | |||||
| } | |||||
| if len(cloudBrains) == 0 { | |||||
| log.Info("HandleTaskWithNoTrainJobDuration:no task need handle") | |||||
| break | |||||
| } | |||||
| handleNoDurationTask(cloudBrains) | |||||
| count += len(cloudBrains) | |||||
| if len(cloudBrains) < 100 { | |||||
| log.Info("HandleTaskWithNoTrainJobDuration:task less than 100") | |||||
| break | |||||
| } | |||||
| if time.Now().Unix()-start > 600 { | |||||
| log.Info("HandleTaskWithNoDuration : time out") | |||||
| ctx.JSON(200, fmt.Sprintf("task stop for time out,count=%d", count)) | |||||
| return | |||||
| } | |||||
| } | |||||
| log.Info("HandleTaskWithNoTrainJobDuration:count=%d", count) | |||||
| ctx.JSON(200, fmt.Sprintf("success,count=%d", count)) | |||||
| } | |||||
| func handleNoDurationTask(cloudBrains []*models.Cloudbrain) { | |||||
| for _, task := range cloudBrains { | |||||
| time.Sleep(time.Millisecond * 100) | |||||
| log.Info("Handle job ,%+v", task) | |||||
| if task.Type == models.TypeCloudBrainOne { | |||||
| result, err := cloudbrain.GetJob(task.JobID) | |||||
| if err != nil { | |||||
| log.Error("GetJob(%s) failed:%v", task.JobName, err) | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| if result != nil { | |||||
| if result.Msg != "success" { | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| jobRes, err := models.ConvertToJobResultPayload(result.Payload) | |||||
| if err != nil || len(jobRes.TaskRoles) == 0 { | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| taskRoles := jobRes.TaskRoles | |||||
| taskRes, err := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||||
| if err != nil || len(taskRes.TaskStatuses) == 0 { | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| task.Status = taskRes.TaskStatuses[0].State | |||||
| log.Info("task startTime = %v endTime= %v ,jobId=%d", jobRes.JobStatus.StartTime, jobRes.JobStatus.EndTime, task.ID) | |||||
| if jobRes.JobStatus.CreatedTime > 0 { | |||||
| task.StartTime = timeutil.TimeStamp(jobRes.JobStatus.CreatedTime / 1000) | |||||
| if jobRes.JobStatus.CompletedTime > 0 { | |||||
| task.EndTime = timeutil.TimeStamp(jobRes.JobStatus.CompletedTime / 1000) | |||||
| } else { | } else { | ||||
| task.TrainJobDuration = "00:00:00" | |||||
| task.EndTime = task.UpdatedUnix | |||||
| } | |||||
| } else { | |||||
| task.StartTime = 0 | |||||
| task.EndTime = 0 | |||||
| } | |||||
| if task.EndTime < task.StartTime { | |||||
| log.Info("endTime[%v] is less than starTime[%v],jobId=%d", task.EndTime, task.StartTime, task.ID) | |||||
| st := task.StartTime | |||||
| task.StartTime = task.EndTime | |||||
| task.EndTime = st | |||||
| } | |||||
| task.Duration = task.EndTime.AsTime().Unix() - task.StartTime.AsTime().Unix() | |||||
| task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | |||||
| } | |||||
| } | |||||
| } else if task.Type == models.TypeCloudBrainTwo { | |||||
| if task.JobType == string(models.JobTypeDebug) { | |||||
| //result, err := modelarts.GetJob(task.JobID) | |||||
| result, err := modelarts.GetNotebook2(task.JobID) | |||||
| if err != nil { | |||||
| log.Error("GetJob(%s) failed:%v", task.JobName, err) | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| if result != nil { | |||||
| task.Status = result.Status | |||||
| startTime := result.Lease.CreateTime | |||||
| duration := result.Lease.Duration / 1000 | |||||
| if startTime > 0 { | |||||
| task.StartTime = timeutil.TimeStamp(startTime / 1000) | |||||
| task.EndTime = task.StartTime.Add(duration) | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | |||||
| continue | |||||
| } | } | ||||
| } | |||||
| } else if task.JobType == string(models.JobTypeTrain) || task.JobType == string(models.JobTypeInference) { | |||||
| result, err := modelarts.GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | |||||
| if err != nil { | |||||
| log.Error("GetTrainJob(%s) failed:%v", task.JobName, err) | |||||
| updateDefaultDuration(task) | |||||
| continue | |||||
| } | |||||
| if result != nil { | |||||
| startTime := result.StartTime / 1000 | |||||
| if startTime > 0 { | |||||
| task.StartTime = timeutil.TimeStamp(startTime) | |||||
| task.EndTime = task.StartTime.Add(result.Duration / 1000) | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -1031,8 +1279,17 @@ func SyncCloudbrainStatus() { | |||||
| log.Error("task.Type(%s) is error:%d", task.JobName, task.Type) | log.Error("task.Type(%s) is error:%d", task.JobName, task.Type) | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| return | |||||
| func updateDefaultDuration(task *models.Cloudbrain) { | |||||
| log.Info("updateDefaultDuration: taskId=%d", task.ID) | |||||
| task.StartTime = task.CreatedUnix | |||||
| task.EndTime = task.UpdatedUnix | |||||
| task.ComputeAndSetDuration() | |||||
| err := models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | |||||
| } | |||||
| } | } | ||||
| func CloudBrainBenchmarkIndex(ctx *context.Context) { | func CloudBrainBenchmarkIndex(ctx *context.Context) { | ||||
| @@ -1059,26 +1316,25 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| if benchmarkTypes == nil { | |||||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||||
| ctx.ServerError("Get BenchmarkTypes faild:", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| for i, task := range ciTasks { | for i, task := range ciTasks { | ||||
| ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | ||||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ||||
| var duration int64 | |||||
| if task.Status == string(models.JobRunning) { | |||||
| duration = time.Now().Unix() - int64(task.Cloudbrain.CreatedUnix) | |||||
| } else { | |||||
| duration = int64(task.Cloudbrain.UpdatedUnix) - int64(task.Cloudbrain.CreatedUnix) | |||||
| if ciTasks[i].TrainJobDuration == "" { | |||||
| if ciTasks[i].Duration == 0 { | |||||
| var duration int64 | |||||
| if task.Status == string(models.JobRunning) { | |||||
| duration = time.Now().Unix() - int64(task.Cloudbrain.CreatedUnix) | |||||
| } else { | |||||
| duration = int64(task.Cloudbrain.UpdatedUnix) - int64(task.Cloudbrain.CreatedUnix) | |||||
| } | |||||
| ciTasks[i].Duration = duration | |||||
| } | |||||
| ciTasks[i].TrainJobDuration = models.ConvertDurationToStr(ciTasks[i].Duration) | |||||
| } | } | ||||
| ciTasks[i].TrainJobDuration = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | |||||
| ciTasks[i].BenchmarkTypeName = "" | ciTasks[i].BenchmarkTypeName = "" | ||||
| if task.BenchmarkTypeID > 0 { | if task.BenchmarkTypeID > 0 { | ||||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||||
| if task.BenchmarkTypeID == benchmarkType.Id { | if task.BenchmarkTypeID == benchmarkType.Id { | ||||
| ciTasks[i].BenchmarkTypeRankLink = benchmarkType.RankLink | ciTasks[i].BenchmarkTypeRankLink = benchmarkType.RankLink | ||||
| ciTasks[i].BenchmarkTypeName = benchmarkType.First | ciTasks[i].BenchmarkTypeName = benchmarkType.First | ||||
| @@ -1102,15 +1358,8 @@ func GetChildTypes(ctx *context.Context) { | |||||
| benchmarkTypeID := ctx.QueryInt("benchmark_type_id") | benchmarkTypeID := ctx.QueryInt("benchmark_type_id") | ||||
| re := make(map[string]interface{}) | re := make(map[string]interface{}) | ||||
| for { | for { | ||||
| if benchmarkTypes == nil { | |||||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", setting.BenchmarkTypes, err, ctx.Data["MsgID"]) | |||||
| re["errMsg"] = "system error" | |||||
| break | |||||
| } | |||||
| } | |||||
| var isExist bool | var isExist bool | ||||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||||
| if benchmarkTypeID == benchmarkType.Id { | if benchmarkTypeID == benchmarkType.Id { | ||||
| isExist = true | isExist = true | ||||
| re["child_types"] = benchmarkType.Second | re["child_types"] = benchmarkType.Second | ||||
| @@ -1141,17 +1390,11 @@ func CloudBrainBenchmarkNew(ctx *context.Context) { | |||||
| ctx.HTML(200, tplCloudBrainBenchmarkNew) | ctx.HTML(200, tplCloudBrainBenchmarkNew) | ||||
| } | } | ||||
| func getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID int) (*models.BenchmarkDataset, error) { | |||||
| func getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID int, ctx *context.Context) (*models.BenchmarkDataset, error) { | |||||
| var childInfo *models.BenchmarkDataset | var childInfo *models.BenchmarkDataset | ||||
| if benchmarkTypes == nil { | |||||
| if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil { | |||||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", setting.BenchmarkTypes, err) | |||||
| return childInfo, err | |||||
| } | |||||
| } | |||||
| var isExist bool | var isExist bool | ||||
| for _, benchmarkType := range benchmarkTypes.BenchmarkType { | |||||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||||
| if benchmarkType.Id == benchmarkTypeID { | if benchmarkType.Id == benchmarkTypeID { | ||||
| for _, childType := range benchmarkType.Second { | for _, childType := range benchmarkType.Second { | ||||
| if childType.Id == benchmarkChildTypeID { | if childType.Id == benchmarkChildTypeID { | ||||
| @@ -1265,7 +1508,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| return | return | ||||
| } | } | ||||
| childInfo, err := getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID) | |||||
| childInfo, err := getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID, ctx) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("getBenchmarkAttachment failed:%v", err, ctx.Data["MsgID"]) | log.Error("getBenchmarkAttachment failed:%v", err, ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| @@ -1305,7 +1548,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| } | } | ||||
| os.RemoveAll(codePath) | os.RemoveAll(codePath) | ||||
| if err := downloadCode(repo, codePath); err != nil { | |||||
| if err := downloadCode(repo, codePath, cloudbrain.DefaultBranchName); err != nil { | |||||
| log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | ||||
| @@ -1370,7 +1613,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, | |||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, cloudbrain.DefaultBranchName, "", "", | |||||
| benchmarkTypeID, benchmarkChildTypeID, resourceSpecId) | benchmarkTypeID, benchmarkChildTypeID, resourceSpecId) | ||||
| if err != nil { | if err != nil { | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| @@ -1395,3 +1638,73 @@ func BenchmarkDel(ctx *context.Context) { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | ||||
| } | } | ||||
| } | } | ||||
| func CloudBrainTrainJobNew(ctx *context.Context) { | |||||
| err := cloudBrainNewDataPrepare(ctx) | |||||
| if err != nil { | |||||
| ctx.ServerError("get new train-job info failed", err) | |||||
| return | |||||
| } | |||||
| ctx.HTML(http.StatusOK, tplCloudBrainTrainJobNew) | |||||
| } | |||||
| func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) { | |||||
| var command string | |||||
| bootFile := form.BootFile | |||||
| params := form.Params | |||||
| if !strings.HasSuffix(bootFile, ".py") { | |||||
| log.Error("bootFile(%s) format error", bootFile) | |||||
| return command, errors.New("bootFile format error") | |||||
| } | |||||
| var parameters models.Parameters | |||||
| var param string | |||||
| if len(params) != 0 { | |||||
| err := json.Unmarshal([]byte(params), ¶meters) | |||||
| if err != nil { | |||||
| log.Error("Failed to Unmarshal params: %s (%v)", params, err) | |||||
| return command, err | |||||
| } | |||||
| for _, parameter := range parameters.Parameter { | |||||
| param += " --" + parameter.Label + "=" + parameter.Value | |||||
| } | |||||
| } | |||||
| command += "python /code/" + bootFile + param + " > " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||||
| return command, nil | |||||
| } | |||||
| func CloudBrainTrainJobDel(ctx *context.Context) { | |||||
| var listType = ctx.Query("listType") | |||||
| if err := deleteCloudbrainJob(ctx); err != nil { | |||||
| log.Error("deleteCloudbrainJob failed: %v", err, ctx.Data["msgID"]) | |||||
| ctx.ServerError(err.Error(), err) | |||||
| return | |||||
| } | |||||
| 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?listType=" + listType) | |||||
| } | |||||
| } | |||||
| func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes { | |||||
| var lang = ctx.Locale.Language() | |||||
| if benchmarkTypesMap[lang] == nil { | |||||
| var val = i18n.Tr(lang, BENCHMARK_TYPE_CODE) | |||||
| //use config | |||||
| val = setting.BenchmarkTypes | |||||
| var tempType *models.BenchmarkTypes | |||||
| if err := json.Unmarshal([]byte(val), &tempType); err != nil { | |||||
| log.Error("json.Unmarshal BenchmarkTypes(%s) failed:%v", val, err, ctx.Data["MsgID"]) | |||||
| return &models.BenchmarkTypes{} | |||||
| } | |||||
| benchmarkTypesMap[lang] = tempType | |||||
| } | |||||
| return benchmarkTypesMap[lang] | |||||
| } | |||||
| @@ -1,7 +1,14 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "encoding/json" | |||||
| "fmt" | |||||
| "net/http" | |||||
| "regexp" | |||||
| "sort" | "sort" | ||||
| "strconv" | |||||
| "strings" | |||||
| "unicode/utf8" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| @@ -12,9 +19,14 @@ import ( | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| tplIndex base.TplName = "repo/datasets/index" | |||||
| tplIndex base.TplName = "repo/datasets/index" | |||||
| tplDatasetCreate base.TplName = "repo/datasets/create" | |||||
| tplDatasetEdit base.TplName = "repo/datasets/edit" | |||||
| taskstplIndex base.TplName = "repo/datasets/tasks/index" | |||||
| ) | ) | ||||
| var titlePattern = regexp.MustCompile(`^[A-Za-z0-9-_\\.]{1,100}$`) | |||||
| // MustEnableDataset check if repository enable internal dataset | // MustEnableDataset check if repository enable internal dataset | ||||
| func MustEnableDataset(ctx *context.Context) { | func MustEnableDataset(ctx *context.Context) { | ||||
| if !ctx.Repo.CanRead(models.UnitTypeDatasets) { | if !ctx.Repo.CanRead(models.UnitTypeDatasets) { | ||||
| @@ -84,43 +96,34 @@ func QueryDataSet(ctx *context.Context) []*models.Attachment { | |||||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | ||||
| ctx.Data["SortType"] = ctx.Query("sort") | ctx.Data["SortType"] = ctx.Query("sort") | ||||
| switch ctx.Query("sort") { | |||||
| case "newest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| case "oldest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix < attachments[j].CreatedUnix | |||||
| }) | |||||
| default: | |||||
| ctx.Data["SortType"] = "newest" | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| } | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| return attachments | return attachments | ||||
| } | } | ||||
| func DatasetIndex(ctx *context.Context) { | func DatasetIndex(ctx *context.Context) { | ||||
| log.Info("dataset index 1") | log.Info("dataset index 1") | ||||
| MustEnableDataset(ctx) | MustEnableDataset(ctx) | ||||
| ctx.Data["PageIsDataset"] = true | |||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| dataset, err := models.GetDatasetByRepo(repo) | dataset, err := models.GetDatasetByRepo(repo) | ||||
| ctx.Data["CanWrite"] = ctx.Repo.CanWrite(models.UnitTypeDatasets) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("query dataset, not found repo.") | |||||
| ctx.NotFound("GetDatasetByRepo", err) | |||||
| log.Warn("query dataset, not found.") | |||||
| ctx.HTML(200, tplIndex) | |||||
| return | return | ||||
| } | } | ||||
| cloudbrainType := -1 | |||||
| if ctx.Query("type") != "" { | |||||
| if ctx.Query("type") == "" { | |||||
| log.Error("query dataset, not found param type") | |||||
| ctx.NotFound("type error", nil) | |||||
| return | |||||
| cloudbrainType = ctx.QueryInt("type") | |||||
| } | } | ||||
| err = models.GetDatasetAttachments(ctx.QueryInt("type"), ctx.IsSigned, ctx.User, dataset) | |||||
| err = models.GetDatasetAttachments(cloudbrainType, ctx.IsSigned, ctx.User, dataset) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetDatasetAttachments", err) | ctx.ServerError("GetDatasetAttachments", err) | ||||
| return | return | ||||
| @@ -128,53 +131,138 @@ func DatasetIndex(ctx *context.Context) { | |||||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | ||||
| ctx.Data["SortType"] = ctx.Query("sort") | |||||
| switch ctx.Query("sort") { | |||||
| case "newest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| case "oldest": | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix < attachments[j].CreatedUnix | |||||
| }) | |||||
| default: | |||||
| ctx.Data["SortType"] = "newest" | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| sort.Slice(attachments, func(i, j int) bool { | |||||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||||
| }) | |||||
| page := ctx.QueryInt("page") | |||||
| if page <= 0 { | |||||
| page = 1 | |||||
| } | } | ||||
| pagesize := ctx.QueryInt("pagesize") | |||||
| if pagesize <= 0 { | |||||
| pagesize = 10 | |||||
| } | |||||
| pager := context.NewPagination(len(attachments), pagesize, page, 5) | |||||
| pageAttachments := getPageAttachments(attachments, page, pagesize) | |||||
| //load attachment creator | |||||
| for _, attachment := range pageAttachments { | |||||
| uploader, _ := models.GetUserByID(attachment.UploaderID) | |||||
| attachment.Uploader = uploader | |||||
| } | |||||
| ctx.Data["Page"] = pager | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| ctx.Data["Title"] = ctx.Tr("dataset.show_dataset") | ctx.Data["Title"] = ctx.Tr("dataset.show_dataset") | ||||
| ctx.Data["Link"] = ctx.Repo.RepoLink + "/datasets" | ctx.Data["Link"] = ctx.Repo.RepoLink + "/datasets" | ||||
| ctx.Data["dataset"] = dataset | ctx.Data["dataset"] = dataset | ||||
| ctx.Data["Attachments"] = attachments | |||||
| ctx.Data["Attachments"] = pageAttachments | |||||
| ctx.Data["IsOwner"] = true | ctx.Data["IsOwner"] = true | ||||
| ctx.Data["StoreType"] = setting.Attachment.StoreType | ctx.Data["StoreType"] = setting.Attachment.StoreType | ||||
| ctx.Data["Type"] = ctx.QueryInt("type") | |||||
| ctx.Data["Type"] = cloudbrainType | |||||
| renderAttachmentSettings(ctx) | renderAttachmentSettings(ctx) | ||||
| ctx.HTML(200, tplIndex) | ctx.HTML(200, tplIndex) | ||||
| } | } | ||||
| func getPageAttachments(attachments []*models.Attachment, page int, pagesize int) []*models.Attachment { | |||||
| begin := (page - 1) * pagesize | |||||
| end := (page) * pagesize | |||||
| if begin > len(attachments)-1 { | |||||
| return nil | |||||
| } | |||||
| if end > len(attachments)-1 { | |||||
| return attachments[begin:] | |||||
| } else { | |||||
| return attachments[begin:end] | |||||
| } | |||||
| } | |||||
| func CreateDataset(ctx *context.Context) { | |||||
| MustEnableDataset(ctx) | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| ctx.HTML(200, tplDatasetCreate) | |||||
| } | |||||
| func EditDataset(ctx *context.Context) { | |||||
| MustEnableDataset(ctx) | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64) | |||||
| dataset, _ := models.GetDatasetByID(datasetId) | |||||
| if dataset == nil { | |||||
| ctx.Error(http.StatusNotFound, "") | |||||
| return | |||||
| } | |||||
| ctx.Data["Dataset"] = dataset | |||||
| ctx.HTML(200, tplDatasetEdit) | |||||
| } | |||||
| func CreateDatasetPost(ctx *context.Context, form auth.CreateDatasetForm) { | |||||
| dataset := &models.Dataset{} | |||||
| if !titlePattern.MatchString(form.Title) { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.title_format_err"))) | |||||
| return | |||||
| } | |||||
| if utf8.RuneCountInString(form.Description) > 1024 { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.description_format_err"))) | |||||
| return | |||||
| } | |||||
| dataset.RepoID = ctx.Repo.Repository.ID | |||||
| dataset.UserID = ctx.User.ID | |||||
| dataset.Category = form.Category | |||||
| dataset.Task = form.Task | |||||
| dataset.Title = form.Title | |||||
| dataset.License = form.License | |||||
| dataset.Description = form.Description | |||||
| dataset.DownloadTimes = 0 | |||||
| if ctx.Repo.Repository.IsPrivate { | |||||
| dataset.Status = 0 | |||||
| } else { | |||||
| dataset.Status = 1 | |||||
| } | |||||
| err := models.CreateDataset(dataset) | |||||
| if err != nil { | |||||
| log.Error("fail to create dataset", err) | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.create_dataset_fail"))) | |||||
| } else { | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | |||||
| } | |||||
| func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | ||||
| ctx.Data["PageIsDataset"] = true | ctx.Data["PageIsDataset"] = true | ||||
| ctx.Data["Title"] = ctx.Tr("dataset.edit_dataset") | ctx.Data["Title"] = ctx.Tr("dataset.edit_dataset") | ||||
| if !titlePattern.MatchString(form.Title) { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.title_format_err"))) | |||||
| return | |||||
| } | |||||
| if utf8.RuneCountInString(form.Description) > 1024 { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.description_format_err"))) | |||||
| return | |||||
| } | |||||
| rel, err := models.GetDatasetByID(form.ID) | rel, err := models.GetDatasetByID(form.ID) | ||||
| ctx.Data["dataset"] = rel | ctx.Data["dataset"] = rel | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetDataset", err) | |||||
| return | |||||
| } | |||||
| if ctx.HasError() { | |||||
| ctx.Data["Error"] = true | |||||
| ctx.HTML(200, tplIndex) | |||||
| log.Error("failed to query dataset", err) | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.query_dataset_fail"))) | |||||
| return | return | ||||
| } | } | ||||
| @@ -184,9 +272,236 @@ func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | |||||
| rel.Task = form.Task | rel.Task = form.Task | ||||
| rel.License = form.License | rel.License = form.License | ||||
| if err = models.UpdateDataset(models.DefaultDBContext(), rel); err != nil { | if err = models.UpdateDataset(models.DefaultDBContext(), rel); err != nil { | ||||
| ctx.Data["Error"] = true | |||||
| ctx.HTML(200, tplIndex) | |||||
| log.Error("%v", err) | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.query_dataset_fail"))) | |||||
| } | } | ||||
| ctx.Redirect(ctx.Repo.RepoLink + "/datasets?type=" + form.Type) | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | |||||
| func DatasetAction(ctx *context.Context) { | |||||
| var err error | |||||
| datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64) | |||||
| switch ctx.Params(":action") { | |||||
| case "star": | |||||
| err = models.StarDataset(ctx.User.ID, datasetId, true) | |||||
| case "unstar": | |||||
| err = models.StarDataset(ctx.User.ID, datasetId, false) | |||||
| } | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("repo.star_fail", ctx.Params(":action")))) | |||||
| } else { | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | |||||
| } | |||||
| func CurrentRepoDataset(ctx *context.Context) { | |||||
| page := ctx.QueryInt("page") | |||||
| cloudbrainType := ctx.QueryInt("type") | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||||
| repo := ctx.Repo.Repository | |||||
| var datasetIDs []int64 | |||||
| dataset, err := models.GetDatasetByRepo(repo) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("GetDatasetByRepo failed", err))) | |||||
| return | |||||
| } | |||||
| datasetIDs = append(datasetIDs, dataset.ID) | |||||
| datasets, count, err := models.Attachments(&models.AttachmentsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.DatasetPagingNum, | |||||
| }, | |||||
| Keyword: keyword, | |||||
| NeedDatasetIDs: true, | |||||
| DatasetIDs: datasetIDs, | |||||
| Type: cloudbrainType, | |||||
| NeedIsPrivate: false, | |||||
| JustNeedZipFile: true, | |||||
| NeedRepoInfo: true, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("datasets", err) | |||||
| return | |||||
| } | |||||
| data, err := json.Marshal(datasets) | |||||
| if err != nil { | |||||
| log.Error("json.Marshal failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "0", | |||||
| "data": string(data), | |||||
| "count": strconv.FormatInt(count, 10), | |||||
| }) | |||||
| } | |||||
| func MyDatasets(ctx *context.Context) { | |||||
| page := ctx.QueryInt("page") | |||||
| cloudbrainType := ctx.QueryInt("type") | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||||
| uploaderID := ctx.User.ID | |||||
| datasets, count, err := models.Attachments(&models.AttachmentsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.DatasetPagingNum, | |||||
| }, | |||||
| Keyword: keyword, | |||||
| NeedDatasetIDs: false, | |||||
| UploaderID: uploaderID, | |||||
| Type: cloudbrainType, | |||||
| NeedIsPrivate: false, | |||||
| JustNeedZipFile: true, | |||||
| NeedRepoInfo: true, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("datasets", err) | |||||
| return | |||||
| } | |||||
| data, err := json.Marshal(datasets) | |||||
| if err != nil { | |||||
| log.Error("json.Marshal failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "0", | |||||
| "data": string(data), | |||||
| "count": strconv.FormatInt(count, 10), | |||||
| }) | |||||
| } | |||||
| func PublicDataset(ctx *context.Context) { | |||||
| page := ctx.QueryInt("page") | |||||
| cloudbrainType := ctx.QueryInt("type") | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||||
| datasets, count, err := models.Attachments(&models.AttachmentsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.DatasetPagingNum, | |||||
| }, | |||||
| Keyword: keyword, | |||||
| NeedDatasetIDs: false, | |||||
| NeedIsPrivate: true, | |||||
| IsPrivate: false, | |||||
| Type: cloudbrainType, | |||||
| JustNeedZipFile: true, | |||||
| NeedRepoInfo: true, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("datasets", err) | |||||
| return | |||||
| } | |||||
| data, err := json.Marshal(datasets) | |||||
| if err != nil { | |||||
| log.Error("json.Marshal failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "0", | |||||
| "data": string(data), | |||||
| "count": strconv.FormatInt(count, 10), | |||||
| }) | |||||
| } | |||||
| func MyFavoriteDataset(ctx *context.Context) { | |||||
| page := ctx.QueryInt("page") | |||||
| cloudbrainType := ctx.QueryInt("type") | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||||
| var datasetIDs []int64 | |||||
| datasetStars, err := models.GetDatasetStarByUser(ctx.User) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("GetDatasetStarByUser failed", err))) | |||||
| log.Error("GetDatasetStarByUser failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| for i, _ := range datasetStars { | |||||
| datasetIDs = append(datasetIDs, datasetStars[i].DatasetID) | |||||
| } | |||||
| datasets, count, err := models.Attachments(&models.AttachmentsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.DatasetPagingNum, | |||||
| }, | |||||
| Keyword: keyword, | |||||
| NeedDatasetIDs: true, | |||||
| DatasetIDs: datasetIDs, | |||||
| NeedIsPrivate: true, | |||||
| IsPrivate: false, | |||||
| Type: cloudbrainType, | |||||
| JustNeedZipFile: true, | |||||
| NeedRepoInfo: true, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("datasets", err) | |||||
| return | |||||
| } | |||||
| data, err := json.Marshal(datasets) | |||||
| if err != nil { | |||||
| log.Error("json.Marshal failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "0", | |||||
| "data": string(data), | |||||
| "count": strconv.FormatInt(count, 10), | |||||
| }) | |||||
| } | |||||
| func GetDatasetStatus(ctx *context.Context) { | |||||
| var ( | |||||
| err error | |||||
| ) | |||||
| UUID := ctx.Params(":uuid") | |||||
| attachment, err := models.GetAttachmentByUUID(UUID) | |||||
| if err != nil { | |||||
| log.Error("GetDatasetStarByUser failed:", err.Error()) | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "-1", | |||||
| "error_msg": err.Error(), | |||||
| "data": "", | |||||
| }) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]string{ | |||||
| "result_code": "0", | |||||
| "UUID": UUID, | |||||
| "AttachmentStatus": fmt.Sprint(attachment.DecompressState), | |||||
| }) | |||||
| } | } | ||||
| @@ -2,6 +2,8 @@ package repo | |||||
| import ( | import ( | ||||
| "archive/zip" | "archive/zip" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "io" | "io" | ||||
| @@ -46,20 +48,26 @@ const ( | |||||
| ) | ) | ||||
| func DebugJobIndex(ctx *context.Context) { | func DebugJobIndex(ctx *context.Context) { | ||||
| debugListType := ctx.Query("debugListType") | |||||
| ctx.Data["ListType"] = debugListType | |||||
| listType := ctx.Query("debugListType") | |||||
| ctx.Data["ListType"] = listType | |||||
| MustEnableCloudbrain(ctx) | MustEnableCloudbrain(ctx) | ||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
| if page <= 0 { | if page <= 0 { | ||||
| page = 1 | page = 1 | ||||
| } | } | ||||
| debugType := modelarts.DebugType | |||||
| typeCloudBrain := models.TypeCloudBrainAll | |||||
| jobTypeNot := false | jobTypeNot := false | ||||
| if debugListType == models.GPUResource { | |||||
| debugType = models.TypeCloudBrainOne | |||||
| } else if debugListType == models.NPUResource { | |||||
| debugType = models.TypeCloudBrainTwo | |||||
| if listType == models.GPUResource { | |||||
| typeCloudBrain = models.TypeCloudBrainOne | |||||
| } else if listType == models.NPUResource { | |||||
| typeCloudBrain = models.TypeCloudBrainTwo | |||||
| } else if listType == models.AllResource { | |||||
| typeCloudBrain = models.TypeCloudBrainAll | |||||
| } else { | |||||
| log.Error("listType(%s) error", listType) | |||||
| ctx.ServerError("listType error", errors.New("listType error")) | |||||
| return | |||||
| } | } | ||||
| var jobTypes []string | var jobTypes []string | ||||
| @@ -70,7 +78,7 @@ func DebugJobIndex(ctx *context.Context) { | |||||
| PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
| }, | }, | ||||
| RepoID: repo.ID, | RepoID: repo.ID, | ||||
| Type: debugType, | |||||
| Type: typeCloudBrain, | |||||
| JobTypeNot: jobTypeNot, | JobTypeNot: jobTypeNot, | ||||
| JobTypes: jobTypes, | JobTypes: jobTypes, | ||||
| }) | }) | ||||
| @@ -92,7 +100,7 @@ func DebugJobIndex(ctx *context.Context) { | |||||
| ctx.Data["Tasks"] = ciTasks | ctx.Data["Tasks"] = ciTasks | ||||
| ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx) | ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx) | ||||
| ctx.Data["RepoIsEmpty"] = repo.IsEmpty | ctx.Data["RepoIsEmpty"] = repo.IsEmpty | ||||
| ctx.Data["debugListType"] = debugListType | |||||
| ctx.Data["debugListType"] = listType | |||||
| ctx.HTML(200, tplDebugJobIndex) | ctx.HTML(200, tplDebugJobIndex) | ||||
| } | } | ||||
| @@ -133,6 +141,8 @@ func notebookNewDataPrepare(ctx *context.Context) error { | |||||
| } | } | ||||
| ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo | ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo | ||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -407,16 +417,46 @@ func NotebookManage(ctx *context.Context) { | |||||
| break | break | ||||
| } | } | ||||
| task.Status = res.Status | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
| resultCode = "-1" | |||||
| errorMsg = "system error" | |||||
| break | |||||
| } | |||||
| status = res.Status | |||||
| if action == models.ActionStart { | |||||
| newTask := &models.Cloudbrain{ | |||||
| Status: status, | |||||
| UserID: task.UserID, | |||||
| RepoID: task.RepoID, | |||||
| JobID: task.JobID, | |||||
| JobName: task.JobName, | |||||
| DisplayJobName: task.DisplayJobName, | |||||
| JobType: task.JobType, | |||||
| Type: task.Type, | |||||
| Uuid: task.Uuid, | |||||
| Image: task.Image, | |||||
| ComputeResource: task.ComputeResource, | |||||
| Description: task.Description, | |||||
| } | |||||
| status = task.Status | |||||
| err = models.RestartCloudbrain(task, newTask) | |||||
| if err != nil { | |||||
| log.Error("RestartCloudbrain(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
| resultCode = "-1" | |||||
| errorMsg = "system error" | |||||
| break | |||||
| } | |||||
| ID = strconv.FormatInt(newTask.ID, 10) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, ID, task.DisplayJobName, models.ActionCreateDebugNPUTask) | |||||
| } else { | |||||
| task.Status = res.Status | |||||
| if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | |||||
| task.EndTime = timeutil.TimeStampNow() | |||||
| } | |||||
| task.ComputeAndSetDuration() | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
| resultCode = "-1" | |||||
| errorMsg = "system error" | |||||
| break | |||||
| } | |||||
| } | |||||
| break | break | ||||
| } | } | ||||
| @@ -473,6 +513,26 @@ func TrainJobIndex(ctx *context.Context) { | |||||
| page = 1 | page = 1 | ||||
| } | } | ||||
| listType := ctx.Query("listType") | |||||
| if len(listType) == 0 { | |||||
| listType = models.AllResource | |||||
| } | |||||
| ctx.Data["ListType"] = listType | |||||
| typeCloudBrain := models.TypeCloudBrainAll | |||||
| if listType == models.GPUResource { | |||||
| typeCloudBrain = models.TypeCloudBrainOne | |||||
| } else if listType == models.NPUResource { | |||||
| typeCloudBrain = models.TypeCloudBrainTwo | |||||
| } else if listType == models.AllResource { | |||||
| typeCloudBrain = models.TypeCloudBrainAll | |||||
| } | |||||
| //else { | |||||
| // log.Error("listType(%s) error", listType) | |||||
| // ctx.ServerError("listType error", errors.New("listType error")) | |||||
| // return | |||||
| //} | |||||
| var jobTypes []string | var jobTypes []string | ||||
| jobTypes = append(jobTypes, string(models.JobTypeTrain)) | jobTypes = append(jobTypes, string(models.JobTypeTrain)) | ||||
| tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | ||||
| @@ -481,7 +541,7 @@ func TrainJobIndex(ctx *context.Context) { | |||||
| PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
| }, | }, | ||||
| RepoID: repo.ID, | RepoID: repo.ID, | ||||
| Type: models.TypeCloudBrainTwo, | |||||
| Type: typeCloudBrain, | |||||
| JobTypeNot: false, | JobTypeNot: false, | ||||
| JobTypes: jobTypes, | JobTypes: jobTypes, | ||||
| IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
| @@ -494,11 +554,16 @@ func TrainJobIndex(ctx *context.Context) { | |||||
| for i, task := range tasks { | for i, task := range tasks { | ||||
| tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | ||||
| tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | ||||
| tasks[i].ComputeResource = models.NPUResource | |||||
| if task.Cloudbrain.Type == models.TypeCloudBrainOne { | |||||
| tasks[i].ComputeResource = models.GPUResource | |||||
| } else if task.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||||
| tasks[i].ComputeResource = models.NPUResource | |||||
| } | |||||
| } | } | ||||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | ||||
| pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
| pager.AddParam(ctx, "listType", "ListType") | |||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| @@ -580,6 +645,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
| return err | return err | ||||
| } | } | ||||
| ctx.Data["config_list"] = configList.ParaConfigs | ctx.Data["config_list"] = configList.ParaConfigs | ||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -746,6 +812,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["uuid"] = task.Uuid | ctx.Data["uuid"] = task.Uuid | ||||
| ctx.Data["flavor_code"] = task.FlavorCode | ctx.Data["flavor_code"] = task.FlavorCode | ||||
| ctx.Data["engine_id"] = task.EngineID | ctx.Data["engine_id"] = task.EngineID | ||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -953,17 +1020,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| return | return | ||||
| } | } | ||||
| //todo: del local code? | |||||
| var parameters models.Parameters | var parameters models.Parameters | ||||
| param := make([]models.Parameter, 0) | param := make([]models.Parameter, 0) | ||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.TrainUrl, | |||||
| Value: outputObsPath, | |||||
| }, models.Parameter{ | |||||
| Label: modelarts.DataUrl, | |||||
| Value: dataPath, | |||||
| }) | |||||
| existDeviceTarget := false | |||||
| if len(params) != 0 { | if len(params) != 0 { | ||||
| err := json.Unmarshal([]byte(params), ¶meters) | err := json.Unmarshal([]byte(params), ¶meters) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -974,6 +1033,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| } | } | ||||
| for _, parameter := range parameters.Parameter { | for _, parameter := range parameters.Parameter { | ||||
| if parameter.Label == modelarts.DeviceTarget { | |||||
| existDeviceTarget = true | |||||
| } | |||||
| if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | ||||
| param = append(param, models.Parameter{ | param = append(param, models.Parameter{ | ||||
| Label: parameter.Label, | Label: parameter.Label, | ||||
| @@ -982,9 +1044,22 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if !existDeviceTarget { | |||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.DeviceTarget, | |||||
| Value: modelarts.Ascend, | |||||
| }) | |||||
| } | |||||
| //save param config | //save param config | ||||
| if isSaveParam == "on" { | if isSaveParam == "on" { | ||||
| saveparams := append(param, models.Parameter{ | |||||
| Label: modelarts.TrainUrl, | |||||
| Value: outputObsPath, | |||||
| }, models.Parameter{ | |||||
| Label: modelarts.DataUrl, | |||||
| Value: dataPath, | |||||
| }) | |||||
| if form.ParameterTemplateName == "" { | if form.ParameterTemplateName == "" { | ||||
| log.Error("ParameterTemplateName is empty") | log.Error("ParameterTemplateName is empty") | ||||
| trainJobNewDataPrepare(ctx) | trainJobNewDataPrepare(ctx) | ||||
| @@ -1006,7 +1081,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| EngineID: int64(engineID), | EngineID: int64(engineID), | ||||
| LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
| PoolID: poolID, | PoolID: poolID, | ||||
| Parameter: param, | |||||
| Parameter: saveparams, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1032,7 +1107,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
| PoolID: poolID, | PoolID: poolID, | ||||
| Uuid: uuid, | Uuid: uuid, | ||||
| Parameters: parameters.Parameter, | |||||
| Parameters: param, | |||||
| CommitID: commitID, | CommitID: commitID, | ||||
| IsLatestVersion: isLatestVersion, | IsLatestVersion: isLatestVersion, | ||||
| BranchName: branch_name, | BranchName: branch_name, | ||||
| @@ -1168,13 +1243,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| var parameters models.Parameters | var parameters models.Parameters | ||||
| param := make([]models.Parameter, 0) | param := make([]models.Parameter, 0) | ||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.TrainUrl, | |||||
| Value: outputObsPath, | |||||
| }, models.Parameter{ | |||||
| Label: modelarts.DataUrl, | |||||
| Value: dataPath, | |||||
| }) | |||||
| existDeviceTarget := true | |||||
| if len(params) != 0 { | if len(params) != 0 { | ||||
| err := json.Unmarshal([]byte(params), ¶meters) | err := json.Unmarshal([]byte(params), ¶meters) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1183,8 +1252,10 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobVersionNew, &form) | ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobVersionNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| for _, parameter := range parameters.Parameter { | for _, parameter := range parameters.Parameter { | ||||
| if parameter.Label == modelarts.DeviceTarget { | |||||
| existDeviceTarget = true | |||||
| } | |||||
| if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | ||||
| param = append(param, models.Parameter{ | param = append(param, models.Parameter{ | ||||
| Label: parameter.Label, | Label: parameter.Label, | ||||
| @@ -1193,9 +1264,22 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if !existDeviceTarget { | |||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.DeviceTarget, | |||||
| Value: modelarts.Ascend, | |||||
| }) | |||||
| } | |||||
| //save param config | //save param config | ||||
| if isSaveParam == "on" { | if isSaveParam == "on" { | ||||
| saveparams := append(param, models.Parameter{ | |||||
| Label: modelarts.TrainUrl, | |||||
| Value: outputObsPath, | |||||
| }, models.Parameter{ | |||||
| Label: modelarts.DataUrl, | |||||
| Value: dataPath, | |||||
| }) | |||||
| if form.ParameterTemplateName == "" { | if form.ParameterTemplateName == "" { | ||||
| log.Error("ParameterTemplateName is empty") | log.Error("ParameterTemplateName is empty") | ||||
| versionErrorDataPrepare(ctx, form) | versionErrorDataPrepare(ctx, form) | ||||
| @@ -1217,7 +1301,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| EngineID: int64(engineID), | EngineID: int64(engineID), | ||||
| LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
| PoolID: poolID, | PoolID: poolID, | ||||
| Parameter: parameters.Parameter, | |||||
| Parameter: saveparams, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1228,12 +1312,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| } | } | ||||
| } | } | ||||
| if err != nil { | |||||
| log.Error("getFlavorNameByEngineID(%s) failed:%v", engineID, err.Error()) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form) | |||||
| return | |||||
| } | |||||
| task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, PreVersionName) | task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, PreVersionName) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error()) | log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error()) | ||||
| @@ -1257,7 +1335,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| PoolID: poolID, | PoolID: poolID, | ||||
| Uuid: uuid, | Uuid: uuid, | ||||
| Params: form.Params, | Params: form.Params, | ||||
| Parameters: parameters.Parameter, | |||||
| Parameters: param, | |||||
| PreVersionId: task.VersionID, | PreVersionId: task.VersionID, | ||||
| CommitID: commitID, | CommitID: commitID, | ||||
| BranchName: branch_name, | BranchName: branch_name, | ||||
| @@ -1535,6 +1613,7 @@ func trainJobGetLog(jobID string) (*models.GetTrainJobLogFileNamesResult, *model | |||||
| func TrainJobDel(ctx *context.Context) { | func TrainJobDel(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
| var listType = ctx.Query("listType") | |||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| var jobTypes []string | var jobTypes []string | ||||
| @@ -1576,12 +1655,13 @@ func TrainJobDel(ctx *context.Context) { | |||||
| if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | if ctx.IsUserSiteAdmin() && isAdminPage == "true" { | ||||
| ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") | ||||
| } else { | } else { | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) | |||||
| } | } | ||||
| } | } | ||||
| func TrainJobStop(ctx *context.Context) { | func TrainJobStop(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
| var listType = ctx.Query("listType") | |||||
| task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
| _, err := modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10)) | _, err := modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10)) | ||||
| @@ -1591,7 +1671,7 @@ func TrainJobStop(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) | |||||
| } | } | ||||
| func canUserCreateTrainJob(uid int64) (bool, error) { | func canUserCreateTrainJob(uid int64) (bool, error) { | ||||
| @@ -1782,7 +1862,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| return | return | ||||
| } | } | ||||
| //todo: del local code? | |||||
| var parameters models.Parameters | var parameters models.Parameters | ||||
| param := make([]models.Parameter, 0) | param := make([]models.Parameter, 0) | ||||
| param = append(param, models.Parameter{ | param = append(param, models.Parameter{ | ||||
| @@ -1792,6 +1871,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| Label: modelarts.CkptUrl, | Label: modelarts.CkptUrl, | ||||
| Value: "s3:/" + ckptUrl, | Value: "s3:/" + ckptUrl, | ||||
| }) | }) | ||||
| existDeviceTarget := false | |||||
| if len(params) != 0 { | if len(params) != 0 { | ||||
| err := json.Unmarshal([]byte(params), ¶meters) | err := json.Unmarshal([]byte(params), ¶meters) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1802,6 +1882,9 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| } | } | ||||
| for _, parameter := range parameters.Parameter { | for _, parameter := range parameters.Parameter { | ||||
| if parameter.Label == modelarts.DeviceTarget { | |||||
| existDeviceTarget = true | |||||
| } | |||||
| if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | ||||
| param = append(param, models.Parameter{ | param = append(param, models.Parameter{ | ||||
| Label: parameter.Label, | Label: parameter.Label, | ||||
| @@ -1810,6 +1893,12 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if !existDeviceTarget { | |||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.DeviceTarget, | |||||
| Value: modelarts.Ascend, | |||||
| }) | |||||
| } | |||||
| req := &modelarts.GenerateInferenceJobReq{ | req := &modelarts.GenerateInferenceJobReq{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| @@ -1977,6 +2066,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| }) | }) | ||||
| ctx.Data["MODEL_COUNT"] = model_count | ctx.Data["MODEL_COUNT"] = model_count | ||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -2246,7 +2336,7 @@ func SetJobCount(ctx *context.Context) { | |||||
| repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
| _, jobCount, err := models.Cloudbrains(&models.CloudbrainsOptions{ | _, jobCount, err := models.Cloudbrains(&models.CloudbrainsOptions{ | ||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: modelarts.DebugType, | |||||
| Type: models.TypeCloudBrainAll, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("Get job faild:", err) | ctx.ServerError("Get job faild:", err) | ||||
| @@ -110,6 +110,8 @@ func RepoStatisticDaily(date string) { | |||||
| Alias: repo.Alias, | Alias: repo.Alias, | ||||
| IsPrivate: repo.IsPrivate, | IsPrivate: repo.IsPrivate, | ||||
| IsMirror: repo.IsMirror, | IsMirror: repo.IsMirror, | ||||
| IsFork: repo.IsFork, | |||||
| RepoCreatedUnix: repo.CreatedUnix, | |||||
| OwnerName: repo.OwnerName, | OwnerName: repo.OwnerName, | ||||
| NumWatches: int64(repo.NumWatches), | NumWatches: int64(repo.NumWatches), | ||||
| NumStars: int64(repo.NumStars), | NumStars: int64(repo.NumStars), | ||||
| @@ -39,6 +39,27 @@ func SummaryStatisticDaily(date string) { | |||||
| log.Error("can not get repository number", err) | log.Error("can not get repository number", err) | ||||
| repositoryNumer = 0 | repositoryNumer = 0 | ||||
| } | } | ||||
| publicRepositoryNumer, err := models.GetAllPublicRepositoriesCount() | |||||
| if err != nil { | |||||
| log.Error("can not get public repository number", err) | |||||
| publicRepositoryNumer = 0 | |||||
| } | |||||
| privateRepositoryNumer := repositoryNumer - publicRepositoryNumer | |||||
| mirrorRepositoryNumber, err := models.GetAllMirrorRepositoriesCount() | |||||
| if err != nil { | |||||
| log.Error("can not get mirror repository number", err) | |||||
| mirrorRepositoryNumber = 0 | |||||
| } | |||||
| forkRepositoryNumber, err := models.GetAllForkRepositoriesCount() | |||||
| if err != nil { | |||||
| log.Error("can not get fork mirror repository number", err) | |||||
| forkRepositoryNumber = 0 | |||||
| } | |||||
| selfRepositoryNumber := repositoryNumer - mirrorRepositoryNumber - forkRepositoryNumber | |||||
| //repository size | //repository size | ||||
| repositorySize, err := models.GetAllRepositoriesSize() | repositorySize, err := models.GetAllRepositoriesSize() | ||||
| if err != nil { | if err != nil { | ||||
| @@ -73,6 +94,11 @@ func SummaryStatisticDaily(date string) { | |||||
| DatasetSize: allDatasetSize, | DatasetSize: allDatasetSize, | ||||
| NumOrganizations: organizationNumber, | NumOrganizations: organizationNumber, | ||||
| NumRepos: repositoryNumer, | NumRepos: repositoryNumer, | ||||
| NumRepoFork: forkRepositoryNumber, | |||||
| NumRepoMirror: mirrorRepositoryNumber, | |||||
| NumRepoPrivate: privateRepositoryNumer, | |||||
| NumRepoPublic: publicRepositoryNumer, | |||||
| NumRepoSelf: selfRepositoryNumber, | |||||
| NumRepoBigModel: topicsCount[0], | NumRepoBigModel: topicsCount[0], | ||||
| NumRepoAI: topicsCount[1], | NumRepoAI: topicsCount[1], | ||||
| NumRepoVision: topicsCount[2], | NumRepoVision: topicsCount[2], | ||||
| @@ -245,10 +245,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||||
| // This section doesn't require repo_name/RepoName to be set in the form, don't show it | // This section doesn't require repo_name/RepoName to be set in the form, don't show it | ||||
| // as an error on the UI for this action | // as an error on the UI for this action | ||||
| ctx.Data["Err_RepoName"] = nil | ctx.Data["Err_RepoName"] = nil | ||||
| if err := models.CreateDefaultDatasetToRepo(repo); err != nil { | |||||
| ctx.ServerError("CreateDefaultDatasetToRepo", err) | |||||
| return | |||||
| } | |||||
| if form.EnableDataset && !models.UnitTypeDatasets.UnitGlobalDisabled() { | if form.EnableDataset && !models.UnitTypeDatasets.UnitGlobalDisabled() { | ||||
| units = append(units, models.RepoUnit{ | units = append(units, models.RepoUnit{ | ||||
| @@ -323,6 +323,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/action/notification", routers.ActionNotification) | m.Get("/action/notification", routers.ActionNotification) | ||||
| m.Get("/recommend/org", routers.RecommendOrgFromPromote) | m.Get("/recommend/org", routers.RecommendOrgFromPromote) | ||||
| m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | ||||
| m.Post("/all/search/", routers.Search) | |||||
| m.Get("/all/search/", routers.EmptySearch) | |||||
| m.Get("/all/dosearch/", routers.SearchApi) | |||||
| m.Get("/home/term", routers.HomeTerm) | m.Get("/home/term", routers.HomeTerm) | ||||
| m.Group("/explore", func() { | m.Group("/explore", func() { | ||||
| m.Get("", func(ctx *context.Context) { | m.Get("", func(ctx *context.Context) { | ||||
| @@ -587,6 +590,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/delete", repo.DeleteAttachment) | m.Post("/delete", repo.DeleteAttachment) | ||||
| m.Get("/get_pre_url", repo.GetPresignedPutObjectURL) | m.Get("/get_pre_url", repo.GetPresignedPutObjectURL) | ||||
| m.Post("/add", repo.AddAttachment) | m.Post("/add", repo.AddAttachment) | ||||
| m.Post("/edit", bindIgnErr(auth.EditAttachmentForm{}), repo.EditAttachment) | |||||
| m.Post("/private", repo.UpdatePublicAttachment) | m.Post("/private", repo.UpdatePublicAttachment) | ||||
| m.Get("/get_chunks", repo.GetSuccessChunks) | m.Get("/get_chunks", repo.GetSuccessChunks) | ||||
| m.Get("/new_multipart", repo.NewMultipart) | m.Get("/new_multipart", repo.NewMultipart) | ||||
| @@ -979,7 +984,24 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/datasets", func() { | m.Group("/datasets", func() { | ||||
| m.Get("", reqRepoDatasetReader, repo.DatasetIndex) | m.Get("", reqRepoDatasetReader, repo.DatasetIndex) | ||||
| m.Post("", reqRepoDatasetWriter, bindIgnErr(auth.EditDatasetForm{}), repo.EditDatasetPost) | |||||
| m.Put("/:id/:action", reqRepoDatasetReader, repo.DatasetAction) | |||||
| m.Get("/create", reqRepoDatasetWriter, repo.CreateDataset) | |||||
| m.Post("/create", reqRepoDatasetWriter, bindIgnErr(auth.CreateDatasetForm{}), repo.CreateDatasetPost) | |||||
| m.Get("/edit/:id", reqRepoDatasetWriter, repo.EditDataset) | |||||
| m.Post("/edit", reqRepoDatasetWriter, bindIgnErr(auth.EditDatasetForm{}), repo.EditDatasetPost) | |||||
| m.Get("/current_repo", repo.CurrentRepoDataset) | |||||
| m.Get("/my_datasets", repo.MyDatasets) | |||||
| m.Get("/public_datasets", repo.PublicDataset) | |||||
| m.Get("/my_favorite", repo.MyFavoriteDataset) | |||||
| m.Group("/status", func() { | |||||
| m.Get("/:uuid", repo.GetDatasetStatus) | |||||
| }) | |||||
| m.Group("/attachments", func() { | |||||
| m.Get("/upload", repo.UploadAttachmentUI) | |||||
| m.Get("/edit/:id", repo.EditAttachmentUI) | |||||
| }, reqSignIn) | |||||
| m.Group("/dirs", func() { | m.Group("/dirs", func() { | ||||
| m.Get("/:uuid", reqRepoDatasetReader, repo.DirIndex) | m.Get("/:uuid", reqRepoDatasetReader, repo.DirIndex) | ||||
| @@ -1016,6 +1038,19 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) | m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainBenchmarkCreate) | ||||
| m.Get("/get_child_types", repo.GetChildTypes) | m.Get("/get_child_types", repo.GetChildTypes) | ||||
| }) | }) | ||||
| m.Group("/train-job", func() { | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
| //m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) | |||||
| m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
| //m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobNewVersion) | |||||
| //m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||||
| }) | |||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainTrainJobNew) | |||||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | |||||
| }) | |||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/modelmanage", func() { | m.Group("/modelmanage", func() { | ||||
| m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) | m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) | ||||
| @@ -10,7 +10,7 @@ import ( | |||||
| "github.com/elliotchance/orderedmap" | "github.com/elliotchance/orderedmap" | ||||
| ) | ) | ||||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 25, 26, 27, 28, 29, 30} | |||||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 25, 26, 27, 28, 29, 30, 31} | |||||
| type ClientsManager struct { | type ClientsManager struct { | ||||
| Clients *orderedmap.OrderedMap | Clients *orderedmap.OrderedMap | ||||
| @@ -43,26 +43,26 @@ | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap"> | <div class="two wide column text center nowrap"> | ||||
| <span>{{$.i18n.Tr "repository"}}</span> | |||||
| <span>{{$.i18n.Tr "repository"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap"> | <div class="two wide column text center nowrap"> | ||||
| <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | |||||
| <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| {{if .Repo}} | {{if .Repo}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | |||||
| <div class="row"> | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| {{$JobID := '0'}} | {{$JobID := '0'}} | ||||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | ||||
| @@ -91,8 +91,8 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | <!-- 任务类型 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | ||||
| @@ -105,12 +105,12 @@ | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| @@ -178,7 +178,7 @@ | |||||
| {{$JobID = .JobID}} | {{$JobID = .JobID}} | ||||
| {{end}} | {{end}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | |||||
| <div class="row"> | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="two wide column nowrap"> | <div class="two wide column nowrap"> | ||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| @@ -200,8 +200,8 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | <!-- 任务类型 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | ||||
| @@ -214,12 +214,12 @@ | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| @@ -296,18 +296,18 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -215,10 +215,10 @@ var _hmt = _hmt || []; | |||||
| localStorage.setItem("isCloseNotice",true) | localStorage.setItem("isCloseNotice",true) | ||||
| } | } | ||||
| function isShowNotice(){ | function isShowNotice(){ | ||||
| var current_notice = localStorage.getItem("notice") | |||||
| var current_notice = localStorage.getItem("notices") | |||||
| if (current_notice != "{{.notice.CommitId}}"){ | |||||
| localStorage.setItem('notice',"{{.notice.CommitId}}"); | |||||
| if (current_notice != "{{.notices.CommitId}}"){ | |||||
| localStorage.setItem('notices',"{{.notices.CommitId}}"); | |||||
| isNewNotice=true; | isNewNotice=true; | ||||
| localStorage.setItem("isCloseNotice",false) | localStorage.setItem("isCloseNotice",false) | ||||
| }else{ | }else{ | ||||
| @@ -216,10 +216,10 @@ var _hmt = _hmt || []; | |||||
| localStorage.setItem("isCloseNotice",true) | localStorage.setItem("isCloseNotice",true) | ||||
| } | } | ||||
| function isShowNotice(){ | function isShowNotice(){ | ||||
| var current_notice = localStorage.getItem("notice") | |||||
| var current_notice = localStorage.getItem("notices") | |||||
| if (current_notice != "{{.notice.CommitId}}"){ | |||||
| localStorage.setItem('notice',"{{.notice.CommitId}}"); | |||||
| if (current_notice != "{{.notices.CommitId}}"){ | |||||
| localStorage.setItem('notices',"{{.notices.CommitId}}"); | |||||
| isNewNotice=true; | isNewNotice=true; | ||||
| localStorage.setItem("isCloseNotice",false) | localStorage.setItem("isCloseNotice",false) | ||||
| }else{ | }else{ | ||||
| @@ -220,10 +220,10 @@ var _hmt = _hmt || []; | |||||
| localStorage.setItem("isCloseNotice",true) | localStorage.setItem("isCloseNotice",true) | ||||
| } | } | ||||
| function isShowNotice(){ | function isShowNotice(){ | ||||
| var current_notice = localStorage.getItem("notice") | |||||
| var current_notice = localStorage.getItem("notices") | |||||
| if (current_notice != "{{.notice.CommitId}}"){ | |||||
| localStorage.setItem('notice',"{{.notice.CommitId}}"); | |||||
| if (current_notice != "{{.notices.CommitId}}"){ | |||||
| localStorage.setItem('notices',"{{.notices.CommitId}}"); | |||||
| isNewNotice=true; | isNewNotice=true; | ||||
| localStorage.setItem("isCloseNotice",false) | localStorage.setItem("isCloseNotice",false) | ||||
| }else{ | }else{ | ||||
| @@ -95,9 +95,9 @@ | |||||
| {{if .IsSigned}} | {{if .IsSigned}} | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="hot"> | <input type="hidden" name="sort" value="hot"> | ||||
| @@ -199,9 +199,9 @@ | |||||
| <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="hot"> | <input type="hidden" name="sort" value="hot"> | ||||
| @@ -93,9 +93,9 @@ | |||||
| {{if .IsSigned}} | {{if .IsSigned}} | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
| @@ -196,9 +196,9 @@ | |||||
| <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
| @@ -96,9 +96,9 @@ | |||||
| {{if .IsSigned}} | {{if .IsSigned}} | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
| @@ -199,9 +199,9 @@ | |||||
| <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> | ||||
| <div class="right stackable menu"> | <div class="right stackable menu"> | ||||
| <form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos"> | |||||
| <form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||||
| <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | ||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..." | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." | |||||
| style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | ||||
| <input type="hidden" name="tab" value="{{$.TabName}}"> | <input type="hidden" name="tab" value="{{$.TabName}}"> | ||||
| <input type="hidden" name="sort" value="{{$.SortType}}"> | <input type="hidden" name="sort" value="{{$.SortType}}"> | ||||
| @@ -217,10 +217,10 @@ var _hmt = _hmt || []; | |||||
| localStorage.setItem("isCloseNotice",true) | localStorage.setItem("isCloseNotice",true) | ||||
| } | } | ||||
| function isShowNotice(){ | function isShowNotice(){ | ||||
| var current_notice = localStorage.getItem("notice") | |||||
| var current_notice = localStorage.getItem("notices") | |||||
| if (current_notice != "{{.notice.CommitId}}"){ | |||||
| localStorage.setItem('notice',"{{.notice.CommitId}}"); | |||||
| if (current_notice != "{{.notices.CommitId}}"){ | |||||
| localStorage.setItem('notices',"{{.notices.CommitId}}"); | |||||
| isNewNotice=true; | isNewNotice=true; | ||||
| localStorage.setItem("isCloseNotice",false) | localStorage.setItem("isCloseNotice",false) | ||||
| }else{ | }else{ | ||||
| @@ -0,0 +1,138 @@ | |||||
| <div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}" data-cloudranin-type="{{.cloudbraintype}}"></div> | |||||
| <div class="inline {{if eq .cloudbraintype 0}} required {{end}} field" id="dataset-base"> | |||||
| <label>{{.i18n.Tr "dataset.dataset"}}</label> | |||||
| <input type="hidden" name="attachment" :value="dataset_uuid"> | |||||
| {{if eq .cloudbraintype 0}} | |||||
| <input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();"> | |||||
| {{else}} | |||||
| <input class="disabled" type="text" :value="dataset_name"> | |||||
| {{end}} | |||||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus"> {{.i18n.Tr "dataset.select_dataset"}}</el-button> | |||||
| <el-dialog | |||||
| title="{{.i18n.Tr "dataset.select_dataset"}}" | |||||
| :visible.sync="dialogVisible" | |||||
| width="50%" | |||||
| > | |||||
| <div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;"> | |||||
| <i class="search icon" style="cursor: pointer;pointer-events:auto" @click="searchDataset()"></i> | |||||
| <input type="text" placeholder="{{.i18n.Tr "dataset.search_dataset"}}" v-model="searchDataItem" @keyup.enter="searchDataset()"> | |||||
| </div> | |||||
| <el-tabs v-model="activeName" @tab-click="handleClick('{{.RepoLink}}',activeName,{{.cloudbraintype}})"> | |||||
| <el-tab-pane label="{{.i18n.Tr "dataset.current_project"}}" name="first"> | |||||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in currentRepoDataset" :key="index"> | |||||
| <div style="width: 90%;"> | |||||
| <div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias} </span><span class="panel_dataset_name">${dataset.Name} </span></div> | |||||
| <div style="margin-top: 8px;display: flex;"> | |||||
| <a :title="dataset.UserName" style="cursor: default;"> | |||||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||||
| </a> | |||||
| <span class="panel_datset_desc">${dataset.Description}</span> | |||||
| </div> | |||||
| </div> | |||||
| <div> | |||||
| <button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||||
| <span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||||
| <i class="CREATING"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||||
| </span> | |||||
| <span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||||
| <i class="FAILED"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </el-tab-pane> | |||||
| <el-tab-pane label="{{.i18n.Tr "dataset.owner_dataset"}}" name="second"> | |||||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in myDataset" :key="index"> | |||||
| <div style="width: 90%;"> | |||||
| <div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||||
| <div style="margin-top: 8px;display: flex;"> | |||||
| <a :title="dataset.UserName" style="cursor: default;"> | |||||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||||
| </a> | |||||
| <span class="panel_datset_desc">${dataset.Description}</span> | |||||
| </div> | |||||
| </div> | |||||
| <div> | |||||
| <button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||||
| <span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||||
| <i class="CREATING"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||||
| </span> | |||||
| <span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||||
| <i class="FAILED"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </el-tab-pane> | |||||
| <el-tab-pane label="{{.i18n.Tr "dataset.public_dataset"}}" name="third"> | |||||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in publicDataset" :key="index"> | |||||
| <div style="width: 90%;"> | |||||
| <div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||||
| <div style="margin-top: 8px;display: flex;"> | |||||
| <a :title="dataset.UserName" style="cursor: default;"> | |||||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||||
| </a> | |||||
| <span class="panel_datset_desc">${dataset.Description}</span> | |||||
| </div> | |||||
| </div> | |||||
| <div> | |||||
| <button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||||
| <span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||||
| <i class="CREATING"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||||
| </span> | |||||
| <span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||||
| <i class="FAILED"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </el-tab-pane> | |||||
| <el-tab-pane label="{{.i18n.Tr "dataset.I_liked"}}" name="fourth"> | |||||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in myFavoriteDataset" :key="index"> | |||||
| <div style="width: 90%;"> | |||||
| <div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||||
| <div style="margin-top: 8px;display: flex;"> | |||||
| <a :title="dataset.UserName" style="cursor: default;"> | |||||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||||
| </a> | |||||
| <span class="panel_datset_desc">${dataset.Description}</span> | |||||
| </div> | |||||
| </div> | |||||
| <div> | |||||
| <button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||||
| <span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||||
| <i class="CREATING"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||||
| </span> | |||||
| <span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||||
| <i class="FAILED"></i> | |||||
| <span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </el-tab-pane> | |||||
| </el-tabs> | |||||
| <div class="center"> | |||||
| <el-pagination | |||||
| background | |||||
| @current-change="handleCurrentChange" | |||||
| :current-page="page" | |||||
| :page-size="5" | |||||
| layout="total,prev, pager, next" | |||||
| :total="totalnums"> | |||||
| </el-pagination> | |||||
| </div> | |||||
| </el-dialog> | |||||
| </div> | |||||
| @@ -0,0 +1,69 @@ | |||||
| <div class="computer only four wide computer column"> | |||||
| <div class="ui grid"> | |||||
| <div class="ui sixteen wide column"> | |||||
| <h2 class="ui medium header" style="margin-top: 0;visibility: hidden;" > | |||||
| {{.i18n.Tr "datasets"}} | |||||
| </h2> | |||||
| <div id="task-square-range-value" style="display: none;"> | |||||
| {{range $task := tasks}} | |||||
| <div class="item" data-task='{{$task}}'></div> | |||||
| {{end}} | |||||
| </div> | |||||
| <div id="square-link" style="display: none;" data-link="{{$.Link}}"></div> | |||||
| <div id="licenses-square-range-value" style="display: none;"> | |||||
| {{range $license := licenses}} | |||||
| <div class="item" data-license="{{$license}}"></div> | |||||
| {{end}} | |||||
| </div> | |||||
| <div class="mg-b-2"> | |||||
| <div class="flex mg-b-1"> | |||||
| <h3 class="font-medium"> | |||||
| {{.i18n.Tr "dataset.category"}} | |||||
| {{if $.Category}} | |||||
| <span class="mg-l-1 underline text-gray-400 text-sm clear_dataset_value" data-clear-value="category"style="cursor: pointer;" >Clear</span> | |||||
| {{end}} | |||||
| </h3> | |||||
| </div> | |||||
| <div class="flex flex-wrap"> | |||||
| {{range $category := categories}} | |||||
| {{$Cate := $.i18n.Tr (printf "dataset.category.%s" $category)}} | |||||
| <a class="tag {{if eq $category $.Category}} tag-active {{else}} tag-gray{{end}}" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$category}}&task={{$.Task}}&license={{$.License}}"><span>{{$Cate}}</span></a> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="mg-b-2"> | |||||
| <div class="flex mg-b-1"> | |||||
| <h3 class="font-medium"> | |||||
| {{.i18n.Tr "dataset.task"}} | |||||
| {{if $.Task}} | |||||
| <span class="mg-l-1 underline text-gray-400 text-sm clear_dataset_value" data-clear-value="task" style="cursor: pointer;" >Clear</span> | |||||
| {{end}} | |||||
| </h3> | |||||
| </div> | |||||
| <div class="flex flex-wrap history-content"> | |||||
| {{range $task := tasks}} | |||||
| {{$Task := $.i18n.Tr (printf "dataset.task.%s" $task)}} | |||||
| <a class="tag {{if eq $task $.Task}} tag-active {{else}} tag-gray{{end}}" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$task}}&license={{$.License}}"><span>{{$Task}}</span></a> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="mg-b-2"> | |||||
| <div class="flex mg-b-1"> | |||||
| <h3 class="font-medium"> | |||||
| {{.i18n.Tr "repo.license"}} | |||||
| {{if $.License}} | |||||
| <span class="mg-l-1 underline text-gray-400 text-sm clear_dataset_value" data-clear-value="license" style="cursor: pointer;" >Clear</span> | |||||
| {{end}} | |||||
| </h3> | |||||
| </div> | |||||
| <div class="flex flex-wrap"> | |||||
| {{range $license := licenses}} | |||||
| <a class="tag {{if eq $license $.License}} tag-active {{else}} tag-gray {{end}}" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$license}}"><span>{{$license}}</span></a> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| @@ -25,7 +25,7 @@ | |||||
| {{range .Datasets}} | {{range .Datasets}} | ||||
| <div class="item"> | <div class="item"> | ||||
| <div class="ui header"> | <div class="ui header"> | ||||
| <a class="name" href="{{.Repo.Link}}/datasets?type=0"> | |||||
| <a class="name" href="{{.Repo.Link}}/datasets"> | |||||
| {{.Repo.OwnerName}} / {{.Repo.Alias}} | {{.Repo.OwnerName}} / {{.Repo.Alias}} | ||||
| </a> | </a> | ||||
| <div class="ui right metas"> | <div class="ui right metas"> | ||||
| @@ -1,15 +1,216 @@ | |||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||
| <style> | |||||
| .mg-b-1{ | |||||
| margin-bottom: 1rem; | |||||
| } | |||||
| .mg-b-2{ | |||||
| margin-bottom: 2rem; | |||||
| } | |||||
| .mg-l-1{ | |||||
| margin-left: 1rem; | |||||
| } | |||||
| .text-gray-400 { | |||||
| --tw-text-opacity: 1; | |||||
| color: rgba(156,163,175,var(--tw-text-opacity)); | |||||
| } | |||||
| .text-sm { | |||||
| font-size: .875rem; | |||||
| line-height: 1.25rem; | |||||
| } | |||||
| .underline { | |||||
| text-decoration: underline; | |||||
| } | |||||
| .flex{ | |||||
| display: flex; | |||||
| } | |||||
| .font-medium{ | |||||
| font-weight: 500; | |||||
| } | |||||
| .flex-wrap{ | |||||
| flex-wrap: wrap; | |||||
| } | |||||
| .tag { | |||||
| background-image: linear-gradient(to bottom,var(--tw-gradient-stops)); | |||||
| border-color: transparent; | |||||
| border-radius: 0.5rem; | |||||
| border-width: 1px; | |||||
| font-size: .875rem; | |||||
| line-height: 1.25rem; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| white-space: nowrap; | |||||
| } | |||||
| .tag-red { | |||||
| --tw-gradient-from: #fef2f2; | |||||
| --tw-gradient-stops: var(--tw-gradient-from),var(--tw-gradient-to,hsla(0,86%,97%,0)); | |||||
| --tw-gradient-to: #fef2f2; | |||||
| --tw-text-opacity: 1; | |||||
| color: rgba(153,27,27,var(--tw-text-opacity)); | |||||
| } | |||||
| .tag-purple { | |||||
| --tw-gradient-from: #f5f3ff; | |||||
| --tw-gradient-stops: var(--tw-gradient-from),var(--tw-gradient-to,rgba(245,243,255,0)); | |||||
| --tw-gradient-to: #f5f3ff; | |||||
| --tw-text-opacity: 1; | |||||
| color: rgba(91,33,182,var(--tw-text-opacity)); | |||||
| } | |||||
| .tag-blue { | |||||
| --tw-gradient-from: #eff6ff; | |||||
| --tw-gradient-stops: var(--tw-gradient-from),var(--tw-gradient-to,rgba(239,246,255,0)); | |||||
| --tw-gradient-to: #eff6ff; | |||||
| --tw-text-opacity: 1; | |||||
| color: rgba(30,64,175,var(--tw-text-opacity)); | |||||
| } | |||||
| .tag.inactive { | |||||
| filter: grayscale(100%); | |||||
| opacity: .5; | |||||
| } | |||||
| .tag.tag-active{ | |||||
| background-color: #0366d6; | |||||
| color: #ffffff; | |||||
| } | |||||
| .tag-gray{ | |||||
| background-color: #f8f9fa; | |||||
| color: #415058; | |||||
| } | |||||
| .tag { | |||||
| align-items: center; | |||||
| display: inline-flex; | |||||
| flex: none; | |||||
| height: 2rem; | |||||
| margin-bottom: 0.35rem; | |||||
| margin-right: 0.35rem; | |||||
| max-width: 100%; | |||||
| } | |||||
| .tag>span { | |||||
| padding: 0.75rem; | |||||
| font-size: 14px; | |||||
| } | |||||
| .repo_dataset_header{ | |||||
| font-size: 12px; | |||||
| color: #3291F8; | |||||
| } | |||||
| .heart-stroke{ | |||||
| stroke: #666; | |||||
| stroke-width: 2; | |||||
| fill: #fff | |||||
| } | |||||
| .stars_active{ | |||||
| fill: #FA8C16 !important; | |||||
| stroke:#FA8C16 !important | |||||
| } | |||||
| </style> | |||||
| <div class="explore repositories"> | <div class="explore repositories"> | ||||
| {{template "explore/dataset_search" .}} | {{template "explore/dataset_search" .}} | ||||
| <div class="ui container"> | |||||
| <div class="ui grid"> | |||||
| {{template "explore/navbar" .}} | |||||
| <div class="ui sixteen wide mobile ten wide tablet ten wide computer column"> | |||||
| {{template "explore/dataset_list" .}} | |||||
| {{template "base/paginate" .}} | |||||
| </div> | |||||
| <div class="ui sixteen wide mobile six wide tablet three wide computer column"> | |||||
| {{template "explore/repo_right" .}} | |||||
| <div> | |||||
| <div class="ui container"> | |||||
| <div class="ui grid"> | |||||
| {{template "explore/dataset_left" .}} | |||||
| <div class="ui sixteen wide mobile sixteen wide tablet twelve wide computer column"> | |||||
| <div class="ui row"> | |||||
| <h2 class="ui left floated medium header"> | |||||
| {{.i18n.Tr "datasets"}} | |||||
| </h2> | |||||
| <div class="ui right floated secondary filter menu"> | |||||
| <!-- Sort --> | |||||
| <div class="ui right dropdown type jump item"> | |||||
| <span class="text"> | |||||
| {{.i18n.Tr "repo.issues.filter_sort"}} | |||||
| <i class="dropdown icon"></i> | |||||
| </span> | |||||
| <div class="menu"> | |||||
| <a class="{{if eq .SortType "newest"}}active{{end}} item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||||
| <a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||||
| <a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a> | |||||
| <a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a> | |||||
| <!-- <a class="{{if eq .SortType "downloadtimes"}}active{{end}} item" href="{{$.Link}}?sort=downloadtimes&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}</a> --> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{if .Datasets}} | |||||
| <div id="datasets-square-range-value" style="display: none;"> | |||||
| {{range .Datasets}} | |||||
| <div class="item" data-num-stars="{{.NumStars}}" data-star-active="{{.IsStaring}}"></div> | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | |||||
| <div class="ui row" style="clear: both;" id="dataset-base"> | |||||
| <div class="ui two cards"> | |||||
| {{range $k, $v :=.Datasets}} | |||||
| <div class="ui card" @click="gotoDataset('{{.Repo.Link}}/datasets')" style="cursor: pointer;box-shadow: 0px 4px 4px 0px rgba(232,232,232,0.6);border: 1px solid rgba(232, 232, 232, 1);"> | |||||
| <div class="content" style="border-bottom: none;"> | |||||
| <div class="repo_dataset_header" style="display: flex;align-items: center;justify-content: space-between;"> | |||||
| <a href="{{.Repo.Link}}/datasets" style="font-size: 12px;color: #3291F8;height: 24px;">{{.Repo.OwnerName}} / {{.Repo.Alias}}</a> | |||||
| {{if $.IsSigned}} | |||||
| <span style="display: flex;align-items: center;justify-content: flex-end;cursor: pointer;" @click.stop="postSquareStar({{.ID}},'{{.Repo.Link}}/datasets',{{$k}})"> | |||||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;"> | |||||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:starActives[{{$k}}]}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||||
| </div> | |||||
| <span style="line-height: 1;color: #101010;">${starItems[{{$k}}]}</span> | |||||
| </span> | |||||
| {{else}} | |||||
| <span style="display: flex;align-items: center;justify-content: flex-end;cursor: pointer;"> | |||||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;"> | |||||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:starActives[{{$k}}]}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||||
| </div> | |||||
| <span style="line-height: 1;color: #101010;">${starItems[{{$k}}]}</span> | |||||
| </span> | |||||
| {{end}} | |||||
| </div> | |||||
| <div style="font-size: 16px;color:#0366D6;font-family: SourceHanSansSC-medium;height: 27px;font-weight: bold;">{{.Title}}</div> | |||||
| {{if or (.Category) (.Task) (.License)}} | |||||
| <div style="font-size: 12px;margin-top: 5px;height: 24px;"> | |||||
| {{if .Category}} | |||||
| {{$category := .Category}} | |||||
| <a class="ui repo-topic label topic" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{.Category}}&task={{$.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.category.%s" $category)}}</a> | |||||
| {{end}} | |||||
| {{if .Task}} | |||||
| {{$task := .Task}} | |||||
| <a class="ui repo-topic label topic" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.task.%s" $task)}}</a> | |||||
| {{end}} | |||||
| {{if .License}} | |||||
| <a class="ui repo-topic label topic" href="{{$.Link}}?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{.License}}">{{.License}}</a> | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | |||||
| <div class="description" style="-webkit-box-orient: vertical;-webkit-line-clamp: 2;display: -webkit-box;overflow: hidden;color:#999999;font-size: 14px;margin-top: 10px;"> | |||||
| <p>{{.Description}}</p> | |||||
| </div> | |||||
| </div> | |||||
| <div class="extra content" style="border-top: none !important;"> | |||||
| <div style="display: flex;align-items: center;"> | |||||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}" title="{{.Repo.OwnerName}}"> | |||||
| <img class="ui avatar image" style="width: 22px;height:22px;" src="/user/avatar/{{.Repo.OwnerName}}/-1"> | |||||
| </a> | |||||
| <span style="color: #999999;font-size: 14px;;">创建于:{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div id="app" style="margin-top: 2rem;"> | |||||
| <div class="center"> | |||||
| <el-pagination | |||||
| background | |||||
| @current-change="handleCurrentChange" | |||||
| :current-page="page" | |||||
| :page-sizes="[30]" | |||||
| :page-size="30" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="{{.Page.Paginater.Total}}"> | |||||
| </el-pagination> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -4,73 +4,73 @@ | |||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M16,20H20V16H16M16,14H20V10H16M10,8H14V4H10M16,8H20V4H16M10,14H14V10H10M4,14H8V10H4M4,20H8V16H4M10,20H14V16H10M4,8H8V4H4V8Z" /> | <path fill="currentColor" d="M16,20H20V16H16M16,14H20V10H16M10,8H14V4H10M16,8H20V4H16M10,14H14V10H10M4,14H8V10H4M4,20H8V16H4M10,20H14V16H10M4,8H8V4H4V8Z" /> | ||||
| </svg> | </svg> | ||||
| 全部领域 | |||||
| {{.i18n.Tr "explore.all_fields"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "大模型"}}active {{end}}item" href="/explore/repos?q=&topic=大模型&sort={{.SortType}}"> | <a class="{{if eq $.Topic "大模型"}}active {{end}}item" href="/explore/repos?q=&topic=大模型&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M19 3H5C3.89 3 3 3.89 3 5V19C3 20.11 3.9 21 5 21H19C20.11 21 21 20.11 21 19V5C21 3.89 20.1 3 19 3M16.1 15.9C15.07 15.9 14.09 15.5 13.35 14.76L12.71 14.12L14.13 12.71L14.76 13.34C15.12 13.7 15.6 13.9 16.11 13.9C17.15 13.9 18 13.05 18 12S17.15 10.1 16.1 10.1C15.6 10.1 15.12 10.3 14.76 10.66L10.65 14.76C9.91 15.5 8.94 15.9 7.9 15.9C5.75 15.9 4 14.15 4 12S5.75 8.1 7.9 8.1C8.94 8.1 9.91 8.5 10.65 9.24L11.29 9.88L9.87 11.3L9.24 10.66C8.88 10.3 8.4 10.1 7.9 10.1C6.85 10.1 6 10.95 6 12S6.85 13.9 7.9 13.9C8.4 13.9 8.88 13.7 9.24 13.34L13.35 9.24C14.09 8.5 15.06 8.1 16.1 8.1C18.25 8.1 20 9.85 20 12S18.25 15.9 16.1 15.9Z" /> | <path fill="currentColor" d="M19 3H5C3.89 3 3 3.89 3 5V19C3 20.11 3.9 21 5 21H19C20.11 21 21 20.11 21 19V5C21 3.89 20.1 3 19 3M16.1 15.9C15.07 15.9 14.09 15.5 13.35 14.76L12.71 14.12L14.13 12.71L14.76 13.34C15.12 13.7 15.6 13.9 16.11 13.9C17.15 13.9 18 13.05 18 12S17.15 10.1 16.1 10.1C15.6 10.1 15.12 10.3 14.76 10.66L10.65 14.76C9.91 15.5 8.94 15.9 7.9 15.9C5.75 15.9 4 14.15 4 12S5.75 8.1 7.9 8.1C8.94 8.1 9.91 8.5 10.65 9.24L11.29 9.88L9.87 11.3L9.24 10.66C8.88 10.3 8.4 10.1 7.9 10.1C6.85 10.1 6 10.95 6 12S6.85 13.9 7.9 13.9C8.4 13.9 8.88 13.7 9.24 13.34L13.35 9.24C14.09 8.5 15.06 8.1 16.1 8.1C18.25 8.1 20 9.85 20 12S18.25 15.9 16.1 15.9Z" /> | ||||
| </svg> | </svg> | ||||
| 大模型 | |||||
| {{.i18n.Tr "explore.large_model"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "AI开发工具"}}active {{end}}item" href="/explore/repos?q=&topic=AI开发工具&sort={{.SortType}}"> | <a class="{{if eq $.Topic "AI开发工具"}}active {{end}}item" href="/explore/repos?q=&topic=AI开发工具&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3M11 8H9V10C9 11.1 8.1 12 7 12C8.1 12 9 12.9 9 14V16H11V18H9C7.9 18 7 17.1 7 16V15C7 13.9 6.1 13 5 13V11C6.1 11 7 10.1 7 9V8C7 6.9 7.9 6 9 6H11V8M19 13C17.9 13 17 13.9 17 15V16C17 17.1 16.1 18 15 18H13V16H15V14C15 12.9 15.9 12 17 12C15.9 12 15 11.1 15 10V8H13V6H15C16.1 6 17 6.9 17 8V9C17 10.1 17.9 11 19 11V13Z" /> | <path fill="currentColor" d="M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3M11 8H9V10C9 11.1 8.1 12 7 12C8.1 12 9 12.9 9 14V16H11V18H9C7.9 18 7 17.1 7 16V15C7 13.9 6.1 13 5 13V11C6.1 11 7 10.1 7 9V8C7 6.9 7.9 6 9 6H11V8M19 13C17.9 13 17 13.9 17 15V16C17 17.1 16.1 18 15 18H13V16H15V14C15 12.9 15.9 12 17 12C15.9 12 15 11.1 15 10V8H13V6H15C16.1 6 17 6.9 17 8V9C17 10.1 17.9 11 19 11V13Z" /> | ||||
| </svg> | </svg> | ||||
| AI开发工具 | |||||
| {{.i18n.Tr "explore.ai_development_tools"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "计算机视觉"}}active {{end}}item" href="/explore/repos?q=&topic=计算机视觉&sort={{.SortType}}"> | <a class="{{if eq $.Topic "计算机视觉"}}active {{end}}item" href="/explore/repos?q=&topic=计算机视觉&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" /> | <path fill="currentColor" d="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" /> | ||||
| </svg> | </svg> | ||||
| 计算机视觉 | |||||
| {{.i18n.Tr "explore.computer_version"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "自然语言处理"}}active {{end}}item" href="/explore/repos?q=&topic=自然语言处理&sort={{.SortType}}"> | <a class="{{if eq $.Topic "自然语言处理"}}active {{end}}item" href="/explore/repos?q=&topic=自然语言处理&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M9,5A4,4 0 0,1 13,9A4,4 0 0,1 9,13A4,4 0 0,1 5,9A4,4 0 0,1 9,5M9,15C11.67,15 17,16.34 17,19V21H1V19C1,16.34 6.33,15 9,15M16.76,5.36C18.78,7.56 18.78,10.61 16.76,12.63L15.08,10.94C15.92,9.76 15.92,8.23 15.08,7.05L16.76,5.36M20.07,2C24,6.05 23.97,12.11 20.07,16L18.44,14.37C21.21,11.19 21.21,6.65 18.44,3.63L20.07,2Z" /> | <path fill="currentColor" d="M9,5A4,4 0 0,1 13,9A4,4 0 0,1 9,13A4,4 0 0,1 5,9A4,4 0 0,1 9,5M9,15C11.67,15 17,16.34 17,19V21H1V19C1,16.34 6.33,15 9,15M16.76,5.36C18.78,7.56 18.78,10.61 16.76,12.63L15.08,10.94C15.92,9.76 15.92,8.23 15.08,7.05L16.76,5.36M20.07,2C24,6.05 23.97,12.11 20.07,16L18.44,14.37C21.21,11.19 21.21,6.65 18.44,3.63L20.07,2Z" /> | ||||
| </svg> | </svg> | ||||
| 自然语言处理 | |||||
| {{.i18n.Tr "explore.natural_language_processing"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "机器学习"}}active {{end}}item" href="/explore/repos?q=&topic=机器学习&sort={{.SortType}}"> | <a class="{{if eq $.Topic "机器学习"}}active {{end}}item" href="/explore/repos?q=&topic=机器学习&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M19,12V13.5A4,4 0 0,1 23,17.5C23,18.32 22.75,19.08 22.33,19.71L21.24,18.62C21.41,18.28 21.5,17.9 21.5,17.5A2.5,2.5 0 0,0 19,15V16.5L16.75,14.25L19,12M19,23V21.5A4,4 0 0,1 15,17.5C15,16.68 15.25,15.92 15.67,15.29L16.76,16.38C16.59,16.72 16.5,17.1 16.5,17.5A2.5,2.5 0 0,0 19,20V18.5L21.25,20.75L19,23M12,3C16.42,3 20,4.79 20,7C20,9.21 16.42,11 12,11C7.58,11 4,9.21 4,7C4,4.79 7.58,3 12,3M4,9C4,11.21 7.58,13 12,13C13.11,13 14.17,12.89 15.14,12.68C14.19,13.54 13.5,14.67 13.18,15.96L12,16C7.58,16 4,14.21 4,12V9M20,9V11H19.5L18.9,11.03C19.6,10.43 20,9.74 20,9M4,14C4,16.21 7.58,18 12,18L13,17.97C13.09,19.03 13.42,20 13.95,20.88L12,21C7.58,21 4,19.21 4,17V14Z" /> | <path fill="currentColor" d="M19,12V13.5A4,4 0 0,1 23,17.5C23,18.32 22.75,19.08 22.33,19.71L21.24,18.62C21.41,18.28 21.5,17.9 21.5,17.5A2.5,2.5 0 0,0 19,15V16.5L16.75,14.25L19,12M19,23V21.5A4,4 0 0,1 15,17.5C15,16.68 15.25,15.92 15.67,15.29L16.76,16.38C16.59,16.72 16.5,17.1 16.5,17.5A2.5,2.5 0 0,0 19,20V18.5L21.25,20.75L19,23M12,3C16.42,3 20,4.79 20,7C20,9.21 16.42,11 12,11C7.58,11 4,9.21 4,7C4,4.79 7.58,3 12,3M4,9C4,11.21 7.58,13 12,13C13.11,13 14.17,12.89 15.14,12.68C14.19,13.54 13.5,14.67 13.18,15.96L12,16C7.58,16 4,14.21 4,12V9M20,9V11H19.5L18.9,11.03C19.6,10.43 20,9.74 20,9M4,14C4,16.21 7.58,18 12,18L13,17.97C13.09,19.03 13.42,20 13.95,20.88L12,21C7.58,21 4,19.21 4,17V14Z" /> | ||||
| </svg> | </svg> | ||||
| 机器学习 | |||||
| {{.i18n.Tr "explore.machine_learning"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "神经网络"}}active {{end}}item" href="/explore/repos?q=&topic=神经网络&sort={{.SortType}}"> | <a class="{{if eq $.Topic "神经网络"}}active {{end}}item" href="/explore/repos?q=&topic=神经网络&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M13 3C9.23 3 6.19 5.95 6 9.66L4.08 12.19C3.84 12.5 4.08 13 4.5 13H6V16C6 17.11 6.89 18 8 18H9V21H16V16.31C18.37 15.19 20 12.8 20 10C20 6.14 16.88 3 13 3M17.06 9.57L15.1 10.09L16.54 11.54C16.89 11.88 16.89 12.46 16.54 12.81C16.19 13.16 15.61 13.16 15.27 12.81L13.81 11.37L13.3 13.33C13.18 13.82 12.68 14.1 12.21 13.97C11.72 13.84 11.44 13.35 11.57 12.87L12.1 10.9L10.13 11.43C9.65 11.56 9.15 11.28 9.03 10.79C8.9 10.32 9.18 9.82 9.67 9.7L11.63 9.19L10.19 7.73C9.84 7.39 9.84 6.82 10.19 6.46C10.54 6.11 11.12 6.11 11.46 6.46L12.91 7.9L13.43 5.94C13.55 5.46 14.04 5.18 14.5 5.3C15 5.43 15.28 5.92 15.16 6.41L14.63 8.37L16.59 7.84C17.08 7.72 17.57 8 17.7 8.5C17.82 8.96 17.54 9.45 17.06 9.57Z" /> | <path fill="currentColor" d="M13 3C9.23 3 6.19 5.95 6 9.66L4.08 12.19C3.84 12.5 4.08 13 4.5 13H6V16C6 17.11 6.89 18 8 18H9V21H16V16.31C18.37 15.19 20 12.8 20 10C20 6.14 16.88 3 13 3M17.06 9.57L15.1 10.09L16.54 11.54C16.89 11.88 16.89 12.46 16.54 12.81C16.19 13.16 15.61 13.16 15.27 12.81L13.81 11.37L13.3 13.33C13.18 13.82 12.68 14.1 12.21 13.97C11.72 13.84 11.44 13.35 11.57 12.87L12.1 10.9L10.13 11.43C9.65 11.56 9.15 11.28 9.03 10.79C8.9 10.32 9.18 9.82 9.67 9.7L11.63 9.19L10.19 7.73C9.84 7.39 9.84 6.82 10.19 6.46C10.54 6.11 11.12 6.11 11.46 6.46L12.91 7.9L13.43 5.94C13.55 5.46 14.04 5.18 14.5 5.3C15 5.43 15.28 5.92 15.16 6.41L14.63 8.37L16.59 7.84C17.08 7.72 17.57 8 17.7 8.5C17.82 8.96 17.54 9.45 17.06 9.57Z" /> | ||||
| </svg> | </svg> | ||||
| 神经网络 | |||||
| {{.i18n.Tr "explore.neural_networks"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "自动驾驶"}}active {{end}}item" href="/explore/repos?q=&topic=自动驾驶&sort={{.SortType}}"> | <a class="{{if eq $.Topic "自动驾驶"}}active {{end}}item" href="/explore/repos?q=&topic=自动驾驶&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M5,14H19L17.5,9.5H6.5L5,14M17.5,19A1.5,1.5 0 0,0 19,17.5A1.5,1.5 0 0,0 17.5,16A1.5,1.5 0 0,0 16,17.5A1.5,1.5 0 0,0 17.5,19M6.5,19A1.5,1.5 0 0,0 8,17.5A1.5,1.5 0 0,0 6.5,16A1.5,1.5 0 0,0 5,17.5A1.5,1.5 0 0,0 6.5,19M18.92,9L21,15V23A1,1 0 0,1 20,24H19A1,1 0 0,1 18,23V22H6V23A1,1 0 0,1 5,24H4A1,1 0 0,1 3,23V15L5.08,9C5.28,8.42 5.85,8 6.5,8H17.5C18.15,8 18.72,8.42 18.92,9M12,0C14.12,0 16.15,0.86 17.65,2.35L16.23,3.77C15.11,2.65 13.58,2 12,2C10.42,2 8.89,2.65 7.77,3.77L6.36,2.35C7.85,0.86 9.88,0 12,0M12,4C13.06,4 14.07,4.44 14.82,5.18L13.4,6.6C13.03,6.23 12.53,6 12,6C11.5,6 10.97,6.23 10.6,6.6L9.18,5.18C9.93,4.44 10.94,4 12,4Z" /> | <path fill="currentColor" d="M5,14H19L17.5,9.5H6.5L5,14M17.5,19A1.5,1.5 0 0,0 19,17.5A1.5,1.5 0 0,0 17.5,16A1.5,1.5 0 0,0 16,17.5A1.5,1.5 0 0,0 17.5,19M6.5,19A1.5,1.5 0 0,0 8,17.5A1.5,1.5 0 0,0 6.5,16A1.5,1.5 0 0,0 5,17.5A1.5,1.5 0 0,0 6.5,19M18.92,9L21,15V23A1,1 0 0,1 20,24H19A1,1 0 0,1 18,23V22H6V23A1,1 0 0,1 5,24H4A1,1 0 0,1 3,23V15L5.08,9C5.28,8.42 5.85,8 6.5,8H17.5C18.15,8 18.72,8.42 18.92,9M12,0C14.12,0 16.15,0.86 17.65,2.35L16.23,3.77C15.11,2.65 13.58,2 12,2C10.42,2 8.89,2.65 7.77,3.77L6.36,2.35C7.85,0.86 9.88,0 12,0M12,4C13.06,4 14.07,4.44 14.82,5.18L13.4,6.6C13.03,6.23 12.53,6 12,6C11.5,6 10.97,6.23 10.6,6.6L9.18,5.18C9.93,4.44 10.94,4 12,4Z" /> | ||||
| </svg> | </svg> | ||||
| 自动驾驶 | |||||
| {{.i18n.Tr "explore.autopilot"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "机器人"}}active {{end}}item" href="/explore/repos?q=&topic=机器人&sort={{.SortType}}"> | <a class="{{if eq $.Topic "机器人"}}active {{end}}item" href="/explore/repos?q=&topic=机器人&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M7.5,13A2.5,2.5 0 0,0 5,15.5A2.5,2.5 0 0,0 7.5,18A2.5,2.5 0 0,0 10,15.5A2.5,2.5 0 0,0 7.5,13M16.5,13A2.5,2.5 0 0,0 14,15.5A2.5,2.5 0 0,0 16.5,18A2.5,2.5 0 0,0 19,15.5A2.5,2.5 0 0,0 16.5,13Z" /> | <path fill="currentColor" d="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M7.5,13A2.5,2.5 0 0,0 5,15.5A2.5,2.5 0 0,0 7.5,18A2.5,2.5 0 0,0 10,15.5A2.5,2.5 0 0,0 7.5,13M16.5,13A2.5,2.5 0 0,0 14,15.5A2.5,2.5 0 0,0 16.5,18A2.5,2.5 0 0,0 19,15.5A2.5,2.5 0 0,0 16.5,13Z" /> | ||||
| </svg> | </svg> | ||||
| 机器人 | |||||
| {{.i18n.Tr "explore.robot"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "联邦学习"}}active {{end}}item" href="/explore/repos?q=&topic=联邦学习&sort={{.SortType}}"> | <a class="{{if eq $.Topic "联邦学习"}}active {{end}}item" href="/explore/repos?q=&topic=联邦学习&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M3 11H11V3H3M5 5H9V9H5M13 21H21V13H13M15 15H19V19H15M3 21H11V13H3M5 15H9V19H5M13 3V11H21V3M19 9H15V5H19Z" /> | <path fill="currentColor" d="M3 11H11V3H3M5 5H9V9H5M13 21H21V13H13M15 15H19V19H15M3 21H11V13H3M5 15H9V19H5M13 3V11H21V3M19 9H15V5H19Z" /> | ||||
| </svg> | </svg> | ||||
| 联邦学习 | |||||
| {{.i18n.Tr "explore.federated_learning"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "数据挖掘"}}active {{end}}item" href="/explore/repos?q=&topic=数据挖掘&sort={{.SortType}}"> | <a class="{{if eq $.Topic "数据挖掘"}}active {{end}}item" href="/explore/repos?q=&topic=数据挖掘&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M18.36,2.64C20,2.64 21.36,4 21.36,5.64C21.36,7.29 20,8.64 18.36,8.64C16.71,8.64 15.36,7.29 15.36,5.64C15.36,5.34 15.41,5.06 15.5,4.8C14.43,4.29 13.25,4 12,4A8,8 0 0,0 4,12L4.04,12.84L2.05,13.05L2,12A10,10 0 0,1 12,2C13.69,2 15.28,2.42 16.67,3.16C17.16,2.83 17.74,2.64 18.36,2.64M18.36,4.64A1,1 0 0,0 17.36,5.64A1,1 0 0,0 18.36,6.64C18.92,6.64 19.36,6.19 19.36,5.64C19.36,5.08 18.92,4.64 18.36,4.64M5.64,15.36C7.29,15.36 8.64,16.71 8.64,18.36C8.64,18.66 8.59,18.94 8.5,19.2C9.57,19.71 10.75,20 12,20A8,8 0 0,0 20,12L19.96,11.16L21.95,10.95L22,12A10,10 0 0,1 12,22C10.31,22 8.72,21.58 7.33,20.84C6.84,21.17 6.26,21.36 5.64,21.36C4,21.36 2.64,20 2.64,18.36C2.64,16.71 4,15.36 5.64,15.36M5.64,17.36C5.08,17.36 4.64,17.81 4.64,18.36C4.64,18.92 5.08,19.36 5.64,19.36A1,1 0 0,0 6.64,18.36A1,1 0 0,0 5.64,17.36M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8Z" /> | <path fill="currentColor" d="M18.36,2.64C20,2.64 21.36,4 21.36,5.64C21.36,7.29 20,8.64 18.36,8.64C16.71,8.64 15.36,7.29 15.36,5.64C15.36,5.34 15.41,5.06 15.5,4.8C14.43,4.29 13.25,4 12,4A8,8 0 0,0 4,12L4.04,12.84L2.05,13.05L2,12A10,10 0 0,1 12,2C13.69,2 15.28,2.42 16.67,3.16C17.16,2.83 17.74,2.64 18.36,2.64M18.36,4.64A1,1 0 0,0 17.36,5.64A1,1 0 0,0 18.36,6.64C18.92,6.64 19.36,6.19 19.36,5.64C19.36,5.08 18.92,4.64 18.36,4.64M5.64,15.36C7.29,15.36 8.64,16.71 8.64,18.36C8.64,18.66 8.59,18.94 8.5,19.2C9.57,19.71 10.75,20 12,20A8,8 0 0,0 20,12L19.96,11.16L21.95,10.95L22,12A10,10 0 0,1 12,22C10.31,22 8.72,21.58 7.33,20.84C6.84,21.17 6.26,21.36 5.64,21.36C4,21.36 2.64,20 2.64,18.36C2.64,16.71 4,15.36 5.64,15.36M5.64,17.36C5.08,17.36 4.64,17.81 4.64,18.36C4.64,18.92 5.08,19.36 5.64,19.36A1,1 0 0,0 6.64,18.36A1,1 0 0,0 5.64,17.36M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8Z" /> | ||||
| </svg> | </svg> | ||||
| 数据挖掘 | |||||
| {{.i18n.Tr "explore.data_mining"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq $.Topic "RISC-V"}}active {{end}}item" href="/explore/repos?q=&topic=RISC-V&sort={{.SortType}}"> | <a class="{{if eq $.Topic "RISC-V"}}active {{end}}item" href="/explore/repos?q=&topic=RISC-V&sort={{.SortType}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | <svg class="svg octicon-inbox" width="16" height="16" viewBox="0 0 24 24"> | ||||
| <path fill="currentColor" d="M17,17H7V7H17M21,11V9H19V7C19,5.89 18.1,5 17,5H15V3H13V5H11V3H9V5H7C5.89,5 5,5.89 5,7V9H3V11H5V13H3V15H5V17A2,2 0 0,0 7,19H9V21H11V19H13V21H15V19H17A2,2 0 0,0 19,17V15H21V13H19V11M13,13H11V11H13M15,9H9V15H15V9Z" /> | <path fill="currentColor" d="M17,17H7V7H17M21,11V9H19V7C19,5.89 18.1,5 17,5H15V3H13V5H11V3H9V5H7C5.89,5 5,5.89 5,7V9H3V11H5V13H3V15H5V17A2,2 0 0,0 7,19H9V21H11V19H13V21H15V19H17A2,2 0 0,0 19,17V15H21V13H19V11M13,13H11V11H13M15,9H9V15H15V9Z" /> | ||||
| </svg> | </svg> | ||||
| RISC-V开发 | |||||
| </a> | |||||
| {{.i18n.Tr "explore.RISC-V_development"}} | |||||
| </a> | |||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| @@ -44,13 +44,13 @@ | |||||
| <svg class="svg octicon-repo" width="16" height="16" aria-hidden="true"> | <svg class="svg octicon-repo" width="16" height="16" aria-hidden="true"> | ||||
| <use xlink:href="#octicon-repo" /> | <use xlink:href="#octicon-repo" /> | ||||
| </svg> | </svg> | ||||
| 热门{{.i18n.Tr "explore.repos"}} | |||||
| {{.i18n.Tr "explore.hot_repo"}} | |||||
| </a> | </a> | ||||
| <a class="{{if eq .SortType "active"}}active{{end}} item" href="{{$.Link}}?q={{$.Keyword}}&topic={{$.Topic}}&sort=active&tab={{$.TabName}}"> | <a class="{{if eq .SortType "active"}}active{{end}} item" href="{{$.Link}}?q={{$.Keyword}}&topic={{$.Topic}}&sort=active&tab={{$.TabName}}"> | ||||
| <svg class="svg octicon-inbox" width="16" height="16" aria-hidden="true"> | <svg class="svg octicon-inbox" width="16" height="16" aria-hidden="true"> | ||||
| <use xlink:href="#octicon-inbox" /> | <use xlink:href="#octicon-inbox" /> | ||||
| </svg> | </svg> | ||||
| 活跃{{.i18n.Tr "explore.repos"}} | |||||
| {{.i18n.Tr "explore.active_repo"}} | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| <a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?q={{$.Keyword}}&topic={{$.Topic}}&sort=recentupdate&tab={{$.TabName}}"> | <a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?q={{$.Keyword}}&topic={{$.Topic}}&sort=recentupdate&tab={{$.TabName}}"> | ||||
| @@ -10,7 +10,19 @@ | |||||
| <div class="ui sixteen wide mobile twelve wide tablet ten wide computer column"> | <div class="ui sixteen wide mobile twelve wide tablet ten wide computer column"> | ||||
| {{template "explore/repo_list" .}} | {{template "explore/repo_list" .}} | ||||
| {{template "base/paginate" .}} | |||||
| <div id="app" style="margin-top: 2rem;"> | |||||
| <div class="center"> | |||||
| <el-pagination | |||||
| background | |||||
| @current-change="handleCurrentChange" | |||||
| :current-page="page" | |||||
| :page-sizes="[20]" | |||||
| :page-size="20" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="{{.Page.Paginater.Total}}"> | |||||
| </el-pagination> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="computer only ui three wide computer column"> | <div class="computer only ui three wide computer column"> | ||||
| {{template "explore/repo_right" .}} | {{template "explore/repo_right" .}} | ||||
| @@ -0,0 +1,95 @@ | |||||
| {{template "base/head" .}} | |||||
| <div class="explore seach"> | |||||
| <div class="repos--seach"> | |||||
| <div class="ui container"> | |||||
| <div id="search_div" class="ui two column centered grid"> | |||||
| <div class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin-top:1.2rem;margin-bottom: 1.2rem;"> | |||||
| <div class="ui fluid action input"> | |||||
| <input name="q" id="keyword_input" value="{{.Keyword}}" placeholder="{{.i18n.Tr "home.search"}}..." autofocus=""> | |||||
| <input type="hidden" name="topic" value=""> | |||||
| <input type="hidden" name="tab" value=""> | |||||
| <input type="hidden" name="sort" value="hot"> | |||||
| <button class="ui green button" onclick="search()">{{.i18n.Tr "home.search"}}</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div id="search_label_div" style="display:none"> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui container seachnav"> | |||||
| <div class="ui secondary pointing menu"> | |||||
| <a id="repo_item" class="item" href="javascript:searchItem(1,10);"> | |||||
| {{.i18n.Tr "home.search_repo"}} | |||||
| <span class="ui circular mini label" id="repo_total"></span> | |||||
| </a> | |||||
| <a id="dataset_item" class="item" href="javascript:searchItem(5,50);"> | |||||
| {{.i18n.Tr "home.search_dataset"}} | |||||
| <span class="ui circular mini label" id="dataset_total"></span> | |||||
| </a> | |||||
| <a id="issue_item" class="item" href="javascript:searchItem(2,20);"> | |||||
| {{.i18n.Tr "home.search_issue"}} | |||||
| <span class="ui circular mini label" id="issue_total"></span> | |||||
| </a> | |||||
| <a id="pr_item" class="item" href="javascript:searchItem(6,60);"> | |||||
| {{.i18n.Tr "home.search_pr"}} | |||||
| <span class="ui circular mini label" id="pr_total"></span> | |||||
| </a> | |||||
| <a id="user_item" class="item" href="javascript:searchItem(3,30);"> | |||||
| {{.i18n.Tr "home.search_user"}} | |||||
| <span class="ui circular mini label" id="user_total"></span> | |||||
| </a> | |||||
| <a id="org_item" class="item" href="javascript:searchItem(4,40);"> | |||||
| {{.i18n.Tr "home.search_org"}} <span class="ui circular mini label" id="org_total"></span> | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui container"> | |||||
| <span id="find_id">{{.i18n.Tr "home.search_finded"}}</span><span id="find_title"></span> | |||||
| <div class="ui right floated secondary filter menu"> | |||||
| <!-- Sort --> | |||||
| <div class="ui right dropdown type jump item"> | |||||
| <span class="text"> | |||||
| {{.i18n.Tr "repo.issues.filter_sort"}} | |||||
| <i class="dropdown icon"></i> | |||||
| </span> | |||||
| <div class="menu" id="sort_type"> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui divider" style="margin-top: 1.25rem;"></div> | |||||
| <div class="ui very relaxed divided list" id="child_search_item"> | |||||
| </div><!--seach list end--> | |||||
| <div class="center page buttons" style="margin: 0px auto 15px"> | |||||
| <div class="ui borderless mini pagination menu" id="page_menu"> | |||||
| </div> | |||||
| </div> | |||||
| <div id="tipmsg"></div> | |||||
| </div> | |||||
| </div> | |||||
| <script src="/self/js/jquery.min.js" type="text/javascript"></script> | |||||
| <script src="/home/search.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
| <div class="am-mt-30"></div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,45 @@ | |||||
| <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> | |||||
| {{template "base/head" .}} | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <input type="hidden" id="dataset-file-desc" value="{{.Attachment.Description}}"> | |||||
| <div style="width: 80%;margin: auto;"> | |||||
| <h4 class="ui top attached header"> | |||||
| {{$.i18n.Tr "dataset.modify_dataset_description"}} | |||||
| </h4> | |||||
| <div class="ui attached segment" style="padding: 2em 3em;"> | |||||
| <div class="ui form" id="dataset-base"> | |||||
| <el-form label-width="140px"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.dataset_available_clusters"}}:' prop="title"> | |||||
| <span style="display: flex;color: #3291F8;"><i class="ri-archive-drawer-line" style="margin-right: 10px;"></i>{{.Attachment.Type | AttachmentResourceType}}</span> | |||||
| <!-- <span>请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> --> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.file"}}:' prop="description"> | |||||
| <span>{{.Attachment.Name}}</span> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.file_description"}}:' prop="description"> | |||||
| <el-input type="textarea" :rows="3" maxlength="255" placeholder="{{$.i18n.Tr "repo.modelarts.train_job.new_place"}}" v-model="descfile"></el-input> | |||||
| </el-form-item> | |||||
| <el-form-item> | |||||
| <el-button style="background-color: #21ba45;" type="success" @click="editDatasetFile({{.Attachment.ID}},'{{$.RepoLink}}')">确定</el-button> | |||||
| <el-button type="info" @click="cancelDataset('','{{$.RepoLink}}')">取消</el-button> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,73 @@ | |||||
| {{template "base/head" .}} | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <input type="hidden" id="postPath" value="{{.Link}}"> | |||||
| <div style="width: 80%;margin: auto;"> | |||||
| <h4 class="ui top attached header"> | |||||
| {{$.i18n.Tr "dataset.upload_dataset_file"}} | |||||
| </h4> | |||||
| <div class="ui attached segment" style="padding: 2em 3em;"> | |||||
| <div class="ui form" id="dataset-base"> | |||||
| <el-form label-width="140px"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.dataset_available_clusters"}}:' prop="title"> | |||||
| <el-button :class="{active:type==0}" size="small" style="margin: 0;border-radius: 0.28571429rem 0 0 0.28571429rem;" @click="uploadGpu">CPU/GPU</el-button> | |||||
| <el-button :class="{active:type==1}" size="small" style="margin: 0 0 0 -4px;border-radius: 0 0.28571429rem 0.28571429rem 0;" @click="uploadNpu">NPU</el-button> | |||||
| <!-- <span>请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> --> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.file_description"}}:' prop="description"> | |||||
| <el-input type="textarea" :rows="3" maxlength="255" placeholder="{{$.i18n.Tr "repo.modelarts.train_job.new_place"}}" v-model="desc"></el-input> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{$.i18n.Tr "dataset.data_upload"}}:' prop="category"> | |||||
| <minio-uploader :uploadtype="type" :desc="desc"></minio-uploader> | |||||
| </el-form-item> | |||||
| <div style='display:none;' | |||||
| id="minioUploader-params" | |||||
| data-uuid="{{.uuid}}" | |||||
| data-add-url="{{.Repository.OwnerName}}/attachments/add" | |||||
| data-accepts="{{.AttachmentAllowedTypes}}" | |||||
| data-remove-url="{{AppSubUrl}}/attachments/delete" | |||||
| data-csrf="{{.CsrfToken}}" | |||||
| dataset-id={{.dataset.ID}} | |||||
| data-max-file="100" | |||||
| data-dataset-id="{{.dataset.ID}}" | |||||
| data-max-size="{{.AttachmentMaxSize}}" | |||||
| data-default-message="{{.i18n.Tr "dropzone.default_message"}}" | |||||
| data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" | |||||
| data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" | |||||
| data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}" | |||||
| data-file-status='{{.i18n.Tr "dropzone.file_status"}}' | |||||
| data-file-init-status='{{.i18n.Tr "dropzone.file_init_status"}}' | |||||
| data-waitting-uploading='{{.i18n.Tr "dropzone.waitting_uploading"}}' | |||||
| data-md5-computing='{{.i18n.Tr "dropzone.md5_computing"}}' | |||||
| data-obs-connecting='{{.i18n.Tr "dropzone.obs-connecting"}}' | |||||
| data-loading-file='{{.i18n.Tr "dropzone.loading_file"}}' | |||||
| data-upload-complete='{{.i18n.Tr "dropzone.upload_complete"}}' | |||||
| data-uploading='{{.i18n.Tr "dropzone.uploading"}}' | |||||
| data-failed='{{.i18n.Tr "dropzone.failed"}}' | |||||
| data-repopath='{{AppSubUrl}}{{$.RepoLink}}/datasets' | |||||
| data-cancel='{{.i18n.Tr "cancel"}}' | |||||
| data-upload='{{.i18n.Tr "dataset.dataset_upload"}}' | |||||
| > | |||||
| </div> | |||||
| <div id="datasetId" datasetId="{{.datasetId}}"></div> | |||||
| </el-form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div style="width: 80%;margin: auto;padding-top: 2em;"> | |||||
| <!-- <p>说明:<br> | |||||
| - 只有<span class="text blue">zip格式</span>zip格式的数据集才能发起云脑任务;<br> | |||||
| - 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。 | |||||
| </p> --> | |||||
| <p style="color: 505559;">{{$.i18n.Tr "dataset.illustrate"}}:</p> | |||||
| <p style="line-height: 1.5;color: #101010;">{{$.i18n.Tr "dataset.illustrate.only"}}<span class="text red"> {{$.i18n.Tr "dataset.illustrate.zip"}} </span>{{$.i18n.Tr "dataset.illustrate.fisrt_end"}};</br> | |||||
| {{$.i18n.Tr "dataset.dataset_explain"}}</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -39,8 +39,8 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="column right aligned"> | <div class="column right aligned"> | ||||
| <a class="ui compact orange basic icon button" href="https://openi.org.cn/projects/Benchmark/#algType" style="box-shadow: none;" target="_blank"><i class="large ri-trophy-fill middle aligned icon"></i>基准测试排行榜</a> | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui compact orange basic icon button" href="https://openi.org.cn/projects/Benchmark/#algType" style="box-shadow: none;" target="_blank"><i class="large ri-trophy-fill middle aligned icon"></i>{{$.i18n.Tr "repo.benchmark_leaderboards"}}</a> | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/benchmark/create">{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a> | <a class="ui green button" href="{{.RepoLink}}/cloudbrain/benchmark/create">{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a> | <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a> | ||||
| @@ -50,12 +50,12 @@ | |||||
| {{if eq 0 (len .Tasks)}} | {{if eq 0 (len .Tasks)}} | ||||
| <div class="ui placeholder segment bgtask-none"> | <div class="ui placeholder segment bgtask-none"> | ||||
| <div class="ui icon header bgtask-header-pic"></div> | <div class="ui icon header bgtask-header-pic"></div> | ||||
| <div class="bgtask-content-header">未创建过评测任务</div> | |||||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.model_Evaluation_not_created"}}</div> | |||||
| <div class="bgtask-content"> | <div class="bgtask-content"> | ||||
| {{if $.RepoIsEmpty}} | {{if $.RepoIsEmpty}} | ||||
| <div class="bgtask-content-txt">代码版本:您还没有初始化代码仓库,请先<a href="{{.RepoLink}}">创建代码版本;</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||||
| {{end}} | {{end}} | ||||
| <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{else}} | ||||
| @@ -85,21 +85,21 @@ | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> | </div> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | </div> | ||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.Cloudbrain.ID}}" style="font-size: 14px;"> | <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.Cloudbrain.ID}}" style="font-size: 14px;"> | ||||
| @@ -122,12 +122,12 @@ | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.Cloudbrain.ID}}">{{.TrainJobDuration}}</span> | |||||
| <div class="one wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.Cloudbrain.ID}}">{{.TrainJobDuration}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| </div> | </div> | ||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| @@ -139,7 +139,7 @@ | |||||
| </div> | </div> | ||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <div class="ui compact buttons" > | |||||
| <div class="ui compact buttons" > | |||||
| <!-- 停止任务 --> | <!-- 停止任务 --> | ||||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| @@ -147,7 +147,7 @@ | |||||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | ||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui basic disabled button"> | <a class="ui basic disabled button"> | ||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| @@ -155,9 +155,9 @@ | |||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | ||||
| 评分 | |||||
| {{$.i18n.Tr "repo.score"}} | |||||
| </a> | </a> | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | ||||
| <input type="hidden" name="debugListType" value="all"> | <input type="hidden" name="debugListType" value="all"> | ||||
| @@ -171,21 +171,33 @@ | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | |||||
| </form> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | |||||
| {{end}} | |||||
| <!-- | <!-- | ||||
| <div class="" style="margin-top: 3.0em;"> | <div class="" style="margin-top: 3.0em;"> | ||||
| <img class="ui middle aligned tiny image" src="/img/ranking_list.jpg"> | |||||
| <img class="ui middle aligned tiny image" src="/img/ranking_list.jpg"> | |||||
| <a class="ui blue" href="{{$.RepoLink}}/cloudbrain/123/rate?isObjectDetcionAll=true" target="_blank">目标检测算法排行榜</a> | <a class="ui blue" href="{{$.RepoLink}}/cloudbrain/123/rate?isObjectDetcionAll=true" target="_blank">目标检测算法排行榜</a> | ||||
| </div> | </div> | ||||
| --> | --> | ||||
| {{template "base/paginate" .}} | |||||
| <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> | ||||
| @@ -204,18 +216,18 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -78,8 +78,8 @@ | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="254"> | <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="254"> | ||||
| @@ -90,7 +90,7 @@ | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">GPU类型</label> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | ||||
| {{range .benchmark_gpu_types}} | {{range .benchmark_gpu_types}} | ||||
| <option value="{{.Queue}}">{{.Value}}</option> | <option value="{{.Queue}}">{{.Value}}</option> | ||||
| @@ -124,7 +124,7 @@ | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label> | ||||
| <span> </span> | <span> </span> | ||||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像或输入镜像地址" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||||
| <input type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | ||||
| <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | ||||
| {{range .images}} | {{range .images}} | ||||
| @@ -136,13 +136,13 @@ | |||||
| </datalist> | </datalist> | ||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">资源规格</label> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="resource_spec_id"> | |||||
| {{range .benchmark_resource_specs}} | {{range .benchmark_resource_specs}} | ||||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| <option name="resource_spec_id" value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -150,25 +150,25 @@ | |||||
| <div class="inline unite min_title field required"> | <div class="inline unite min_title field required"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | ||||
| <input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" value="train.py" tabindex="3" autofocus required maxlength="254" > | <input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" value="train.py" tabindex="3" autofocus required maxlength="254" > | ||||
| <a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||||
| <a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</a> | |||||
| </div> | </div> | ||||
| <div class="inline unite min_title field required"> | <div class="inline unite min_title field required"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | ||||
| <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" tabindex="3" autofocus required maxlength="254" > | <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" tabindex="3" autofocus required maxlength="254" > | ||||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">查看样例</a> | |||||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | </div> | ||||
| <!-- 模态框 --> | <!-- 模态框 --> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -217,7 +217,7 @@ | |||||
| setChildType(); | setChildType(); | ||||
| } | } | ||||
| } | } | ||||
| function validate(){ | function validate(){ | ||||
| $('.ui.form') | $('.ui.form') | ||||
| .form({ | .form({ | ||||
| @@ -239,7 +239,7 @@ | |||||
| // $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| }, | }, | ||||
| onFailure: function(e){ | |||||
| onFailure: function(e){ | |||||
| return false; | return false; | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -247,6 +247,6 @@ | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| validate() | |||||
| validate() | |||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -82,7 +82,7 @@ | |||||
| vertical-align: inherit; | vertical-align: inherit; | ||||
| } | } | ||||
| .ti-text-form-label { | .ti-text-form-label { | ||||
| padding-bottom: 20px; | padding-bottom: 20px; | ||||
| padding-right: 20px; | padding-right: 20px; | ||||
| color: #8a8e99; | color: #8a8e99; | ||||
| @@ -152,7 +152,7 @@ td, th { | |||||
| opacity: .45 !important; | opacity: .45 !important; | ||||
| } | } | ||||
| .pad20{ | .pad20{ | ||||
| border:0px !important; | border:0px !important; | ||||
| } | } | ||||
| .model_file_bread{ | .model_file_bread{ | ||||
| @@ -196,14 +196,20 @@ td, th { | |||||
| <span class="accordion-panel-title-content"> | <span class="accordion-panel-title-content"> | ||||
| <span> | <span> | ||||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | <div class="ac-display-inblock title_text acc-margin-bottom"> | ||||
| <span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| <span class="cti-mgRight-sm"> | |||||
| {{if not (eq .StartTime 0)}} | |||||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||||
| {{else}} | |||||
| <td>{{TimeSinceUnix1 .CreatedUnix}}<td> | |||||
| {{end}} | |||||
| </span> | |||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | ||||
| <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | ||||
| </span> | </span> | ||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | ||||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | ||||
| </div> | </div> | ||||
| </span> | </span> | ||||
| </span> | </span> | ||||
| @@ -244,23 +250,29 @@ td, th { | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| <span style="font-size: 12px;" class=""> | |||||
| {{if not (eq .StartTime 0)}} | |||||
| {{TimeSinceUnix1 .StartTime}} | |||||
| {{else}} | |||||
| {{TimeSinceUnix1 .CreatedUnix}} | |||||
| {{end}} | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | ||||
| {{$.duration}} | {{$.duration}} | ||||
| @@ -269,9 +281,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 镜像 | |||||
| 镜像 | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | {{.Image}} | ||||
| @@ -280,30 +292,30 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 类型 | |||||
| 类型 | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | ||||
| {{$.BenchmarkTypeName}} | {{$.BenchmarkTypeName}} | ||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| </tbody> | </tbody> | ||||
| </table> | </table> | ||||
| </div> | </div> | ||||
| <div class="ac-grid-col"> | <div class="ac-grid-col"> | ||||
| <table class="ti-form"> | <table class="ti-form"> | ||||
| <tbody class="ti-text-form"> | <tbody class="ti-text-form"> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 训练程序 | 训练程序 | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| train.py | train.py | ||||
| @@ -314,19 +326,19 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 测试程序 | 测试程序 | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| test.py | test.py | ||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" title="{{.Description}}"> | <div class="text-span text-span-w" title="{{.Description}}"> | ||||
| {{.Description}} | {{.Description}} | ||||
| @@ -336,9 +348,9 @@ td, th { | |||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{$.resource_spec}} | {{$.resource_spec}} | ||||
| @@ -348,9 +360,9 @@ td, th { | |||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 创建者 | |||||
| 创建者 | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.User.Name}} | {{.User.Name}} | ||||
| @@ -359,9 +371,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 子类型 | |||||
| 子类型 | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkChildTypeName"> | <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkChildTypeName"> | ||||
| {{$.BenchmarkChildTypeName}} | {{$.BenchmarkChildTypeName}} | ||||
| @@ -373,7 +385,7 @@ td, th { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="second{{$k}}"> | <div class="ui tab" data-tab="second{{$k}}"> | ||||
| @@ -386,11 +398,11 @@ td, th { | |||||
| <input type="hidden" name="start_line" value> | <input type="hidden" name="start_line" value> | ||||
| <pre id="log_file{{.VersionName}}"></pre> | <pre id="log_file{{.VersionName}}"></pre> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -400,24 +412,24 @@ td, th { | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| @@ -430,7 +442,7 @@ td, th { | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| $('.secondary.menu .item').tab(); | $('.secondary.menu .item').tab(); | ||||
| }); | }); | ||||
| let userName | let userName | ||||
| let repoPath | let repoPath | ||||
| let jobName | let jobName | ||||
| @@ -454,5 +466,5 @@ td, th { | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| }); | }); | ||||
| } | } | ||||
| </script> | |||||
| </script> | |||||
| @@ -101,6 +101,7 @@ | |||||
| } | } | ||||
| </style> | </style> | ||||
| <div id="mask"> | <div id="mask"> | ||||
| @@ -116,6 +117,7 @@ | |||||
| <div class="repository"> | <div class="repository"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <div class="repository new repo ui middle very relaxed page grid"> | <div class="repository new repo ui middle very relaxed page grid"> | ||||
| <div class="column"> | <div class="column"> | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="ui negative message" id="messageInfo"> | <div class="ui negative message" id="messageInfo"> | ||||
| @@ -147,12 +149,12 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | ||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="input {{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | ||||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="select {{.i18n.Tr "cloudbrain.task_type"}}" style='width:385px' name="job_type"> | |||||
| <option name="job_type" value="DEBUG">DEBUG</option> | <option name="job_type" value="DEBUG">DEBUG</option> | ||||
| {{if .is_snn4imagenet_enabled}} | {{if .is_snn4imagenet_enabled}} | ||||
| <option name="job_type" value="SNN4IMAGENET">SNN4IMAGENET</option> | <option name="job_type" value="SNN4IMAGENET">SNN4IMAGENET</option> | ||||
| @@ -200,22 +202,13 @@ | |||||
| {{end}} | {{end}} | ||||
| </datalist> | </datalist> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | |||||
| <label>{{.i18n.Tr "cloudbrain.dataset"}}</label> | |||||
| <select id="cloudbrain_dataset" class="ui search dropdown" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||||
| {{range .attachments}} | |||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| {{template "custom/select_dataset" .}} | |||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="resource_spec_id"> | |||||
| {{range .resource_specs}} | {{range .resource_specs}} | ||||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| <option name="resource_spec_id" value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -354,4 +347,5 @@ | |||||
| $('#store_category').attr("value", selected_value) | $('#store_category').attr("value", selected_value) | ||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -74,11 +74,19 @@ | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td> 开始时间 </td> | <td> 开始时间 </td> | ||||
| <td>{{.JobStatus.StartTime}}</td> | |||||
| {{if not (eq $.task.StartTime 0)}} | |||||
| <td>{{TimeSinceUnix1 $.task.StartTime}}</td> | |||||
| {{else}} | |||||
| <td>无<td> | |||||
| {{end}} | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td> 结束时间 </td> | <td> 结束时间 </td> | ||||
| <td>{{.JobStatus.EndTime}}</td> | |||||
| {{if not (eq $.task.EndTime 0)}} | |||||
| <td>{{TimeSinceUnix1 $.task.EndTime}}</td> | |||||
| {{else}} | |||||
| <td>无<td> | |||||
| {{end}} | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td> ExitCode </td> | <td> ExitCode </td> | ||||
| @@ -0,0 +1,451 @@ | |||||
| {{template "base/head" .}} | |||||
| <style> | |||||
| .unite{ | |||||
| font-family: SourceHanSansSC-medium !important; | |||||
| color: rgba(16, 16, 16, 100) !important; | |||||
| } | |||||
| .title{ | |||||
| font-size: 16px !important; | |||||
| padding-left: 3rem !important; | |||||
| } | |||||
| .min_title{ | |||||
| font-size: 14px !important; | |||||
| padding-left: 6rem !important; | |||||
| margin-bottom: 2rem !important; | |||||
| } | |||||
| .width{ | |||||
| width:100% !important; | |||||
| } | |||||
| .width80{ | |||||
| width: 80.7% !important; | |||||
| margin-left: 10px; | |||||
| } | |||||
| .width806{ | |||||
| width: 80.6% !important; | |||||
| margin-left: -2px; | |||||
| } | |||||
| .width85{ | |||||
| width: 85% !important; | |||||
| margin-left: 4.5rem !important; | |||||
| } | |||||
| .width81{ | |||||
| margin-left: 1.5rem !important; | |||||
| width: 81% !important; | |||||
| } | |||||
| .add{font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 0px 5px 5px 0px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| .min{ | |||||
| font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 5px 0px 0px 5px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| </style> | |||||
| <!-- <div class="ui page dimmer"> | |||||
| <div class="ui text loader">{{.i18n.Tr "loading"}}</div> | |||||
| </div> --> | |||||
| <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="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| {{template "base/alert" .}} | |||||
| <h4 class="ui top attached header"> | |||||
| {{.i18n.Tr "repo.modelarts.train_job.new"}} | |||||
| </h4> | |||||
| <div class="ui attached segment"> | |||||
| <!-- equal width --> | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <input type="hidden" name="action" value="update"> | |||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||||
| <a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| </svg> | |||||
| CPU/GPU | |||||
| </a> | |||||
| <a class="item" href="{{.RepoLink}}/modelarts/train-job/create"> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| </svg> | |||||
| Ascend NPU</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| </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="255" 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> | |||||
| </div> | |||||
| <div class="ui divider"></div> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
| <select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
| {{if .branch_name}} | |||||
| <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branch_name }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| <option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branchName }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="inline required field" style="display: none;"> | |||||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
| <option name="job_type" value="TRAIN">TRAIN</option> | |||||
| </select> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
| <select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||||
| {{range .train_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="required unite min_title inline field" style="position: relative;"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}} </label> | |||||
| <input class="width81" type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||||
| <datalist class="ui search" id="cloudbrain_image" name="image"> | |||||
| {{range .images}} | |||||
| <option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
| {{end}} | |||||
| {{range .public_images}} | |||||
| <option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
| {{end}} | |||||
| </datalist> | |||||
| </div> | |||||
| <div class="inline unite min_title field required"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
| {{if .bootFile}} | |||||
| <input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | |||||
| <input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
| {{end}} | |||||
| <span> | |||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
| </span> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> | |||||
| </div> | |||||
| <div class="required unite min_title inline field" style="position: relative;"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.dataset"}}</label> | |||||
| <select id="cloudbrain_dataset" class="ui search dropdown width80" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||||
| {{range .attachments}} | |||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| <span class="tooltips">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||||
| </div> | |||||
| <div class="inline unite min_title field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||||
| <div class="dynamic field" style="margin-top: 1rem;"> | |||||
| {{if .params}} | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="required inline unite min_title field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
| {{range .train_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="inline unite min_title field"> | |||||
| <button class="ui create_train_job green button"> | |||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||||
| </button> | |||||
| <a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
| </div> | |||||
| <!-- 模态框 --> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| //let url_href = window.location.pathname.split('create')[0] | |||||
| //$(".ui.button").attr('href',url_href) | |||||
| $('select.dropdown') | |||||
| .dropdown(); | |||||
| $('.menu .item') | |||||
| .tab(); | |||||
| let sever_num = $('#trainjob_work_server_num') | |||||
| $('.add').click(function(){ | |||||
| sever_num.val(parseInt(sever_num.val())+1) | |||||
| if(sever_num.val()>=26){ | |||||
| sever_num.val(parseInt(sever_num.val())-1) | |||||
| } | |||||
| }) | |||||
| $('.min').click(function(){ | |||||
| sever_num.val(parseInt(sever_num.val())-1) | |||||
| if(sever_num.val()<=0){ | |||||
| sever_num.val(parseInt(sever_num.val())+1) | |||||
| } | |||||
| }) | |||||
| // 参数增加、删除、修改、保存 | |||||
| function Add_parameter(i){ | |||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>'+ | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| $(".dynamic.field").append(value) | |||||
| } | |||||
| $('#add_run_para').click(function(){ | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| }); | |||||
| $(".dynamic.field").on("click",".trash.icon", function() { | |||||
| var index = $(this).parent().parent().index() | |||||
| $(this).parent().parent().remove() | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| var cur_index = $(this).index() | |||||
| $(this).attr('id', 'para' + cur_index) | |||||
| }) | |||||
| }); | |||||
| $('.ui.parameter.green.button').click(function(){ | |||||
| var parameters = []; | |||||
| $('table tr').each(function() { | |||||
| $(this).find('td:eq(1)').each(function(){ | |||||
| parameters.push($(this).text()); | |||||
| }) | |||||
| $(this).find('input').each(function(){ | |||||
| parameters.push($(this).text()) | |||||
| }) | |||||
| }); | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| for(var i = 2; i < parameters.length; i++){ | |||||
| switch(i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for(var j = 0; j < para.length; j++){ | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| } | |||||
| }) | |||||
| $('.ui.save.checkbox').click(function(){ | |||||
| $(this).checkbox({ | |||||
| onChange: function(){ | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
| $('#save_para').removeClass("disabled") | |||||
| }else{ | |||||
| $('#save_para').addClass("disabled") | |||||
| } | |||||
| } | |||||
| }); | |||||
| }) | |||||
| $('.question.circle.icon').hover(function(){ | |||||
| $(this).popup('show') | |||||
| }); | |||||
| $(".item.active.parameter_config").click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('setting', 'closable', false) | |||||
| .modal('show'); | |||||
| }) | |||||
| $('.ui.deny.button').click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| }) | |||||
| $('select.dropdown') | |||||
| .dropdown(); | |||||
| function validate(){ | |||||
| $('.ui.form') | |||||
| .form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| boot_file: { | |||||
| identifier : 'boot_file', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/.+\.py$/g]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment:{ | |||||
| identifier : 'attachment', | |||||
| rules: [ | |||||
| { | |||||
| type: 'empty', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| work_server_number: { | |||||
| identifier : 'work_server_number', | |||||
| rules: [ | |||||
| { | |||||
| type : 'integer[1..25]', | |||||
| } | |||||
| ] | |||||
| } | |||||
| }, | |||||
| onSuccess: function(){ | |||||
| // $('.ui.page.dimmer').dimmer('show') | |||||
| document.getElementById("mask").style.display = "block" | |||||
| }, | |||||
| onFailure: function(e){ | |||||
| return false; | |||||
| } | |||||
| }) | |||||
| } | |||||
| document.onreadystatechange = function() { | |||||
| if (document.readyState === "complete") { | |||||
| document.getElementById("mask").style.display = "none" | |||||
| } | |||||
| } | |||||
| function send_run_para(){ | |||||
| var run_parameters = [] | |||||
| var msg = {} | |||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
| run_parameters.push({"label": para_name, "value": para_value}) | |||||
| }) | |||||
| msg["parameter"] = run_parameters | |||||
| msg = JSON.stringify(msg) | |||||
| $('#store_run_para').val(msg) | |||||
| } | |||||
| function get_name(){ | |||||
| let name1=$("#engine_name .text").text() | |||||
| let name2=$("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | |||||
| $("input#ai_flaver_name").val(name2) | |||||
| } | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | |||||
| get_name() | |||||
| send_run_para() | |||||
| validate() | |||||
| }) | |||||
| </script> | |||||
| @@ -0,0 +1,653 @@ | |||||
| {{template "base/head" .}} | |||||
| <style> | |||||
| .according-panel-heading{ | |||||
| box-sizing: border-box; | |||||
| padding: 8px 16px; | |||||
| color: #252b3a; | |||||
| background-color: #f2f5fc; | |||||
| line-height: 1.5; | |||||
| cursor: pointer; | |||||
| -moz-user-select: none; | |||||
| -webkit-user-select: none; | |||||
| -ms-user-select: none; | |||||
| -khtml-user-select: none; | |||||
| user-select: none; | |||||
| } | |||||
| .accordion-panel-title { | |||||
| margin-top: 0; | |||||
| margin-bottom: 0; | |||||
| color: #252b3a; | |||||
| } | |||||
| .accordion-panel-title-content{ | |||||
| vertical-align: middle; | |||||
| display: inline-block; | |||||
| width: calc(100% - 32px); | |||||
| cursor: default; | |||||
| } | |||||
| .acc-margin-bottom { | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| .title_text { | |||||
| font-size: 12px; | |||||
| } | |||||
| .ac-display-inblock { | |||||
| display: inline-block; | |||||
| } | |||||
| .cti-mgRight-sm { | |||||
| margin-right: 8px; | |||||
| } | |||||
| .ac-text-normal { | |||||
| font-size: 14px; | |||||
| color: #575d6c; | |||||
| } | |||||
| .uc-accordionTitle-black { | |||||
| color: #333; | |||||
| } | |||||
| .accordion-border{ | |||||
| border:1px solid #cce2ff; | |||||
| } | |||||
| .padding0{ | |||||
| padding: 0 !important; | |||||
| } | |||||
| .content-pad{ | |||||
| padding: 15px 35px; | |||||
| } | |||||
| .content-margin{ | |||||
| margin:10px 5px ; | |||||
| } | |||||
| .tab_2_content { | |||||
| min-height: 360px; | |||||
| margin-left: 10px; | |||||
| } | |||||
| .ac-grid { | |||||
| display: block; | |||||
| *zoom: 1; | |||||
| } | |||||
| .ac-grid-col { | |||||
| float: left; | |||||
| width: 100%; | |||||
| } | |||||
| .ac-grid-col2 .ac-grid-col { | |||||
| width: 50%; | |||||
| } | |||||
| .ti-form { | |||||
| text-align: left; | |||||
| max-width: 100%; | |||||
| vertical-align: middle; | |||||
| } | |||||
| .ti-form>tbody { | |||||
| font-size: 12px; | |||||
| } | |||||
| .ti-form>tbody, .ti-form>tbody>tr { | |||||
| vertical-align: inherit; | |||||
| } | |||||
| .ti-text-form-label { | |||||
| padding-bottom: 20px; | |||||
| padding-right: 20px; | |||||
| color: #8a8e99; | |||||
| font-size: 12px; | |||||
| white-space: nowrap !important; | |||||
| width: 80px; | |||||
| line-height: 30px; | |||||
| } | |||||
| .ti-text-form-content{ | |||||
| line-height: 30px; | |||||
| padding-bottom: 20px; | |||||
| } | |||||
| .ti-form>tbody>tr>td { | |||||
| vertical-align: top; | |||||
| white-space: normal; | |||||
| } | |||||
| td, th { | |||||
| padding: 0; | |||||
| } | |||||
| .ac-grid-col .text-span { | |||||
| width: 450px; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| white-space: nowrap; | |||||
| } | |||||
| .redo-color{ | |||||
| color: #3291F8; | |||||
| } | |||||
| .ti-action-menu-item:not(:last-child){ | |||||
| margin-right: 10px; | |||||
| padding-right: 11px; | |||||
| text-decoration: none!important; | |||||
| color: #526ecc; | |||||
| cursor: pointer; | |||||
| display: inline-block; | |||||
| -moz-user-select: none; | |||||
| -webkit-user-select: none; | |||||
| -ms-user-select: none; | |||||
| -khtml-user-select: none; | |||||
| user-select: none; | |||||
| position: relative; | |||||
| } | |||||
| .ti-action-menu-item:not(:last-child):after { | |||||
| content: ""; | |||||
| display: inline-block; | |||||
| position: absolute; | |||||
| height: 12px; | |||||
| right: 0; | |||||
| top: 50%; | |||||
| -webkit-transform: translateY(-6px); | |||||
| -ms-transform: translateY(-6px); | |||||
| -o-transform: translateY(-6px); | |||||
| transform: translateY(-6px); | |||||
| border-right: 1px solid #dfe1e6; | |||||
| } | |||||
| .text-width80{ | |||||
| width: 100px; | |||||
| line-height: 30px; | |||||
| } | |||||
| .border-according{ | |||||
| border: 1px solid #dfe1e6; | |||||
| } | |||||
| .disabled { | |||||
| cursor: default; | |||||
| pointer-events: none; | |||||
| color: rgba(0,0,0,.6) !important; | |||||
| opacity: .45 !important; | |||||
| } | |||||
| .pad20{ | |||||
| border:0px !important; | |||||
| } | |||||
| .model_file_bread{ | |||||
| margin-bottom: -0.5rem !important; | |||||
| padding-left: 1rem; | |||||
| padding-top: 0.5rem ; | |||||
| } | |||||
| </style> | |||||
| <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="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <h4 class="ui header" id="vertical-segment"> | |||||
| <div class="ui breadcrumb"> | |||||
| <a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||||
| {{.i18n.Tr "repo.cloudbrain"}} | |||||
| </a> | |||||
| <div class="divider"> / </div> | |||||
| <a class="section" href="{{$.RepoLink}}/modelarts/train-job"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job"}} | |||||
| </a> | |||||
| <div class="divider"> / </div> | |||||
| <div class="active section">{{.displayJobName}}</div> | |||||
| </div> | |||||
| </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"> | |||||
| <i class="dropdown icon"></i> | |||||
| <span class="accordion-panel-title-content"> | |||||
| <span> | |||||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||||
| <span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||||
| <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | |||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||||
| </div> | |||||
| </span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="{{if eq $k 0}}active{{end}} content"> | |||||
| <div class="content-pad"> | |||||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||||
| <a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||||
| <a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||||
| <a class="item" data-tab="third{{$k}}" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||||
| </div> | |||||
| <div class="ui tab active" data-tab="first{{$k}}"> | |||||
| <div style="padding-top: 10px;"> | |||||
| <div class="tab_2_content"> | |||||
| <div class="ac-grid ac-grid-col2"> | |||||
| <div class="ac-grid-col"> | |||||
| <table class="ti-form"> | |||||
| <tbody class="ti-text-form"> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.cloudbrain_task"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.DisplayJobName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||||
| {{.Status}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||||
| {{$.duration}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{$.resource_type}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{$.resource_spec}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div> | |||||
| <div class="ac-grid-col"> | |||||
| <table class="ti-form"> | |||||
| <tbody class="ti-text-form"> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| 镜像 | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||||
| {{.Image}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.BranchName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.BootFile}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.DatasetName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80" > | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" title="{{.Parameters}}"> | |||||
| {{.Parameters}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" title="{{.Description}}"> | |||||
| {{.Description}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui tab" data-tab="second{{$k}}"> | |||||
| <div> | |||||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
| <div id="header"></div> | |||||
| </div> | |||||
| <div class="ui attached log" id="log{{.VersionName}}" style="height: 300px !important; overflow: auto;"> | |||||
| <input type="hidden" name="end_line" value> | |||||
| <input type="hidden" name="start_line" value> | |||||
| <pre id="log_file{{.VersionName}}"></pre> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui tab" data-tab="third{{$k}}"> | |||||
| <input type="hidden" name="model{{.VersionName}}" value="-1"> | |||||
| <input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||||
| <div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||||
| <div class="active section">{{.VersionName}}</div> | |||||
| <div class="divider"> / </div> | |||||
| </div> | |||||
| <div id="dir_list{{.VersionName}}"> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} {{template "base/paginate" .}} | |||||
| </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> | |||||
| $('.menu .item').tab() | |||||
| $(document).ready(function(){ | |||||
| $('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||||
| }); | |||||
| $(document).ready(function(){ | |||||
| $('.secondary.menu .item').tab(); | |||||
| }); | |||||
| let userName | |||||
| let repoPath | |||||
| let jobID | |||||
| let downlaodFlag = {{$.canDownload}} | |||||
| let taskID = {{$.task.ID}} | |||||
| let realJobName = {{$.task.JobName}} | |||||
| $(document).ready(function(){ | |||||
| let url = window.location.href; | |||||
| let urlArr = url.split('/') | |||||
| userName = urlArr.slice(-5)[0] | |||||
| repoPath = urlArr.slice(-4)[0] | |||||
| jobID = urlArr.slice(-1)[0] | |||||
| }) | |||||
| function stopBubbling(e) { | |||||
| e = window.event || e; | |||||
| if (e.stopPropagation) { | |||||
| e.stopPropagation(); //阻止事件 冒泡传播 | |||||
| } else { | |||||
| e.cancelBubble = true; //ie兼容 | |||||
| } | |||||
| } | |||||
| let timeid = window.setInterval(loadJobStatus, 30000); | |||||
| $(document).ready(loadJobStatus); | |||||
| function loadLog(version_name){ | |||||
| document.getElementById("mask").style.display = "block" | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||||
| $('input[name=end_line]').val(data.EndLine) | |||||
| $('input[name=start_line]').val(data.StartLine) | |||||
| $(`#log_file${version_name}`).text(data.Content) | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }); | |||||
| } | |||||
| function loadModelFile(version_name,parents,filename,init){ | |||||
| parents = parents || '' | |||||
| filename = filename || '' | |||||
| init = init || '' | |||||
| console.log("start") | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | |||||
| $(`#dir_list${version_name}`).empty() | |||||
| renderDir(data,version_name) | |||||
| if(init==="init"){ | |||||
| $(`input[name=model${version_name}]`).val("") | |||||
| $(`input[name=modelback${version_name}]`).val(version_name) | |||||
| $(`#file_breadcrumb${version_name}`).empty() | |||||
| let htmlBread = "" | |||||
| htmlBread += `<div class='active section'>${version_name}</div>` | |||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBread) | |||||
| }else{ | |||||
| renderBrend(version_name,parents,filename,init) | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err,version_name); | |||||
| }); | |||||
| } | |||||
| function renderBrend(version_name,parents,filename,init){ | |||||
| if(init=="folder"){ | |||||
| let htmlBrend = "" | |||||
| let sectionName=$(`#file_breadcrumb${version_name} .active.section`).text() | |||||
| let parents1 = $(`input[name=model${version_name}]`).val() | |||||
| let filename1 = $(`input[name=modelback${version_name}]`).val() | |||||
| if(parents1===""){ | |||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','','init')">${sectionName}</a>`) | |||||
| }else{ | |||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | |||||
| } | |||||
| htmlBrend += `<div class='active section'>${filename}</div>` | |||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBrend) | |||||
| $(`input[name=model${version_name}]`).val(parents) | |||||
| $(`input[name=modelback${version_name}]`).val(filename) | |||||
| }else{ | |||||
| $(`input[name=model${version_name}]`).val(parents) | |||||
| $(`input[name=modelback${version_name}]`).val(filename) | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).nextAll().remove() | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | |||||
| $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | |||||
| } | |||||
| } | |||||
| function renderDir(data,version_name){ | |||||
| let html="" | |||||
| html += "<div class='ui grid' style='margin:0;'>" | |||||
| html += "<div class='row' style='padding: 0;'>" | |||||
| html += "<div class='ui sixteen wide column' style='padding:1rem;'>" | |||||
| html += "<div class='dir list'>" | |||||
| html += "<table id='repo-files-table' class='ui single line table pad20'>" | |||||
| html += '<tbody>' | |||||
| // html += "</tbody>" | |||||
| for(let i=0;i<data.Dirs.length;i++){ | |||||
| let dirs_size = renderSize(data.Dirs[i].Size) | |||||
| html += "<tr>" | |||||
| html += "<td class='name six wid'>" | |||||
| html += "<span class='truncate'>" | |||||
| html += "<span class='octicon octicon-file-directory'>" | |||||
| html += "</span>" | |||||
| if(data.Dirs[i].IsDir){ | |||||
| 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{ | |||||
| if(downlaodFlag){ | |||||
| html += `<a href="${location.href}/download_model?version_name=${version_name}&fileName=${data.Dirs[i].FileName}&parentDir=${data.Dirs[i].ParenDir}&jobName=${realJobName}">` | |||||
| } | |||||
| 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>' | |||||
| html += "</span>" | |||||
| html += "</td>" | |||||
| html += "<td class='message seven wide'>" | |||||
| if(data.Dirs[i].IsDir){ | |||||
| html += "<span class='truncate has-emoji'></span>" | |||||
| }else{ | |||||
| html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | |||||
| } | |||||
| html += "</td>" | |||||
| html += "<td class='text right age three wide'>" | |||||
| html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | |||||
| html += "</td>" | |||||
| html += "</tr>" | |||||
| } | |||||
| html += "</tbody>" | |||||
| html += "</table>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| $(`#dir_list${version_name}`).append(html) | |||||
| } | |||||
| function renderSize(value){ | |||||
| if(null==value||value==''){ | |||||
| return "0 Bytes"; | |||||
| } | |||||
| var unitArr = new Array("Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"); | |||||
| var index=0; | |||||
| var srcsize = parseFloat(value); | |||||
| index=Math.floor(Math.log(srcsize)/Math.log(1024)); | |||||
| var size =srcsize/Math.pow(1024,index); | |||||
| size=size.toFixed(0);//保留的小数位数 | |||||
| return size+unitArr[index]; | |||||
| } | |||||
| function loadJobStatus() { | |||||
| $(".ui.accordion.border-according").each((index, job) => { | |||||
| const jobID = job.dataset.jobid; | |||||
| const repoPath = job.dataset.repopath; | |||||
| const versionname = job.dataset.version | |||||
| // ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||||
| // if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED' | |||||
| // || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED' | |||||
| // || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||||
| // return | |||||
| // } | |||||
| let status = $(`#${versionname}-status-span`).text() | |||||
| if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUCCEEDED'].includes(status)){ | |||||
| return | |||||
| } | |||||
| let stopArray=["KILLED","FAILED","START_FAILED","KILLING","COMPLETED","SUCCEEDED"] | |||||
| $.get(`/api/v1/repos/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`, (data) => { | |||||
| //$(`#${versionname}-duration-span`).text(data.JobDuration) | |||||
| $(`#${versionname}-status-span span`).text(data.JobStatus) | |||||
| $(`#${versionname}-status-span i`).attr("class",data.JobStatus) | |||||
| // detail status and duration | |||||
| //$('#'+versionname+'-duration').text(data.JobDuration) | |||||
| $('#'+versionname+'-status').text(data.JobStatus) | |||||
| if(stopArray.includes(data.JobStatus)){ | |||||
| $('#'+versionname+'-stop').addClass('disabled') | |||||
| } | |||||
| if(data.JobStatus==="COMPLETED"){ | |||||
| $('#'+versionname+'-create-model').removeClass('disabled').addClass('blue') | |||||
| } | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| function refreshStatus(version_name){ | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`,(data)=>{ | |||||
| // header status and duration | |||||
| //$(`#${version_name}-duration-span`).text(data.JobDuration) | |||||
| $(`#${version_name}-status-span span`).text(data.JobStatus) | |||||
| $(`#${version_name}-status-span i`).attr("class",data.JobStatus) | |||||
| // detail status and duration | |||||
| //$('#'+version_name+'-duration').text(data.JobDuration) | |||||
| $('#'+version_name+'-status').text(data.JobStatus) | |||||
| loadLog(version_name) | |||||
| }).fail(function(err) { | |||||
| console.log(err); | |||||
| }); | |||||
| stopBubbling(arguments.callee.caller.arguments[0]) | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,69 @@ | |||||
| <style> | |||||
| #dataset-base>.field>label{ | |||||
| width:120px !important; | |||||
| text-align:right !important; | |||||
| } | |||||
| </style> | |||||
| <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> | |||||
| {{template "base/head" .}} | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <input type="hidden" id="postPath" value="{{.Link}}"> | |||||
| <div style="width: 80%;margin: auto;"> | |||||
| <h4 class="ui top attached header"> | |||||
| {{.i18n.Tr "dataset.create_new_dataset"}} | |||||
| </h4> | |||||
| <div class="ui attached segment" style="padding: 2em 3em;"> | |||||
| <div class="ui form" id="dataset-base"> | |||||
| <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="140px"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <el-form-item label='{{.i18n.Tr "dataset.dataset_name"}}' prop="title"> | |||||
| <el-input v-model="ruleForm.title"></el-input> | |||||
| <span style="font-size: 12px;color: #888;line-height: 1;margin-top: 0.5em;display: inline-block;">{{.i18n.Tr "dataset.dataset_name_tooltips"}}</span> | |||||
| <!-- <span>请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> --> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.dataset_description"}}' prop="description"> | |||||
| <el-input type="textarea" :rows="3" maxlength="1024" placeholder="{{.i18n.Tr "dataset.dataset_desc"}}" v-model="ruleForm.description"></el-input> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.category"}}' prop="category"> | |||||
| <el-select v-model="ruleForm.category" placeholder='{{.i18n.Tr "dataset.select_category"}}' style="width: 60%;"> | |||||
| {{range $category := categories}} | |||||
| <el-option label='{{$.i18n.Tr (printf "dataset.category.%s" $category)}}' value='{{$category}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.task"}}' prop="task"> | |||||
| <el-select v-model="ruleForm.task" placeholder='{{.i18n.Tr "dataset.select_task"}}' style="width: 60%;"> | |||||
| {{range $task := tasks}} | |||||
| <el-option label='{{$.i18n.Tr (printf "dataset.task.%s" $task)}}' value='{{$task}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "repo.license"}}' prop="license"> | |||||
| <el-select v-model="ruleForm.license" placeholder='{{.i18n.Tr "repo.license_helper"}}' style="width: 60%;"> | |||||
| {{range $license := licenses}} | |||||
| <el-option label='{{$license}}' value='{{$license}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item> | |||||
| <el-button style="background-color: #21ba45;" type="success" @click="createDataset('ruleForm')">{{.i18n.Tr "repo.confirm_choice"}}</el-button> | |||||
| <el-button type="info" @click="cancelDataset('create','')">{{.i18n.Tr "cancel"}}</el-button> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,72 @@ | |||||
| <style> | |||||
| #dataset-base>.field>label{ | |||||
| width:120px !important; | |||||
| text-align:right !important; | |||||
| } | |||||
| </style> | |||||
| <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> | |||||
| {{template "base/head" .}} | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <input type="hidden" id="postPath" value="{{.Link}}"> | |||||
| <div style="width: 80%;margin: auto;"> | |||||
| <h4 class="ui top attached header"> | |||||
| {{.i18n.Tr "dataset.modify_dataset"}} | |||||
| </h4> | |||||
| <div id="dataset-edit-value" style="display: none;" data-edit-id="{{.Dataset.ID}}" data-edit-title="{{.Dataset.Title}}" data-edit-description="{{.Dataset.Description}}" | |||||
| data-edit-category="{{.Dataset.Category}}" data-edit-task="{{.Dataset.Task}}" data-edit-license="{{.Dataset.License}}"> | |||||
| </div> | |||||
| <div class="ui attached segment" style="padding: 2em 3em;"> | |||||
| <div class="ui form" id="dataset-base"> | |||||
| <el-form :model="ruleForm1" :rules="rules" ref="ruleForm" label-width="140px"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <el-form-item label='{{.i18n.Tr "dataset.dataset_name"}}' prop="title"> | |||||
| <el-input v-model="ruleForm1.title"></el-input> | |||||
| <span style="font-size: 12px;color: #888;line-height: 1;margin-top: 0.5em;display: inline-block;">{{.i18n.Tr "dataset.dataset_name_tooltips"}}</span> | |||||
| <!-- <span>请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> --> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.dataset_description"}}' prop="description"> | |||||
| <el-input type="textarea" :rows="3" maxlength="1024" placeholder="{{.i18n.Tr "dataset.dataset_desc"}}" v-model="ruleForm1.description"></el-input> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.category"}}' prop="category"> | |||||
| <el-select v-model="ruleForm1.category" placeholder='{{.i18n.Tr "dataset.select_category"}}' style="width: 60%;"> | |||||
| {{range $category := categories}} | |||||
| <el-option label='{{$.i18n.Tr (printf "dataset.category.%s" $category)}}' value='{{$category}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "dataset.task"}}' prop="task"> | |||||
| <el-select v-model="ruleForm1.task" placeholder='{{.i18n.Tr "dataset.select_task"}}' style="width: 60%;"> | |||||
| {{range $task := tasks}} | |||||
| <el-option label='{{$.i18n.Tr (printf "dataset.task.%s" $task)}}' value='{{$task}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item label='{{.i18n.Tr "repo.license"}}' prop="license"> | |||||
| <el-select v-model="ruleForm1.license" placeholder='{{.i18n.Tr "repo.license_helper"}}' style="width: 60%;"> | |||||
| {{range $license := licenses}} | |||||
| <el-option label='{{$license}}' value='{{$license}}'></el-option> | |||||
| {{end}} | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| <el-form-item> | |||||
| <el-button style="background-color: #21ba45;" type="success" @click="editDataset('ruleForm',{{.Dataset.ID}})">{{.i18n.Tr "repo.confirm_choice"}}</el-button> | |||||
| <el-button type="info" @click="cancelDataset('edit','')">{{.i18n.Tr "cancel"}}</el-button> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -6,145 +6,341 @@ | |||||
| margin: -1px; | margin: -1px; | ||||
| background: #FFF !important; | background: #FFF !important; | ||||
| } | } | ||||
| .dataset_title{ | |||||
| font-size: 14px; | |||||
| max-width: 80%; | |||||
| display: inline-block !important; | |||||
| margin-left: 6px !important; | |||||
| padding-right: 0 !important; | |||||
| } | |||||
| .wrapper { | |||||
| display: flex; | |||||
| overflow: hidden; | |||||
| padding: 0 1rem; | |||||
| } | |||||
| .exp{ | |||||
| display: none; | |||||
| } | |||||
| .exp:checked+.text{ | |||||
| max-height: none; | |||||
| } | |||||
| .exp:checked+.text::after{ | |||||
| visibility: hidden; | |||||
| } | |||||
| .exp:checked+.text .btn::before{ | |||||
| visibility: hidden; | |||||
| } | |||||
| .exp:checked+.text .btn::after{ | |||||
| content:'{{$.i18n.Tr "org.fold"}}' | |||||
| } | |||||
| .wrapper>.text { | |||||
| font-family: SourceHanSansSC-regular; | |||||
| font-size: 14px; | |||||
| color: #101010; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| text-align: justify; | |||||
| position: relative; | |||||
| line-height: 1.5; | |||||
| max-height: 3em; | |||||
| transition: .3s max-height; | |||||
| word-wrap: break-word; | |||||
| word-break: break-all; | |||||
| } | |||||
| .wrapper>.text::before { | |||||
| content: ''; | |||||
| height: calc(100% - 20px); | |||||
| float: right; | |||||
| } | |||||
| .wrapper>.text::after { | |||||
| content: ''; | |||||
| width: 999vw; | |||||
| height: 999vw; | |||||
| position: absolute; | |||||
| box-shadow: inset calc(100px - 999vw) calc(30px - 999vw) 0 0 #fff; | |||||
| margin-left: -100px; | |||||
| } | |||||
| .btn{ | |||||
| position: relative; | |||||
| float: right; | |||||
| clear: both; | |||||
| margin-left: 20px; | |||||
| font-size: 14px; | |||||
| padding: 0 8px; | |||||
| background: #3F51B5; | |||||
| line-height: 20px; | |||||
| border-radius: 4px; | |||||
| color: #fff; | |||||
| cursor: pointer; | |||||
| /* margin-top: -30px; */ | |||||
| } | |||||
| .btn::after{ | |||||
| content:'{{$.i18n.Tr "org.unfold"}}' | |||||
| } | |||||
| .btn::before{ | |||||
| content: '...'; | |||||
| position: absolute; | |||||
| left: -5px; | |||||
| color: #333; | |||||
| transform: translateX(-100%) | |||||
| } | |||||
| .el-button--text{color:#0366d6 ;} | |||||
| .heart-stroke{ | |||||
| stroke: #666; | |||||
| stroke-width: 2; | |||||
| fill: #fff | |||||
| } | |||||
| .stars_active{ | |||||
| fill: #FA8C16 !important; | |||||
| stroke:#FA8C16 !important | |||||
| } | |||||
| .diy-popper{ | |||||
| max-width: 400px; | |||||
| } | |||||
| </style> | </style> | ||||
| <div class="repository release dataset-list view"> | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <script> | |||||
| $(document).ready(function() { | |||||
| const params = new URLSearchParams(window.location.search); | |||||
| if (params.get('type') == 0){ | |||||
| $('.contorl_component').attr("id", 'minioUploader') | |||||
| }else{ | |||||
| $('.contorl_component').attr("id", 'obsUploader') | |||||
| } | |||||
| }); | |||||
| </script> | |||||
| <form class="ui container" action="{{.Link}}" method="post"> | |||||
| <input name="id" value="{{.dataset.ID}}" type="hidden" /> | |||||
| <!-- | |||||
| <span class="alert" style="font-size:20px;color:red"> | |||||
| <strong>{{.i18n.Tr "dataset.alert"}}</strong> | |||||
| </span> | |||||
| --> | |||||
| <div id="datasetId" datasetId="{{.dataset.ID}}"> | |||||
| {{.CsrfTokenHtml}} | |||||
| {{template "base/alert" .}} | |||||
| <div class="ui stackable grid {{if .Error}}hide{{end}}" id="dataset-content"> | |||||
| <div class="row"> | |||||
| <div class="column sixteen {{if .Permission.CanWrite $.UnitTypeDatasets}}twelve{{end}} wide"> | |||||
| <h2>{{.dataset.Title}}</h2> | |||||
| </div> | |||||
| {{if .Permission.CanWrite $.UnitTypeDatasets}} | |||||
| <div class="column four wide right aligned"> | |||||
| <a class="ui green button" href="javascript:void(0)" id="dataset-edit"> | |||||
| {{.i18n.Tr "dataset.edit"}} | |||||
| </a> | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | |||||
| <div class="row"> | |||||
| <div class="column sixteen wide"> | |||||
| {{if .dataset.Description }} | |||||
| <span class="no-description text-italic">{{.dataset.Description}}</span> | |||||
| {{else}} | |||||
| <span class="no-description text-italic">{{.Repository.DescriptionHTML}}</span> | |||||
| {{if .dataset}} | |||||
| <div id="dataset-range-value" data-num-stars="{{.dataset.NumStars}}" data-star-active="{{$.IsStaringDataset}}" style="display: none;"> | |||||
| {{range .Attachments}} | |||||
| <div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | |||||
| {{end}} | |||||
| </div> | |||||
| <div id="dataset-base"> | |||||
| <div class="ui container"> | |||||
| <div class="ui mobile reversed stackable grid"> | |||||
| <div class="row"> | |||||
| <div class="column thirteen wide"><h2>{{.dataset.Title}}</h2></div> | |||||
| <div class="column three wide right aligned"> | |||||
| <span style="display: flex;align-items: center;justify-content: flex-end;height: 36px;"> | |||||
| {{if $.IsSigned}} | |||||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:star_active}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||||
| </div> | |||||
| <span style="line-height: 1;">${num_stars}</span> | |||||
| {{else}} | |||||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;"> | |||||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:star_active}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||||
| </div> | |||||
| <span style="line-height: 1;">${num_stars}</span> | |||||
| {{end}} | |||||
| <a style="margin-left:30px;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||||
| </span> | |||||
| </div> | |||||
| {{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}} | |||||
| <div class="column thirteen wide"> | |||||
| {{if .dataset.Category}} | |||||
| {{$category := .dataset.Category}} | |||||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{.dataset.Category}}&task={{$.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.category.%s" $category)}}</a> | |||||
| {{end}} | |||||
| {{if .dataset.Task}} | |||||
| {{$task := .dataset.Task}} | |||||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{.dataset.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.task.%s" $task)}}</a> | |||||
| {{end}} | |||||
| {{if .dataset.License}} | |||||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{.dataset.License}}">{{.dataset.License}}</a> | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| <div class="ui grid form segment success {{if not .Error}}hide{{end}}" id="dataset-content-edit"> | |||||
| <label class="d-block">{{.i18n.Tr "dataset.title"}}</label> | |||||
| <div class="sixteen wide column"> | |||||
| <input name="title" placeholder='{{.i18n.Tr "dataset.title"}}' value="{{.dataset.Title}}" autofocus required maxlength="255"> | |||||
| </div> | |||||
| <label class="d-block">{{.i18n.Tr "dataset.description"}}</label> | |||||
| <div class="sixteen wide column"> | |||||
| <textarea name="description" rows="3">{{.dataset.Description}}</textarea> | |||||
| </div> | |||||
| <input name="type" value="{{.Type}}" type="hidden" /> | |||||
| <div class="sixteen wide column"> | |||||
| <a class="ui button" id="cancel">{{.i18n.Tr "cancel"}}</a> | |||||
| <button class="ui green button" id="submit">{{.i18n.Tr "dataset.update_dataset"}}</button> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui blue mini menu selectcloudbrain"> | |||||
| <a class="{{if eq .Type 0}}active {{end}}item" href="{{.RepoLink}}/datasets?type=0">{{svg "octicon-server" 16}} CPU / GPU</a> | |||||
| <a class="{{if eq .Type 1}}active {{end}}item" href="{{.RepoLink}}/datasets?type=1">{{svg "octicon-server" 16}} Ascend NPU</a> | |||||
| </div> | |||||
| <div class="ui stackable grid"> | |||||
| <div class="twelve wide column"> | |||||
| <div class="ui sixteen wide column"> | |||||
| <div class="ui two column stackable grid"> | |||||
| <div class="column"> | |||||
| <strong>{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}</strong> | |||||
| </div> | |||||
| <div class="column right aligned" style="z-index:1"> | |||||
| <div class="ui right dropdown type jump item"> | |||||
| <span class="text"> | |||||
| {{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> | |||||
| </span> | |||||
| <div class="menu"> | |||||
| <a class="item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||||
| <a class="item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||||
| {{if .dataset.Description}} | |||||
| <div class="row" style="padding-top: 0;"> | |||||
| <div class=" wrapper"> | |||||
| <input id="exp1" class="exp" type="checkbox"> | |||||
| <div class="text"> | |||||
| <label class="btn" for="exp1"></label> | |||||
| {{.dataset.Description}} | |||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="dataset list"> | |||||
| {{template "repo/datasets/dataset_list" .}} | |||||
| {{end}} | |||||
| <div class="row"> | |||||
| <div class="column ten wide"></div> | |||||
| <div class="column six wide right aligned"> | |||||
| <el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | |||||
| <i slot="prefix" style="display: inline-block;color: #101010;" class="el-input__icon ri-archive-drawer-line"></i> | |||||
| <el-option label="{{$.i18n.Tr "repo.gpu_type_all"}}" value="-1"></el-option> | |||||
| <el-option label="CPU/GPU" value="0"></el-option> | |||||
| <el-option label="NPU" value="1"></el-option> | |||||
| </el-select> | |||||
| <el-button icon="el-icon-upload" {{if not $.CanWrite}} disabled {{end}} type="primary" size="small" @click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="dataset ui middle very relaxed page"> | |||||
| <div class="column"> | |||||
| {{if .Permission.CanWrite $.UnitTypeDatasets}} | |||||
| <div style='display:none;' | |||||
| id="minioUploader-params" | |||||
| data-uuid="{{.uuid}}" | |||||
| data-add-url="{{AppSubUrl}}/attachments/add" | |||||
| data-accepts="{{.AttachmentAllowedTypes}}" | |||||
| data-remove-url="{{AppSubUrl}}/attachments/delete" | |||||
| data-csrf="{{.CsrfToken}}" | |||||
| dataset-id={{.dataset.ID}} | |||||
| data-max-file="100" | |||||
| data-dataset-id="{{.dataset.ID}}" | |||||
| data-max-size="{{.AttachmentMaxSize}}" | |||||
| data-default-message="{{.i18n.Tr "dropzone.default_message"}}" | |||||
| data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" | |||||
| data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" | |||||
| data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}" | |||||
| data-file-status='{{.i18n.Tr "dropzone.file_status"}}' | |||||
| data-file-init-status='{{.i18n.Tr "dropzone.file_init_status"}}' | |||||
| data-waitting-uploading='{{.i18n.Tr "dropzone.waitting_uploading"}}' | |||||
| data-md5-computing='{{.i18n.Tr "dropzone.md5_computing"}}' | |||||
| data-obs-connecting='{{.i18n.Tr "dropzone.obs-connecting"}}' | |||||
| data-loading-file='{{.i18n.Tr "dropzone.loading_file"}}' | |||||
| data-upload-complete='{{.i18n.Tr "dropzone.upload_complete"}}' | |||||
| data-uploading='{{.i18n.Tr "dropzone.uploading"}}' | |||||
| data-failed='{{.i18n.Tr "dropzone.failed"}}' | |||||
| > | |||||
| </div> | |||||
| <div class="contorl_component"></div> | |||||
| {{end}} | |||||
| <div class="row"> | |||||
| <div class="ui sixteen wide column dataset"> | |||||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||||
| <div class="row"> | |||||
| <!-- 数据集名称 --> | |||||
| <div class="four wide column" style="width: 24% !important;"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "dataset.dataset_file_name"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||||
| {{$.i18n.Tr "repo.model.manage.size"}} | |||||
| </div> | |||||
| <div class="two wide column text center"> | |||||
| {{$.i18n.Tr "dataset.dataset_available_clusters"}} | |||||
| </div> | |||||
| <div class="one wide column text center"> | |||||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||||
| </div> | |||||
| <div class="one wide column text center"> | |||||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||||
| </div> | |||||
| <div class="three wide column text center"> | |||||
| {{$.i18n.Tr "dataset.dataset_upload_time"}} | |||||
| </div> | |||||
| <div class="four wide column text center"> | |||||
| {{$.i18n.Tr "repo.cloudbrain_operate"}} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range $k, $v :=.Attachments}} | |||||
| <div class="ui grid stackable item" id="{{.FileChunk.UUID}}"> | |||||
| <div class="row"> | |||||
| <!-- 数据集名称 --> | |||||
| <div class="four wide column" style="width: 24% !important;display: flex;align-items: center;"> | |||||
| {{if .Description}} | |||||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||||
| <div slot="content" >{{.Description}}</br><span><i class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||||
| {{.Name}} | |||||
| </a> | |||||
| </el-tooltip> | |||||
| {{else}} | |||||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||||
| <div slot="content" ><span><i class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||||
| {{.Name}} | |||||
| </a> | |||||
| </el-tooltip> | |||||
| {{end}} | |||||
| <i class="ri-lock-2-line" style="color: #fa8c16;" v-if="privates[{{$k}}]"></i> | |||||
| <!-- <i class="COMPLETED" v-if="zipStatus[{{$k}}]==1"></i> | |||||
| <i class="WAITING" v-if="zipStatus[{{$k}}]==2"></i> | |||||
| <i class="FAILED" v-if="zipStatus[{{$k}}]==3"></i> --> | |||||
| </div> | |||||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||||
| {{.Size | FileSize}} | |||||
| </div> | |||||
| <div class="two wide column text center"> | |||||
| {{.Type | AttachmentResourceType}} | |||||
| </div> | |||||
| <div class="one wide column text center"> | |||||
| {{$x:=.IsPrivate | AttachmentStatus}} | |||||
| <span style="color: #fa8c16;" v-if="privates[{{$k}}]">{{$.i18n.Tr "home.show_private"}}</span> | |||||
| <span style="color: #13c28d;" v-else="privates[{{$k}}]">{{$.i18n.Tr "org.settings.visibility.public"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center"> | |||||
| {{if .Uploader.Name}} | |||||
| <a href="{{AppSubUrl}}/{{.Uploader.Name}}" title="{{.Uploader.Name}}"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/{{.Uploader.Name}}/-1"></a> | |||||
| {{else}} | |||||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||||
| {{end}} | |||||
| </div> | |||||
| <div class="three wide column text center"> | |||||
| {{.CreatedUnix | TimeSinceUnix1}} | |||||
| </div> | |||||
| <div class="four wide column text right"> | |||||
| <!-- <el-button type="text">下载</el-button> | |||||
| <el-button type="text">预览</el-button> | |||||
| <el-button type="text">标注</el-button> | |||||
| <el-button type="text"> | |||||
| <el-popover | |||||
| placement="right" | |||||
| width="400" | |||||
| trigger="click"> | |||||
| <span>asdasd</span> | |||||
| <el-button slot="reference" type="text"><i class="ri-more-line"></i></el-button> | |||||
| </el-popover> | |||||
| </el-button> --> | |||||
| <div class="ui compact buttons"> | |||||
| <a class="ui basic blue button" href="{{.DownloadURL}}">{{$.i18n.Tr "dataset.download"}}</a> | |||||
| {{if eq .DecompressState 1}} | |||||
| <a class="ui basic blue button" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{$.i18n.Tr "preview"}}</a> | |||||
| {{end}} | |||||
| {{if and (.CanDel) (not $.Repository.IsPrivate)}} | |||||
| <span class="ui basic blue button" style="color: #13c28d !important;" @click="setPrivate('{{.FileChunk.UUID}}',false,{{$k}})" v-if="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_public"}}</span> | |||||
| <span class="ui basic blue button" style="color: #fa8c16 !important;" @click="setPrivate('{{.FileChunk.UUID}}',true,{{$k}})" v-else="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_private"}}</span> | |||||
| {{end}} | |||||
| <!-- {{if $.CanRead}} | |||||
| <a class="ui basic blue button" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'>标注</a> | |||||
| {{else}} | |||||
| <a class="ui basic disabled button">标注</a> | |||||
| {{end}} --> | |||||
| <a class="ui basic blue button"> | |||||
| <el-dropdown size="medium"> | |||||
| <span class="el-dropdown-link"> | |||||
| {{$.i18n.Tr "repo.more"}}<i class="el-icon-arrow-down el-icon--right"></i> | |||||
| </span> | |||||
| <el-dropdown-menu slot="dropdown"> | |||||
| <el-dropdown-item class="clipboard" data-clipboard-text="{{.DownloadURL}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_url"}}</el-dropdown-item> | |||||
| <el-dropdown-item class="clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_md5"}}</el-dropdown-item> | |||||
| {{if and ($.CanWrite) (eq .DecompressState 1) }} | |||||
| <el-dropdown-item @click.native="gotoAnnotate('{{$.RepoLink}}','{{.UUID}}',{{.Type}})">{{$.i18n.Tr "dataset.annotation"}}</el-dropdown-item> | |||||
| {{end}} | |||||
| {{if .CanDel}} | |||||
| <el-dropdown-item @click.native="gotoDatasetEidt('{{$.RepoLink}}',{{.ID}})">{{$.i18n.Tr "dataset.modify_description"}}</el-dropdown-item> | |||||
| <el-dropdown-item style="color: red;" @click.native="delDataset('{{.FileChunk.UUID}}')">{{$.i18n.Tr "dataset.delete"}}</el-dropdown-item> | |||||
| {{end}} | |||||
| </el-dropdown-menu> | |||||
| </el-dropdown> | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="four wide column"> | |||||
| {{template "repo/datasets/right_side" .}} | |||||
| </div> | |||||
| </div> | </div> | ||||
| </form> | |||||
| </div> | |||||
| <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> | |||||
| {{else}} | |||||
| <div class="ui placeholder segment bgtask-none"> | |||||
| <div class="ui icon header bgtask-header-pic"></div> | |||||
| <div class="bgtask-content-header">{{.i18n.Tr "dataset.dataset_no_create"}}</div> | |||||
| {{if $.CanWrite}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/datasets/create">{{.i18n.Tr "dataset.create_new_dataset"}}</a> | |||||
| {{end}} | |||||
| <div class="bgtask-content"> | |||||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div> | |||||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui small basic delete modal" id="data-dataset-delete-modal"> | <div class="ui small basic delete modal" id="data-dataset-delete-modal"> | ||||
| <div class="ui icon header"> | |||||
| <i class="trash icon"></i> | |||||
| <div class="ui icon header"> | |||||
| <i class="trash icon"></i> | |||||
| {{.i18n.Tr "dataset.attachment.delete"}} | {{.i18n.Tr "dataset.attachment.delete"}} | ||||
| </div> | |||||
| <div class="content"> | |||||
| <p>{{.i18n.Tr "dataset.attachment.delete_desc" | Str2html}}</p> | |||||
| </div> | |||||
| {{template "base/delete_modal_actions" .}} | |||||
| </div> | |||||
| <div class="content"> | |||||
| <p>{{.i18n.Tr "dataset.attachment.delete_desc" | Str2html}}</p> | |||||
| </div> | |||||
| {{template "base/delete_modal_actions" .}} | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| @@ -208,7 +208,7 @@ | |||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <!-- 提示框 --> | <!-- 提示框 --> | ||||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" data-debug-again="{{$.i18n.Tr "repo.debug_again"}}"></div> | |||||
| <!-- 列表容器 --> | <!-- 列表容器 --> | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| @@ -242,14 +242,14 @@ | |||||
| {{if eq 0 (len .Tasks)}} | {{if eq 0 (len .Tasks)}} | ||||
| <div class="ui placeholder segment bgtask-none"> | <div class="ui placeholder segment bgtask-none"> | ||||
| <div class="ui icon header bgtask-header-pic"></div> | <div class="ui icon header bgtask-header-pic"></div> | ||||
| <div class="bgtask-content-header">未创建过调试任务</div> | |||||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.debug_task_not_created"}}</div> | |||||
| <div class="bgtask-content"> | <div class="bgtask-content"> | ||||
| {{if $.RepoIsEmpty}} | {{if $.RepoIsEmpty}} | ||||
| <div class="bgtask-content-txt">代码版本:您还没有初始化代码仓库,请先<a href="{{.RepoLink}}">创建代码版本</a>;</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||||
| {{end}} | {{end}} | ||||
| <div class="bgtask-content-txt">运行时长:最长不超过4个小时,超过4个小时将自动停止;</div> | |||||
| <div class="bgtask-content-txt">数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境;</div> | |||||
| <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.debug_task_running_limit"}}</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{else}} | ||||
| @@ -443,7 +443,20 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} {{template "base/paginate" .}} | |||||
| {{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> | ||||
| @@ -458,18 +471,18 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -138,7 +138,7 @@ | |||||
| {{end}} | {{end}} | ||||
| {{if .Permission.CanRead $.UnitTypeDatasets}} | {{if .Permission.CanRead $.UnitTypeDatasets}} | ||||
| <a class="{{if .PageIsDataset}}active{{end}} item" href="{{.RepoLink}}/datasets?type=0"> | |||||
| <a class="{{if .PageIsDataset}}active{{end}} item" href="{{.RepoLink}}/datasets"> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13 2.715 7.429a.5.5 0 0 1 0-.858l8.77-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg> | <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13 2.715 7.429a.5.5 0 0 1 0-.858l8.77-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg> | ||||
| {{.i18n.Tr "datasets"}} | {{.i18n.Tr "datasets"}} | ||||
| </a> | </a> | ||||
| @@ -39,7 +39,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="column right aligned"> | <div class="column right aligned"> | ||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/modelarts/inference-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | <a class="ui green button" href="{{.RepoLink}}/modelarts/inference-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | ||||
| @@ -49,16 +49,16 @@ | |||||
| {{if eq 0 (len .Tasks)}} | {{if eq 0 (len .Tasks)}} | ||||
| <div class="ui placeholder segment bgtask-none"> | <div class="ui placeholder segment bgtask-none"> | ||||
| <div class="ui icon header bgtask-header-pic"></div> | <div class="ui icon header bgtask-header-pic"></div> | ||||
| <div class="bgtask-content-header">未创建过推理任务</div> | |||||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.inference_job_not_created"}}</div> | |||||
| <div class="bgtask-content"> | <div class="bgtask-content"> | ||||
| {{if $.RepoIsEmpty}} | {{if $.RepoIsEmpty}} | ||||
| <div class="bgtask-content-txt">代码版本:您还没有初始化代码仓库,请先<a href="{{.RepoLink}}">创建代码版本;</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||||
| {{end}} | {{end}} | ||||
| {{if eq 0 $.MODEL_COUNT}} | {{if eq 0 $.MODEL_COUNT}} | ||||
| <div class="bgtask-content-txt">模型文件:您还没有模型文件,请先通过<a href="{{.RepoLink}}/modelarts/train-job">训练任务</a>产生并 <a href="{{.RepoLink}}/modelmanage/show_model">导出模型</a> ;</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.model_not_exist" .RepoLink .RepoLink | Safe}}</div> | |||||
| {{end}} | {{end}} | ||||
| <div class="bgtask-content-txt">数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境;</div> | |||||
| <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{else}} | ||||
| @@ -88,32 +88,32 @@ | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <!-- <div class="two wide column text center padding0"> | <!-- <div class="two wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> --> | </div> --> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | </div> | ||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | ||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 模型版本 --> | <!-- 模型版本 --> | ||||
| <!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | <!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | ||||
| <div class="three wide column text center padding0"> | |||||
| <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 class="three wide column text center padding0"> | |||||
| <a id="{{.JobName}}" class="goto_modelmanage" href="javascript:void(0);" data-variation="inverted" data-position="top center" data-content="{{$.i18n.Tr "repo.modelarts.infer_job.tooltip"}}" data-jobname={{.JobName}} data-modelname={{.ModelName}} data-version={{.ModelVersion}} data-repopath="{{$.RepoLink}}">{{.ModelName}} </a> <span style="font-size: 12px;">{{.ModelVersion}}</span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center padding0" > | <div class="two wide column text center padding0" > | ||||
| @@ -126,12 +126,12 @@ | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="two wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||||
| <div class="two wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <!-- <div class="two wide column text center padding0"> | <!-- <div class="two wide column text center padding0"> | ||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| </div> --> | </div> --> | ||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| @@ -186,7 +186,20 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} {{template "base/paginate" .}} | |||||
| {{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> | ||||
| @@ -205,18 +218,18 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -68,9 +68,9 @@ | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | ||||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" 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="255" 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> | ||||
| @@ -107,7 +107,7 @@ | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_name_version"> | <div class="menu" id="model_name_version"> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="five wide field"> | <div class="five wide field"> | ||||
| @@ -123,10 +123,10 @@ | |||||
| <div class="menu" id="model_checkpoint"> | <div class="menu" id="model_checkpoint"> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <span > | <span > | ||||
| <i class="question circle icon" data-content="模型文件位置存储在环境变量ckpt_url中。" data-position="top center" data-variation="inverted mini"></i> | |||||
| <i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.model_file_path_rule"}}" data-position="top center" data-variation="inverted mini"></i> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- AI引擎 --> | <!-- AI引擎 --> | ||||
| @@ -171,17 +171,17 @@ | |||||
| <!-- 数据集 --> | <!-- 数据集 --> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | ||||
| <select class="ui dropdown width35" id="trainjob_datasets" name="attachment" placeholder="选择数据集" required> | |||||
| <select class="ui dropdown width35" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}" required> | |||||
| {{if $.uuid}} | {{if $.uuid}} | ||||
| <option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | <option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | ||||
| {{end}} | {{end}} | ||||
| {{range .attachments}} | {{range .attachments}} | ||||
| <option value="">选择数据集</option> | |||||
| <option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | ||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| <span> | <span> | ||||
| <i class="question circle icon" data-content="数据集位置存储在环境变量data_url中。" data-position="top center" data-variation="inverted mini"></i> | |||||
| <i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.dataset_path_rule"}}" data-position="top center" data-variation="inverted mini"></i> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- 启动文件 --> | <!-- 启动文件 --> | ||||
| @@ -195,9 +195,9 @@ | |||||
| <span > | <span > | ||||
| <i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i> | <i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i> | ||||
| </span> | </span> | ||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">查看样例</a> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | </div> | ||||
| <!-- 运行参数 --> | <!-- 运行参数 --> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| @@ -222,7 +222,7 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required field " style="display: none;"> | <div class="required field " style="display: none;"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | ||||
| <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | ||||
| @@ -243,11 +243,11 @@ | |||||
| <!-- 计算节点 --> | <!-- 计算节点 --> | ||||
| <div class="inline required unite min_title field"> | <div class="inline required unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | ||||
| <div class="ui labeled input" style="width: 5%;"> | <div class="ui labeled input" style="width: 5%;"> | ||||
| <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | ||||
| </div> | </div> | ||||
| <span class="tooltips" style="display: block;">推理输出路径存储在环境变量result_url中。</span> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.inference_output_path_rule"}}</span> | |||||
| </div> | </div> | ||||
| <!-- 表单操作 --> | <!-- 表单操作 --> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| @@ -255,7 +255,7 @@ | |||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | |||||
| </div> | |||||
| <!-- 模态框 --> | <!-- 模态框 --> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| @@ -283,7 +283,7 @@ | |||||
| $("#select_model").dropdown('set text',nameList[0]) | $("#select_model").dropdown('set text',nameList[0]) | ||||
| $("#select_model").dropdown('set value',nameList[0],nameList[0]) | $("#select_model").dropdown('set value',nameList[0],nameList[0]) | ||||
| } | } | ||||
| $('#select_model').removeClass("loading") | $('#select_model').removeClass("loading") | ||||
| }) | }) | ||||
| // 根据选中的模型名称获取相应的模型版本 | // 根据选中的模型名称获取相应的模型版本 | ||||
| @@ -323,7 +323,7 @@ | |||||
| if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | ||||
| html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | ||||
| } | } | ||||
| }) | }) | ||||
| $('#model_checkpoint').append(html) | $('#model_checkpoint').append(html) | ||||
| $("#select_model_checkpoint").removeClass("loading") | $("#select_model_checkpoint").removeClass("loading") | ||||
| @@ -332,7 +332,7 @@ | |||||
| $("#select_model_checkpoint").dropdown('set text',initVersionText) | $("#select_model_checkpoint").dropdown('set text',initVersionText) | ||||
| $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | ||||
| }) | }) | ||||
| $("input#ai_model_version").val(text) | $("input#ai_model_version").val(text) | ||||
| $("input#ai_model_label").val(label) | $("input#ai_model_label").val(label) | ||||
| @@ -348,15 +348,15 @@ | |||||
| } | } | ||||
| $('.question.circle.icon').hover(function(){ | $('.question.circle.icon').hover(function(){ | ||||
| $(this).popup('show') | |||||
| $(this).popup('show') | |||||
| }); | }); | ||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | function Add_parameter(i){ | ||||
| value = '<div class="two fields width84" id= "para'+ i +'">' + | value = '<div class="two fields width84" id= "para'+ i +'">' + | ||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | '<div class="field"> ' + | ||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | ||||
| '</div>'+ | '</div>'+ | ||||
| @@ -366,7 +366,7 @@ | |||||
| '</span>' + | '</span>' + | ||||
| '</div>' | '</div>' | ||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | |||||
| } | |||||
| $('#add_run_para').click(function(){ | $('#add_run_para').click(function(){ | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| @@ -459,7 +459,7 @@ | |||||
| onSuccess: function(){ | onSuccess: function(){ | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| }, | }, | ||||
| onFailure: function(e){ | |||||
| onFailure: function(e){ | |||||
| return false; | return false; | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -470,8 +470,8 @@ | |||||
| } | } | ||||
| } | } | ||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| send_run_para() | |||||
| send_run_para() | |||||
| get_name() | get_name() | ||||
| validate() | validate() | ||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -82,7 +82,7 @@ | |||||
| vertical-align: inherit; | vertical-align: inherit; | ||||
| } | } | ||||
| .ti-text-form-label { | .ti-text-form-label { | ||||
| padding-bottom: 20px; | padding-bottom: 20px; | ||||
| padding-right: 20px; | padding-right: 20px; | ||||
| color: #8a8e99; | color: #8a8e99; | ||||
| @@ -152,7 +152,7 @@ td, th { | |||||
| opacity: .45 !important; | opacity: .45 !important; | ||||
| } | } | ||||
| .pad20{ | .pad20{ | ||||
| border:0px !important; | border:0px !important; | ||||
| } | } | ||||
| .model_file_bread{ | .model_file_bread{ | ||||
| @@ -180,12 +180,12 @@ td, th { | |||||
| {{with .task}} | {{with .task}} | ||||
| <div class="content-pad" style="border: 1px solid #e2e2e2;margin-top: 24px;padding: 20px 60px 40px 60px;"> | <div class="content-pad" style="border: 1px solid #e2e2e2;margin-top: 24px;padding: 20px 60px 40px 60px;"> | ||||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | ||||
| <a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | <a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | ||||
| <a class="item" data-tab="second" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | <a class="item" data-tab="second" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | ||||
| <a class="item" data-tab="third" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | <a class="item" data-tab="third" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | ||||
| </div> | </div> | ||||
| <div class="ui tab active" data-tab="first"> | <div class="ui tab active" data-tab="first"> | ||||
| <div style="padding-top: 10px;"> | <div style="padding-top: 10px;"> | ||||
| <div class="tab_2_content"> | <div class="tab_2_content"> | ||||
| @@ -218,7 +218,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.run_version"}} | {{$.i18n.Tr "repo.modelarts.run_version"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.VersionName}} | {{.VersionName}} | ||||
| @@ -227,20 +227,26 @@ td, th { | |||||
| </tr> --> | </tr> --> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| <span style="font-size: 12px;" class=""> | |||||
| {{if not (eq .StartTime 0)}} | |||||
| {{TimeSinceUnix1 .StartTime}} | |||||
| {{else}} | |||||
| {{TimeSinceUnix1 .CreatedUnix}} | |||||
| {{end}} | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | ||||
| {{.TrainJobDuration}} | {{.TrainJobDuration}} | ||||
| @@ -248,23 +254,23 @@ td, th { | |||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.EngineName}} | {{.EngineName}} | ||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.model.manage.description"}} | {{$.i18n.Tr "repo.model.manage.description"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;"> | <div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;"> | ||||
| {{if .Description}} | {{if .Description}} | ||||
| @@ -279,7 +285,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 创建人 | 创建人 | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-creator"> | <div class="text-span text-span-w" id="{{.VersionName}}-creator"> | ||||
| {{$.userName}} | {{$.userName}} | ||||
| @@ -288,7 +294,7 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| @@ -304,19 +310,19 @@ td, th { | |||||
| <tbody class="ti-text-form"> | <tbody class="ti-text-form"> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.infer_job_model"}} | |||||
| {{$.i18n.Tr "repo.modelarts.infer_job_model"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| <span>{{.ModelName}}</span> | <span>{{.ModelName}}</span> | ||||
| <span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</span> | <span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</span> | ||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.infer_job_model_file"}} | |||||
| {{$.i18n.Tr "repo.modelarts.infer_job_model_file"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| @@ -328,10 +334,10 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.model_label"}} | {{$.i18n.Tr "repo.modelarts.model_label"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-labels"> | <div class="text-span text-span-w" id="{{.VersionName}}-labels"> | ||||
| {{if .LabelName}} | {{if .LabelName}} | ||||
| {{range $.labelName}} | {{range $.labelName}} | ||||
| <a class="ui label" title="{{.}}">{{.}}</a> | <a class="ui label" title="{{.}}">{{.}}</a> | ||||
| @@ -342,7 +348,7 @@ td, th { | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | {{$.i18n.Tr "repo.modelarts.code_version"}} | ||||
| @@ -358,7 +364,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BootFile}} | {{.BootFile}} | ||||
| @@ -367,9 +373,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.infer_dataset"}} | |||||
| {{$.i18n.Tr "repo.modelarts.infer_dataset"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.DatasetName}} | {{.DatasetName}} | ||||
| @@ -378,9 +384,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80" > | <td class="ti-no-ng-animate ti-text-form-label text-width80" > | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" title="{{.Parameters}}"> | <div class="text-span text-span-w" title="{{.Parameters}}"> | ||||
| {{if .Parameters}} | {{if .Parameters}} | ||||
| @@ -393,9 +399,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.FlavorName}} | {{.FlavorName}} | ||||
| @@ -407,10 +413,10 @@ td, th { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="second"> | <div class="ui tab" data-tab="second"> | ||||
| <div> | <div> | ||||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | <div class="ui message message{{.VersionName}}" style="display: none;"> | ||||
| @@ -421,9 +427,9 @@ td, th { | |||||
| <input type="hidden" name="start_line" value> | <input type="hidden" name="start_line" value> | ||||
| <pre id="log_file{{.VersionName}}"></pre> | <pre id="log_file{{.VersionName}}"></pre> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="third"> | <div class="ui tab" data-tab="third"> | ||||
| <input type="hidden" name="model{{.VersionName}}" value="-1"> | <input type="hidden" name="model{{.VersionName}}" value="-1"> | ||||
| @@ -434,34 +440,34 @@ td, th { | |||||
| </div> | </div> | ||||
| <div id="dir_list{{.VersionName}}"> | <div id="dir_list{{.VersionName}}"> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 确认模态框 --> | <!-- 确认模态框 --> | ||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -493,7 +499,7 @@ function loadLog(version_name){ | |||||
| }); | }); | ||||
| } | } | ||||
| function logScroll(version_name) { | function logScroll(version_name) { | ||||
| let container = document.querySelector(`#log${version_name}`) | let container = document.querySelector(`#log${version_name}`) | ||||
| let scrollTop = container.scrollTop | let scrollTop = container.scrollTop | ||||
| let scrollHeight = container.scrollHeight | let scrollHeight = container.scrollHeight | ||||
| @@ -506,7 +512,7 @@ function logScroll(version_name) { | |||||
| $(`.message${version_name} #header`).text('您已翻阅至日志底部') | $(`.message${version_name} #header`).text('您已翻阅至日志底部') | ||||
| $(`.message${version_name}`).css('display', 'block') | $(`.message${version_name}`).css('display', 'block') | ||||
| setTimeout(function(){ | setTimeout(function(){ | ||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| }, 1000) | }, 1000) | ||||
| }else{ | }else{ | ||||
| if(end_line===data.EndLine){ | if(end_line===data.EndLine){ | ||||
| @@ -514,9 +520,9 @@ function logScroll(version_name) { | |||||
| } | } | ||||
| else{ | else{ | ||||
| $(`#log${version_name} input[name=end_line]`).val(data.EndLine) | $(`#log${version_name} input[name=end_line]`).val(data.EndLine) | ||||
| $(`#log${version_name}`).append('<pre>' + data.Content) | |||||
| $(`#log${version_name}`).append('<pre>' + data.Content) | |||||
| } | } | ||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| @@ -529,7 +535,7 @@ function logScroll(version_name) { | |||||
| $(`.message${version_name} #header`).text('您已翻阅至日志顶部') | $(`.message${version_name} #header`).text('您已翻阅至日志顶部') | ||||
| $(`.message${version_name}`).css('display', 'block') | $(`.message${version_name}`).css('display', 'block') | ||||
| setTimeout(function(){ | setTimeout(function(){ | ||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| }, 1000) | }, 1000) | ||||
| }else{ | }else{ | ||||
| $(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | $(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | ||||
| @@ -557,7 +563,7 @@ function loadModelFile(version_name,parents,filename,init){ | |||||
| filename = filename || '' | filename = filename || '' | ||||
| init = init || '' | init = init || '' | ||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/result_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/result_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | ||||
| $(`#dir_list${version_name}`).empty() | |||||
| $(`#dir_list${version_name}`).empty() | |||||
| renderDir(data,version_name) | renderDir(data,version_name) | ||||
| if(init==="init"){ | if(init==="init"){ | ||||
| $(`input[name=model${version_name}]`).val("") | $(`input[name=model${version_name}]`).val("") | ||||
| @@ -565,7 +571,7 @@ function loadModelFile(version_name,parents,filename,init){ | |||||
| $(`#file_breadcrumb${version_name}`).empty() | $(`#file_breadcrumb${version_name}`).empty() | ||||
| let htmlBread = "" | let htmlBread = "" | ||||
| htmlBread += `<div class='active section'>result</div>` | htmlBread += `<div class='active section'>result</div>` | ||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBread) | $(`#file_breadcrumb${version_name}`).append(htmlBread) | ||||
| }else{ | }else{ | ||||
| renderBrend(version_name,parents,filename,init) | renderBrend(version_name,parents,filename,init) | ||||
| @@ -573,7 +579,7 @@ function loadModelFile(version_name,parents,filename,init){ | |||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err,version_name); | console.log(err,version_name); | ||||
| }); | }); | ||||
| } | } | ||||
| function renderBrend(version_name,parents,filename,init){ | function renderBrend(version_name,parents,filename,init){ | ||||
| if(init=="folder"){ | if(init=="folder"){ | ||||
| @@ -586,9 +592,9 @@ function renderBrend(version_name,parents,filename,init){ | |||||
| }else{ | }else{ | ||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | ||||
| } | } | ||||
| htmlBrend += `<div class='active section'>${filename}</div>` | htmlBrend += `<div class='active section'>${filename}</div>` | ||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBrend) | $(`#file_breadcrumb${version_name}`).append(htmlBrend) | ||||
| $(`input[name=model${version_name}]`).val(parents) | $(`input[name=model${version_name}]`).val(parents) | ||||
| $(`input[name=modelback${version_name}]`).val(filename) | $(`input[name=modelback${version_name}]`).val(filename) | ||||
| @@ -599,7 +605,7 @@ function renderBrend(version_name,parents,filename,init){ | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | ||||
| $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | ||||
| } | } | ||||
| } | } | ||||
| function renderDir(data,version_name){ | function renderDir(data,version_name){ | ||||
| let html="" | let html="" | ||||
| @@ -638,14 +644,14 @@ function renderDir(data,version_name){ | |||||
| }else{ | }else{ | ||||
| html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | ||||
| } | } | ||||
| html += "</td>" | html += "</td>" | ||||
| html += "<td class='text right age three wide'>" | html += "<td class='text right age three wide'>" | ||||
| html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | ||||
| html += "</td>" | html += "</td>" | ||||
| html += "</tr>" | html += "</tr>" | ||||
| } | } | ||||
| html += "</tbody>" | html += "</tbody>" | ||||
| html += "</table>" | html += "</table>" | ||||
| @@ -655,4 +661,4 @@ function renderDir(data,version_name){ | |||||
| html += "</div>" | html += "</div>" | ||||
| $(`#dir_list${version_name}`).append(html) | $(`#dir_list${version_name}`).append(html) | ||||
| } | } | ||||
| </script> | |||||
| </script> | |||||
| @@ -30,7 +30,7 @@ | |||||
| <div class="ui attached segment"> | <div class="ui attached segment"> | ||||
| <!-- <br> --> | <!-- <br> --> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>计算资源</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | <div class="ui blue small menu compact selectcloudbrain"> | ||||
| <a class="item" href="{{.RepoLink}}/cloudbrain/create"> | <a class="item" href="{{.RepoLink}}/cloudbrain/create"> | ||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | ||||
| @@ -47,29 +47,19 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>任务名称</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>镜像</label> | |||||
| <select id="cloudbrain_image" class="ui search dropdown" placeholder="选择镜像" style='width:385px' name="image_id"> | |||||
| <label>{{.i18n.Tr "cloudbrain.mirror"}}</label> | |||||
| <select id="cloudbrain_image" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" style='width:385px' name="image_id"> | |||||
| {{range .images}} | {{range .images}} | ||||
| <option name="image_id" value="{{.Id}}">{{.Value}}</option> | <option name="image_id" value="{{.Id}}">{{.Value}}</option> | ||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </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"> | |||||
| {{range .attachments}} | |||||
| <option name="attachment" data-value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
| {{end}} | |||||
| </datalist> | |||||
| <input type="hidden" name="attachment" id="answerInput-hidden"> | |||||
| </div> | |||||
| {{template "custom/select_dataset" .}} | |||||
| <!--<div class="inline required field"> | <!--<div class="inline required field"> | ||||
| <label>工作环境</label> | <label>工作环境</label> | ||||
| @@ -80,7 +70,7 @@ | |||||
| <input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> --> | </div> --> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>规格</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.specification"}}</label> | |||||
| <select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor"> | <select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor"> | ||||
| {{range .flavors}} | {{range .flavors}} | ||||
| <option name="flavor" value="{{.Value}}">{{.Desc}}</option> | <option name="flavor" value="{{.Value}}">{{.Desc}}</option> | ||||
| @@ -93,14 +83,14 @@ | |||||
| <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> --> | </div> --> | ||||
| <div class="inline field"> | <div class="inline field"> | ||||
| <label>描述</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.description"}}</label> | |||||
| <input name="description" id="cloudbrain_description" tabindex="3" autofocus maxlength="255"> | <input name="description" id="cloudbrain_description" tabindex="3" autofocus maxlength="255"> | ||||
| </div> | </div> | ||||
| <div class="inline field"> | <div class="inline field"> | ||||
| <label></label> | <label></label> | ||||
| <button class="ui green button"> | <button class="ui green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||||
| </button> | |||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||||
| </button> | |||||
| <a class="ui button cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -118,8 +108,8 @@ | |||||
| form.onsubmit = function(e){ | form.onsubmit = function(e){ | ||||
| let value_task = $("input[name='display_job_name']").val() | let value_task = $("input[name='display_job_name']").val() | ||||
| let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | ||||
| let flag = re.test(value_task) | let flag = re.test(value_task) | ||||
| if(!flag){ | if(!flag){ | ||||
| @@ -128,12 +118,12 @@ | |||||
| $('#messageInfo p').text(str) | $('#messageInfo p').text(str) | ||||
| return false | return false | ||||
| } | } | ||||
| let min_value_task = value_task.toLowerCase() | let min_value_task = value_task.toLowerCase() | ||||
| $("input[name='display_job_name']").attr("value",min_value_task) | $("input[name='display_job_name']").attr("value",min_value_task) | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| } | } | ||||
| // 点击按钮后遮罩层显示 | // 点击按钮后遮罩层显示 | ||||
| // function showmask() { | // function showmask() { | ||||
| @@ -149,7 +139,6 @@ | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| $(function() { | $(function() { | ||||
| $("#cloudbrain_job_type").change(function() { | $("#cloudbrain_job_type").change(function() { | ||||
| if ($(this).val() == 'BENCHMARK') { | if ($(this).val() == 'BENCHMARK') { | ||||
| @@ -159,20 +148,11 @@ | |||||
| } | } | ||||
| }) | }) | ||||
| }) | }) | ||||
| document.querySelector('input[list]').addEventListener('input',function(e){ | |||||
| var input = e.target, | |||||
| list = input.getAttribute('list'), | |||||
| options = document.querySelectorAll('#'+list+' option'), | |||||
| hiddenInput = document.getElementById(input.getAttribute('id')+'-hidden'), | |||||
| inputValue = input.value; | |||||
| hiddenInput.value = inputValue; | |||||
| for (let i=0;i<options.length;i++){ | |||||
| var option = options[i] | |||||
| if(option.innerText===inputValue){ | |||||
| hiddenInput.value = option.getAttribute('data-value'); | |||||
| break | |||||
| } | |||||
| } | |||||
| }) | |||||
| </script> | |||||
| $(document).ready(function(){ | |||||
| $(document).keydown(function(event){ | |||||
| if(event.keyCode==13){ | |||||
| event.preventDefault(); | |||||
| } | |||||
| }); | |||||
| }); | |||||
| </script> | |||||
| @@ -39,8 +39,18 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="column right aligned"> | <div class="column right aligned"> | ||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/modelarts/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | |||||
| <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;"> | |||||
| {{svg "octicon-server" 16}} | |||||
| <div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||||
| <i class="dropdown icon"></i> | |||||
| <div class="menu"> | |||||
| <div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||||
| <div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||||
| <div class="item" data-value="NPU">NPU</div> | |||||
| </div> | |||||
| </div> | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | |||||
| {{else}} | {{else}} | ||||
| <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | <a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a> | ||||
| {{end}} | {{end}} | ||||
| @@ -49,13 +59,13 @@ | |||||
| {{if eq 0 (len .Tasks)}} | {{if eq 0 (len .Tasks)}} | ||||
| <div class="ui placeholder segment bgtask-none"> | <div class="ui placeholder segment bgtask-none"> | ||||
| <div class="ui icon header bgtask-header-pic"></div> | <div class="ui icon header bgtask-header-pic"></div> | ||||
| <div class="bgtask-content-header">未创建过训练任务</div> | |||||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.train_task_not_created"}}</div> | |||||
| <div class="bgtask-content"> | <div class="bgtask-content"> | ||||
| {{if $.RepoIsEmpty}} | {{if $.RepoIsEmpty}} | ||||
| <div class="bgtask-content-txt">代码版本:您还没有初始化代码仓库,请先<a href="{{.RepoLink}}">创建代码版本;</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||||
| {{end}} | {{end}} | ||||
| <div class="bgtask-content-txt">数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境;</div> | |||||
| <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div> | |||||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{else}} | ||||
| @@ -85,31 +95,31 @@ | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> | </div> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | </div> | ||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href='{{if eq .ComputeResource "NPU" }}{{$.Link}}/{{.JobID}}{{else}}{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}{{end}}' title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 版本数量 --> | <!-- 版本数量 --> | ||||
| <div class="one wide column text center padding0"> | |||||
| <span style="font-size: 12px;">{{.VersionCount}} </span> | |||||
| <div class="one wide column text center padding0"> | |||||
| <span style="font-size: 12px;">{{.VersionCount}} </span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | ||||
| @@ -122,12 +132,12 @@ | |||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="two wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||||
| <div class="two wide column text center padding0"> | |||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||||
| </div> | </div> | ||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| @@ -143,7 +153,7 @@ | |||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <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}}"> | |||||
| <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" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" data-repopath='{{$.RepoRelPath}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}' data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -154,7 +164,8 @@ | |||||
| </div> | </div> | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | |||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='{{if eq .ComputeResource "NPU" }}{{$.Link}}/{{.JobID}}{{else}}{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}{{end}}/del' method="post"> | |||||
| <input type="hidden" name="listType" value="{{$.ListType}}"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | ||||
| @@ -169,7 +180,20 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} {{template "base/paginate" .}} | |||||
| {{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> | ||||
| @@ -188,21 +212,45 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | |||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| let url = {{$.RepoLink}}; | |||||
| let all = {{$.i18n.Tr "repo.gpu_type_all"}} | |||||
| $(document).ready(function(){ | |||||
| const params = new URLSearchParams(location.search) | |||||
| if(!location.search){ | |||||
| $('.default.text').text(all) | |||||
| }else{ | |||||
| if(params.has('listType') && params.get('listType')=='all'){ | |||||
| $('.default.text').text(all) | |||||
| } | |||||
| else{ | |||||
| $('.default.text').text(params.get('listType')) | |||||
| } | |||||
| } | |||||
| $('.ui.selection.dropdown').dropdown({ | |||||
| onChange:function(value){ | |||||
| location.href = `${url}/modelarts/train-job?listType=${value}` | |||||
| } | |||||
| }) | |||||
| }) | |||||
| </script> | |||||
| @@ -78,12 +78,30 @@ | |||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | ||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | ||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||||
| <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| </svg> | |||||
| CPU/GPU | |||||
| </a> | |||||
| <a class="active item" href="{{.RepoLink}}/modelarts/train-job/create"> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| </svg> | |||||
| Ascend NPU</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | ||||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | ||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" 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="255" 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> | ||||
| @@ -91,7 +109,7 @@ | |||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | ||||
| @@ -147,22 +165,22 @@ | |||||
| <span> | <span> | ||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | ||||
| </span> | </span> | ||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">查看样例</a> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | ||||
| <select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="选择数据集"> | |||||
| <select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}"> | |||||
| {{if $.uuid}} | {{if $.uuid}} | ||||
| <option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | <option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | ||||
| {{end}} | {{end}} | ||||
| {{range .attachments}} | {{range .attachments}} | ||||
| <option value="">选择数据集</option> | |||||
| <option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | ||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| <span class="tooltips">数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。</span> | |||||
| <span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| @@ -223,24 +241,24 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required unite min_title field"> | <div class="inline required unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | ||||
| <div class="ui labeled input" style="width: 5%;"> | <div class="ui labeled input" style="width: 5%;"> | ||||
| <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | </div> | ||||
| <!-- 模态框 --> | <!-- 模态框 --> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -272,9 +290,9 @@ | |||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | function Add_parameter(i){ | ||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | value = '<div class="two fields width85" id= "para'+ i +'">' + | ||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | '<div class="field"> ' + | ||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | ||||
| '</div>'+ | '</div>'+ | ||||
| @@ -284,7 +302,7 @@ | |||||
| '</span>' + | '</span>' + | ||||
| '</div>' | '</div>' | ||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | |||||
| } | |||||
| $('#add_run_para').click(function(){ | $('#add_run_para').click(function(){ | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| @@ -310,7 +328,7 @@ | |||||
| $(this).find('input').each(function(){ | $(this).find('input').each(function(){ | ||||
| parameters.push($(this).text()) | parameters.push($(this).text()) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.modal') | $('.ui.parameter.modal') | ||||
| .modal('hide'); | .modal('hide'); | ||||
| @@ -353,9 +371,9 @@ | |||||
| onChange: function(){ | onChange: function(){ | ||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | if ($('.ui.save.checkbox').checkbox('is checked')){ | ||||
| $('#save_para').removeClass("disabled") | $('#save_para').removeClass("disabled") | ||||
| }else{ | }else{ | ||||
| $('#save_para').addClass("disabled") | |||||
| $('#save_para').addClass("disabled") | |||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -395,7 +413,7 @@ | |||||
| identifier : 'display_job_name', | identifier : 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -421,7 +439,7 @@ | |||||
| // $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| }, | }, | ||||
| onFailure: function(e){ | |||||
| onFailure: function(e){ | |||||
| return false; | return false; | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -453,6 +471,6 @@ | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| get_name() | get_name() | ||||
| send_run_para() | send_run_para() | ||||
| validate() | |||||
| validate() | |||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -2,11 +2,11 @@ | |||||
| <div class="modelarts"> | <div class="modelarts"> | ||||
| <div class="repository release modelarts train_job view container"> | <div class="repository release modelarts train_job view container"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <div class="ui container"> | |||||
| <div class="ui container"> | |||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| {{template "repo/modelarts/navbar" .}} | |||||
| {{template "repo/modelarts/navbar" .}} | |||||
| <!-- 右侧 --> | <!-- 右侧 --> | ||||
| <div class="ui thirteen wide column"> | |||||
| <div class="ui thirteen wide column"> | |||||
| <div class="ui column stackable grid"> | <div class="ui column stackable grid"> | ||||
| <div class="column"> | <div class="column"> | ||||
| <h2>{{.i18n.Tr "repo.modelarts.train_job_para_admin"}}</h2> | <h2>{{.i18n.Tr "repo.modelarts.train_job_para_admin"}}</h2> | ||||
| @@ -29,7 +29,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 任务展示 --> | <!-- 任务展示 --> | ||||
| <div class="dataset list"> | <div class="dataset list"> | ||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| @@ -38,12 +38,12 @@ | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="five wide column"> | <div class="five wide column"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}"> | <a class="title" href="{{$.Link}}/{{.JobID}}"> | ||||
| <span class="fitted">{{.JobName}}</span> | <span class="fitted">{{.JobName}}</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 引擎类型--> | |||||
| <!-- 引擎类型--> | |||||
| <div class="four wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | <div class="four wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | ||||
| {{.Status}} | {{.Status}} | ||||
| </div> | </div> | ||||
| @@ -59,7 +59,7 @@ | |||||
| <span class="fitted">编辑</span> | <span class="fitted">编辑</span> | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 删除 --> | <!-- 删除 --> | ||||
| <div class="two wide column"> | <div class="two wide column"> | ||||
| <div class="ui text center clipboard"> | <div class="ui text center clipboard"> | ||||
| @@ -69,7 +69,7 @@ | |||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} {{template "base/paginate" .}} | {{end}} {{template "base/paginate" .}} | ||||
| @@ -78,7 +78,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -86,18 +86,18 @@ | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -105,7 +105,7 @@ | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| <script> | |||||
| // 删除时用户确认 | // 删除时用户确认 | ||||
| function assertDelete(obj) { | function assertDelete(obj) { | ||||
| if (obj.style.color == "rgb(204, 204, 204)") { | if (obj.style.color == "rgb(204, 204, 204)") { | ||||
| @@ -82,7 +82,7 @@ | |||||
| vertical-align: inherit; | vertical-align: inherit; | ||||
| } | } | ||||
| .ti-text-form-label { | .ti-text-form-label { | ||||
| padding-bottom: 20px; | padding-bottom: 20px; | ||||
| padding-right: 20px; | padding-right: 20px; | ||||
| color: #8a8e99; | color: #8a8e99; | ||||
| @@ -152,7 +152,7 @@ td, th { | |||||
| opacity: .45 !important; | opacity: .45 !important; | ||||
| } | } | ||||
| .pad20{ | .pad20{ | ||||
| border:0px !important; | border:0px !important; | ||||
| } | } | ||||
| .model_file_bread{ | .model_file_bread{ | ||||
| @@ -213,7 +213,7 @@ td, th { | |||||
| {{else}} | {{else}} | ||||
| <a class="ti-action-menu-item disabled" id="{{.VersionName}}-stop" onclick="stopVersion({{.VersionName}})">{{$.i18n.Tr "repo.stop"}}</a> | <a class="ti-action-menu-item disabled" id="{{.VersionName}}-stop" onclick="stopVersion({{.VersionName}})">{{$.i18n.Tr "repo.stop"}}</a> | ||||
| {{end}} | {{end}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a class="ti-action-menu-item" onclick="deleteVersion({{.VersionName}})" style="color: #FF4D4F;">{{$.i18n.Tr "repo.delete"}}</a> | <a class="ti-action-menu-item" onclick="deleteVersion({{.VersionName}})" style="color: #FF4D4F;">{{$.i18n.Tr "repo.delete"}}</a> | ||||
| @@ -222,8 +222,13 @@ td, th { | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | <div class="ac-display-inblock title_text acc-margin-bottom"> | ||||
| <span class="cti-mgRight-sm">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||||
| <span class="cti-mgRight-sm"> | |||||
| {{if not (eq .Cloudbrain.StartTime 0)}} | |||||
| {{TimeSinceUnix1 .Cloudbrain.StartTime}} | |||||
| {{else}} | |||||
| {{TimeSinceUnix1 .Cloudbrain.CreatedUnix}} | |||||
| {{end}}</span> | |||||
| <span class="cti-mgRight-sm"> {{$.i18n.Tr "repo.modelarts.current_version"}}:{{.VersionName}}</span> | <span class="cti-mgRight-sm"> {{$.i18n.Tr "repo.modelarts.current_version"}}:{{.VersionName}}</span> | ||||
| <span class="cti-mgRight-sm"> {{$.i18n.Tr "repo.modelarts.parent_version"}}:{{.PreVersionName}}</span> | <span class="cti-mgRight-sm"> {{$.i18n.Tr "repo.modelarts.parent_version"}}:{{.PreVersionName}}</span> | ||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | ||||
| @@ -242,7 +247,7 @@ td, th { | |||||
| <div class="{{if eq $k 0}}active{{end}} content"> | <div class="{{if eq $k 0}}active{{end}} content"> | ||||
| <div class="content-pad"> | <div class="content-pad"> | ||||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | ||||
| <a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | <a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | ||||
| <a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | <a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | ||||
| <a class="item" data-tab="third{{$k}}" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | <a class="item" data-tab="third{{$k}}" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | ||||
| @@ -279,7 +284,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.run_version"}} | {{$.i18n.Tr "repo.modelarts.run_version"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.VersionName}} | {{.VersionName}} | ||||
| @@ -288,20 +293,25 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||||
| <span style="font-size: 12px;" class=""> | |||||
| {{if not (eq .Cloudbrain.StartTime 0)}} | |||||
| {{TimeSinceUnix1 .Cloudbrain.StartTime}} | |||||
| {{else}} | |||||
| {{TimeSinceUnix1 .Cloudbrain.CreatedUnix}} | |||||
| {{end}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | ||||
| {{.TrainJobDuration}} | {{.TrainJobDuration}} | ||||
| @@ -310,9 +320,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.FlavorName}} | {{.FlavorName}} | ||||
| @@ -321,7 +331,7 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| @@ -337,7 +347,7 @@ td, th { | |||||
| <tbody class="ti-text-form"> | <tbody class="ti-text-form"> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| @@ -349,7 +359,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | {{$.i18n.Tr "repo.modelarts.code_version"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| @@ -360,7 +370,7 @@ td, th { | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | ||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BootFile}} | {{.BootFile}} | ||||
| @@ -369,9 +379,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.DatasetName}} | {{.DatasetName}} | ||||
| @@ -380,9 +390,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80" > | <td class="ti-no-ng-animate ti-text-form-label text-width80" > | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" title="{{.Parameters}}"> | <div class="text-span text-span-w" title="{{.Parameters}}"> | ||||
| {{.Parameters}} | {{.Parameters}} | ||||
| @@ -392,9 +402,9 @@ td, th { | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" title="{{.Cloudbrain.Description}}"> | <div class="text-span text-span-w" title="{{.Cloudbrain.Description}}"> | ||||
| {{.Cloudbrain.Description}} | {{.Cloudbrain.Description}} | ||||
| @@ -406,7 +416,7 @@ td, th { | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="second{{$k}}"> | <div class="ui tab" data-tab="second{{$k}}"> | ||||
| @@ -419,9 +429,9 @@ td, th { | |||||
| <input type="hidden" name="start_line" value> | <input type="hidden" name="start_line" value> | ||||
| <pre id="log_file{{.VersionName}}"></pre> | <pre id="log_file{{.VersionName}}"></pre> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="third{{$k}}"> | <div class="ui tab" data-tab="third{{$k}}"> | ||||
| <input type="hidden" name="model{{.VersionName}}" value="-1"> | <input type="hidden" name="model{{.VersionName}}" value="-1"> | ||||
| @@ -432,7 +442,7 @@ td, th { | |||||
| </div> | </div> | ||||
| <div id="dir_list{{.VersionName}}"> | <div id="dir_list{{.VersionName}}"> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -445,18 +455,18 @@ td, th { | |||||
| <div id="deletemodel"> | <div id="deletemodel"> | ||||
| <div class="ui basic modal"> | <div class="ui basic modal"> | ||||
| <div class="ui icon header"> | <div class="ui icon header"> | ||||
| <i class="trash icon"></i> 删除任务 | |||||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||||
| </div> | </div> | ||||
| <div class="content"> | <div class="content"> | ||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -474,19 +484,19 @@ td, th { | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <input type="hidden" name="trainTaskCreate" value="true"> | <input type="hidden" name="trainTaskCreate" value="true"> | ||||
| <div class="two inline fields "> | |||||
| <div class="two inline fields "> | |||||
| <div class="required ten wide field"> | <div class="required ten wide field"> | ||||
| <label style="margin-left: -23px;">选择训练任务</label> | <label style="margin-left: -23px;">选择训练任务</label> | ||||
| <input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | <input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | ||||
| <input class="width83" id="JobName" readonly required> | <input class="width83" id="JobName" readonly required> | ||||
| </div> | </div> | ||||
| <div class="required six widde field"> | <div class="required six widde field"> | ||||
| <label>版本</label> | <label>版本</label> | ||||
| <input class="width70" id="VersionName" name="VersionName" readonly required> | <input class="width70" id="VersionName" name="VersionName" readonly required> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required inline field" id="modelname"> | <div class="required inline field" id="modelname"> | ||||
| <label>模型名称</label> | <label>模型名称</label> | ||||
| <input style="width: 45%;" id="name" name="Name" required maxlength="25" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | <input style="width: 45%;" id="name" name="Name" required maxlength="25" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | ||||
| @@ -503,7 +513,7 @@ td, th { | |||||
| <label for="description">模型描述</label> | <label for="description">模型描述</label> | ||||
| <textarea style="width: 83%;margin-left: 7px;" id="Description" name="Description" rows="3" maxlength="255" 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, 256)"></textarea> | <textarea style="width: 83%;margin-left: 7px;" id="Description" name="Description" rows="3" maxlength="255" 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, 256)"></textarea> | ||||
| </div> | </div> | ||||
| <div class="inline field" style="margin-left: 75px;"> | <div class="inline field" style="margin-left: 75px;"> | ||||
| <button onclick="createModel()" type="button" class="ui create_train_job green button" style="position: absolute;"> | <button onclick="createModel()" type="button" class="ui create_train_job green button" style="position: absolute;"> | ||||
| {{.i18n.Tr "repo.model.manage.sava_model"}} | {{.i18n.Tr "repo.model.manage.sava_model"}} | ||||
| @@ -514,8 +524,8 @@ td, th { | |||||
| <button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button> | <button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -529,7 +539,7 @@ td, th { | |||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| $('.secondary.menu .item').tab(); | $('.secondary.menu .item').tab(); | ||||
| }); | }); | ||||
| let userName | let userName | ||||
| let repoPath | let repoPath | ||||
| let jobID | let jobID | ||||
| @@ -562,7 +572,7 @@ td, th { | |||||
| $('input[name="JobId"]').val(obj.JobID) | $('input[name="JobId"]').val(obj.JobID) | ||||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | ||||
| $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | ||||
| createModelName() | |||||
| createModelName() | |||||
| }, | }, | ||||
| onHide:function(){ | onHide:function(){ | ||||
| document.getElementById("formId").reset(); | document.getElementById("formId").reset(); | ||||
| @@ -595,7 +605,7 @@ td, th { | |||||
| $("#mask").css({"display":"none","z-index":"1"}) | $("#mask").css({"display":"none","z-index":"1"}) | ||||
| } | } | ||||
| }) | }) | ||||
| } | } | ||||
| function createModelName(){ | function createModelName(){ | ||||
| let repoName = location.pathname.split('/')[2] | let repoName = location.pathname.split('/')[2] | ||||
| @@ -627,9 +637,9 @@ td, th { | |||||
| // return | // return | ||||
| // } | // } | ||||
| let status = $(`#${versionname}-status-span`).text() | let status = $(`#${versionname}-status-span`).text() | ||||
| if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'].includes(status)){ | if(['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'].includes(status)){ | ||||
| return | |||||
| return | |||||
| } | } | ||||
| let stopArray=["KILLED","FAILED","START_FAILED","KILLING","COMPLETED"] | let stopArray=["KILLED","FAILED","START_FAILED","KILLING","COMPLETED"] | ||||
| $.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => { | $.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => { | ||||
| @@ -682,7 +692,7 @@ td, th { | |||||
| }else{ | }else{ | ||||
| $('#accordion'+version_name).remove() | $('#accordion'+version_name).remove() | ||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| }); | }); | ||||
| @@ -695,7 +705,7 @@ td, th { | |||||
| } | } | ||||
| }) | }) | ||||
| .modal('show') | .modal('show') | ||||
| } | } | ||||
| function stopVersion(version_name){ | function stopVersion(version_name){ | ||||
| stopBubbling(arguments.callee.caller.arguments[0]) | stopBubbling(arguments.callee.caller.arguments[0]) | ||||
| @@ -705,7 +715,7 @@ td, th { | |||||
| refreshStatus(version_name) | refreshStatus(version_name) | ||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | |||||
| console.log(err); | |||||
| }); | }); | ||||
| } | } | ||||
| function loadLog(version_name){ | function loadLog(version_name){ | ||||
| @@ -722,7 +732,7 @@ td, th { | |||||
| filename = filename || '' | filename = filename || '' | ||||
| init = init || '' | init = init || '' | ||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | ||||
| $(`#dir_list${version_name}`).empty() | |||||
| $(`#dir_list${version_name}`).empty() | |||||
| renderDir(data,version_name) | renderDir(data,version_name) | ||||
| if(init==="init"){ | if(init==="init"){ | ||||
| $(`input[name=model${version_name}]`).val("") | $(`input[name=model${version_name}]`).val("") | ||||
| @@ -730,7 +740,7 @@ td, th { | |||||
| $(`#file_breadcrumb${version_name}`).empty() | $(`#file_breadcrumb${version_name}`).empty() | ||||
| let htmlBread = "" | let htmlBread = "" | ||||
| htmlBread += `<div class='active section'>${version_name}</div>` | htmlBread += `<div class='active section'>${version_name}</div>` | ||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBread) | $(`#file_breadcrumb${version_name}`).append(htmlBread) | ||||
| }else{ | }else{ | ||||
| renderBrend(version_name,parents,filename,init) | renderBrend(version_name,parents,filename,init) | ||||
| @@ -738,7 +748,7 @@ td, th { | |||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err,version_name); | console.log(err,version_name); | ||||
| }); | }); | ||||
| } | } | ||||
| function renderBrend(version_name,parents,filename,init){ | function renderBrend(version_name,parents,filename,init){ | ||||
| if(init=="folder"){ | if(init=="folder"){ | ||||
| @@ -751,9 +761,9 @@ td, th { | |||||
| }else{ | }else{ | ||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | ||||
| } | } | ||||
| htmlBrend += `<div class='active section'>${filename}</div>` | htmlBrend += `<div class='active section'>${filename}</div>` | ||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBrend) | $(`#file_breadcrumb${version_name}`).append(htmlBrend) | ||||
| $(`input[name=model${version_name}]`).val(parents) | $(`input[name=model${version_name}]`).val(parents) | ||||
| $(`input[name=modelback${version_name}]`).val(filename) | $(`input[name=modelback${version_name}]`).val(filename) | ||||
| @@ -764,7 +774,7 @@ td, th { | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | ||||
| $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | ||||
| } | } | ||||
| } | } | ||||
| function renderDir(data,version_name){ | function renderDir(data,version_name){ | ||||
| let html="" | let html="" | ||||
| @@ -803,14 +813,14 @@ td, th { | |||||
| }else{ | }else{ | ||||
| html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | html += "<span class='truncate has-emoji'>"+ `${dirs_size}` + "</span>" | ||||
| } | } | ||||
| html += "</td>" | html += "</td>" | ||||
| html += "<td class='text right age three wide'>" | html += "<td class='text right age three wide'>" | ||||
| html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | ||||
| html += "</td>" | html += "</td>" | ||||
| html += "</tr>" | html += "</tr>" | ||||
| } | } | ||||
| html += "</tbody>" | html += "</tbody>" | ||||
| html += "</table>" | html += "</table>" | ||||
| @@ -820,9 +830,9 @@ td, th { | |||||
| html += "</div>" | html += "</div>" | ||||
| $(`#dir_list${version_name}`).append(html) | $(`#dir_list${version_name}`).append(html) | ||||
| } | } | ||||
| function logScroll(version_name) { | function logScroll(version_name) { | ||||
| let container = document.querySelector(`#log${version_name}`) | let container = document.querySelector(`#log${version_name}`) | ||||
| let scrollTop = container.scrollTop | let scrollTop = container.scrollTop | ||||
| let scrollHeight = container.scrollHeight | let scrollHeight = container.scrollHeight | ||||
| @@ -835,7 +845,7 @@ td, th { | |||||
| $(`.message${version_name} #header`).text('您已翻阅至日志底部') | $(`.message${version_name} #header`).text('您已翻阅至日志底部') | ||||
| $(`.message${version_name}`).css('display', 'block') | $(`.message${version_name}`).css('display', 'block') | ||||
| setTimeout(function(){ | setTimeout(function(){ | ||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| }, 1000) | }, 1000) | ||||
| }else{ | }else{ | ||||
| if(end_line===data.EndLine){ | if(end_line===data.EndLine){ | ||||
| @@ -843,9 +853,9 @@ td, th { | |||||
| } | } | ||||
| else{ | else{ | ||||
| $(`#log${version_name} input[name=end_line]`).val(data.EndLine) | $(`#log${version_name} input[name=end_line]`).val(data.EndLine) | ||||
| $(`#log${version_name}`).append('<pre>' + data.Content) | |||||
| $(`#log${version_name}`).append('<pre>' + data.Content) | |||||
| } | } | ||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| @@ -858,7 +868,7 @@ td, th { | |||||
| $(`.message${version_name} #header`).text('您已翻阅至日志顶部') | $(`.message${version_name} #header`).text('您已翻阅至日志顶部') | ||||
| $(`.message${version_name}`).css('display', 'block') | $(`.message${version_name}`).css('display', 'block') | ||||
| setTimeout(function(){ | setTimeout(function(){ | ||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| $(`.message${version_name}`).css('display', 'none') | |||||
| }, 1000) | }, 1000) | ||||
| }else{ | }else{ | ||||
| $(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | $(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | ||||
| @@ -869,4 +879,4 @@ td, th { | |||||
| }); | }); | ||||
| } | } | ||||
| } | } | ||||
| </script> | |||||
| </script> | |||||
| @@ -97,7 +97,7 @@ | |||||
| <input id="parents_version" style="width: 60%;" value="" tabindex="3" disabled > | <input id="parents_version" style="width: 60%;" value="" tabindex="3" disabled > | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | ||||
| <textarea style="width: 80%;" id="description" value="{{.description}}" name="description" rows="3" maxlength="255" 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, 256)">{{.description}}</textarea> | <textarea style="width: 80%;" id="description" value="{{.description}}" name="description" rows="3" maxlength="255" 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, 256)">{{.description}}</textarea> | ||||
| @@ -105,7 +105,7 @@ | |||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | ||||
| @@ -119,7 +119,7 @@ | |||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -160,24 +160,24 @@ | |||||
| <span> | <span> | ||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | ||||
| </span> | </span> | ||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">查看样例</a> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | ||||
| <select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="选择数据集"> | |||||
| <select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}"> | |||||
| {{if .dataset_name}} | {{if .dataset_name}} | ||||
| <option name="attachment" value="{{.uuid}}">{{.dataset_name}}</option> | <option name="attachment" value="{{.uuid}}">{{.dataset_name}}</option> | ||||
| {{end}} | {{end}} | ||||
| {{range .attachments}} | {{range .attachments}} | ||||
| <option value="">选择数据集</option> | |||||
| <option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||||
| {{if ne $.uuid .UUID}} | {{if ne $.uuid .UUID}} | ||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | ||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| <span class="tooltips">数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。</span> | |||||
| <span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| @@ -243,24 +243,24 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required unite min_title field"> | <div class="inline required unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | ||||
| <div class="ui labeled input" style="width: 5%;"> | <div class="ui labeled input" style="width: 5%;"> | ||||
| <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="{{.work_server_number}}" readonly> | <input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="{{.work_server_number}}" readonly> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | </div> | ||||
| <!-- 模态框 --> | <!-- 模态框 --> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -298,9 +298,9 @@ | |||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | function Add_parameter(i){ | ||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | value = '<div class="two fields width85" id= "para'+ i +'">' + | ||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | '<div class="field"> ' + | ||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | ||||
| '</div>'+ | '</div>'+ | ||||
| @@ -310,7 +310,7 @@ | |||||
| '</span>' + | '</span>' + | ||||
| '</div>' | '</div>' | ||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | |||||
| } | |||||
| $('#add_run_para').click(function(){ | $('#add_run_para').click(function(){ | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| @@ -336,7 +336,7 @@ | |||||
| $(this).find('input').each(function(){ | $(this).find('input').each(function(){ | ||||
| parameters.push($(this).text()) | parameters.push($(this).text()) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.modal') | $('.ui.parameter.modal') | ||||
| .modal('hide'); | .modal('hide'); | ||||
| @@ -379,9 +379,9 @@ | |||||
| onChange: function(){ | onChange: function(){ | ||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | if ($('.ui.save.checkbox').checkbox('is checked')){ | ||||
| $('#save_para').removeClass("disabled") | $('#save_para').removeClass("disabled") | ||||
| }else{ | }else{ | ||||
| $('#save_para').addClass("disabled") | |||||
| $('#save_para').addClass("disabled") | |||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -535,7 +535,7 @@ | |||||
| // $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| }, | }, | ||||
| onFailure: function(e){ | |||||
| onFailure: function(e){ | |||||
| return false; | return false; | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -569,6 +569,6 @@ | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| get_name() | get_name() | ||||
| send_run_para() | send_run_para() | ||||
| validate() | |||||
| validate() | |||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -38,7 +38,7 @@ | |||||
| <div class="bgtask-content-txt">训练任务:您还没创建过训练任务,请先创建<a href="{{.RepoLink}}/modelarts/train-job">训练任务</a>。</div> | <div class="bgtask-content-txt">训练任务:您还没创建过训练任务,请先创建<a href="{{.RepoLink}}/modelarts/train-job">训练任务</a>。</div> | ||||
| {{end}} | {{end}} | ||||
| <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | <div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | ||||
| </div> | </div> | ||||
| <div style="display: none;"> | <div style="display: none;"> | ||||
| <div id="model_list"></div> | <div id="model_list"></div> | ||||
| @@ -79,10 +79,10 @@ | |||||
| </div> | </div> | ||||
| <div class="actions"> | <div class="actions"> | ||||
| <div class="ui red basic inverted cancel button"> | <div class="ui red basic inverted cancel button"> | ||||
| <i class="remove icon"></i> 取消操作 | |||||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||||
| </div> | </div> | ||||
| <div class="ui green basic inverted ok button"> | <div class="ui green basic inverted ok button"> | ||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -99,7 +99,7 @@ | |||||
| <!-- <p>asdasdasd</p> --> | <!-- <p>asdasdasd</p> --> | ||||
| </div> | </div> | ||||
| <input type="hidden" name="_csrf" value=""> | <input type="hidden" name="_csrf" value=""> | ||||
| <div class="two inline fields "> | |||||
| <div class="two inline fields "> | |||||
| <div class="required ten wide field"> | <div class="required ten wide field"> | ||||
| <label style="margin-left: -23px;">选择训练任务</label> | <label style="margin-left: -23px;">选择训练任务</label> | ||||
| <div class="ui dropdown selection search width83 loading" id="choice_model"> | <div class="ui dropdown selection search width83 loading" id="choice_model"> | ||||
| @@ -117,7 +117,7 @@ | |||||
| <div class="default text">选择版本</div> | <div class="default text">选择版本</div> | ||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="job-version"> | <div class="menu" id="job-version"> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -149,8 +149,8 @@ | |||||
| <button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button> | <button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -179,7 +179,7 @@ | |||||
| $("#job-name").empty() | $("#job-name").empty() | ||||
| createModelName() | createModelName() | ||||
| loadTrainList() | loadTrainList() | ||||
| }, | }, | ||||
| onHide:function(){ | onHide:function(){ | ||||
| document.getElementById("formId").reset(); | document.getElementById("formId").reset(); | ||||
| @@ -188,7 +188,7 @@ | |||||
| $('.ui.dimmer').css({"background-color":""}) | $('.ui.dimmer').css({"background-color":""}) | ||||
| $('.ui.error.message').text() | $('.ui.error.message').text() | ||||
| $('.ui.error.message').css('display','none') | $('.ui.error.message').css('display','none') | ||||
| } | } | ||||
| }) | }) | ||||
| .modal('show') | .modal('show') | ||||
| @@ -221,7 +221,7 @@ | |||||
| } | } | ||||
| function loadTrainList(){ | function loadTrainList(){ | ||||
| $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | ||||
| console.log(data) | |||||
| const n_length = data.length | const n_length = data.length | ||||
| let train_html='' | let train_html='' | ||||
| for (let i=0;i<n_length;i++){ | for (let i=0;i<n_length;i++){ | ||||
| @@ -233,7 +233,7 @@ | |||||
| $('#choice_model .default.text').text(data[0].DisplayJobName) | $('#choice_model .default.text').text(data[0].DisplayJobName) | ||||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | $('#choice_model input[name="JobId"]').val(data[0].JobID) | ||||
| loadTrainVersion() | loadTrainVersion() | ||||
| }) | }) | ||||
| } | } | ||||
| function loadTrainVersion(value){ | function loadTrainVersion(value){ | ||||
| @@ -251,7 +251,7 @@ | |||||
| $('#choice_version .default.text').text(data[0].VersionName) | $('#choice_version .default.text').text(data[0].VersionName) | ||||
| $('#choice_version input[name="VersionName"]').val(data[0].VersionName) | $('#choice_version input[name="VersionName"]').val(data[0].VersionName) | ||||
| } | } | ||||
| }) | }) | ||||
| } | } | ||||
| </script> | </script> | ||||
| @@ -77,13 +77,15 @@ | |||||
| {{else if eq .GetOpType 26}} | {{else if eq .GetOpType 26}} | ||||
| {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 27}} | {{else if eq .GetOpType 27}} | ||||
| {{$.i18n.Tr "action.task_trainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{$.i18n.Tr "action.task_nputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{else if eq .GetOpType 28}} | {{else if eq .GetOpType 28}} | ||||
| {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 29}} | {{else if eq .GetOpType 29}} | ||||
| {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 30}} | {{else if eq .GetOpType 30}} | ||||
| {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 31}} | |||||
| {{$.i18n.Tr "action.task_gputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{end}} | {{end}} | ||||
| </p> | </p> | ||||
| {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | ||||
| @@ -129,6 +131,8 @@ | |||||
| <span class="text grey"><i class="ri-vip-crown-line icon big"></i></span> | <span class="text grey"><i class="ri-vip-crown-line icon big"></i></span> | ||||
| {{else if eq .GetOpType 30}} | {{else if eq .GetOpType 30}} | ||||
| <span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | <span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | ||||
| {{else if eq .GetOpType 31}} | |||||
| <span class="text grey"><i class="ri-character-recognition-line icon big"></i></span> | |||||
| {{else}} | {{else}} | ||||
| <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | ||||
| {{end}} | {{end}} | ||||
| @@ -8,9 +8,11 @@ | |||||
| {{ file_status_text }} | {{ file_status_text }} | ||||
| <strong class="success text red">{{ status }}</strong> | <strong class="success text red">{{ status }}</strong> | ||||
| </p> | </p> | ||||
| <p>说明:<br> | |||||
| <el-button style="background-color: #21ba45;" type="success" :disabled="btnFlag" @click="onFileAdded">{{upload}}</el-button> | |||||
| <el-button type="info" @click="cancelDataset">{{cancel}}</el-button> | |||||
| <!-- <p>说明:<br> | |||||
| - 只有zip格式的数据集才能发起云脑任务;<br> | - 只有zip格式的数据集才能发起云脑任务;<br> | ||||
| - 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> | |||||
| - 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> --> | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -24,9 +26,19 @@ import qs from 'qs'; | |||||
| import createDropzone from '../features/dropzone.js'; | import createDropzone from '../features/dropzone.js'; | ||||
| const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config; | const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config; | ||||
| const CloudBrainType = 0; | |||||
| // const uploadtype = 0; | |||||
| export default { | export default { | ||||
| props:{ | |||||
| uploadtype:{ | |||||
| type:Number, | |||||
| required:true | |||||
| }, | |||||
| desc:{ | |||||
| type:String, | |||||
| default:'' | |||||
| } | |||||
| }, | |||||
| data() { | data() { | ||||
| return { | return { | ||||
| dropzoneUploader: null, | dropzoneUploader: null, | ||||
| @@ -36,7 +48,12 @@ export default { | |||||
| progress: 0, | progress: 0, | ||||
| status: '', | status: '', | ||||
| dropzoneParams: {}, | dropzoneParams: {}, | ||||
| file_status_text: '' | |||||
| file_status_text: '', | |||||
| file:{}, | |||||
| repoPath:'', | |||||
| btnFlag:false, | |||||
| cancel:'', | |||||
| upload:'', | |||||
| }; | }; | ||||
| }, | }, | ||||
| @@ -44,33 +61,47 @@ export default { | |||||
| this.dropzoneParams = $('div#minioUploader-params'); | this.dropzoneParams = $('div#minioUploader-params'); | ||||
| this.file_status_text = this.dropzoneParams.data('file-status'); | this.file_status_text = this.dropzoneParams.data('file-status'); | ||||
| this.status = this.dropzoneParams.data('file-init-status'); | this.status = this.dropzoneParams.data('file-init-status'); | ||||
| let previewTemplate = ''; | |||||
| previewTemplate += '<div class="dz-preview dz-file-preview">\n '; | |||||
| previewTemplate += ' <div class="dz-details">\n '; | |||||
| previewTemplate += ' <div class="dz-filename">'; | |||||
| previewTemplate += | |||||
| ' <span data-dz-name data-dz-thumbnail></span>'; | |||||
| previewTemplate += ' </div>\n '; | |||||
| previewTemplate += ' <div class="dz-size" data-dz-size style="white-space: nowrap"></div>\n '; | |||||
| previewTemplate += ' </div>\n '; | |||||
| previewTemplate += ' <div class="dz-progress ui active progress">'; | |||||
| previewTemplate += | |||||
| ' <div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div>\n '; | |||||
| previewTemplate += ' </div>\n '; | |||||
| previewTemplate += ' <div class="dz-success-mark">'; | |||||
| previewTemplate += ' <span>上传成功</span>'; | |||||
| previewTemplate += ' </div>\n '; | |||||
| previewTemplate += ' <div class="dz-error-mark">'; | |||||
| previewTemplate += ' <span>上传失败</span>'; | |||||
| previewTemplate += ' </div>\n '; | |||||
| previewTemplate += ' <div class="dz-error-message">'; | |||||
| previewTemplate += ' <span data-dz-errormessage></span>'; | |||||
| previewTemplate += ' </div>\n'; | |||||
| previewTemplate += '</div>'; | |||||
| this.repoPath = this.dropzoneParams.data('repopath'); | |||||
| this.cancel = this.dropzoneParams.data('cancel'); | |||||
| this.upload = this.dropzoneParams.data('upload'); | |||||
| // let previewTemplate = ''; | |||||
| // previewTemplate += '<div class="dz-preview dz-file-preview">\n '; | |||||
| // previewTemplate += ' <div class="dz-details">\n '; | |||||
| // previewTemplate += ' <div class="dz-filename">'; | |||||
| // previewTemplate += | |||||
| // ' <span data-dz-name data-dz-thumbnail></span>'; | |||||
| // previewTemplate += ' </div>\n '; | |||||
| // previewTemplate += ' <div class="dz-size" data-dz-size style="white-space: nowrap"></div>\n '; | |||||
| // previewTemplate += ' </div>\n '; | |||||
| // previewTemplate += ' <div class="dz-progress ui active progress">'; | |||||
| // previewTemplate += | |||||
| // ' <div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div>\n '; | |||||
| // previewTemplate += ' </div>\n '; | |||||
| // previewTemplate += ' <div class="dz-success-mark">'; | |||||
| // previewTemplate += ' <span>上传成功</span>'; | |||||
| // previewTemplate += ' </div>\n '; | |||||
| // previewTemplate += ' <div class="dz-error-mark">'; | |||||
| // previewTemplate += ' <span>上传失败</span>'; | |||||
| // previewTemplate += ' </div>\n '; | |||||
| // previewTemplate += ' <div class="dz-error-message">'; | |||||
| // previewTemplate += ' <span data-dz-errormessage></span>'; | |||||
| // previewTemplate += ' </div>\n'; | |||||
| // previewTemplate += '</div>'; | |||||
| let previewTemplate = '' | |||||
| previewTemplate += '<div class="dz-preview dz-file-preview" style="width:100%;background: none;">' | |||||
| previewTemplate += '<div class="dz-details" style="opacity: 1;">' | |||||
| previewTemplate += '<div class="dz-filename"><span data-dz-name></span></div>' | |||||
| previewTemplate += '<div class="dz-size" data-dz-size></div>' | |||||
| previewTemplate += '<div class="dz-progress ui active progress" style="top: 75%;width: 80%;left: 15%;"><div class="dz-upload bar" data-dz-uploadprogress><div class="progress"></div></div></div>' | |||||
| // previewTemplate += '<img data-dz-thumbnail />' | |||||
| previewTemplate += '</div>' | |||||
| previewTemplate += '<div class="dz-success-mark"><span>✔</span></div>' | |||||
| previewTemplate += '<div class="dz-error-mark"><span>✘</span></div>' | |||||
| previewTemplate += '<div class="dz-error-message"><span data-dz-errormessage></span></div>' | |||||
| previewTemplate += '</div>' | |||||
| const $dropzone = $('div#dataset'); | const $dropzone = $('div#dataset'); | ||||
| console.log('createDropzone'); | |||||
| const dropzoneUploader = await createDropzone($dropzone[0], { | const dropzoneUploader = await createDropzone($dropzone[0], { | ||||
| url: '/todouploader', | url: '/todouploader', | ||||
| maxFiles: this.maxFiles, | maxFiles: this.maxFiles, | ||||
| @@ -84,10 +115,7 @@ export default { | |||||
| previewTemplate | previewTemplate | ||||
| }); | }); | ||||
| dropzoneUploader.on('addedfile', (file) => { | dropzoneUploader.on('addedfile', (file) => { | ||||
| setTimeout(() => { | |||||
| // eslint-disable-next-line no-unused-expressions | |||||
| file.accepted && this.onFileAdded(file); | |||||
| }, 200); | |||||
| this.file = file | |||||
| }); | }); | ||||
| dropzoneUploader.on('maxfilesexceeded', function (file) { | dropzoneUploader.on('maxfilesexceeded', function (file) { | ||||
| if (this.files[0].status !== 'success') { | if (this.files[0].status !== 'success') { | ||||
| @@ -102,14 +130,23 @@ export default { | |||||
| this.dropzoneUploader = dropzoneUploader; | this.dropzoneUploader = dropzoneUploader; | ||||
| }, | }, | ||||
| methods: { | methods: { | ||||
| cancelDataset(){ | |||||
| location.href = this.repoPath | |||||
| this.dropzoneUploader.removeAllFiles(true) | |||||
| }, | |||||
| resetStatus() { | resetStatus() { | ||||
| this.progress = 0; | this.progress = 0; | ||||
| this.status = ''; | this.status = ''; | ||||
| console.log(this.uploadtype) | |||||
| }, | }, | ||||
| updateProgress(file, progress) { | updateProgress(file, progress) { | ||||
| console.log("progress---",progress) | |||||
| file.previewTemplate.querySelector( | file.previewTemplate.querySelector( | ||||
| '.dz-upload' | '.dz-upload' | ||||
| ).style.width = `${progress}%`; | |||||
| ).style.width = `${progress}%` | |||||
| file.previewTemplate.querySelector( | |||||
| '.dz-upload' | |||||
| ).style.background = '#409eff'; | |||||
| }, | }, | ||||
| emitDropzoneSuccess(file) { | emitDropzoneSuccess(file) { | ||||
| file.status = 'success'; | file.status = 'success'; | ||||
| @@ -122,18 +159,24 @@ export default { | |||||
| this.dropzoneUploader.emit('error', file); | this.dropzoneUploader.emit('error', file); | ||||
| // this.dropzoneUploader.emit('complete', file); | // this.dropzoneUploader.emit('complete', file); | ||||
| }, | }, | ||||
| onFileAdded(file) { | |||||
| file.datasetId = document | |||||
| onFileAdded() { | |||||
| this.btnFlag = true | |||||
| this.file.datasetId = document | |||||
| .getElementById('datasetId') | .getElementById('datasetId') | ||||
| .getAttribute('datasetId'); | .getAttribute('datasetId'); | ||||
| this.resetStatus(); | this.resetStatus(); | ||||
| this.computeMD5(file); | |||||
| console.log(this.file,!this.file?.upload) | |||||
| if(!this.file?.upload){ | |||||
| this.btnFlag = false | |||||
| return | |||||
| } | |||||
| this.computeMD5(this.file); | |||||
| }, | }, | ||||
| finishUpload(file) { | finishUpload(file) { | ||||
| this.emitDropzoneSuccess(file); | this.emitDropzoneSuccess(file); | ||||
| setTimeout(() => { | setTimeout(() => { | ||||
| window.location.reload(); | |||||
| window.location.href = this.repoPath | |||||
| }, 1000); | }, 1000); | ||||
| }, | }, | ||||
| @@ -249,7 +292,7 @@ export default { | |||||
| file_name: file.name, | file_name: file.name, | ||||
| size: file.size, | size: file.size, | ||||
| dataset_id: file.datasetId, | dataset_id: file.datasetId, | ||||
| type: CloudBrainType, | |||||
| type: this.uploadtype, | |||||
| _csrf: csrf | _csrf: csrf | ||||
| }) | }) | ||||
| ); | ); | ||||
| @@ -260,6 +303,8 @@ export default { | |||||
| const params = { | const params = { | ||||
| params: { | params: { | ||||
| md5: file.uniqueIdentifier, | md5: file.uniqueIdentifier, | ||||
| type: this.uploadtype, | |||||
| file_name: file.name, | |||||
| _csrf: csrf | _csrf: csrf | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -282,13 +327,15 @@ export default { | |||||
| }, | }, | ||||
| async newMultiUpload(file) { | async newMultiUpload(file) { | ||||
| console.log(this.uploadtype,this) | |||||
| const res = await axios.get('/attachments/new_multipart', { | const res = await axios.get('/attachments/new_multipart', { | ||||
| params: { | params: { | ||||
| totalChunkCounts: file.totalChunkCounts, | totalChunkCounts: file.totalChunkCounts, | ||||
| md5: file.uniqueIdentifier, | md5: file.uniqueIdentifier, | ||||
| size: file.size, | size: file.size, | ||||
| fileType: file.type, | fileType: file.type, | ||||
| type: CloudBrainType, | |||||
| type: this.uploadtype, | |||||
| file_name: file.name, | |||||
| _csrf: csrf | _csrf: csrf | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -306,6 +353,7 @@ export default { | |||||
| fileReader = new FileReader(), | fileReader = new FileReader(), | ||||
| time = new Date().getTime(); | time = new Date().getTime(); | ||||
| let currentChunk = 0; | let currentChunk = 0; | ||||
| let _this = this | |||||
| function loadNext() { | function loadNext() { | ||||
| const start = currentChunk * chunkSize; | const start = currentChunk * chunkSize; | ||||
| @@ -329,7 +377,8 @@ export default { | |||||
| uploadID: file.uploadID, | uploadID: file.uploadID, | ||||
| size: partSize, | size: partSize, | ||||
| chunkNumber: currentChunk + 1, | chunkNumber: currentChunk + 1, | ||||
| type: CloudBrainType, | |||||
| type: _this.uploadtype, | |||||
| file_name: file.name, | |||||
| _csrf: csrf | _csrf: csrf | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -343,14 +392,27 @@ export default { | |||||
| } | } | ||||
| async function uploadMinioNewMethod(url,e){ | |||||
| async function uploadMinioNewMethod(url,e){ | |||||
| var xhr = new XMLHttpRequest(); | var xhr = new XMLHttpRequest(); | ||||
| xhr.open('PUT', url, false); | |||||
| xhr.setRequestHeader('Content-Type', 'text/plain') | |||||
| xhr.send(e.target.result); | |||||
| var etagValue = xhr.getResponseHeader('etag'); | |||||
| //console.log(etagValue); | |||||
| etags[currentChunk] = etagValue; | |||||
| xhr.open('PUT', url, false); | |||||
| if(_this.uploadtype===0){ | |||||
| xhr.setRequestHeader('Content-Type', 'text/plain') | |||||
| xhr.send(e.target.result); | |||||
| var etagValue = xhr.getResponseHeader('etag'); | |||||
| etags[currentChunk] = etagValue; | |||||
| } | |||||
| else if(_this.uploadtype===1){ | |||||
| xhr.setRequestHeader('Content-Type', '') | |||||
| xhr.send(e.target.result); | |||||
| var etagValue = xhr.getResponseHeader('ETag'); | |||||
| //console.log(etagValue); | |||||
| etags[currentChunk] = etagValue; | |||||
| } | |||||
| } | } | ||||
| async function updateChunk(currentChunk) { | async function updateChunk(currentChunk) { | ||||
| @@ -395,6 +457,7 @@ export default { | |||||
| } | } | ||||
| async function completeUpload() { | async function completeUpload() { | ||||
| console.log(_this.uploadtype) | |||||
| return await axios.post( | return await axios.post( | ||||
| '/attachments/complete_multipart', | '/attachments/complete_multipart', | ||||
| qs.stringify({ | qs.stringify({ | ||||
| @@ -403,8 +466,9 @@ export default { | |||||
| file_name: file.name, | file_name: file.name, | ||||
| size: file.size, | size: file.size, | ||||
| dataset_id: file.datasetId, | dataset_id: file.datasetId, | ||||
| type: CloudBrainType, | |||||
| _csrf: csrf | |||||
| type: _this.uploadtype, | |||||
| _csrf: csrf, | |||||
| description:_this.desc | |||||
| }) | }) | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -430,6 +494,7 @@ export default { | |||||
| 1}/${chunks}个分片上传` | 1}/${chunks}个分片上传` | ||||
| ); | ); | ||||
| this.progress = Math.ceil((currentChunk / chunks) * 100); | this.progress = Math.ceil((currentChunk / chunks) * 100); | ||||
| console.log("((currentChunk / chunks) * 100).toFixed(2)",((currentChunk / chunks) * 100).toFixed(2)) | |||||
| this.updateProgress(file, ((currentChunk / chunks) * 100).toFixed(2)); | this.updateProgress(file, ((currentChunk / chunks) * 100).toFixed(2)); | ||||
| this.status = `${this.dropzoneParams.data('uploading')} ${( | this.status = `${this.dropzoneParams.data('uploading')} ${( | ||||
| (currentChunk / chunks) * | (currentChunk / chunks) * | ||||
| @@ -443,6 +508,7 @@ export default { | |||||
| file.size | file.size | ||||
| } 用时:${(new Date().getTime() - time) / 1000} s` | } 用时:${(new Date().getTime() - time) / 1000} s` | ||||
| ); | ); | ||||
| this.updateProgress(file, 100); | |||||
| this.progress = 100; | this.progress = 100; | ||||
| this.status = this.dropzoneParams.data('upload-complete'); | this.status = this.dropzoneParams.data('upload-complete'); | ||||
| this.finishUpload(file); | this.finishUpload(file); | ||||
| @@ -455,7 +521,7 @@ export default { | |||||
| <style> | <style> | ||||
| .dropzone-wrapper { | .dropzone-wrapper { | ||||
| margin: 2em auto; | |||||
| margin: 0; | |||||
| } | } | ||||
| .ui .dropzone { | .ui .dropzone { | ||||
| border: 2px dashed #0087f5; | border: 2px dashed #0087f5; | ||||
| @@ -473,4 +539,8 @@ export default { | |||||
| border-bottom: 1px solid #dadce0; | border-bottom: 1px solid #dadce0; | ||||
| min-height: 0; | min-height: 0; | ||||
| } | } | ||||
| .upload-info{ | |||||
| margin-top: 1em; | |||||
| margin-bottom: 3em; | |||||
| } | |||||
| </style> | </style> | ||||
| @@ -460,7 +460,7 @@ export default { | |||||
| <style> | <style> | ||||
| .dropzone-wrapper { | .dropzone-wrapper { | ||||
| margin: 2em auto; | |||||
| margin: 0; | |||||
| } | } | ||||
| .ui .dropzone { | .ui .dropzone { | ||||
| border: 2px dashed #0087f5; | border: 2px dashed #0087f5; | ||||
| @@ -478,4 +478,7 @@ export default { | |||||
| border-bottom: 1px solid #dadce0; | border-bottom: 1px solid #dadce0; | ||||
| min-height: 0; | min-height: 0; | ||||
| } | } | ||||
| .upload-info{ | |||||
| margin-top: 0.2em; | |||||
| } | |||||
| </style> | </style> | ||||
| @@ -148,6 +148,31 @@ | |||||
| prop="contributor" | prop="contributor" | ||||
| label="贡献者数" | label="贡献者数" | ||||
| align="center"> | align="center"> | ||||
| </el-table-column> | |||||
| <el-table-column | |||||
| prop="isFork" | |||||
| label="派生" | |||||
| align="center"> | |||||
| <template slot-scope="scope"> | |||||
| {{scope.row.isFork|changeType}} | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column | |||||
| prop="isMirror" | |||||
| label="镜像" | |||||
| align="center"> | |||||
| <template slot-scope="scope"> | |||||
| {{scope.row.isMirror|changeType}} | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column | |||||
| prop="createUnix" | |||||
| label="项目创建时间" | |||||
| width="120px" | |||||
| align="center"> | |||||
| <template slot-scope="scope"> | |||||
| {{scope.row.createUnix|transformTimestamp}} | |||||
| </template> | |||||
| </el-table-column> | </el-table-column> | ||||
| </el-table> | </el-table> | ||||
| </div> | </div> | ||||
| @@ -1140,6 +1165,17 @@ | |||||
| return " <a href=\" mailto:" + value.email + "class=\"circular ui button\">" +value.user+ "</a>" | return " <a href=\" mailto:" + value.email + "class=\"circular ui button\">" +value.user+ "</a>" | ||||
| } | } | ||||
| }, | |||||
| transformTimestamp(timestamp){ | |||||
| let a = new Date(timestamp*1000); | |||||
| const date = new Date(a); | |||||
| const Y = date.getFullYear() + '/'; | |||||
| const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '/'; | |||||
| const D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' '; | |||||
| const h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':'; | |||||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes()); | |||||
| const dateString = Y + M + D + h + m ;//+ s; | |||||
| return dateString; | |||||
| }, | }, | ||||
| }, | }, | ||||
| @@ -1,4 +1,6 @@ | |||||
| export default async function initCloudrain() { | export default async function initCloudrain() { | ||||
| let debug_button = $('.cloudbrain_debug').data('debug') | |||||
| let debug_again_button = $('.cloudbrain_debug').data('debug-again') | |||||
| let timeid = window.setInterval(loadJobStatus, 15000); | let timeid = window.setInterval(loadJobStatus, 15000); | ||||
| $(document).ready(loadJobStatus); | $(document).ready(loadJobStatus); | ||||
| function loadJobStatus() { | function loadJobStatus() { | ||||
| @@ -24,7 +26,7 @@ export default async function initCloudrain() { | |||||
| finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | ||||
| } | } | ||||
| if(status==="RUNNING"){ | if(status==="RUNNING"){ | ||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_button).css("margin","0 1rem") | |||||
| $('#model-image-'+ID).removeClass('disabled').addClass('blue') | $('#model-image-'+ID).removeClass('disabled').addClass('blue') | ||||
| } | } | ||||
| if(status!=="RUNNING"){ | if(status!=="RUNNING"){ | ||||
| @@ -36,7 +38,7 @@ export default async function initCloudrain() { | |||||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | ||||
| } | } | ||||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | ||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin","0") | |||||
| } | } | ||||
| if(["RUNNING","WAITING"].includes(status)){ | if(["RUNNING","WAITING"].includes(status)){ | ||||
| $('#ai-stop-'+ID).removeClass('disabled').addClass('blue') | $('#ai-stop-'+ID).removeClass('disabled').addClass('blue') | ||||
| @@ -114,7 +116,7 @@ export default async function initCloudrain() { | |||||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | $('#' + ID+'-icon').removeClass().addClass(res.status) | ||||
| $('#' + ID+ '-text').text(res.status) | $('#' + ID+ '-text').text(res.status) | ||||
| if(res.status==="STOPPED"){ | if(res.status==="STOPPED"){ | ||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin","0") | |||||
| $('#ai-image-'+ID).removeClass('blue').addClass('disabled') | $('#ai-image-'+ID).removeClass('blue').addClass('disabled') | ||||
| $('#ai-model-debug-'+ID).removeClass('blue').addClass('disabled') | $('#ai-model-debug-'+ID).removeClass('blue').addClass('disabled') | ||||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | ||||
| @@ -214,7 +216,7 @@ export default async function initCloudrain() { | |||||
| $('#' + ID+ '-text').text(res.status) | $('#' + ID+ '-text').text(res.status) | ||||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | ||||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | ||||
| $('#ai-debug-'+ID).text("调试").css("margin","0 1rem") | |||||
| $('#ai-debug-'+ID).text(debug_button).css("margin","0 1rem") | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | ||||
| @@ -43,7 +43,7 @@ import Contributors from './components/Contributors.vue' | |||||
| import Model from './components/Model.vue'; | import Model from './components/Model.vue'; | ||||
| import WxAutorize from './components/WxAutorize.vue' | import WxAutorize from './components/WxAutorize.vue' | ||||
| import initCloudrain from './features/cloudrbanin.js' | import initCloudrain from './features/cloudrbanin.js' | ||||
| // import $ from 'jquery.js' | |||||
| Vue.use(ElementUI); | Vue.use(ElementUI); | ||||
| Vue.prototype.$axios = axios; | Vue.prototype.$axios = axios; | ||||
| @@ -2918,6 +2918,7 @@ $(document).ready(async () => { | |||||
| initVueApp(); | initVueApp(); | ||||
| initVueUploader(); | initVueUploader(); | ||||
| initObsUploader(); | initObsUploader(); | ||||
| initVueDataset(); | |||||
| initVueEditAbout(); | initVueEditAbout(); | ||||
| initVueEditTopic(); | initVueEditTopic(); | ||||
| initVueContributors(); | initVueContributors(); | ||||
| @@ -3658,6 +3659,594 @@ function initVueEditAbout() { | |||||
| }); | }); | ||||
| } | } | ||||
| function initVueDataset() { | |||||
| const el = document.getElementById('dataset-base'); | |||||
| if (!el) { | |||||
| return; | |||||
| } | |||||
| let link=$('#square-link').data('link') | |||||
| let repolink = $('.dataset-repolink').data('repolink') | |||||
| let cloudbrainType = $('.dataset-repolink').data('cloudranin-type') | |||||
| const clearBtn = document.getElementsByClassName("clear_dataset_value"); | |||||
| const params = new URLSearchParams(location.search) | |||||
| for (let i = 0; i < clearBtn.length; i++) { | |||||
| clearBtn[i].addEventListener('click',function(e){ | |||||
| let searchType=e.target.getAttribute("data-clear-value") | |||||
| if(params.has(searchType)){ | |||||
| params.delete(searchType) | |||||
| let clearSearch = params.toString() | |||||
| location.href = link + '?' + clearSearch | |||||
| } | |||||
| }) | |||||
| } | |||||
| const items = [] | |||||
| const zipStatus = [] | |||||
| $('#dataset-range-value').find('.item').each(function(){ | |||||
| items.push($(this).data('private')) | |||||
| zipStatus.push($(this).data('decompress-state')) | |||||
| }) | |||||
| let num_stars = $('#dataset-range-value').data('num-stars') | |||||
| let star_active = $('#dataset-range-value').data('star-active') | |||||
| const ruleForm = {} | |||||
| if(document.getElementById('dataset-edit-value')){ | |||||
| let $this = $('#dataset-edit-value') | |||||
| ruleForm.title = $this.data('edit-title') || '' | |||||
| ruleForm.description = $this.data('edit-description') || '' | |||||
| ruleForm.category = $this.data('edit-category') || '' | |||||
| ruleForm.task = $this.data('edit-task') || '' | |||||
| ruleForm.license = $this.data('edit-license') || '' | |||||
| ruleForm.id = $this.data('edit-id')|| '' | |||||
| ruleForm._csrf = csrf | |||||
| } | |||||
| const starItems = [] | |||||
| const starActives = [] | |||||
| $('#datasets-square-range-value').find('.item').each(function(){ | |||||
| starItems.push($(this).data('num-stars')) | |||||
| starActives.push($(this).data('star-active')) | |||||
| }) | |||||
| const taskLists = [] | |||||
| const licenseLists = [] | |||||
| $('#task-square-range-value').find('.item').each(function(){ | |||||
| taskLists.push($(this).data('task')) | |||||
| }) | |||||
| $('#task-square-range-value').find('.item').each(function(){ | |||||
| licenseLists.push($(this).data('license')) | |||||
| }) | |||||
| let dataset_file_desc | |||||
| if(document.getElementById('dataset-file-desc')){ | |||||
| dataset_file_desc = document.getElementById('dataset-file-desc').value | |||||
| } | |||||
| // getEditInit(){ | |||||
| // if($('#dataset-edit-value')){ | |||||
| // $this = $('#dataset-edit-value') | |||||
| // this.ruleForm.title = $this.data('edit-title') || '' | |||||
| // this.ruleForm.description = $this.data('edit-description') || '' | |||||
| // this.ruleForm.category = $this.data('edit-category') || '' | |||||
| // this.ruleForm.task = $this.data('edit-task') || '' | |||||
| // this.ruleForm.license = $this.data('edit-license') || '' | |||||
| // this.ruleForm.id = $this.data('edit-id')|| '' | |||||
| // } | |||||
| // }, | |||||
| new Vue({ | |||||
| delimiters: ['${', '}'], | |||||
| el, | |||||
| data: { | |||||
| suburl: AppSubUrl, | |||||
| url:'', | |||||
| type:0, | |||||
| desc:'', | |||||
| descfile:'', | |||||
| datasetType:'', | |||||
| privates:[], | |||||
| zipStatus:[], | |||||
| starItems:[], | |||||
| starActives:[], | |||||
| taskLists:[], | |||||
| taskShow:[], | |||||
| licenseLists:[], | |||||
| licenseShow:[], | |||||
| hasMoreBthHis: false, | |||||
| showMoreHis:false, | |||||
| star_active:false, | |||||
| num_stars:0, | |||||
| dialogVisible:false, | |||||
| activeName: 'first', | |||||
| searchDataItem:'', | |||||
| currentRepoDataset:[], | |||||
| myDataset:[], | |||||
| publicDataset:[], | |||||
| myFavoriteDataset:[], | |||||
| page:1, | |||||
| totalnums:0, | |||||
| repolink:'', | |||||
| cloudbrainType:0, | |||||
| dataset_uuid:'', | |||||
| dataset_name:'', | |||||
| loadingDataIndex:true, | |||||
| timer:null, | |||||
| ruleForm:{ | |||||
| title:'', | |||||
| description:'', | |||||
| category:'', | |||||
| task:'', | |||||
| license:'', | |||||
| _csrf:csrf, | |||||
| }, | |||||
| ruleForm1:{ | |||||
| title:'', | |||||
| description:'', | |||||
| category:'', | |||||
| task:'', | |||||
| license:'', | |||||
| _csrf:'', | |||||
| id:'' | |||||
| }, | |||||
| rules: { | |||||
| title: [ | |||||
| { required: true, message: '请输入数据集名称', trigger: 'blur' }, | |||||
| { min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }, | |||||
| // {required:true,message:'test',pattern:'/^[a-zA-Z0-9-_]{1,100}[^-]$/',trigger:'blur'}, | |||||
| { validator: (rule, value, callback) => { | |||||
| if (/^[a-zA-Z0-9-_.]{0,100}$/.test(value) == false) { | |||||
| callback(new Error("输入不符合数据集名称规则")); | |||||
| } else { | |||||
| callback(); | |||||
| } | |||||
| }, trigger: 'blur'} | |||||
| ], | |||||
| description: [ | |||||
| { required: true, message: '请输入数据集描述详情', trigger: 'blur' } | |||||
| ], | |||||
| category: [ | |||||
| { required: true, message: '请选择分类', trigger: 'change' } | |||||
| ], | |||||
| task: [ | |||||
| { required: true, message: '请选择研究方向/应用领域', trigger: 'change' } | |||||
| ], | |||||
| // license: [ | |||||
| // { required: true, message: '请选择活动区域', trigger: 'change' } | |||||
| // ] | |||||
| }, | |||||
| }, | |||||
| components: { | |||||
| MinioUploader, | |||||
| ObsUploader | |||||
| }, | |||||
| mounted(){ | |||||
| // if(document.getElementById('postPath')){ | |||||
| // this.url = document.getElementById('postPath').value | |||||
| // } | |||||
| // this.privates = items | |||||
| // this.num_stars = num_stars | |||||
| // this.star_active = star_active | |||||
| // this.ruleForm1 = ruleForm | |||||
| // // this.getEditInit() | |||||
| // this.getTypeList() | |||||
| this.getTypeList() | |||||
| if(!!document.getElementById('dataset-repolink-init')){ | |||||
| this.getCurrentRepoDataset(this.repolink,this.cloudbrainType) | |||||
| } | |||||
| }, | |||||
| created(){ | |||||
| if(document.getElementById('postPath')){ | |||||
| this.url = document.getElementById('postPath').value | |||||
| } | |||||
| this.privates = items | |||||
| this.zipStatus = zipStatus | |||||
| this.num_stars = num_stars | |||||
| this.star_active = star_active | |||||
| this.ruleForm1 = ruleForm | |||||
| // this.getEditInit() | |||||
| this.starItems = starItems | |||||
| this.starActives = starActives | |||||
| this.taskLists = taskLists | |||||
| this.licenseLists = licenseLists | |||||
| this.descfile = dataset_file_desc | |||||
| this.repolink = repolink | |||||
| this.cloudbrainType = cloudbrainType | |||||
| }, | |||||
| methods:{ | |||||
| handleCurrentChange(val) { | |||||
| this.page = val | |||||
| switch(this.activeName){ | |||||
| case 'first': | |||||
| this.getCurrentRepoDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'second': | |||||
| this.getMyDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'third': | |||||
| this.getPublicDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'fourth': | |||||
| this.getStarDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| } | |||||
| }, | |||||
| createDataset(formName){ | |||||
| let _this = this | |||||
| this.$refs[formName].validate((valid)=>{ | |||||
| if(valid){ | |||||
| document.getElementById("mask").style.display = "block" | |||||
| _this.$axios.post(_this.url,_this.qs.stringify(_this.ruleForm)).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| document.getElementById("mask").style.display = "none" | |||||
| location.href = _this.url.split('/create')[0]+'?type=-1' | |||||
| }else{ | |||||
| console.log(res.data.Message) | |||||
| } | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }).catch(error=>{ | |||||
| console.log(error) | |||||
| }) | |||||
| } | |||||
| else{ | |||||
| return false | |||||
| } | |||||
| }) | |||||
| }, | |||||
| cancelDataset(getpage,attachment){ | |||||
| if(getpage && !attachment){ | |||||
| if(getpage==='create'){ | |||||
| location.href = this.url.split('/create')[0]+'?type=-1' | |||||
| }else if(getpage==='edit'){ | |||||
| location.href = this.url.split('/edit')[0]+'?type=-1' | |||||
| }else{ | |||||
| location.href='/' | |||||
| } | |||||
| } | |||||
| else{ | |||||
| location.href = `${AppSubUrl}${attachment}/datasets` | |||||
| } | |||||
| }, | |||||
| gotoUpload(repolink,datsetId){ | |||||
| location.href = `${AppSubUrl}${repolink}/datasets/attachments/upload?datasetId=${datsetId}` | |||||
| }, | |||||
| gotoDataset(datsetUrl){ | |||||
| location.href = datsetUrl | |||||
| }, | |||||
| gotoAnnotate(repolink,uuid,type){ | |||||
| location.href = `${AppSubUrl}${repolink}/datasets/label/${uuid}?type=${type}` | |||||
| }, | |||||
| uploadGpu(){ | |||||
| this.type=0 | |||||
| }, | |||||
| uploadNpu(){ | |||||
| this.type=1 | |||||
| }, | |||||
| setPrivate(uuid,privateFlag,index){ | |||||
| const params = {_csrf:csrf,file:uuid,is_private:privateFlag} | |||||
| this.$axios.post('/attachments/private',this.qs.stringify(params)).then((res)=>{ | |||||
| this.$set(this.privates,index,privateFlag) | |||||
| }).catch(error=>{ | |||||
| console.log(error) | |||||
| }) | |||||
| }, | |||||
| delDataset(uuid){ | |||||
| let _this = this | |||||
| const params = {_csrf:csrf,file:uuid} | |||||
| $('#data-dataset-delete-modal') | |||||
| .modal({ | |||||
| closable: false, | |||||
| onApprove() { | |||||
| _this.$axios.post('/attachments/delete',_this.qs.stringify(params)).then((res)=>{ | |||||
| // $('#'+uuid).hide() | |||||
| location.reload() | |||||
| }).catch(error=>{ | |||||
| console.log(error) | |||||
| }) | |||||
| } | |||||
| }) | |||||
| .modal('show'); | |||||
| }, | |||||
| // getEditInit(){ | |||||
| // if($('#dataset-edit-value')){ | |||||
| // $this = $('#dataset-edit-value') | |||||
| // this.ruleForm.title = $this.data('edit-title') || '' | |||||
| // this.ruleForm.description = $this.data('edit-description') || '' | |||||
| // this.ruleForm.category = $this.data('edit-category') || '' | |||||
| // this.ruleForm.task = $this.data('edit-task') || '' | |||||
| // this.ruleForm.license = $this.data('edit-license') || '' | |||||
| // this.ruleForm.id = $this.data('edit-id')|| '' | |||||
| // } | |||||
| // }, | |||||
| editDataset(formName,id){ | |||||
| let _this = this | |||||
| this.url = this.url.split(`/${id}`)[0] | |||||
| this.$refs[formName].validate((valid)=>{ | |||||
| if(valid){ | |||||
| document.getElementById("mask").style.display = "block" | |||||
| _this.$axios.post(_this.url,_this.qs.stringify(_this.ruleForm1)).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| document.getElementById("mask").style.display = "none" | |||||
| location.href = _this.url.split('/edit')[0]+'?type=-1' | |||||
| }else{ | |||||
| console.log(res.data.Message) | |||||
| } | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }).catch((err)=>{ | |||||
| console.log(err) | |||||
| }) | |||||
| } | |||||
| else{ | |||||
| return false | |||||
| } | |||||
| }) | |||||
| }, | |||||
| editDatasetFile(id,backurl){ | |||||
| let url = '/attachments/edit' | |||||
| const params={id:id,description:this.descfile,_csrf:csrf} | |||||
| // document.getElementById("mask").style.display = "block" | |||||
| this.$axios.post(url,this.qs.stringify(params)).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| location.href = `${AppSubUrl}${backurl}/datasets` | |||||
| }else{ | |||||
| console.log(res.data.Message) | |||||
| } | |||||
| }).catch((err)=>{ | |||||
| console.log(err) | |||||
| }) | |||||
| }, | |||||
| postStar(id,link){ | |||||
| if(this.star_active){ | |||||
| let url = link+'/'+ id + '/unstar' | |||||
| this.$axios.put(url).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| this.star_active = false | |||||
| this.num_stars = this.num_stars -1 | |||||
| } | |||||
| }) | |||||
| }else{ | |||||
| let url = link+'/'+ id + '/star' | |||||
| this.$axios.put(url).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| this.star_active = true | |||||
| this.num_stars = this.num_stars + 1 | |||||
| } | |||||
| }) | |||||
| } | |||||
| }, | |||||
| postSquareStar(id,link,index){ | |||||
| if(this.starActives[index]){ | |||||
| let url = link+'/'+ id + '/unstar' | |||||
| this.$axios.put(url).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| this.$set(this.starActives,index,false) | |||||
| this.$set(this.starItems,index,this.starItems[index]-1) | |||||
| } | |||||
| }) | |||||
| }else{ | |||||
| let url = link+'/'+ id + '/star' | |||||
| this.$axios.put(url).then((res)=>{ | |||||
| if(res.data.Code===0){ | |||||
| this.$set(this.starActives,index,true) | |||||
| this.$set(this.starItems,index,this.starItems[index]+1) | |||||
| } | |||||
| }) | |||||
| } | |||||
| }, | |||||
| getTypeList(){ | |||||
| const params = new URLSearchParams(window.location.search) | |||||
| if( window.location.search && params.has('type')){ | |||||
| if(params.get('type')==0){ | |||||
| this.datasetType = '0' | |||||
| } | |||||
| if(params.get('type')==1){ | |||||
| this.datasetType = '1' | |||||
| } | |||||
| if(params.get('type')==-1){ | |||||
| this.datasetType = '-1' | |||||
| } | |||||
| }else { | |||||
| this.datasetType = '-1' | |||||
| } | |||||
| }, | |||||
| changeDatasetType(val){ | |||||
| const searchParams = new URLSearchParams(window.location.search) | |||||
| if (!window.location.search) { | |||||
| window.location.href = window.location.href + '?type='+val | |||||
| } else if (searchParams.has('type')) { | |||||
| window.location.href = window.location.href.replace(/type=([0-9]|-[0-9])/g,'type='+val) | |||||
| } else { | |||||
| window.location.href=window.location.href+'&type='+val | |||||
| } | |||||
| }, | |||||
| gotoDatasetEidt(repolink,id){ | |||||
| location.href = `${repolink}/datasets/attachments/edit/${id}` | |||||
| }, | |||||
| handleClick(repoLink, tabName,type) { | |||||
| if(tabName=="first"){ | |||||
| this.page=1 | |||||
| this.searchDataItem='' | |||||
| this.getCurrentRepoDataset(repoLink,type) | |||||
| } | |||||
| if(tabName=="second"){ | |||||
| this.page=1 | |||||
| this.searchDataItem='' | |||||
| this.getMyDataset(repoLink,type) | |||||
| } | |||||
| if(tabName=="third"){ | |||||
| this.page=1 | |||||
| this.searchDataItem='' | |||||
| this.getPublicDataset(repoLink,type) | |||||
| } | |||||
| if(tabName=="fourth"){ | |||||
| this.page=1 | |||||
| this.searchDataItem='' | |||||
| this.getStarDataset(repoLink,type) | |||||
| } | |||||
| }, | |||||
| polling (checkStatuDataset,repoLink) { | |||||
| this.timer = window.setInterval(() => { | |||||
| setTimeout(() => { | |||||
| this.getDatasetStatus(checkStatuDataset,repoLink) | |||||
| },0) | |||||
| },15000) | |||||
| }, | |||||
| getDatasetStatus(checkStatuDataset,repoLink){ | |||||
| const getmap = checkStatuDataset.map((item)=>{ | |||||
| let url = `${AppSubUrl}${repolink}/datasets/status/${item.UUID}` | |||||
| return this.$axios.get(url) | |||||
| }) | |||||
| this.$axios.all(getmap) | |||||
| .then((res)=>{ | |||||
| let flag = res.some((item)=>{ | |||||
| return item.data.AttachmentStatus == 1 | |||||
| }) | |||||
| flag && clearInterval(this.timer) | |||||
| flag && this.refreshStatusDataset() | |||||
| } | |||||
| ) | |||||
| }, | |||||
| refreshStatusDataset(){ | |||||
| switch(this.activeName){ | |||||
| case 'first': | |||||
| this.getCurrentRepoDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'second': | |||||
| this.getMyDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'third': | |||||
| this.getPublicDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'fourth': | |||||
| this.getStarDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| } | |||||
| }, | |||||
| getCurrentRepoDataset(repoLink,type){ | |||||
| clearInterval(this.timer) | |||||
| this.loadingDataIndex = true | |||||
| let url = repoLink + '/datasets/current_repo' | |||||
| this.$axios.get(url,{ | |||||
| params:{ | |||||
| type:type, | |||||
| page:this.page, | |||||
| q:this.searchDataItem | |||||
| } | |||||
| }).then((res)=>{ | |||||
| this.currentRepoDataset = JSON.parse(res.data.data) | |||||
| const checkStatuDataset = this.currentRepoDataset.filter(item=>item.DecompressState===2) | |||||
| if(checkStatuDataset.length>0){ | |||||
| this.polling(checkStatuDataset,repoLink) | |||||
| } | |||||
| this.totalnums = parseInt(res.data.count) | |||||
| this.loadingDataIndex = false | |||||
| }) | |||||
| }, | |||||
| getMyDataset(repoLink,type){ | |||||
| clearInterval(this.timer) | |||||
| this.loadingDataIndex = true | |||||
| let url = repoLink + '/datasets/my_datasets' | |||||
| this.$axios.get(url,{ | |||||
| params:{ | |||||
| type:type, | |||||
| page:this.page, | |||||
| q:this.searchDataItem | |||||
| } | |||||
| }).then((res)=>{ | |||||
| this.myDataset = JSON.parse(res.data.data) | |||||
| const checkStatuDataset = this.myDataset.filter(item=>item.DecompressState===2) | |||||
| if(checkStatuDataset.length>0){ | |||||
| this.polling(checkStatuDataset,repoLink) | |||||
| } | |||||
| this.totalnums = parseInt(res.data.count) | |||||
| this.loadingDataIndex = false | |||||
| }) | |||||
| }, | |||||
| getPublicDataset(repoLink,type){ | |||||
| clearInterval(this.timer) | |||||
| this.loadingDataIndex = true | |||||
| let url = repoLink + '/datasets/public_datasets' | |||||
| this.$axios.get(url,{ | |||||
| params:{ | |||||
| type:type, | |||||
| page:this.page, | |||||
| q:this.searchDataItem | |||||
| } | |||||
| }).then((res)=>{ | |||||
| this.publicDataset = JSON.parse(res.data.data) | |||||
| const checkStatuDataset = this.publicDataset.filter(item=>item.DecompressState===2) | |||||
| if(checkStatuDataset.length>0){ | |||||
| this.polling(checkStatuDataset,repoLink) | |||||
| } | |||||
| this.totalnums = parseInt(res.data.count) | |||||
| this.loadingDataIndex = false | |||||
| }) | |||||
| }, | |||||
| getStarDataset(repoLink,type){ | |||||
| clearInterval(this.timer) | |||||
| this.loadingDataIndex = true | |||||
| let url = repoLink + '/datasets/my_favorite' | |||||
| this.$axios.get(url,{ | |||||
| params:{ | |||||
| type:type, | |||||
| page:this.page, | |||||
| q:this.searchDataItem | |||||
| } | |||||
| }).then((res)=>{ | |||||
| this.myFavoriteDataset = JSON.parse(res.data.data) | |||||
| const checkStatuDataset = this.myFavoriteDataset.filter(item=>item.DecompressState===2) | |||||
| if(checkStatuDataset.length>0){ | |||||
| this.polling(checkStatuDataset,repoLink) | |||||
| } | |||||
| this.totalnums= parseInt(res.data.count) | |||||
| this.loadingDataIndex = false | |||||
| }) | |||||
| }, | |||||
| selectDataset(uuid,name){ | |||||
| this.dataset_uuid = uuid | |||||
| this.dataset_name = name | |||||
| this.dialogVisible = false | |||||
| }, | |||||
| searchDataset(){ | |||||
| switch(this.activeName){ | |||||
| case 'first': | |||||
| this.page = 1 | |||||
| this.getCurrentRepoDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'second': | |||||
| this.page = 1 | |||||
| this.getMyDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'third': | |||||
| this.page = 1 | |||||
| this.getPublicDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| case 'fourth': | |||||
| this.page = 1 | |||||
| this.getStarDataset(this.repolink,this.cloudbrainType) | |||||
| break | |||||
| } | |||||
| } | |||||
| }, | |||||
| }); | |||||
| } | |||||
| function initVueEditTopic() { | function initVueEditTopic() { | ||||
| const el = document.getElementById('topic_edit1'); | const el = document.getElementById('topic_edit1'); | ||||
| @@ -222,3 +222,38 @@ | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .panel_creator_reponam{ | |||||
| display: inline-block; | |||||
| border-radius: 4px; | |||||
| padding: 4px; | |||||
| font-size: 12px; | |||||
| text-align: center; | |||||
| background-color: rgba(161, 220, 255, 0.2); | |||||
| color: #101010; | |||||
| } | |||||
| .panel_dataset_name{ | |||||
| font-size: 15px; | |||||
| color: #0366D6; | |||||
| text-align: center; | |||||
| margin-left: 1rem; | |||||
| } | |||||
| .panel_datset_desc{ | |||||
| white-space: nowrap; | |||||
| display: inline-block; | |||||
| overflow: hidden; | |||||
| width: 90%; | |||||
| text-overflow: ellipsis; | |||||
| } | |||||
| .el-dialog__body{ | |||||
| padding-top:0 | |||||
| } | |||||
| #dataset-base{ | |||||
| .active{ | |||||
| color: #0087f5!important; | |||||
| border: 1px solid #0087f5!important; | |||||
| /* margin: -1px!important; */ | |||||
| background: #fff!important; | |||||
| } | |||||
| } | |||||
| @@ -375,6 +375,10 @@ display: block; | |||||
| font-size: 18px; | font-size: 18px; | ||||
| margin-bottom: 1rem; | margin-bottom: 1rem; | ||||
| } | } | ||||
| .bgtask-content-button{ | |||||
| margin-top: 1em; | |||||
| margin-bottom: 1em; | |||||
| } | |||||
| .selectcloudbrain .active.item{ | .selectcloudbrain .active.item{ | ||||
| color: #0087f5 !important; | color: #0087f5 !important; | ||||
| @@ -624,6 +628,32 @@ display: block; | |||||
| .a_margin{ | .a_margin{ | ||||
| margin: 0px !important; | margin: 0px !important; | ||||
| } | } | ||||
| /*pages*/ | |||||
| .ui.borderless.pagination {border:none} | |||||
| .ui.pagination.menu .item { | |||||
| min-width: 32px; | |||||
| text-align: center; | |||||
| height: 32px; | |||||
| border-radius: .28571429rem; | |||||
| margin: 0 5px; | |||||
| background-color: #F2F2F2; | |||||
| } | |||||
| .ui.pagination.menu>.item:first-child, .ui.pagination.menu .item:last-child { | |||||
| background-color: #FFF !important; | |||||
| } | |||||
| .ui.ui.menu .item.disabled{ | |||||
| background-color: #F2F2F2; | |||||
| } | |||||
| .ui.pagination.menu .active.item { | |||||
| background-color: #3291F8; | |||||
| color: #FFF; | |||||
| } | |||||
| .ui.pagination.menu .item>.input { | |||||
| margin: 0em .5em; | |||||
| width: 3em; | |||||
| height: 32px; | |||||
| } | |||||
| @media only screen and (max-width: 767px) { | @media only screen and (max-width: 767px) { | ||||
| .following.bar #navbar .brand{ | .following.bar #navbar .brand{ | ||||
| padding-top: 6px; | padding-top: 6px; | ||||
| @@ -779,4 +809,87 @@ display: block; | |||||
| border: none !important; | border: none !important; | ||||
| color: #0366d6 !important; | color: #0366d6 !important; | ||||
| box-shadow: -15px 0px 10px #fff; | box-shadow: -15px 0px 10px #fff; | ||||
| } | |||||
| /**seach**/ | |||||
| /**搜索导航条适配窄屏**/ | |||||
| .seachnav{ | |||||
| overflow-x: auto; | |||||
| overflow-y: hidden; | |||||
| scrollbar-width: none; /* firefox */ | |||||
| -ms-overflow-style: none; /* IE 10+ */ | |||||
| } | |||||
| .seachnav::-webkit-scrollbar { | |||||
| display: none; /* Chrome Safari */ | |||||
| } | |||||
| .ui.green.button, .ui.green.buttons .button{ | |||||
| background-color: #5BB973; | |||||
| } | |||||
| .seach .repos--seach{ | |||||
| padding-bottom: 0; | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu{ | |||||
| border-bottom: none; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .item > i{ | |||||
| margin-right: 5px; | |||||
| } | |||||
| .seach .ui.secondary.pointing.menu .active.item{ | |||||
| border-bottom-width: 2px; | |||||
| margin: 0 0 -1px; | |||||
| } | |||||
| .seach .ui.menu .active.item>.label { | |||||
| background: #1684FC; | |||||
| color: #FFF; | |||||
| } | |||||
| .seach .ui.menu .item>.label:not(.active.item>.label) { | |||||
| background: #e8e8e8; | |||||
| color: rgba(0,0,0,.6); | |||||
| } | |||||
| .highlight{ | |||||
| color: red; | |||||
| } | |||||
| .ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||||
| width: calc(100% - 4.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| .seach .ui.list .list>.item .header, .seach .ui.list>.item .header{ | |||||
| margin-bottom: 0.5em; | |||||
| font-size: 1.4rem !important; | |||||
| font-weight: normal; | |||||
| } | |||||
| .seach .time, .seach .time a{ | |||||
| font-size: 12px; | |||||
| color: grey; | |||||
| } | |||||
| .seach .list .item.members .ui.avatar.image { | |||||
| width: 3.2em; | |||||
| height: 3.2em; | |||||
| } | |||||
| .ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content { | |||||
| width: calc(100% - 4.0em); | |||||
| margin-left: 0; | |||||
| } | |||||
| .searchlabel{ | |||||
| color: rgba(16, 16, 16, 100); | |||||
| font-size: 24px; | |||||
| text-align: left; | |||||
| font-family: SourceHanSansSC-medium; | |||||
| } | |||||
| .hiddenSearch{ | |||||
| margin: auto; | |||||
| display: none; | |||||
| } | |||||
| #tipmsg { | |||||
| display: none; | |||||
| z-index: 9999; | |||||
| width:150; | |||||
| height: 80; | |||||
| } | } | ||||