Browse Source

Merge remote-tracking branch 'origin/V20220328' into zouap

tags/v1.22.3.2^2
zouap 3 years ago
parent
commit
c62131ec78
67 changed files with 3573 additions and 943 deletions
  1. +6
    -0
      README.md
  2. +132
    -0
      models/attachment.go
  3. +16
    -0
      models/base_message.go
  4. +54
    -14
      models/cloudbrain.go
  5. +70
    -28
      models/dataset.go
  6. +70
    -0
      models/dataset_star.go
  7. +1
    -0
      models/models.go
  8. +34
    -6
      models/repo.go
  9. +5
    -4
      models/user.go
  10. +17
    -6
      modules/auth/dataset.go
  11. +2
    -0
      modules/context/repo.go
  12. +17
    -0
      modules/dataset/dataset.go
  13. +2
    -0
      modules/modelarts/modelarts.go
  14. +5
    -3
      modules/setting/setting.go
  15. +26
    -20
      modules/templates/helper.go
  16. +102
    -8
      options/locale/locale_en-US.ini
  17. +96
    -2
      options/locale/locale_zh-CN.ini
  18. +9
    -0
      routers/api/v1/repo/cloudbrain.go
  19. +22
    -15
      routers/api/v1/repo/modelarts.go
  20. +19
    -19
      routers/api/v1/repo/repo_dashbord.go
  21. +29
    -6
      routers/home.go
  22. +76
    -19
      routers/repo/attachment.go
  23. +84
    -60
      routers/repo/cloudbrain.go
  24. +367
    -52
      routers/repo/dataset.go
  25. +58
    -28
      routers/repo/modelarts.go
  26. +0
    -4
      routers/repo/setting.go
  27. +20
    -1
      routers/routes/routes.go
  28. +23
    -23
      templates/admin/cloudbrain/list.tmpl
  29. +3
    -3
      templates/base/head.tmpl
  30. +3
    -3
      templates/base/head_fluid.tmpl
  31. +3
    -3
      templates/base/head_home.tmpl
  32. +3
    -3
      templates/base/head_pro.tmpl
  33. +134
    -0
      templates/custom/select_dataset.tmpl
  34. +69
    -0
      templates/explore/dataset_left.tmpl
  35. +1
    -1
      templates/explore/dataset_list.tmpl
  36. +210
    -9
      templates/explore/datasets.tmpl
  37. +14
    -14
      templates/explore/repo_left.tmpl
  38. +2
    -2
      templates/explore/repo_list.tmpl
  39. +45
    -0
      templates/repo/attachment/edit.tmpl
  40. +73
    -0
      templates/repo/attachment/upload.tmpl
  41. +25
    -25
      templates/repo/cloudbrain/benchmark/index.tmpl
  42. +17
    -17
      templates/repo/cloudbrain/benchmark/new.tmpl
  43. +43
    -43
      templates/repo/cloudbrain/benchmark/show.tmpl
  44. +9
    -15
      templates/repo/cloudbrain/new.tmpl
  45. +69
    -0
      templates/repo/datasets/create.tmpl
  46. +72
    -0
      templates/repo/datasets/edit.tmpl
  47. +321
    -125
      templates/repo/datasets/index.tmpl
  48. +10
    -10
      templates/repo/debugjob/index.tmpl
  49. +1
    -1
      templates/repo/editor/upload.tmpl
  50. +1
    -1
      templates/repo/header.tmpl
  51. +21
    -21
      templates/repo/modelarts/inferencejob/index.tmpl
  52. +25
    -25
      templates/repo/modelarts/inferencejob/new.tmpl
  53. +59
    -59
      templates/repo/modelarts/inferencejob/show.tmpl
  54. +27
    -33
      templates/repo/modelarts/notebook/new.tmpl
  55. +21
    -21
      templates/repo/modelarts/trainjob/index.tmpl
  56. +23
    -23
      templates/repo/modelarts/trainjob/new.tmpl
  57. +15
    -15
      templates/repo/modelarts/trainjob/para_manage.tmpl
  58. +61
    -61
      templates/repo/modelarts/trainjob/show.tmpl
  59. +23
    -23
      templates/repo/modelarts/trainjob/version_new.tmpl
  60. +12
    -12
      templates/repo/modelmanage/index.tmpl
  61. +121
    -51
      web_src/js/components/MinioUploader.vue
  62. +4
    -1
      web_src/js/components/ObsUploader.vue
  63. +36
    -0
      web_src/js/components/ProAnalysis.vue
  64. +6
    -4
      web_src/js/features/cloudrbanin.js
  65. +590
    -1
      web_src/js/index.js
  66. +35
    -0
      web_src/less/_dataset.less
  67. +4
    -0
      web_src/less/openi.less

+ 6
- 0
README.md View File

@@ -41,6 +41,7 @@
## 授权许可
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://git.openi.org.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。


## 需要帮助?
如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询:
- 点击[这里](https://git.openi.org.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**)
@@ -49,3 +50,8 @@

## 启智社区小白训练营:
- 结合案例给大家详细讲解如何使用社区平台,帮助无技术背景的小白成长为启智社区达人 (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)。```

+ 132
- 0
models/attachment.go View File

@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"path"
"strings"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/obs"
@@ -18,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/timeutil"

gouuid "github.com/satori/go.uuid"
"xorm.io/builder"
"xorm.io/xorm"
)

@@ -38,6 +40,7 @@ type Attachment struct {
UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added
CommentID int64
Name string
Description string `xorm:"TEXT"`
DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"`
IsPrivate bool `xorm:"DEFAULT false"`
@@ -47,6 +50,7 @@ type Attachment struct {

FileChunk *FileChunk `xorm:"-"`
CanDel bool `xorm:"-"`
Uploader *User `xorm:"-"`
}

type AttachmentUsername struct {
@@ -54,6 +58,27 @@ type AttachmentUsername struct {
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() {
if a.DatasetID > 0 {
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 {
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 {
var sess *xorm.Session
@@ -503,3 +540,98 @@ func GetAttachmentSizeByDatasetID(datasetID int64) (int64, error) {
func GetAllAttachmentSize() (int64, error) {
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
}

+ 16
- 0
models/base_message.go View File

@@ -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,
}
}

+ 54
- 14
models/cloudbrain.go View File

@@ -1,6 +1,7 @@
package models

import (
"code.gitea.io/gitea/modules/util"
"encoding/json"
"fmt"
"strconv"
@@ -102,15 +103,15 @@ type Cloudbrain struct {
ContainerIp string
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
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
BenchmarkTypeID int
BenchmarkChildTypeID int
@@ -150,6 +151,44 @@ type Cloudbrain struct {
Repo *Repository `xorm:"-"`
BenchmarkTypeName 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 {
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 ConvertDurationToStr(duration int64) string {
if duration == 0 {
return "00:00:00"
}
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)
}

type CloudbrainInfo struct {
@@ -1019,6 +1058,7 @@ type GetTrainJobResult struct {
NasShareAddr string `json:"nas_share_addr"`
DatasetName string
ModelMetricList string `json:"model_metric_list"` //列表里包含f1_score,recall,precision,accuracy,若有的话
StartTime int64 `json:"start_time"` //训练作业开始时间。
}

type GetTrainJobLogResult struct {
@@ -1117,7 +1157,7 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
} else {
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).
Join("left", "`user`", condition).Count(new(CloudbrainInfo))

@@ -1327,13 +1367,13 @@ func GetCloudbrainByJobIDAndIsLatestVersion(jobID string, isLatestVersion string

func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) {
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
}

func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) {
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
}

@@ -1377,7 +1417,7 @@ func UpdateTrainJobVersion(job *Cloudbrain) error {
func updateJobTrainVersion(e Engine, job *Cloudbrain) error {
var sess *xorm.Session
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
}

@@ -1457,7 +1497,7 @@ func UpdateInferenceJob(job *Cloudbrain) error {
func updateInferenceJob(e Engine, job *Cloudbrain) error {
var sess *xorm.Session
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
}
func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) {


+ 70
- 28
models/dataset.go View File

@@ -22,6 +22,7 @@ type Dataset struct {
Category string
Description string `xorm:"TEXT"`
DownloadTimes int64
NumStars int `xorm:"INDEX NOT NULL DEFAULT 0"`
License string
Task string
ReleaseID int64 `xorm:"INDEX"`
@@ -35,6 +36,11 @@ type Dataset struct {
Attachments []*Attachment `xorm:"-"`
}

type DatasetWithStar struct {
Dataset
IsStaring bool
}

func (d *Dataset) IsPrivate() bool {
switch d.Status {
case DatasetStatusPrivate:
@@ -91,33 +97,37 @@ type SearchDatasetOptions struct {
OwnerID int64
RepoID int64
IncludePublic bool
Category string
Task string
License string
ListOptions
SearchOrderBy
IsOwner bool
}

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 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 {
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) {
@@ -130,7 +140,18 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
cond = cond.And(builder.Neq{"dataset.status": DatasetStatusDeleted})

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 {
@@ -139,12 +160,13 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {

if opts.IncludePublic {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
cond = cond.And(builder.Eq{"attachment.is_private": false})
if opts.OwnerID > 0 {
if len(opts.Keyword) == 0 {
cond = cond.Or(builder.Eq{"repository.owner_id": opts.OwnerID})
} else {
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)

}
@@ -153,6 +175,7 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
cond = cond.And(builder.Eq{"repository.owner_id": opts.OwnerID})
if !opts.IsOwner {
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()

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 {
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 {
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)

// 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
@@ -301,9 +340,6 @@ func GetDatasetByID(id int64) (*Dataset, error) {
}

func GetDatasetByRepo(repo *Repository) (*Dataset, error) {
if err := CreateDefaultDatasetToRepo(repo); err != nil {
return nil, err
}
dataset := &Dataset{RepoID: repo.ID}
has, err := x.Get(dataset)
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 {
var err error
sess := x.NewSession()


+ 70
- 0
models/dataset_star.go View File

@@ -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
}

+ 1
- 0
models/models.go View File

@@ -129,6 +129,7 @@ func init() {
new(LanguageStat),
new(EmailHash),
new(Dataset),
new(DatasetStar),
new(Cloudbrain),
new(FileChunk),
new(BlockChain),


+ 34
- 6
models/repo.go View File

@@ -1281,10 +1281,6 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...Cr
return fmt.Errorf("copyDefaultWebhooksToRepo: %v", err)
}

if err = CreateDefaultDatasetToRepo(repo); err != nil {
return fmt.Errorf("models.CreateDefaultDatasetToRepo: %v", err)
}

return nil
}

@@ -1602,6 +1598,34 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
if err != nil {
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...
@@ -2692,7 +2716,7 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi
log.Error("ReadLatestFileInRepo error when OpenRepository,error=%v", err)
return nil, err
}
commitID, err := gitRepo.GetBranchCommitID(refName)
_, err = gitRepo.GetBranchCommitID(refName)
if err != nil {
log.Error("ReadLatestFileInRepo error when GetBranchCommitID,error=%v", err)
return nil, err
@@ -2724,5 +2748,9 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi
if n >= 0 {
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
}

+ 5
- 4
models/user.go View File

@@ -153,10 +153,11 @@ type User struct {
UseCustomAvatar bool

// 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
NumTeams int


+ 17
- 6
modules/auth/dataset.go View File

@@ -9,11 +9,10 @@ import (
type CreateDatasetForm struct {
Title string `binding:"Required"`
Category string `binding:"Required"`
Description string `binding:"Required;MaxSize(254)"`
Description string `binding:"Required"`
License string `binding:"Required;MaxSize(64)"`
Task string `binding:"Required;MaxSize(64)"`
ReleaseID int64 `xorm:"INDEX"`
Private bool
Files []string
}

@@ -25,11 +24,23 @@ type EditDatasetForm struct {
ID int64 `binding:"Required"`
Title string `binding:"Required"`
Category string `binding:"Required"`
Description string `binding:"Required;MaxSize(254)"`
Description string `binding:"Required"`
License string `binding:"Required;MaxSize(64)"`
Task string `binding:"Required;MaxSize(64)"`
Private bool
ReleaseID int64 `xorm:"INDEX"`
ReleaseID int64 `xorm:"INDEX"`
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)
}

+ 2
- 0
modules/context/repo.go View File

@@ -475,6 +475,8 @@ func RepoAssignment() macaron.Handler {
if ctx.IsSigned {
ctx.Data["IsWatchingRepo"] = models.IsWatching(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 {


+ 17
- 0
modules/dataset/dataset.go View File

@@ -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"
}
}

+ 2
- 0
modules/modelarts/modelarts.go View File

@@ -51,6 +51,8 @@ const (
DataUrl = "data_url"
ResultUrl = "result_url"
CkptUrl = "ckpt_url"
DeviceTarget = "device_target"
Ascend = "Ascend"
PerPage = 10
IsLatestVersion = "1"
NotLatestVersion = "0"


+ 5
- 3
modules/setting/setting.go View File

@@ -165,6 +165,7 @@ var (
ExplorePagingNum int
ContributorPagingNum int
IssuePagingNum int
DatasetPagingNum int
RepoSearchPagingNum int
MembersPagingNum int
FeedMaxCommitNum int
@@ -207,6 +208,7 @@ var (
ExplorePagingNum: 20,
ContributorPagingNum: 50,
IssuePagingNum: 10,
DatasetPagingNum: 5,
RepoSearchPagingNum: 10,
MembersPagingNum: 20,
FeedMaxCommitNum: 5,
@@ -512,9 +514,9 @@ var (
ProfileID string
PoolInfos string
Flavor string
DebugHost string
ImageInfos string
Capacity int
DebugHost string
ImageInfos string
Capacity int
//train-job
ResourcePools string
Engines string


+ 26
- 20
modules/templates/helper.go View File

@@ -23,6 +23,8 @@ import (
"time"
"unicode"

"code.gitea.io/gitea/modules/dataset"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/emoji"
@@ -86,20 +88,22 @@ func NewFuncMap() []template.FuncMap {
"AllowedReactions": func() []string {
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 {
return a + b
},
@@ -340,11 +344,13 @@ func NewTextFuncMap() []texttmpl.FuncMap {
"AppDomain": func() string {
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 {
return t.Format(time.RFC1123Z)
},
@@ -746,5 +752,5 @@ func licenses() []string {

// Dataset tasks
func tasks() []string {
return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_recognition", "speech_synthesis"}
return []string{"machine_translation", "question_answering_system", "information_retrieval", "knowledge_graph", "text_annotation", "text_categorization", "emotion_analysis", "language_modeling", "speech_recognition", "automatic_digest", "information_extraction", "description_generation", "image_classification", "face_recognition", "image_search", "target_detection", "image_description_generation", "vehicle_license_plate_recognition", "medical_image_analysis", "unmanned", "unmanned_security", "drone", "vr_ar", "2_d_vision", "2.5_d_vision", "3_d_reconstruction", "image_processing", "video_processing", "visual_input_system", "speech_coding", "speech_enhancement", "speech_synthesis"}
}

+ 102
- 8
options/locale/locale_en-US.ini View File

@@ -285,6 +285,20 @@ code_search_results = Search results for '%s'
code_last_indexed_at = Last indexed %s
save=Save
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]
create_new_account = Register Account
@@ -721,8 +735,13 @@ alert = To initiate a cloud brain task, please upload the dataset in zip format.
dataset = Dataset
dataset_setting= Dataset Setting
title = Name
title_format_err=Name can only contain number,letter,'-','_' or '.', and can be up to 100 characters long.
description = Description
description_format_err=Description's length can be up to 1024 characters long.
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
edit_dataset= Edit Dataset
update_dataset= Update Dataset
@@ -741,7 +760,8 @@ private = private
public = public
dir = directory
back = back
copy_url=copy download url
copy_url=Copy Download Url
copy_md5 = Copy MD5
directory=preview of the datasets
create_label_task=create label task
visibility = visibility
@@ -792,12 +812,49 @@ category.computer_vision= computer vision
category.natural_language_processing= natural language processing
category.speech_processing= speech 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
public= public
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]
owner = Owner
repo_name = Repository Name
@@ -827,7 +884,7 @@ repo_label_helpe = Press Enter to complete
issue_labels = Issue Labels
issue_labels_helper = Select an issue label set.
license = License
license_helper = Select a license file.
license_helper = Select a license file
readme = README
readme_helper = Select a README file template.
auto_init = Initialize Repository (Adds .gitignore, License and README)
@@ -860,6 +917,7 @@ model_noright=No right
model_rename=Duplicate model name, please modify model name.

debug=Debug
debug_again=Restart
stop=Stop
delete=Delete
more=More
@@ -867,7 +925,7 @@ gpu_type_all=All
model_download=Model Download
submit_image=Submit Image
download=Download
score=Score

cloudbrain=Cloudbrain
cloudbrain.new=New cloudbrain
@@ -882,7 +940,7 @@ cloudbrain1 = cloudbrain1
cloudbrain2 = cloudbrain2
cloudbrain_selection = select cloudbrain
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
cloudbrain_creator=Creator
cloudbrain_task = Task Name
@@ -989,13 +1047,28 @@ cloudbrain.benchmark.evaluate_child_type=Child Type
cloudbrain.benchmark.evaluate_mirror=Mirror
cloudbrain.benchmark.evaluate_train=Train 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_file = Model File
modelarts.infer_job = Inference Job
modelarts.infer_job.model_version = Model/Version
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.


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.create_error=Equal Name and Version has existed.
model.manage.model_name = Model Name
@@ -1077,6 +1150,7 @@ unstar = Unstar
star = Star
fork = Fork
download_archive = Download Repository
star_fail=Failed to %s the dataset.

no_desc = No Description
no_label = No labels
@@ -2831,4 +2905,24 @@ benchmark_path = Benchmark script path
snn4imagenet_path = Snn4imagenet script path
brainscore_path = Brainscore script path
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

+ 96
- 2
options/locale/locale_zh-CN.ini View File

@@ -287,6 +287,20 @@ code_search_results=“%s” 的搜索结果是
code_last_indexed_at=最后索引于 %s
save=保存
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]
create_new_account=注册帐号
@@ -724,8 +738,14 @@ alert=如果要发起云脑任务,请上传zip格式的数据集
dataset=数据集
dataset_setting=数据集设置
title=名称
title_format_err=名称最多允许输入100个字符,只允许字母,数字,中划线 (‘-’),下划线 (‘_’) 和点 (‘.’) 。
description=描述
description_format_err=描述最多允许输入1024个字符。
create_dataset=创建数据集
create_dataset_fail=创建数据集失败。
query_dataset_fail=查询数据集失败。
edit_attachment_fail=修改描述失败。

show_dataset=数据集
edit_dataset=编辑数据集
update_dataset=更新数据集
@@ -801,6 +821,44 @@ attachment.delete_desc= 你确定要删除该版本的数据集么?一旦删
public=公有
private=私有
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]
owner=拥有者
@@ -831,7 +889,7 @@ repo_label_helpe=输入完成后回车键完成标签确定。
issue_labels=任务标签
issue_labels_helper=选择一个任务标签集
license=授权许可
license_helper=选择授权许可文件
license_helper=选择授权许可文件
readme=自述
readme_helper=选择自述文件模板。
auto_init=初始化存储库 (添加. gitignore、许可证和自述文件)
@@ -872,6 +930,7 @@ gpu_type_all=全部
model_download=结果下载
submit_image=提交镜像
download=模型下载
score=评分

cloudbrain=云脑
cloudbrain.new=新建任务
@@ -995,7 +1054,7 @@ cloudbrain.benchmark.evaluate_child_type=子类型
cloudbrain.benchmark.evaluate_mirror=镜像
cloudbrain.benchmark.evaluate_train=训练程序
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_file = 模型文件
@@ -1005,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.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.create_error=相同的名称和版本的模型已经存在。
model.manage.model_name = 模型名称
@@ -1086,6 +1157,8 @@ unstar=取消点赞
star=点赞
fork=派生
download_archive=下载此项目
star_fail=%s失败。


no_desc=暂无描述
no_label = 暂无标签
@@ -2840,3 +2913,24 @@ snn4imagenet_path = snn4imagenet脚本存放路径
brainscore_path = brainscore脚本存放路径
start_command = 启动命令
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 = 共享内存


+ 9
- 0
routers/api/v1/repo/cloudbrain.go View File

@@ -6,6 +6,7 @@
package repo

import (
"code.gitea.io/gitea/modules/timeutil"
"net/http"
"sort"
"time"
@@ -77,9 +78,17 @@ func GetCloudbrainTask(ctx *context.APIContext) {
job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP
job.ContainerID = taskRes.TaskStatuses[0].ContainerID
job.Status = taskRes.TaskStatuses[0].State

if job.StartTime == 0 && !taskRes.TaskStatuses[0].StartAt.IsZero() {
job.StartTime = timeutil.TimeStamp(taskRes.TaskStatuses[0].StartAt.Unix())
}
}

if result.JobStatus.State != string(models.JobWaiting) {
if job.EndTime == 0 && models.IsCloudBrainOneDebugJobTerminal(job.Status) {
job.EndTime = timeutil.TimeStampNow()
}
job.ComputeAndSetDuration()
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)


+ 22
- 15
routers/api/v1/repo/modelarts.go View File

@@ -6,12 +6,11 @@
package repo

import (
"code.gitea.io/gitea/modules/timeutil"
"net/http"
"strconv"
"strings"

"code.gitea.io/gitea/modules/util"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
@@ -67,8 +66,14 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {
ctx.NotFound(err)
return
}

if job.StartTime == 0 && result.Lease.CreateTime > 0 {
job.StartTime = timeutil.TimeStamp(result.Lease.CreateTime / 1000)
}
job.Status = result.Status
if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) {
job.EndTime = timeutil.TimeStampNow()
}
job.ComputeAndSetDuration()
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
@@ -133,16 +138,17 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {
ctx.NotFound(err)
return
}

if job.StartTime == 0 && result.StartTime > 0 {
job.StartTime = timeutil.TimeStamp(result.StartTime / 1000)
}
job.Status = modelarts.TransTrainJobStatus(result.IntStatus)
job.Duration = result.Duration
job.Duration = result.Duration / 1000
job.TrainJobDuration = result.TrainJobDuration

if result.Duration != 0 {
job.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000)
job.TrainJobDuration = models.ConvertDurationToStr(job.Duration)

} 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.UpdateTrainJobVersion(job)
@@ -366,16 +372,17 @@ func GetModelArtsInferenceJob(ctx *context.APIContext) {
ctx.NotFound(err)
return
}

if job.StartTime == 0 && result.StartTime > 0 {
job.StartTime = timeutil.TimeStamp(result.StartTime / 1000)
}
job.Status = modelarts.TransTrainJobStatus(result.IntStatus)
job.Duration = result.Duration
job.Duration = result.Duration / 1000
job.TrainJobDuration = result.TrainJobDuration

if result.Duration != 0 {
job.TrainJobDuration = util.AddZero(result.Duration/3600000) + ":" + util.AddZero(result.Duration%3600000/60000) + ":" + util.AddZero(result.Duration%60000/1000)
job.TrainJobDuration = models.ConvertDurationToStr(result.Duration)

} 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)


+ 19
- 19
routers/api/v1/repo/repo_dashbord.go View File

@@ -292,41 +292,41 @@ func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, p

func allProjectsPeroidHeader(ctx *context.Context) map[string]string {

return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.isFork"), "F1": ctx.Tr("admin.repos.isMirror"), "G1": ctx.Tr("admin.repos.openi"), "H1": ctx.Tr("admin.repos.visit"), "I1": ctx.Tr("admin.repos.download"), "J1": ctx.Tr("admin.repos.pr"), "K1": ctx.Tr("admin.repos.commit"),
"L1": ctx.Tr("admin.repos.watches"), "M1": ctx.Tr("admin.repos.stars"), "N1": ctx.Tr("admin.repos.forks"), "O1": ctx.Tr("admin.repos.issues"), "P1": ctx.Tr("admin.repos.closedIssues"), "Q1": ctx.Tr("admin.repos.contributor"), "R1": ctx.Tr("admin.repos.create")}
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"), "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 {
return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): getBoolDisplay(rs.IsFork, ctx), getCellName("F", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("G", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64),
getCellName("H", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("I", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("J", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("K", row): strconv.FormatInt(rs.NumCommits, 10),
getCellName("L", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("M", row): strconv.FormatInt(rs.NumStars, 10), getCellName("N", row): strconv.FormatInt(rs.NumForks, 10), getCellName("O", row): strconv.FormatInt(rs.NumIssues, 10),
getCellName("P", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("Q", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("R", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
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("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("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 {

return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "私有", "E1": "迁移", "F1": "镜像", "G1": "OpenI指数",
"H1": "影响力", "I1": "成熟度", "J1": "活跃度", "K1": "项目健康度", "L1": "团队健康度", "M1": "项目发展趋势",
"N1": "关注数", "O1": "点赞数", "P1": "派生数", "Q1": "代码下载量", "R1": "评论数", "S1": "浏览量", "T1": "已解决任务数", "U1": "版本发布数量", "V1": "有效开发年龄",
"W1": "数据集", "X1": "模型数", "Y1": "百科页面数量", "Z1": "提交数", "AA1": "任务数", "AB1": "PR数", "AC1": "版本发布数量", "AD1": "任务完成比例", "AE1": "贡献者数", "AF1": "关键贡献者数",
"AG1": "新人增长量", "AH1": "代码规模增长量", "AI1": "任务增长量", "AJ1": "新人增长量", "AK1": "提交增长量", "AL1": "评论增长量", "AM1": "项目创建时间",
return map[string]string{"A1": "ID", "B1": "项目名称", "C1": "拥有者", "D1": "私有", "E1": "OpenI指数",
"F1": "影响力", "G1": "成熟度", "H1": "活跃度", "I1": "项目健康度", "J1": "团队健康度", "K1": "项目发展趋势",
"L1": "关注数", "M1": "点赞数", "N1": "派生数", "O1": "代码下载量", "P1": "评论数", "Q1": "浏览量", "R1": "已解决任务数", "S1": "版本发布数量", "T1": "有效开发年龄",
"U1": "数据集", "V1": "模型数", "W1": "百科页面数量", "X1": "提交数", "Y1": "任务数", "Z1": "PR数", "AA1": "版本发布数量", "AB1": "任务完成比例", "AC1": "贡献者数", "AD1": "关键贡献者数",
"AE1": "新人增长量", "AF1": "代码规模增长量", "AG1": "任务增长量", "AH1": "新人增长量", "AI1": "提交增长量", "AJ1": "评论增长量", "AK1": "迁移", "AL1": "镜像", "AM1": "项目创建时间",
}

}

func allProjectsOpenIValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string {

return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): getBoolDisplay(rs.IsFork, ctx), getCellName("F", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("G", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64),
getCellName("H", row): strconv.FormatFloat(rs.Impact, 'f', 2, 64), getCellName("I", row): strconv.FormatFloat(rs.Completeness, 'f', 2, 64), getCellName("J", row): strconv.FormatFloat(rs.Liveness, 'f', 2, 64), getCellName("K", row): strconv.FormatFloat(rs.ProjectHealth, 'f', 2, 64), getCellName("L", row): strconv.FormatFloat(rs.TeamHealth, 'f', 2, 64), getCellName("M", row): strconv.FormatFloat(rs.Growth, 'f', 2, 64),
getCellName("N", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("O", row): strconv.FormatInt(rs.NumStars, 10), getCellName("P", row): strconv.FormatInt(rs.NumForks, 10), getCellName("Q", row): strconv.FormatInt(rs.NumDownloads, 10),
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("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("R", row): strconv.FormatInt(rs.NumComments, 10), getCellName("S", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("T", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("U", row): strconv.FormatInt(rs.NumVersions, 10),
getCellName("V", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("W", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("X", row): strconv.FormatInt(rs.NumModels, 10), getCellName("Y", row): strconv.FormatInt(rs.NumWikiViews, 10),
getCellName("Z", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("AA", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("AB", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AC", row): strconv.FormatInt(rs.NumVersions, 10),
getCellName("AD", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AE", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AF", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AG", row): strconv.FormatInt(rs.NumContributorsGrowth, 10),
getCellName("AH", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AK", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AL", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), getCellName("AM", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
getCellName("P", row): strconv.FormatInt(rs.NumComments, 10), getCellName("Q", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("R", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("S", row): strconv.FormatInt(rs.NumVersions, 10),
getCellName("T", row): strconv.FormatInt(rs.NumDevMonths, 10), getCellName("U", row): strconv.FormatInt(rs.DatasetSize, 10), getCellName("V", row): strconv.FormatInt(rs.NumModels, 10), getCellName("W", row): strconv.FormatInt(rs.NumWikiViews, 10),
getCellName("X", row): strconv.FormatInt(rs.NumCommits, 10), getCellName("Y", row): strconv.FormatInt(rs.NumIssues, 10), getCellName("Z", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("AA", row): strconv.FormatInt(rs.NumVersions, 10),
getCellName("AB", row): strconv.FormatFloat(float64(rs.IssueFixedRate), 'f', 2, 64), getCellName("AC", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("AD", row): strconv.FormatInt(rs.NumKeyContributor, 10), getCellName("AE", row): strconv.FormatInt(rs.NumContributorsGrowth, 10),
getCellName("AF", row): strconv.FormatInt(rs.NumCommitLinesGrowth, 10), getCellName("AG", row): strconv.FormatInt(rs.NumIssuesGrowth, 10), getCellName("AH", row): strconv.FormatInt(rs.NumContributorsGrowth, 10), getCellName("AI", row): strconv.FormatInt(rs.NumCommitsGrowth, 10), getCellName("AJ", row): strconv.FormatInt(rs.NumCommentsGrowth, 10), getCellName("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),
}

}


+ 29
- 6
routers/home.go View File

@@ -274,10 +274,11 @@ func ExploreDatasets(ctx *context.Context) {
// ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled

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")
if page <= 0 {
@@ -301,6 +302,10 @@ func ExploreDatasets(ctx *context.Context) {
orderBy = models.SearchOrderBySizeReverse
case "downloadtimes":
orderBy = models.SearchOrderByDownloadTimes
case "moststars":
orderBy = models.SearchOrderByStarsReverse
case "feweststars":
orderBy = models.SearchOrderByStars
default:
ctx.Data["SortType"] = "recentupdate"
orderBy = models.SearchOrderByRecentUpdated
@@ -308,6 +313,9 @@ func ExploreDatasets(ctx *context.Context) {

keyword := strings.Trim(ctx.Query("q"), " ")

category := ctx.Query("category")
task := ctx.Query("task")
license := ctx.Query("license")
var ownerID int64
if ctx.User != nil && !ctx.User.IsAdmin {
ownerID = ctx.User.ID
@@ -316,25 +324,40 @@ func ExploreDatasets(ctx *context.Context) {
Keyword: keyword,
IncludePublic: true,
SearchOrderBy: orderBy,
Category: category,
Task: task,
License: license,
OwnerID: ownerID,
ListOptions: models.ListOptions{
Page: page,
PageSize: setting.UI.ExplorePagingNum,
PageSize: 30,
},
}

datasets, count, err = models.SearchDataset(opts)

if err != nil {
ctx.ServerError("SearchDatasets", err)
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)
ctx.Data["Keyword"] = opts.Keyword
ctx.Data["Category"] = category
ctx.Data["Task"] = task
ctx.Data["License"] = license
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager

ctx.Data["Datasets"] = datasets
ctx.Data["Datasets"] = datasetsWithStar
ctx.Data["Total"] = count
ctx.Data["PageIsDatasets"] = true
ctx.HTML(200, tplExploreDataset)


+ 76
- 19
routers/repo/attachment.go View File

@@ -15,6 +15,10 @@ import (
"strconv"
"strings"

"code.gitea.io/gitea/modules/auth"

"code.gitea.io/gitea/modules/base"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/labelmsg"
@@ -30,8 +34,10 @@ import (

const (
//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 {
@@ -63,6 +69,40 @@ func renderAttachmentSettings(ctx *context.Context) {
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
func UploadAttachment(ctx *context.Context) {
if !setting.Attachment.Enabled {
@@ -241,14 +281,20 @@ func GetAttachment(ctx *context.Context) {
}

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
} 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")
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{
UUID: uuid,
UploaderID: ctx.User.ID,
IsPrivate: true,
IsPrivate: dataset.IsPrivate(),
Name: fileName,
Size: ctx.QueryInt64("size"),
DatasetID: ctx.QueryInt64("dataset_id"),
@@ -798,6 +850,9 @@ func CompleteMultipart(ctx *context.Context) {
typeCloudBrain := ctx.QueryInt("type")
fileName := ctx.Query("file_name")

log.Warn("uuid:" + uuid)
log.Warn("typeCloudBrain:" + strconv.Itoa(typeCloudBrain))

err := checkTypeCloudBrain(typeCloudBrain)
if err != nil {
ctx.ServerError("checkTypeCloudBrain failed", err)
@@ -835,22 +890,24 @@ func CompleteMultipart(ctx *context.Context) {
ctx.Error(500, fmt.Sprintf("UpdateFileChunk: %v", err))
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{
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 {
ctx.Error(500, fmt.Sprintf("InsertAttachment: %v", err))
return
}
dataset, _ := models.GetDatasetByID(attachment.DatasetID)
repository, _ := models.GetRepositoryByID(dataset.RepoID)
notification.NotifyOtherTask(ctx.User, repository, fmt.Sprint(attachment.Type), attachment.Name, models.ActionUploadAttachment)



+ 84
- 60
routers/repo/cloudbrain.go View File

@@ -2,9 +2,11 @@ package repo

import (
"bufio"
"code.gitea.io/gitea/modules/timeutil"
"encoding/json"
"errors"
"fmt"
"github.com/unknwon/i18n"
"io"
"net/http"
"os"
@@ -45,6 +47,10 @@ var (
benchmarkResourceSpecs *models.ResourceSpecs
)

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-]$`)

// MustEnableDataset check if repository enable internal cb
@@ -130,12 +136,7 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error {
}
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 {
json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos)
@@ -162,6 +163,8 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error {
ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath
ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled

ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne

return nil
}

@@ -339,13 +342,6 @@ func CloudBrainRestart(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)
}

@@ -380,6 +376,9 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) {
task.Status = taskRes.TaskStatuses[0].State
task.ContainerID = taskRes.TaskStatuses[0].ContainerID
task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP
if task.StartTime == 0 && !taskRes.TaskStatuses[0].StartAt.IsZero() {
task.StartTime = timeutil.TimeStamp(taskRes.TaskStatuses[0].StartAt.Unix())
}
err = models.UpdateJob(task)
if err != nil {
ctx.Data["error"] = err.Error()
@@ -405,14 +404,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) {
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 {
for _, benchmarkType := range benchmarkTypes.BenchmarkType {
for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType {
if task.BenchmarkTypeID == benchmarkType.Id {
ctx.Data["BenchmarkTypeName"] = benchmarkType.First
for _, benchmarkChildType := range benchmarkType.Second {
@@ -425,8 +418,16 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) {
}
}
}

ctx.Data["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000)
if task.TrainJobDuration == "" {
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.TrainJobDuration = models.ConvertDurationToStr(duration)
}
ctx.Data["duration"] = task.TrainJobDuration
ctx.Data["task"] = task
ctx.Data["jobName"] = task.JobName
ctx.Data["displayJobName"] = task.DisplayJobName
@@ -489,6 +490,10 @@ func CloudBrainStop(ctx *context.Context) {
}

task.Status = string(models.JobStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
@@ -582,6 +587,10 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) {
log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err)
} else {
taskInfo.Status = string(models.JobStopped)
if taskInfo.EndTime == 0 {
taskInfo.EndTime = timeutil.TimeStampNow()
}
taskInfo.ComputeAndSetDuration()
err = models.UpdateJob(taskInfo)
if err != nil {
log.Warn("UpdateJob failed", err)
@@ -953,6 +962,13 @@ func SyncCloudbrainStatus() {
task.Status = taskRes.TaskStatuses[0].State
if task.Status != string(models.JobWaiting) {
task.Duration = time.Now().Unix() - taskRes.TaskStatuses[0].StartAt.Unix()
if task.StartTime == 0 && !taskRes.TaskStatuses[0].StartAt.IsZero() {
task.StartTime = timeutil.TimeStamp(taskRes.TaskStatuses[0].StartAt.Unix())
}
if task.EndTime == 0 && models.IsCloudBrainOneDebugJobTerminal(task.Status) {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
@@ -973,6 +989,10 @@ func SyncCloudbrainStatus() {
continue
}
task.Status = string(models.JobStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
@@ -991,7 +1011,13 @@ func SyncCloudbrainStatus() {

if result != nil {
task.Status = result.Status

if task.StartTime == 0 && result.Lease.CreateTime > 0 {
task.StartTime = timeutil.TimeStamp(result.Lease.CreateTime / 1000)
}
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)
@@ -1007,14 +1033,15 @@ func SyncCloudbrainStatus() {

if result != nil {
task.Status = modelarts.TransTrainJobStatus(result.IntStatus)
task.Duration = result.Duration
task.Duration = result.Duration / 1000
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)

} else {
task.TrainJobDuration = "00:00:00"
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)
@@ -1059,26 +1086,22 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) {
return
}

if benchmarkTypes == nil {
if err := json.Unmarshal([]byte(setting.BenchmarkTypes), &benchmarkTypes); err != nil {
ctx.ServerError("Get BenchmarkTypes faild:", err)
return
}
}

for i, task := range ciTasks {
ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource
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 == "" {
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].TrainJobDuration = models.ConvertDurationToStr(duration)
}
ciTasks[i].TrainJobDuration = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000)
ciTasks[i].BenchmarkTypeName = ""
if task.BenchmarkTypeID > 0 {
for _, benchmarkType := range benchmarkTypes.BenchmarkType {
for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType {
if task.BenchmarkTypeID == benchmarkType.Id {
ciTasks[i].BenchmarkTypeRankLink = benchmarkType.RankLink
ciTasks[i].BenchmarkTypeName = benchmarkType.First
@@ -1102,15 +1125,8 @@ func GetChildTypes(ctx *context.Context) {
benchmarkTypeID := ctx.QueryInt("benchmark_type_id")
re := make(map[string]interface{})
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
for _, benchmarkType := range benchmarkTypes.BenchmarkType {
for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType {
if benchmarkTypeID == benchmarkType.Id {
isExist = true
re["child_types"] = benchmarkType.Second
@@ -1141,17 +1157,11 @@ func CloudBrainBenchmarkNew(ctx *context.Context) {
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
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
for _, benchmarkType := range benchmarkTypes.BenchmarkType {
for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType {
if benchmarkType.Id == benchmarkTypeID {
for _, childType := range benchmarkType.Second {
if childType.Id == benchmarkChildTypeID {
@@ -1265,7 +1275,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF
return
}

childInfo, err := getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID)
childInfo, err := getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID, ctx)
if err != nil {
log.Error("getBenchmarkAttachment failed:%v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
@@ -1395,3 +1405,17 @@ func BenchmarkDel(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark")
}
}

func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes {
var lang = ctx.Locale.Language()
if benchmarkTypesMap[lang] == nil {
var val = i18n.Tr(lang, BENCHMARK_TYPE_CODE)
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]
}

+ 367
- 52
routers/repo/dataset.go View File

@@ -1,7 +1,14 @@
package repo

import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"sort"
"strconv"
"strings"
"unicode/utf8"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
@@ -12,9 +19,14 @@ import (
)

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
func MustEnableDataset(ctx *context.Context) {
if !ctx.Repo.CanRead(models.UnitTypeDatasets) {
@@ -84,43 +96,34 @@ func QueryDataSet(ctx *context.Context) []*models.Attachment {
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
})

return attachments
}

func DatasetIndex(ctx *context.Context) {
log.Info("dataset index 1")
MustEnableDataset(ctx)
ctx.Data["PageIsDataset"] = true

repo := ctx.Repo.Repository

dataset, err := models.GetDatasetByRepo(repo)
ctx.Data["CanWrite"] = ctx.Repo.CanWrite(models.UnitTypeDatasets)
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
}
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 {
ctx.ServerError("GetDatasetAttachments", err)
return
@@ -128,53 +131,138 @@ func DatasetIndex(ctx *context.Context) {

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["Link"] = ctx.Repo.RepoLink + "/datasets"
ctx.Data["dataset"] = dataset
ctx.Data["Attachments"] = attachments
ctx.Data["Attachments"] = pageAttachments
ctx.Data["IsOwner"] = true
ctx.Data["StoreType"] = setting.Attachment.StoreType
ctx.Data["Type"] = ctx.QueryInt("type")
ctx.Data["Type"] = cloudbrainType

renderAttachmentSettings(ctx)

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) {
ctx.Data["PageIsDataset"] = true

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)
ctx.Data["dataset"] = rel

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
}

@@ -184,9 +272,236 @@ func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) {
rel.Task = form.Task
rel.License = form.License
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),
})
}

+ 58
- 28
routers/repo/modelarts.go View File

@@ -2,6 +2,7 @@ package repo

import (
"archive/zip"
"code.gitea.io/gitea/modules/timeutil"
"encoding/json"
"errors"
"io"
@@ -133,6 +134,8 @@ func notebookNewDataPrepare(ctx *context.Context) error {
}
ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo

ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo

return nil
}

@@ -408,6 +411,10 @@ func NotebookManage(ctx *context.Context) {
}

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"])
@@ -580,6 +587,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
return err
}
ctx.Data["config_list"] = configList.ParaConfigs
ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo

return nil
}
@@ -746,6 +754,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error {
ctx.Data["uuid"] = task.Uuid
ctx.Data["flavor_code"] = task.FlavorCode
ctx.Data["engine_id"] = task.EngineID
ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo

configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
if err != nil {
@@ -953,17 +962,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
return
}

//todo: del local code?

var parameters models.Parameters
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 {
err := json.Unmarshal([]byte(params), &parameters)
if err != nil {
@@ -974,6 +975,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
}

for _, parameter := range parameters.Parameter {
if parameter.Label == modelarts.DeviceTarget {
existDeviceTarget = true
}
if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
param = append(param, models.Parameter{
Label: parameter.Label,
@@ -982,9 +986,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
if isSaveParam == "on" {
saveparams := append(param, models.Parameter{
Label: modelarts.TrainUrl,
Value: outputObsPath,
}, models.Parameter{
Label: modelarts.DataUrl,
Value: dataPath,
})
if form.ParameterTemplateName == "" {
log.Error("ParameterTemplateName is empty")
trainJobNewDataPrepare(ctx)
@@ -1006,7 +1023,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
EngineID: int64(engineID),
LogUrl: logObsPath,
PoolID: poolID,
Parameter: param,
Parameter: saveparams,
})

if err != nil {
@@ -1032,7 +1049,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
LogUrl: logObsPath,
PoolID: poolID,
Uuid: uuid,
Parameters: parameters.Parameter,
Parameters: param,
CommitID: commitID,
IsLatestVersion: isLatestVersion,
BranchName: branch_name,
@@ -1168,13 +1185,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ

var parameters models.Parameters
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 {
err := json.Unmarshal([]byte(params), &parameters)
if err != nil {
@@ -1183,8 +1194,10 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobVersionNew, &form)
return
}

for _, parameter := range parameters.Parameter {
if parameter.Label == modelarts.DeviceTarget {
existDeviceTarget = true
}
if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
param = append(param, models.Parameter{
Label: parameter.Label,
@@ -1193,9 +1206,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
if isSaveParam == "on" {
saveparams := append(param, models.Parameter{
Label: modelarts.TrainUrl,
Value: outputObsPath,
}, models.Parameter{
Label: modelarts.DataUrl,
Value: dataPath,
})
if form.ParameterTemplateName == "" {
log.Error("ParameterTemplateName is empty")
versionErrorDataPrepare(ctx, form)
@@ -1217,7 +1243,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
EngineID: int64(engineID),
LogUrl: logObsPath,
PoolID: poolID,
Parameter: parameters.Parameter,
Parameter: saveparams,
})

if err != nil {
@@ -1228,12 +1254,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)
if err != nil {
log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error())
@@ -1257,7 +1277,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
PoolID: poolID,
Uuid: uuid,
Params: form.Params,
Parameters: parameters.Parameter,
Parameters: param,
PreVersionId: task.VersionID,
CommitID: commitID,
BranchName: branch_name,
@@ -1782,7 +1802,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference
return
}

//todo: del local code?
var parameters models.Parameters
param := make([]models.Parameter, 0)
param = append(param, models.Parameter{
@@ -1792,6 +1811,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference
Label: modelarts.CkptUrl,
Value: "s3:/" + ckptUrl,
})
existDeviceTarget := false
if len(params) != 0 {
err := json.Unmarshal([]byte(params), &parameters)
if err != nil {
@@ -1802,6 +1822,9 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference
}

for _, parameter := range parameters.Parameter {
if parameter.Label == modelarts.DeviceTarget {
existDeviceTarget = true
}
if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
param = append(param, models.Parameter{
Label: parameter.Label,
@@ -1810,6 +1833,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{
JobName: jobName,
@@ -1977,6 +2006,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
New: MODEL_LATEST,
})
ctx.Data["MODEL_COUNT"] = model_count
ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo

return nil
}


+ 0
- 4
routers/repo/setting.go View File

@@ -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
// as an error on the UI for this action
ctx.Data["Err_RepoName"] = nil
if err := models.CreateDefaultDatasetToRepo(repo); err != nil {
ctx.ServerError("CreateDefaultDatasetToRepo", err)
return
}

if form.EnableDataset && !models.UnitTypeDatasets.UnitGlobalDisabled() {
units = append(units, models.RepoUnit{


+ 20
- 1
routers/routes/routes.go View File

@@ -589,6 +589,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/delete", repo.DeleteAttachment)
m.Get("/get_pre_url", repo.GetPresignedPutObjectURL)
m.Post("/add", repo.AddAttachment)

m.Post("/edit", bindIgnErr(auth.EditAttachmentForm{}), repo.EditAttachment)
m.Post("/private", repo.UpdatePublicAttachment)
m.Get("/get_chunks", repo.GetSuccessChunks)
m.Get("/new_multipart", repo.NewMultipart)
@@ -981,7 +983,24 @@ func RegisterRoutes(m *macaron.Macaron) {

m.Group("/datasets", func() {
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.Get("/:uuid", reqRepoDatasetReader, repo.DirIndex)


+ 23
- 23
templates/admin/cloudbrain/list.tmpl View File

@@ -43,26 +43,26 @@
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<div class="one wide column text center nowrap">
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span>
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span>
</div>
<div class="one wide column text center nowrap">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="two wide column text center nowrap">
<span>{{$.i18n.Tr "repository"}}</span>
<span>{{$.i18n.Tr "repository"}}</span>
</div>
<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 class="two wide column text center nowrap" style="width: 17.5%!important;">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>
</div>
</div>
</div>
</div>
{{range .Tasks}}
{{if .Repo}}
<div class="ui grid stackable item">
<div class="row">
<div class="row">
<!-- 任务名 -->
{{$JobID := '0'}}
{{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}}
@@ -91,8 +91,8 @@
{{end}}
</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 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>
</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 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 class="one wide column text center nowrap">
@@ -178,7 +178,7 @@
{{$JobID = .JobID}}
{{end}}
<div class="ui grid stackable item">
<div class="row">
<div class="row">
<!-- 任务名 -->
<div class="two wide column nowrap">
{{if eq .JobType "DEBUG"}}
@@ -200,8 +200,8 @@
{{end}}
</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 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>
</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 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 class="one wide column text center nowrap">
@@ -296,18 +296,18 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>
<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>


+ 3
- 3
templates/base/head.tmpl View File

@@ -215,10 +215,10 @@ var _hmt = _hmt || [];
localStorage.setItem("isCloseNotice",true)
}
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;
localStorage.setItem("isCloseNotice",false)
}else{


+ 3
- 3
templates/base/head_fluid.tmpl View File

@@ -216,10 +216,10 @@ var _hmt = _hmt || [];
localStorage.setItem("isCloseNotice",true)
}
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;
localStorage.setItem("isCloseNotice",false)
}else{


+ 3
- 3
templates/base/head_home.tmpl View File

@@ -220,10 +220,10 @@ var _hmt = _hmt || [];
localStorage.setItem("isCloseNotice",true)
}
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;
localStorage.setItem("isCloseNotice",false)
}else{


+ 3
- 3
templates/base/head_pro.tmpl View File

@@ -217,10 +217,10 @@ var _hmt = _hmt || [];
localStorage.setItem("isCloseNotice",true)
}
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;
localStorage.setItem("isCloseNotice",false)
}else{


+ 134
- 0
templates/custom/select_dataset.tmpl View File

@@ -0,0 +1,134 @@

<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">
<input type="text" :value="dataset_name" disabled>
<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>

+ 69
- 0
templates/explore/dataset_left.tmpl View File

@@ -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>

+ 1
- 1
templates/explore/dataset_list.tmpl View File

@@ -25,7 +25,7 @@
{{range .Datasets}}
<div class="item">
<div class="ui header">
<a class="name" href="{{.Repo.Link}}/datasets?type=0">
<a class="name" href="{{.Repo.Link}}/datasets">
{{.Repo.OwnerName}} / {{.Repo.Alias}}
</a>
<div class="ui right metas">


+ 210
- 9
templates/explore/datasets.tmpl View File

@@ -1,15 +1,216 @@
{{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">
{{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>


+ 14
- 14
templates/explore/repo_left.tmpl View File

@@ -4,73 +4,73 @@
<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" />
</svg>
全部领域
{{.i18n.Tr "explore.all_fields"}}
</a>
<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">
<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>
大模型
{{.i18n.Tr "explore.large_model"}}
</a>
<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">
<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>
AI开发工具
{{.i18n.Tr "explore.ai_development_tools"}}
</a>
<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">
<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>
计算机视觉
{{.i18n.Tr "explore.computer_version"}}
</a>
<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">
<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>
自然语言处理
{{.i18n.Tr "explore.natural_language_processing"}}
</a>
<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">
<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>
机器学习
{{.i18n.Tr "explore.machine_learning"}}
</a>
<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">
<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>
神经网络
{{.i18n.Tr "explore.neural_networks"}}
</a>
<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">
<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>
自动驾驶
{{.i18n.Tr "explore.autopilot"}}
</a>
<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">
<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>
机器人
{{.i18n.Tr "explore.robot"}}
</a>
<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">
<path fill="currentColor" d="M3 11H11V3H3M5 5H9V9H5M13 21H21V13H13M15 15H19V19H15M3 21H11V13H3M5 15H9V19H5M13 3V11H21V3M19 9H15V5H19Z" />
</svg>
联邦学习
{{.i18n.Tr "explore.federated_learning"}}
</a>
<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">
<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>
数据挖掘
{{.i18n.Tr "explore.data_mining"}}
</a>
<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">
<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>
RISC-V开发
</a>
{{.i18n.Tr "explore.RISC-V_development"}}
</a>
</div>
</div>
</div>

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

@@ -44,13 +44,13 @@
<svg class="svg octicon-repo" width="16" height="16" aria-hidden="true">
<use xlink:href="#octicon-repo" />
</svg>
热门{{.i18n.Tr "explore.repos"}}
{{.i18n.Tr "explore.hot_repo"}}
</a>
<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">
<use xlink:href="#octicon-inbox" />
</svg>
活跃{{.i18n.Tr "explore.repos"}}
{{.i18n.Tr "explore.active_repo"}}
</a>
{{end}}
<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?q={{$.Keyword}}&topic={{$.Topic}}&sort=recentupdate&tab={{$.TabName}}">


+ 45
- 0
templates/repo/attachment/edit.tmpl View File

@@ -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" .}}

+ 73
- 0
templates/repo/attachment/upload.tmpl View File

@@ -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">&nbsp;{{$.i18n.Tr "dataset.illustrate.zip"}}&nbsp;</span>{{$.i18n.Tr "dataset.illustrate.fisrt_end"}};</br>
{{$.i18n.Tr "dataset.dataset_explain"}}</p>

</div>
</div>
</div>
{{template "base/footer" .}}

+ 25
- 25
templates/repo/cloudbrain/benchmark/index.tmpl View File

@@ -39,8 +39,8 @@
</div>
</div>
<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>
{{else}}
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a>
@@ -50,12 +50,12 @@
{{if eq 0 (len .Tasks)}}
<div class="ui placeholder segment bgtask-none">
<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">
{{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}}
<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>
{{else}}
@@ -85,21 +85,21 @@
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<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 class="one wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="three wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>
</div>
</div>
</div>
</div>

{{range .Tasks}}
<div class="ui grid stackable item">
<div class="row">
<!-- 任务名 -->
<div class="three wide column padding0">
<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>
</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 class="two wide column text center padding0">
<span style="font-size: 12px;">{{.ComputeResource}}</span>
<span style="font-size: 12px;">{{.ComputeResource}}</span>
</div>
<!-- 创建者 -->
<div class="one wide column text center padding0">
@@ -139,7 +139,7 @@
</div>

<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;">
{{$.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}}">
{{$.i18n.Tr "repo.stop"}}
</a>
{{else}}
<a class="ui basic disabled button">
{{$.i18n.Tr "repo.stop"}}
@@ -155,9 +155,9 @@
{{end}}
</form>
<a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank">
评分
{{$.i18n.Tr "repo.score"}}
</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">
<input type="hidden" name="debugListType" value="all">
@@ -171,20 +171,20 @@
{{$.i18n.Tr "repo.delete"}}
</a>
{{end}}
</form>
</form>
</div>
</div>
</div>
</div>
{{end}}
{{end}}

<!--
<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>
</div>
-->
{{template "base/paginate" .}}
</div>

@@ -204,18 +204,18 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>


+ 17
- 17
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -78,8 +78,8 @@
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 80%;" name="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 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">
{{range .benchmark_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
@@ -124,7 +124,7 @@
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>
<datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image">
{{range .images}}
@@ -136,13 +136,13 @@
</datalist>
</div>


<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}}
<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}}
</select>
</div>
@@ -150,25 +150,25 @@
<div class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label>
<input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" value="train.py" tabindex="3" autofocus required maxlength="254" >
<a 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 class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label>
<input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" tabindex="3" autofocus required maxlength="254" >
<a 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 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="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
@@ -217,7 +217,7 @@
setChildType();
}
}
function validate(){
$('.ui.form')
.form({
@@ -239,7 +239,7 @@
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
onFailure: function(e){
return false;
}
})
@@ -247,6 +247,6 @@


$('.ui.create_train_job.green.button').click(function(e) {
validate()
validate()
})
</script>
</script>

+ 43
- 43
templates/repo/cloudbrain/benchmark/show.tmpl View File

@@ -82,7 +82,7 @@
vertical-align: inherit;
}
.ti-text-form-label {
padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
@@ -152,7 +152,7 @@ td, th {
opacity: .45 !important;
}
.pad20{
border:0px !important;
}
.model_file_bread{
@@ -196,14 +196,14 @@ td, th {
<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">{{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>
@@ -244,12 +244,12 @@ td, th {
</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"}}
{{$.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>
@@ -258,9 +258,9 @@ td, th {
</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"}}
{{$.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}}
@@ -269,9 +269,9 @@ td, th {
</tr>
<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}}
@@ -280,30 +280,30 @@ td, th {
</tr>
<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}}-BenchmarkTypeName">
{{$.BenchmarkTypeName}}
</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">
train.py
@@ -314,19 +314,19 @@ td, th {
<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">
test.py
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.description"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" title="{{.Description}}">
{{.Description}}
@@ -336,9 +336,9 @@ td, th {

<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"}}
{{$.i18n.Tr "repo.modelarts.train_job.standard"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{$.resource_spec}}
@@ -348,9 +348,9 @@ td, th {

<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">
{{.User.Name}}
@@ -359,9 +359,9 @@ td, th {
</tr>
<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}}-BenchmarkChildTypeName">
{{$.BenchmarkChildTypeName}}
@@ -373,7 +373,7 @@ td, th {
</div>
</div>
</div>
</div>
</div>
<div class="ui tab" data-tab="second{{$k}}">
@@ -386,11 +386,11 @@ td, th {
<input type="hidden" name="start_line" value>
<pre id="log_file{{.VersionName}}"></pre>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -400,24 +400,24 @@ td, th {
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>
<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>
{{template "base/footer" .}}

@@ -430,7 +430,7 @@ td, th {
$(document).ready(function(){
$('.secondary.menu .item').tab();
});
let userName
let repoPath
let jobName
@@ -454,5 +454,5 @@ td, th {
document.getElementById("mask").style.display = "none"
});
}
</script>
</script>

+ 9
- 15
templates/repo/cloudbrain/new.tmpl View File

@@ -101,6 +101,7 @@
}



</style>

<div id="mask">
@@ -116,6 +117,7 @@
<div class="repository">
{{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid">
<div class="column">
{{template "base/alert" .}}
<div class="ui negative message" id="messageInfo">
@@ -147,12 +149,12 @@
</div>
<div class="inline required field">
<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 class="inline required field">
<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>
{{if .is_snn4imagenet_enabled}}
<option name="job_type" value="SNN4IMAGENET">SNN4IMAGENET</option>
@@ -200,22 +202,13 @@
{{end}}
</datalist>
</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">
<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}}
<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}}
</select>
</div>
@@ -354,4 +347,5 @@
$('#store_category').attr("value", selected_value)
})


</script>

+ 69
- 0
templates/repo/datasets/create.tmpl View File

@@ -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" .}}

+ 72
- 0
templates/repo/datasets/edit.tmpl View File

@@ -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" .}}

+ 321
- 125
templates/repo/datasets/index.tmpl View File

@@ -6,145 +6,341 @@
margin: -1px;
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>
<div class="repository release dataset-list view">
<div class="repository">
{{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 and (.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}}
</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 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 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 class="four wide column">
{{template "repo/datasets/right_side" .}}
</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 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"}}
</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>
{{template "base/footer" .}}

+ 10
- 10
templates/repo/debugjob/index.tmpl View File

@@ -208,7 +208,7 @@
{{template "repo/header" .}}
{{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">

@@ -242,14 +242,14 @@
{{if eq 0 (len .Tasks)}}
<div class="ui placeholder segment bgtask-none">
<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">
{{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}}
<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>
{{else}}
@@ -458,18 +458,18 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>


+ 1
- 1
templates/repo/editor/upload.tmpl View File

@@ -27,7 +27,7 @@
</div>
<div class="field">
<div class="files"></div>
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" 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"}}"></div>
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}asdsadsad" 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"}}"></div>
</div>
{{template "repo/editor/commit_form" .}}
</form>


+ 1
- 1
templates/repo/header.tmpl View File

@@ -138,7 +138,7 @@
{{end}}

{{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>
{{.i18n.Tr "datasets"}}
</a>


+ 21
- 21
templates/repo/modelarts/inferencejob/index.tmpl View File

@@ -39,7 +39,7 @@
</div>
</div>
<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>
{{else}}
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a>
@@ -49,16 +49,16 @@
{{if eq 0 (len .Tasks)}}
<div class="ui placeholder segment bgtask-none">
<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">
{{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}}
{{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}}
<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>
{{else}}
@@ -88,32 +88,32 @@
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<!-- <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 class="one wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="three wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>
</div>
</div>
</div>
</div>

{{range .Tasks}}
<div class="ui grid stackable item">
<div class="row">
<!-- 任务名 -->
<div class="three wide column padding0">
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;">
<span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
</a>
</div>
<!-- 模型版本 -->
<!-- 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}}&nbsp;</a>&nbsp;<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}}&nbsp;</a>&nbsp;<span style="font-size: 12px;">{{.ModelVersion}}</span>
</div>
<!-- 任务状态 -->
<div class="two wide column text center padding0" >
@@ -126,12 +126,12 @@
<span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div>
<!-- 任务运行时间 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
</div>
<!-- 计算资源 -->
<!-- <div class="two wide column text center padding0">
<span style="font-size: 12px;">{{.ComputeResource}}</span>
<span style="font-size: 12px;">{{.ComputeResource}}</span>
</div> -->
<!-- 创建者 -->
<div class="one wide column text center padding0">
@@ -205,18 +205,18 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>


+ 25
- 25
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -68,9 +68,9 @@
<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}}" 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 class="unite min_title inline field">
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>&nbsp;&nbsp;
<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>
<div class="menu" id="model_name_version">
</div>
</div>
</div>
<div class="five wide field">
@@ -123,10 +123,10 @@
<div class="menu" id="model_checkpoint">
</div>
</div>
</div>
<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>
</div>
<!-- AI引擎 -->
@@ -171,17 +171,17 @@
<!-- 数据集 -->
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label>&nbsp;&nbsp;&nbsp;&nbsp;
<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}}
<option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option>
{{end}}
{{range .attachments}}
<option value="">选择数据集</option>
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option>
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option>
{{end}}
</select>
<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>
</div>
<!-- 启动文件 -->
@@ -195,9 +195,9 @@
<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>
</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 class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>&nbsp;&nbsp;
@@ -222,7 +222,7 @@
{{end}}
</div>
</div>
<div class="required field " style="display: none;">
<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">
@@ -243,11 +243,11 @@
<!-- 计算节点 -->
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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>
</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 class="inline unite min_title field">
@@ -255,7 +255,7 @@
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</div>
<!-- 模态框 -->
</form>
</div>
@@ -283,7 +283,7 @@
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}
$('#select_model').removeClass("loading")
})
// 根据选中的模型名称获取相应的模型版本
@@ -323,7 +323,7 @@
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>`
}
})
$('#model_checkpoint').append(html)
$("#select_model_checkpoint").removeClass("loading")
@@ -332,7 +332,7 @@
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
})

$("input#ai_model_version").val(text)
$("input#ai_model_label").val(label)
@@ -348,15 +348,15 @@
}

$('.question.circle.icon').hover(function(){
$(this).popup('show')
$(this).popup('show')
});

// 参数增加、删除、修改、保存
function Add_parameter(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"> ' +
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' +
'</div>'+
@@ -366,7 +366,7 @@
'</span>' +
'</div>'
$(".dynamic.field").append(value)
}
}

$('#add_run_para').click(function(){
var len = $(".dynamic.field .two.fields").length
@@ -459,7 +459,7 @@
onSuccess: function(){
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
onFailure: function(e){
return false;
}
})
@@ -470,8 +470,8 @@
}
}
$('.ui.create_train_job.green.button').click(function(e) {
send_run_para()
send_run_para()
get_name()
validate()
})
</script>
</script>

+ 59
- 59
templates/repo/modelarts/inferencejob/show.tmpl View File

@@ -82,7 +82,7 @@
vertical-align: inherit;
}
.ti-text-form-label {
padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
@@ -152,7 +152,7 @@ td, th {
opacity: .45 !important;
}
.pad20{
border:0px !important;
}
.model_file_bread{
@@ -180,12 +180,12 @@ td, th {
{{with .task}}
<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);">
<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="third" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a>
</div>
<div class="ui tab active" data-tab="first">
<div style="padding-top: 10px;">
<div class="tab_2_content">
@@ -218,7 +218,7 @@ td, th {
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.run_version"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.VersionName}}
@@ -227,9 +227,9 @@ td, th {
</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"}}
{{$.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>
@@ -238,9 +238,9 @@ td, th {
</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"}}
{{$.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">
{{.TrainJobDuration}}
@@ -248,23 +248,23 @@ td, th {
</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.AI_driver"}}
{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.EngineName}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.model.manage.description"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;">
{{if .Description}}
@@ -279,7 +279,7 @@ td, th {
<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}}-creator">
{{$.userName}}
@@ -288,7 +288,7 @@ td, th {
</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.compute_node"}}
{{$.i18n.Tr "repo.modelarts.train_job.compute_node"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
@@ -304,19 +304,19 @@ td, th {
<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.modelarts.infer_job_model"}}
{{$.i18n.Tr "repo.modelarts.infer_job_model"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span>{{.ModelName}}</span>&nbsp;&nbsp;
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</span>&nbsp;&nbsp;
</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.infer_job_model_file"}}
{{$.i18n.Tr "repo.modelarts.infer_job_model_file"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
@@ -328,10 +328,10 @@ td, th {
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.model_label"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-labels">
{{if .LabelName}}
{{range $.labelName}}
<a class="ui label" title="{{.}}">{{.}}</a>
@@ -342,7 +342,7 @@ td, th {
</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"}}
@@ -358,7 +358,7 @@ td, th {
<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}}
@@ -367,9 +367,9 @@ td, th {
</tr>
<tr class="ti-no-ng-animate">
<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 class="ti-text-form-content">
<div class="text-span text-span-w">
{{.DatasetName}}
@@ -378,9 +378,9 @@ td, th {
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" title="{{.Parameters}}">
{{if .Parameters}}
@@ -393,9 +393,9 @@ td, th {
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.standard"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.FlavorName}}
@@ -407,10 +407,10 @@ td, th {
</div>
</div>
</div>
</div>
</div>
<div class="ui tab" data-tab="second">
<div>
<div class="ui message message{{.VersionName}}" style="display: none;">
@@ -421,9 +421,9 @@ td, th {
<input type="hidden" name="start_line" value>
<pre id="log_file{{.VersionName}}"></pre>
</div>
</div>
</div>
<div class="ui tab" data-tab="third">
<input type="hidden" name="model{{.VersionName}}" value="-1">
@@ -434,34 +434,34 @@ td, th {

</div>
<div id="dir_list{{.VersionName}}">
</div>
</div>
</div>
{{end}}
</div>
<!-- 确认模态框 -->
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>
<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>
@@ -493,7 +493,7 @@ function loadLog(version_name){
});
}
function logScroll(version_name) {
let container = document.querySelector(`#log${version_name}`)
let scrollTop = container.scrollTop
let scrollHeight = container.scrollHeight
@@ -506,7 +506,7 @@ function logScroll(version_name) {
$(`.message${version_name} #header`).text('您已翻阅至日志底部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){
$(`.message${version_name}`).css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000)
}else{
if(end_line===data.EndLine){
@@ -514,9 +514,9 @@ function logScroll(version_name) {
}
else{
$(`#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) {
console.log(err);
@@ -529,7 +529,7 @@ function logScroll(version_name) {
$(`.message${version_name} #header`).text('您已翻阅至日志顶部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){
$(`.message${version_name}`).css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000)
}else{
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值
@@ -557,7 +557,7 @@ function loadModelFile(version_name,parents,filename,init){
filename = filename || ''
init = init || ''
$.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)
if(init==="init"){
$(`input[name=model${version_name}]`).val("")
@@ -565,7 +565,7 @@ function loadModelFile(version_name,parents,filename,init){
$(`#file_breadcrumb${version_name}`).empty()
let htmlBread = ""
htmlBread += `<div class='active section'>result</div>`
htmlBread += "<div class='divider'> / </div>"
htmlBread += "<div class='divider'> / </div>"
$(`#file_breadcrumb${version_name}`).append(htmlBread)
}else{
renderBrend(version_name,parents,filename,init)
@@ -573,7 +573,7 @@ function loadModelFile(version_name,parents,filename,init){
}).fail(function(err) {
console.log(err,version_name);
});
}
function renderBrend(version_name,parents,filename,init){
if(init=="folder"){
@@ -586,9 +586,9 @@ function renderBrend(version_name,parents,filename,init){
}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>"
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)
@@ -599,7 +599,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} div.section:contains(${filename})`).append("<div class='divider'> / </div>")
}
}
function renderDir(data,version_name){
let html=""
@@ -638,14 +638,14 @@ function renderDir(data,version_name){
}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>"
@@ -655,4 +655,4 @@ function renderDir(data,version_name){
html += "</div>"
$(`#dir_list${version_name}`).append(html)
}
</script>
</script>

+ 27
- 33
templates/repo/modelarts/notebook/new.tmpl View File

@@ -30,7 +30,7 @@
<div class="ui attached segment">
<!-- <br> -->
<div class="inline required field">
<label>计算资源</label>
<label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<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">
@@ -47,22 +47,25 @@
</div>
</div>
<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,'')">
</div>

<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}}
<option name="image_id" value="{{.Id}}">{{.Value}}</option>
{{end}}
</select>
</div>
<<<<<<< HEAD
{{template "custom/select_dataset" .}}
=======

<div class="inline field">
<label>数据集</label>
<input type="text" list="cloudbrain_dataset" placeholder="选择数据集" name="" id="answerInput" autofocus maxlength="36">
<label>{{.i18n.Tr "cloudbrain.dataset"}}</label>
<input type="text" list="cloudbrain_dataset" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}" 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>
@@ -70,6 +73,7 @@
</datalist>
<input type="hidden" name="attachment" id="answerInput-hidden">
</div>
>>>>>>> V20220328

<!--<div class="inline required field">
<label>工作环境</label>
@@ -80,7 +84,7 @@
<input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly">
</div> -->
<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">
{{range .flavors}}
<option name="flavor" value="{{.Value}}">{{.Desc}}</option>
@@ -93,14 +97,14 @@
<input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly">
</div> -->
<div class="inline field">
<label>描述</label>
<label>{{.i18n.Tr "cloudbrain.description"}}</label>
<input name="description" id="cloudbrain_description" tabindex="3" autofocus maxlength="255">
</div>
<div class="inline field">
<label></label>
<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>
</div>
</div>
@@ -118,8 +122,8 @@

form.onsubmit = function(e){
let value_task = $("input[name='display_job_name']").val()
let re = /^[a-z0-9][a-z0-9-_]{1,36}$/
let flag = re.test(value_task)
if(!flag){
@@ -128,12 +132,12 @@
$('#messageInfo p').text(str)
return false
}
let min_value_task = value_task.toLowerCase()
$("input[name='display_job_name']").attr("value",min_value_task)
document.getElementById("mask").style.display = "block"
}
// 点击按钮后遮罩层显示
// function showmask() {
@@ -149,7 +153,6 @@

$('select.dropdown')
.dropdown();

$(function() {
$("#cloudbrain_job_type").change(function() {
if ($(this).val() == 'BENCHMARK') {
@@ -159,20 +162,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>

+ 21
- 21
templates/repo/modelarts/trainjob/index.tmpl View File

@@ -39,7 +39,7 @@
</div>
</div>
<div class="column right aligned">
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}
<a class="ui green button" href="{{.RepoLink}}/modelarts/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a>
{{else}}
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a>
@@ -49,13 +49,13 @@
{{if eq 0 (len .Tasks)}}
<div class="ui placeholder segment bgtask-none">
<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">
{{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}}
<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>
{{else}}
@@ -85,31 +85,31 @@
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<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 class="one wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="three wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>
</div>
</div>
</div>
</div>

{{range .Tasks}}
<div class="ui grid stackable item">
<div class="row">
<!-- 任务名 -->
<div class="three wide column padding0">
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;">
<span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
</a>
</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 class="two wide column padding0" style="padding-left: 2.2rem !important;">
@@ -122,12 +122,12 @@
<span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div>
<!-- 任务运行时间 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
</div>
<!-- 计算资源 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;">{{.ComputeResource}}</span>
<span style="font-size: 12px;">{{.ComputeResource}}</span>
</div>
<!-- 创建者 -->
<div class="one wide column text center padding0">
@@ -188,21 +188,21 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>
{{template "base/footer" .}}
{{template "base/footer" .}}

+ 23
- 23
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -81,9 +81,9 @@
<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;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span>
<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"}}&nbsp;&nbsp;</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>
@@ -91,7 +91,7 @@
<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>
@@ -147,22 +147,22 @@
<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/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 class="required unite min_title inline field">
<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}}
<option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option>
{{end}}
{{range .attachments}}
<option value="">选择数据集</option>
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option>
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option>
{{end}}
</select>
<span class="tooltips">数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。</span>
<span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</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>
@@ -223,24 +223,24 @@
</div>
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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>

</div>
</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="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
@@ -272,9 +272,9 @@
// 参数增加、删除、修改、保存
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_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>'+
@@ -284,7 +284,7 @@
'</span>' +
'</div>'
$(".dynamic.field").append(value)
}
}

$('#add_run_para').click(function(){
var len = $(".dynamic.field .two.fields").length
@@ -310,7 +310,7 @@
$(this).find('input').each(function(){
parameters.push($(this).text())
})
});
$('.ui.parameter.modal')
.modal('hide');
@@ -353,9 +353,9 @@
onChange: function(){
if ($('.ui.save.checkbox').checkbox('is checked')){
$('#save_para').removeClass("disabled")
}else{
$('#save_para').addClass("disabled")
$('#save_para').addClass("disabled")
}
}
});
@@ -421,7 +421,7 @@
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
onFailure: function(e){
return false;
}
})
@@ -453,6 +453,6 @@
$('.ui.create_train_job.green.button').click(function(e) {
get_name()
send_run_para()
validate()
validate()
})
</script>
</script>

+ 15
- 15
templates/repo/modelarts/trainjob/para_manage.tmpl View File

@@ -2,11 +2,11 @@
<div class="modelarts">
<div class="repository release modelarts train_job view container">
{{template "repo/header" .}}
<div class="ui container">
<div class="ui container">
<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="column">
<h2>{{.i18n.Tr "repo.modelarts.train_job_para_admin"}}</h2>
@@ -29,7 +29,7 @@
</div>
</div>
</div>
<!-- 任务展示 -->
<div class="dataset list">
{{range .Tasks}}
@@ -38,12 +38,12 @@
<!-- 任务名 -->
<div class="five wide column">
<a class="title" href="{{$.Link}}/{{.JobID}}">
<span class="fitted">{{.JobName}}</span>
</a>
</div>
<!-- 引擎类型-->
<!-- 引擎类型-->
<div class="four wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
{{.Status}}
</div>
@@ -59,7 +59,7 @@
<span class="fitted">编辑</span>
</a>
</div>
<!-- 删除 -->
<div class="two wide column">
<div class="ui text center clipboard">
@@ -69,7 +69,7 @@
</form>
</div>
</div>
</div>
</div>
{{end}} {{template "base/paginate" .}}
@@ -78,7 +78,7 @@
</div>
</div>
</div>
</div>
</div>
</div>
</div>

@@ -86,18 +86,18 @@
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>
@@ -105,7 +105,7 @@
</div>
{{template "base/footer" .}}

<script>
<script>
// 删除时用户确认
function assertDelete(obj) {
if (obj.style.color == "rgb(204, 204, 204)") {


+ 61
- 61
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -82,7 +82,7 @@
vertical-align: inherit;
}
.ti-text-form-label {
padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
@@ -152,7 +152,7 @@ td, th {
opacity: .45 !important;
}
.pad20{
border:0px !important;
}
.model_file_bread{
@@ -213,7 +213,7 @@ td, th {
{{else}}
<a class="ti-action-menu-item disabled" id="{{.VersionName}}-stop" onclick="stopVersion({{.VersionName}})">{{$.i18n.Tr "repo.stop"}}</a>
{{end}}

{{if .CanDel}}
<a class="ti-action-menu-item" onclick="deleteVersion({{.VersionName}})" style="color: #FF4D4F;">{{$.i18n.Tr "repo.delete"}}</a>
@@ -222,8 +222,8 @@ td, th {
{{end}}
</div>
<div class="ac-display-inblock title_text acc-margin-bottom">
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span>
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</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.status"}}:
@@ -242,7 +242,7 @@ td, th {
<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>
@@ -279,7 +279,7 @@ td, th {
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.run_version"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.VersionName}}
@@ -288,9 +288,9 @@ td, th {
</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"}}
{{$.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 .Cloudbrain.CreatedUnix}}</span>
@@ -299,9 +299,9 @@ td, th {
</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"}}
{{$.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">
{{.TrainJobDuration}}
@@ -310,9 +310,9 @@ td, th {
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.standard"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.FlavorName}}
@@ -321,7 +321,7 @@ td, th {
</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.compute_node"}}
{{$.i18n.Tr "repo.modelarts.train_job.compute_node"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
@@ -337,7 +337,7 @@ td, th {
<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.modelarts.train_job.AI_driver"}}
{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
@@ -349,7 +349,7 @@ td, th {
<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}}
@@ -360,7 +360,7 @@ td, th {
<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}}
@@ -369,9 +369,9 @@ td, th {
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.DatasetName}}
@@ -380,9 +380,9 @@ td, th {
</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"}}
{{$.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}}
@@ -392,9 +392,9 @@ td, th {
</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"}}
{{$.i18n.Tr "repo.modelarts.train_job.description"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" title="{{.Cloudbrain.Description}}">
{{.Cloudbrain.Description}}
@@ -406,7 +406,7 @@ td, th {
</div>
</div>
</div>
</div>
</div>
<div class="ui tab" data-tab="second{{$k}}">
@@ -419,9 +419,9 @@ td, th {
<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">
@@ -432,7 +432,7 @@ td, th {

</div>
<div id="dir_list{{.VersionName}}">
</div>
</div>

@@ -445,18 +445,18 @@ td, th {
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> 删除任务
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>
<div class="content">
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p>
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<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 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>
@@ -474,19 +474,19 @@ td, th {
{{$.CsrfTokenHtml}}
<input type="hidden" name="trainTaskCreate" value="true">

<div class="two inline fields ">
<div class="two inline fields ">
<div class="required ten wide field">
<label style="margin-left: -23px;">选择训练任务</label>
<input type="hidden" class="width83" id="JobId" name="JobId" readonly required>
<input class="width83" id="JobName" readonly required>
</div>
<div class="required six widde field">
<label>版本</label>
<input class="width70" id="VersionName" name="VersionName" readonly required>
</div>
</div>
<div class="required inline field" id="modelname">
<label>模型名称</label>
<input style="width: 45%;" id="name" name="Name" required maxlength="25" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
@@ -503,7 +503,7 @@ td, th {
<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>
</div>
<div class="inline field" style="margin-left: 75px;">
<button onclick="createModel()" type="button" class="ui create_train_job green button" style="position: absolute;">
{{.i18n.Tr "repo.model.manage.sava_model"}}
@@ -514,8 +514,8 @@ td, th {
<button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button>
</div>
</div>
</div>
</div>
</div>
@@ -529,7 +529,7 @@ td, th {
$(document).ready(function(){
$('.secondary.menu .item').tab();
});
let userName
let repoPath
let jobID
@@ -562,7 +562,7 @@ td, th {
$('input[name="JobId"]').val(obj.JobID)
$('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled')
$('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"})
createModelName()
createModelName()
},
onHide:function(){
document.getElementById("formId").reset();
@@ -595,7 +595,7 @@ td, th {
$("#mask").css({"display":"none","z-index":"1"})
}
})
}
function createModelName(){
let repoName = location.pathname.split('/')[2]
@@ -627,9 +627,9 @@ td, th {
// return
// }
let status = $(`#${versionname}-status-span`).text()
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"]
$.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => {
@@ -682,7 +682,7 @@ td, th {
}else{
$('#accordion'+version_name).remove()
}
}).fail(function(err) {
console.log(err);
});
@@ -695,7 +695,7 @@ td, th {
}
})
.modal('show')
}
function stopVersion(version_name){
stopBubbling(arguments.callee.caller.arguments[0])
@@ -705,7 +705,7 @@ td, th {
refreshStatus(version_name)
}
}).fail(function(err) {
console.log(err);
console.log(err);
});
}
function loadLog(version_name){
@@ -722,7 +722,7 @@ td, th {
filename = filename || ''
init = init || ''
$.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)
if(init==="init"){
$(`input[name=model${version_name}]`).val("")
@@ -730,7 +730,7 @@ td, th {
$(`#file_breadcrumb${version_name}`).empty()
let htmlBread = ""
htmlBread += `<div class='active section'>${version_name}</div>`
htmlBread += "<div class='divider'> / </div>"
htmlBread += "<div class='divider'> / </div>"
$(`#file_breadcrumb${version_name}`).append(htmlBread)
}else{
renderBrend(version_name,parents,filename,init)
@@ -738,7 +738,7 @@ td, th {
}).fail(function(err) {
console.log(err,version_name);
});
}
function renderBrend(version_name,parents,filename,init){
if(init=="folder"){
@@ -751,9 +751,9 @@ td, th {
}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>"
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)
@@ -764,7 +764,7 @@ td, th {
$(`#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=""
@@ -803,14 +803,14 @@ td, th {
}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>"
@@ -820,9 +820,9 @@ td, th {
html += "</div>"
$(`#dir_list${version_name}`).append(html)
}
function logScroll(version_name) {
let container = document.querySelector(`#log${version_name}`)
let scrollTop = container.scrollTop
let scrollHeight = container.scrollHeight
@@ -835,7 +835,7 @@ td, th {
$(`.message${version_name} #header`).text('您已翻阅至日志底部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){
$(`.message${version_name}`).css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000)
}else{
if(end_line===data.EndLine){
@@ -843,9 +843,9 @@ td, th {
}
else{
$(`#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) {
console.log(err);
@@ -858,7 +858,7 @@ td, th {
$(`.message${version_name} #header`).text('您已翻阅至日志顶部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){
$(`.message${version_name}`).css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000)
}else{
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值
@@ -869,4 +869,4 @@ td, th {
});
}
}
</script>
</script>

+ 23
- 23
templates/repo/modelarts/trainjob/version_new.tmpl View File

@@ -97,7 +97,7 @@
<input id="parents_version" style="width: 60%;" value="" tabindex="3" disabled >
{{end}}
</div>
<div class="unite min_title inline field">
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</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>
@@ -105,7 +105,7 @@
<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>
@@ -119,7 +119,7 @@
{{end}}
{{end}}
</select>
</div>


@@ -160,24 +160,24 @@
<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/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 class="required unite min_title inline field">
<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}}
<option name="attachment" value="{{.uuid}}">{{.dataset_name}}</option>
{{end}}
{{range .attachments}}
<option value="">选择数据集</option>
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option>
{{if ne $.uuid .UUID}}
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option>
{{end}}
{{end}}
</select>
<span class="tooltips">数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。</span>
<span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</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>
@@ -243,24 +243,24 @@
</div>
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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>

</div>
</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="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
@@ -298,9 +298,9 @@
// 参数增加、删除、修改、保存
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_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>'+
@@ -310,7 +310,7 @@
'</span>' +
'</div>'
$(".dynamic.field").append(value)
}
}

$('#add_run_para').click(function(){
var len = $(".dynamic.field .two.fields").length
@@ -336,7 +336,7 @@
$(this).find('input').each(function(){
parameters.push($(this).text())
})
});
$('.ui.parameter.modal')
.modal('hide');
@@ -379,9 +379,9 @@
onChange: function(){
if ($('.ui.save.checkbox').checkbox('is checked')){
$('#save_para').removeClass("disabled")
}else{
$('#save_para').addClass("disabled")
$('#save_para').addClass("disabled")
}
}
});
@@ -535,7 +535,7 @@
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
onFailure: function(e){
return false;
}
})
@@ -569,6 +569,6 @@
$('.ui.create_train_job.green.button').click(function(e) {
get_name()
send_run_para()
validate()
validate()
})
</script>
</script>

+ 12
- 12
templates/repo/modelmanage/index.tmpl View File

@@ -38,7 +38,7 @@
<div class="bgtask-content-txt">训练任务:您还没创建过训练任务,请先创建<a href="{{.RepoLink}}/modelarts/train-job">训练任务</a>。</div>
{{end}}
<div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div>
</div>
<div style="display: none;">
<div id="model_list"></div>
@@ -79,10 +79,10 @@
</div>
<div class="actions">
<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 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>
@@ -99,7 +99,7 @@
<!-- <p>asdasdasd</p> -->
</div>
<input type="hidden" name="_csrf" value="">
<div class="two inline fields ">
<div class="two inline fields ">
<div class="required ten wide field">
<label style="margin-left: -23px;">选择训练任务</label>
<div class="ui dropdown selection search width83 loading" id="choice_model">
@@ -117,7 +117,7 @@
<div class="default text">选择版本</div>
<i class="dropdown icon"></i>
<div class="menu" id="job-version">
</div>
</div>
</div>
@@ -149,8 +149,8 @@
<button class="ui button cancel" >{{.i18n.Tr "repo.cloudbrain.cancel"}}</button>
</div>
</div>
</div>


@@ -179,7 +179,7 @@
$("#job-name").empty()
createModelName()
loadTrainList()
},
onHide:function(){
document.getElementById("formId").reset();
@@ -188,7 +188,7 @@
$('.ui.dimmer').css({"background-color":""})
$('.ui.error.message').text()
$('.ui.error.message').css('display','none')
}
})
.modal('show')
@@ -221,7 +221,7 @@
}
function loadTrainList(){
$.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => {
console.log(data)
const n_length = data.length
let train_html=''
for (let i=0;i<n_length;i++){
@@ -233,7 +233,7 @@
$('#choice_model .default.text').text(data[0].DisplayJobName)
$('#choice_model input[name="JobId"]').val(data[0].JobID)
loadTrainVersion()
})
}
function loadTrainVersion(value){
@@ -251,7 +251,7 @@
$('#choice_version .default.text').text(data[0].VersionName)
$('#choice_version input[name="VersionName"]').val(data[0].VersionName)
}
})
}
</script>


+ 121
- 51
web_src/js/components/MinioUploader.vue View File

@@ -8,9 +8,11 @@
{{ file_status_text }}
<strong class="success text red">{{ status }}</strong>
</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>
- 云脑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>
</template>

@@ -24,9 +26,19 @@ import qs from 'qs';
import createDropzone from '../features/dropzone.js';

const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config;
const CloudBrainType = 0;
// const uploadtype = 0;

export default {
props:{
uploadtype:{
type:Number,
required:true
},
desc:{
type:String,
default:''
}
},
data() {
return {
dropzoneUploader: null,
@@ -36,7 +48,12 @@ export default {
progress: 0,
status: '',
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.file_status_text = this.dropzoneParams.data('file-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');
console.log('createDropzone');
const dropzoneUploader = await createDropzone($dropzone[0], {
url: '/todouploader',
maxFiles: this.maxFiles,
@@ -84,10 +115,7 @@ export default {
previewTemplate
});
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) {
if (this.files[0].status !== 'success') {
@@ -102,14 +130,23 @@ export default {
this.dropzoneUploader = dropzoneUploader;
},
methods: {
cancelDataset(){
location.href = this.repoPath
this.dropzoneUploader.removeAllFiles(true)
},
resetStatus() {
this.progress = 0;
this.status = '';
console.log(this.uploadtype)
},
updateProgress(file, progress) {
console.log("progress---",progress)
file.previewTemplate.querySelector(
'.dz-upload'
).style.width = `${progress}%`;
).style.width = `${progress}%`
file.previewTemplate.querySelector(
'.dz-upload'
).style.background = '#409eff';
},
emitDropzoneSuccess(file) {
file.status = 'success';
@@ -122,18 +159,24 @@ export default {
this.dropzoneUploader.emit('error', file);
// this.dropzoneUploader.emit('complete', file);
},
onFileAdded(file) {
file.datasetId = document
onFileAdded() {
this.btnFlag = true
this.file.datasetId = document
.getElementById('datasetId')
.getAttribute('datasetId');
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) {
this.emitDropzoneSuccess(file);
setTimeout(() => {
window.location.reload();
window.location.href = this.repoPath
}, 1000);
},

@@ -249,7 +292,7 @@ export default {
file_name: file.name,
size: file.size,
dataset_id: file.datasetId,
type: CloudBrainType,
type: this.uploadtype,
_csrf: csrf
})
);
@@ -260,6 +303,8 @@ export default {
const params = {
params: {
md5: file.uniqueIdentifier,
type: this.uploadtype,
file_name: file.name,
_csrf: csrf
}
};
@@ -282,13 +327,15 @@ export default {
},

async newMultiUpload(file) {
console.log(this.uploadtype,this)
const res = await axios.get('/attachments/new_multipart', {
params: {
totalChunkCounts: file.totalChunkCounts,
md5: file.uniqueIdentifier,
size: file.size,
fileType: file.type,
type: CloudBrainType,
type: this.uploadtype,
file_name: file.name,
_csrf: csrf
}
});
@@ -306,6 +353,7 @@ export default {
fileReader = new FileReader(),
time = new Date().getTime();
let currentChunk = 0;
let _this = this

function loadNext() {
const start = currentChunk * chunkSize;
@@ -329,7 +377,8 @@ export default {
uploadID: file.uploadID,
size: partSize,
chunkNumber: currentChunk + 1,
type: CloudBrainType,
type: _this.uploadtype,
file_name: file.name,
_csrf: csrf
}
});
@@ -343,14 +392,27 @@ export default {
}
async function uploadMinioNewMethod(url,e){
async function uploadMinioNewMethod(url,e){
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) {
@@ -395,6 +457,7 @@ export default {
}

async function completeUpload() {
console.log(_this.uploadtype)
return await axios.post(
'/attachments/complete_multipart',
qs.stringify({
@@ -403,8 +466,9 @@ export default {
file_name: file.name,
size: file.size,
dataset_id: file.datasetId,
type: CloudBrainType,
_csrf: csrf
type: _this.uploadtype,
_csrf: csrf,
description:_this.desc
})
);
}
@@ -430,6 +494,7 @@ export default {
1}/${chunks}个分片上传`
);
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.status = `${this.dropzoneParams.data('uploading')} ${(
(currentChunk / chunks) *
@@ -443,6 +508,7 @@ export default {
file.size
} 用时:${(new Date().getTime() - time) / 1000} s`
);
this.updateProgress(file, 100);
this.progress = 100;
this.status = this.dropzoneParams.data('upload-complete');
this.finishUpload(file);
@@ -455,7 +521,7 @@ export default {

<style>
.dropzone-wrapper {
margin: 2em auto;
margin: 0;
}
.ui .dropzone {
border: 2px dashed #0087f5;
@@ -473,4 +539,8 @@ export default {
border-bottom: 1px solid #dadce0;
min-height: 0;
}
.upload-info{
margin-top: 1em;
margin-bottom: 3em;
}
</style>

+ 4
- 1
web_src/js/components/ObsUploader.vue View File

@@ -460,7 +460,7 @@ export default {

<style>
.dropzone-wrapper {
margin: 2em auto;
margin: 0;
}
.ui .dropzone {
border: 2px dashed #0087f5;
@@ -478,4 +478,7 @@ export default {
border-bottom: 1px solid #dadce0;
min-height: 0;
}
.upload-info{
margin-top: 0.2em;
}
</style>

+ 36
- 0
web_src/js/components/ProAnalysis.vue View File

@@ -148,6 +148,31 @@
prop="contributor"
label="贡献者数"
align="center">
</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="isFork"
label="镜像"
align="center">
<template slot-scope="scope">
{{scope.row.isFork|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>
</div>
@@ -1140,6 +1165,17 @@
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;
},
},


+ 6
- 4
web_src/js/features/cloudrbanin.js View File

@@ -1,4 +1,6 @@
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);
$(document).ready(loadJobStatus);
function loadJobStatus() {
@@ -24,7 +26,7 @@ export default async function initCloudrain() {
finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled')
}
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')
}
if(status!=="RUNNING"){
@@ -36,7 +38,7 @@ export default async function initCloudrain() {
$('#ai-debug-'+ID).removeClass('blue').addClass('disabled')
}
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)){
$('#ai-stop-'+ID).removeClass('disabled').addClass('blue')
@@ -114,7 +116,7 @@ export default async function initCloudrain() {
$('#' + ID+'-icon').removeClass().addClass(res.status)
$('#' + ID+ '-text').text(res.status)
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-model-debug-'+ID).removeClass('blue').addClass('disabled')
$('#ai-delete-'+ID).removeClass('disabled').addClass('blue')
@@ -214,7 +216,7 @@ export default async function initCloudrain() {
$('#' + ID+ '-text').text(res.status)
$('#ai-debug-'+ID).removeClass('blue').addClass('disabled')
$('#ai-delete-'+ID).removeClass('blue').addClass('disabled')
$('#ai-debug-'+ID).text("调试").css("margin","0 1rem")
$('#ai-debug-'+ID).text(debug_button).css("margin","0 1rem")
}
}else{
$('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut();


+ 590
- 1
web_src/js/index.js View File

@@ -43,7 +43,7 @@ import Contributors from './components/Contributors.vue'
import Model from './components/Model.vue';
import WxAutorize from './components/WxAutorize.vue'
import initCloudrain from './features/cloudrbanin.js'
// import $ from 'jquery.js'

Vue.use(ElementUI);
Vue.prototype.$axios = axios;
@@ -2918,6 +2918,7 @@ $(document).ready(async () => {
initVueApp();
initVueUploader();
initObsUploader();
initVueDataset();
initVueEditAbout();
initVueEditTopic();
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() {
const el = document.getElementById('topic_edit1');


+ 35
- 0
web_src/less/_dataset.less View File

@@ -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;
}
}

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

@@ -375,6 +375,10 @@ display: block;
font-size: 18px;
margin-bottom: 1rem;
}
.bgtask-content-button{
margin-top: 1em;
margin-bottom: 1em;
}

.selectcloudbrain .active.item{
color: #0087f5 !important;


Loading…
Cancel
Save