Browse Source

Merge remote-tracking branch 'origin/V20220428' into zouap_static

pull/2002/head
zouap 3 years ago
parent
commit
b8ddb556e1
29 changed files with 486 additions and 72 deletions
  1. +8
    -0
      models/attachment.go
  2. +2
    -0
      models/cloudbrain.go
  3. +2
    -2
      models/cloudbrain_image.go
  4. +14
    -2
      models/dataset.go
  5. +10
    -0
      modules/auth/cloudbrain.go
  6. +40
    -1
      modules/cloudbrain/resty.go
  7. +7
    -1
      modules/storage/minio_ext.go
  8. +7
    -2
      modules/storage/obs.go
  9. +6
    -0
      options/locale/locale_en-US.ini
  10. +6
    -0
      options/locale/locale_zh-CN.ini
  11. +7
    -0
      routers/admin/cloudbrains.go
  12. +23
    -1
      routers/admin/dataset.go
  13. +2
    -0
      routers/home.go
  14. +2
    -2
      routers/repo/attachment.go
  15. +47
    -0
      routers/repo/cloudbrain.go
  16. +3
    -0
      routers/repo/dataset.go
  17. +3
    -0
      routers/routes/routes.go
  18. +5
    -3
      routers/user/profile.go
  19. +129
    -0
      templates/admin/cloudbrain/imagecommit.tmpl
  20. +6
    -15
      templates/admin/dataset/list.tmpl
  21. +4
    -4
      templates/custom/select_dataset.tmpl
  22. +4
    -4
      templates/custom/select_dataset_train.tmpl
  23. +4
    -2
      templates/explore/datasets.tmpl
  24. +20
    -1
      templates/repo/cloudbrain/new.tmpl
  25. +60
    -1
      templates/repo/modelarts/trainjob/show.tmpl
  26. +3
    -0
      web_src/js/components/MinioUploader.vue
  27. +14
    -12
      web_src/js/components/images/adminImages.vue
  28. +21
    -2
      web_src/js/features/images.js
  29. +27
    -17
      web_src/js/index.js

+ 8
- 0
models/attachment.go View File

@@ -65,6 +65,7 @@ type AttachmentInfo struct {
Repo *Repository `xorm:"extends"` Repo *Repository `xorm:"extends"`
RelAvatarLink string `xorm:"extends"` RelAvatarLink string `xorm:"extends"`
UserName string `xorm:"extends"` UserName string `xorm:"extends"`
Recommend bool `xorm:"-"`
} }


type AttachmentsOptions struct { type AttachmentsOptions struct {
@@ -79,6 +80,7 @@ type AttachmentsOptions struct {
JustNeedZipFile bool JustNeedZipFile bool
NeedRepoInfo bool NeedRepoInfo bool
Keyword string Keyword string
RecommendOnly bool
} }


func (a *Attachment) AfterUpdate() { func (a *Attachment) AfterUpdate() {
@@ -579,6 +581,11 @@ func Attachments(opts *AttachmentsOptions) ([]*AttachmentInfo, int64, error) {
builder.Eq{"attachment.is_private": opts.IsPrivate}, builder.Eq{"attachment.is_private": opts.IsPrivate},
) )
} }
if opts.RecommendOnly {
cond = cond.And(builder.In("attachment.id", builder.Select("attachment.id").
From("attachment").
Join("INNER", "dataset", "attachment.dataset_id = dataset.id and dataset.recommend=true")))
}


if opts.JustNeedZipFile { if opts.JustNeedZipFile {
var DecompressState []int32 var DecompressState []int32
@@ -627,6 +634,7 @@ func Attachments(opts *AttachmentsOptions) ([]*AttachmentInfo, int64, error) {
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("GetDatasetByID failed error: %v", err) return nil, 0, fmt.Errorf("GetDatasetByID failed error: %v", err)
} }
attachment.Recommend = dataset.Recommend
repo, err := GetRepositoryByID(dataset.RepoID) repo, err := GetRepositoryByID(dataset.RepoID)
if err == nil { if err == nil {
attachment.Repo = repo attachment.Repo = repo


+ 2
- 0
models/cloudbrain.go View File

@@ -580,6 +580,8 @@ type CommitImageParams struct {
Topics []string Topics []string
CloudBrainType int CloudBrainType int
UID int64 UID int64
Place string
Type int
} }


type CommitImageResult struct { type CommitImageResult struct {


+ 2
- 2
models/cloudbrain_image.go View File

@@ -567,12 +567,12 @@ func isImageStaring(e Engine, userID, imageID int64) bool {
} }
func RecommendImage(imageId int64, recommond bool) error { func RecommendImage(imageId int64, recommond bool) error {


image := Image{Type: getRecommondType(recommond)}
image := Image{Type: GetRecommondType(recommond)}
_, err := x.ID(imageId).Cols("type").Update(image) _, err := x.ID(imageId).Cols("type").Update(image)
return err return err
} }


func getRecommondType(recommond bool) int {
func GetRecommondType(recommond bool) int {
if recommond { if recommond {


return RECOMMOND_TYPE return RECOMMOND_TYPE


+ 14
- 2
models/dataset.go View File

@@ -23,7 +23,8 @@ type Dataset struct {
Category string Category string
Description string `xorm:"TEXT"` Description string `xorm:"TEXT"`
DownloadTimes int64 DownloadTimes int64
NumStars int `xorm:"INDEX NOT NULL DEFAULT 0"`
NumStars int `xorm:"INDEX NOT NULL DEFAULT 0"`
Recommend bool `xorm:"INDEX NOT NULL DEFAULT false"`
License string License string
Task string Task string
ReleaseID int64 `xorm:"INDEX"` ReleaseID int64 `xorm:"INDEX"`
@@ -99,6 +100,7 @@ type SearchDatasetOptions struct {
OwnerID int64 OwnerID int64
RepoID int64 RepoID int64
IncludePublic bool IncludePublic bool
RecommendOnly bool
Category string Category string
Task string Task string
License string License string
@@ -132,6 +134,13 @@ func CreateDataset(dataset *Dataset) (err error) {


} }


func RecommendDataset(dataSetId int64, recommend bool) error {

dataset := Dataset{Recommend: recommend}
_, err := x.ID(dataSetId).Cols("recommend").Update(dataset)
return err
}

func SearchDataset(opts *SearchDatasetOptions) (DatasetList, int64, error) { func SearchDataset(opts *SearchDatasetOptions) (DatasetList, int64, error) {
cond := SearchDatasetCondition(opts) cond := SearchDatasetCondition(opts)
return SearchDatasetByCondition(opts, cond) return SearchDatasetByCondition(opts, cond)
@@ -146,6 +155,9 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
if opts.RepoID > 0 { if opts.RepoID > 0 {
cond = cond.And(builder.Eq{"dataset.repo_id": opts.RepoID}) cond = cond.And(builder.Eq{"dataset.repo_id": opts.RepoID})
} }
if opts.RecommendOnly {
cond = cond.And(builder.Eq{"dataset.recommend": opts.RecommendOnly})
}


if opts.IncludePublic { if opts.IncludePublic {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
@@ -198,7 +210,7 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da
defer sess.Close() defer sess.Close()


datasets := make(DatasetList, 0, opts.PageSize) datasets := make(DatasetList, 0, opts.PageSize)
selectColumnsSql := "distinct dataset.id,dataset.title, dataset.status, dataset.category, dataset.description, dataset.download_times, dataset.license, dataset.task, dataset.release_id, dataset.user_id, dataset.repo_id, dataset.created_unix,dataset.updated_unix,dataset.num_stars"
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,dataset.recommend"


count, err := sess.Distinct("dataset.id").Join("INNER", "repository", "repository.id = dataset.repo_id"). count, err := sess.Distinct("dataset.id").Join("INNER", "repository", "repository.id = dataset.repo_id").
Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). Join("INNER", "attachment", "attachment.dataset_id=dataset.id").


+ 10
- 0
modules/auth/cloudbrain.go View File

@@ -33,6 +33,16 @@ type CommitImageCloudBrainForm struct {
Topics string `form:"topics"` Topics string `form:"topics"`
} }


type CommitAdminImageCloudBrainForm struct {
Description string `form:"description" binding:"Required"`
Type int `form:"type" binding:"Required"`
Tag string `form:"tag" binding:"Required;MaxSize(100)" `
IsPrivate bool `form:"isPrivate" binding:"Required"`
Topics string `form:"topics"`
Place string `form:"place" binding:"Required"`
IsRecommend bool `form:"isRecommend" binding:"Required"`
}

type EditImageCloudBrainForm struct { type EditImageCloudBrainForm struct {
ID int64 `form:"id" binding:"Required"` ID int64 `form:"id" binding:"Required"`
Description string `form:"description" binding:"Required"` Description string `form:"description" binding:"Required"`


+ 40
- 1
modules/cloudbrain/resty.go View File

@@ -312,12 +312,51 @@ sendjob:
return nil return nil
}) })
if err == nil { if err == nil {

go updateImageStatus(image, isSetCreatedUnix, createTime) go updateImageStatus(image, isSetCreatedUnix, createTime)
} }
return err return err
} }


func CommitAdminImage(params models.CommitImageParams) error {

exist, err := models.IsImageExist(params.ImageTag)

if err != nil {
return fmt.Errorf("resty CommitImage: %v", err)
}
if exist {
return models.ErrorImageTagExist{
Tag: params.ImageTag,
}
}

image := models.Image{
CloudbrainType: params.CloudBrainType,
UID: params.UID,
IsPrivate: params.IsPrivate,
Tag: params.ImageTag,
Description: params.ImageDescription,
Place: params.Place,
Status: models.IMAGE_STATUS_SUCCESS,
Type: params.Type,
}

err = models.WithTx(func(ctx models.DBContext) error {

if err := models.CreateLocalImage(&image); err != nil {
log.Error("Failed to insert image record.", err)
return fmt.Errorf("resty CommitImage: %v", err)
}

if err := models.SaveImageTopics(image.ID, params.Topics...); err != nil {
log.Error("Failed to insert image record.", err)
return fmt.Errorf("resty CommitImage: %v", err)
}
return nil
})
return err
}

func updateImageStatus(image models.Image, isSetCreatedUnix bool, createTime time.Time) { func updateImageStatus(image models.Image, isSetCreatedUnix bool, createTime time.Time) {
attemps := 5 attemps := 5
commitSuccess := false commitSuccess := false


+ 7
- 1
modules/storage/minio_ext.go View File

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


import ( import (
"encoding/xml" "encoding/xml"
"errors"
"path" "path"
"sort" "sort"
"strconv" "strconv"
@@ -129,7 +130,7 @@ func NewMultiPartUpload(uuid string) (string, error) {
return core.NewMultipartUpload(bucketName, objectName, miniov6.PutObjectOptions{}) return core.NewMultipartUpload(bucketName, objectName, miniov6.PutObjectOptions{})
} }


func CompleteMultiPartUpload(uuid string, uploadID string) (string, error) {
func CompleteMultiPartUpload(uuid string, uploadID string, totalChunks int) (string, error) {
client, core, err := getClients() client, core, err := getClients()
if err != nil { if err != nil {
log.Error("getClients failed:", err.Error()) log.Error("getClients failed:", err.Error())
@@ -146,6 +147,11 @@ func CompleteMultiPartUpload(uuid string, uploadID string) (string, error) {
return "", err return "", err
} }


if len(partInfos) != totalChunks {
log.Error("ListObjectParts number(%d) is not equal the set total chunk number(%d)", len(partInfos), totalChunks)
return "", errors.New("the parts is not complete")
}

var complMultipartUpload completeMultipartUpload var complMultipartUpload completeMultipartUpload
for _, partInfo := range partInfos { for _, partInfo := range partInfos {
complMultipartUpload.Parts = append(complMultipartUpload.Parts, miniov6.CompletePart{ complMultipartUpload.Parts = append(complMultipartUpload.Parts, miniov6.CompletePart{


+ 7
- 2
modules/storage/obs.go View File

@@ -85,7 +85,7 @@ func listAllParts(uuid, uploadID, key string) (output *obs.ListPartsOutput, err
}) })
} }


if len(temp.Parts) < temp.MaxParts {
if !temp.IsTruncated {
break break
} else { } else {
continue continue
@@ -128,7 +128,7 @@ func NewObsMultiPartUpload(uuid, fileName string) (string, error) {
return output.UploadId, nil return output.UploadId, nil
} }


func CompleteObsMultiPartUpload(uuid, uploadID, fileName string) error {
func CompleteObsMultiPartUpload(uuid, uploadID, fileName string, totalChunks int) error {
input := &obs.CompleteMultipartUploadInput{} input := &obs.CompleteMultipartUploadInput{}
input.Bucket = setting.Bucket input.Bucket = setting.Bucket
input.Key = strings.TrimPrefix(path.Join(setting.BasePath, path.Join(uuid[0:1], uuid[1:2], uuid, fileName)), "/") input.Key = strings.TrimPrefix(path.Join(setting.BasePath, path.Join(uuid[0:1], uuid[1:2], uuid, fileName)), "/")
@@ -140,6 +140,11 @@ func CompleteObsMultiPartUpload(uuid, uploadID, fileName string) error {
return err return err
} }


if len(allParts.Parts) != totalChunks {
log.Error("listAllParts number(%d) is not equal the set total chunk number(%d)", len(allParts.Parts), totalChunks)
return errors.New("the parts is not complete")
}

input.Parts = allParts.Parts input.Parts = allParts.Parts


output, err := ObsCli.CompleteMultipartUpload(input) output, err := ObsCli.CompleteMultipartUpload(input)


+ 6
- 0
options/locale/locale_en-US.ini View File

@@ -1389,6 +1389,7 @@ issues.filter_sort.feweststars = Fewest stars
issues.filter_sort.mostforks = Most forks issues.filter_sort.mostforks = Most forks
issues.filter_sort.fewestforks = Fewest forks issues.filter_sort.fewestforks = Fewest forks
issues.filter_sort.downloadtimes = Most downloaded issues.filter_sort.downloadtimes = Most downloaded
issues.filter_sort.moststars = Most star
issues.action_open = Open issues.action_open = Open
issues.action_close = Close issues.action_close = Close
issues.action_label = Label issues.action_label = Label
@@ -2502,11 +2503,15 @@ repos.contributor=Contributor
repos.yes=Yes repos.yes=Yes
repos.no=No repos.no=No


images.recommend = Recommend
images.unrecommend = Unrecommend


datasets.dataset_manage_panel= Dataset Manage datasets.dataset_manage_panel= Dataset Manage
datasets.owner=Owner datasets.owner=Owner
datasets.name=name datasets.name=name
datasets.private=Private datasets.private=Private
datasets.recommend=Set recommend
datasets.unrecommend=Set unrecommend


cloudbrain.all_task_types=All Task Types cloudbrain.all_task_types=All Task Types
cloudbrain.all_computing_resources=All Computing Resources cloudbrain.all_computing_resources=All Computing Resources
@@ -2964,6 +2969,7 @@ snn4imagenet_path = Snn4imagenet script path
brainscore_path = Brainscore script path brainscore_path = Brainscore script path
start_command = Start command start_command = Start command
choose_mirror = select mirror or enter mirror path choose_mirror = select mirror or enter mirror path
input_mirror = Please enter image path
select_dataset = select dataset select_dataset = select dataset
specification = specification specification = specification
select_specification = select specification select_specification = select specification


+ 6
- 0
options/locale/locale_zh-CN.ini View File

@@ -1401,6 +1401,7 @@ issues.filter_sort.feweststars=点赞由少到多
issues.filter_sort.mostforks=派生由多到少 issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多 issues.filter_sort.fewestforks=派生由少到多
issues.filter_sort.downloadtimes=下载次数 issues.filter_sort.downloadtimes=下载次数
issues.filter_sort.moststars=收藏数量
issues.action_open=开启 issues.action_open=开启
issues.action_close=关闭 issues.action_close=关闭
issues.action_label=标签 issues.action_label=标签
@@ -2512,11 +2513,15 @@ repos.contributor=贡献者数
repos.yes=是 repos.yes=是
repos.no=否 repos.no=否


images.recommend = 推荐
images.unrecommend = 不推荐


datasets.dataset_manage_panel=数据集管理 datasets.dataset_manage_panel=数据集管理
datasets.owner=所有者 datasets.owner=所有者
datasets.name=名称 datasets.name=名称
datasets.private=私有 datasets.private=私有
datasets.recommend=设为推荐
datasets.unrecommend=取消推荐


cloudbrain.all_task_types=全部任务类型 cloudbrain.all_task_types=全部任务类型
cloudbrain.all_computing_resources=全部计算资源 cloudbrain.all_computing_resources=全部计算资源
@@ -2974,6 +2979,7 @@ snn4imagenet_path = snn4imagenet脚本存放路径
brainscore_path = brainscore脚本存放路径 brainscore_path = brainscore脚本存放路径
start_command = 启动命令 start_command = 启动命令
choose_mirror = 选择镜像或输入镜像地址 choose_mirror = 选择镜像或输入镜像地址
input_mirror = 请输入云脑镜像地址
select_dataset = 选择数据集 select_dataset = 选择数据集
specification = 规格 specification = 规格
select_specification = 选择资源规格 select_specification = 选择资源规格


+ 7
- 0
routers/admin/cloudbrains.go View File

@@ -21,6 +21,7 @@ import (
const ( const (
tplCloudBrains base.TplName = "admin/cloudbrain/list" tplCloudBrains base.TplName = "admin/cloudbrain/list"
tplImages base.TplName = "admin/cloudbrain/images" tplImages base.TplName = "admin/cloudbrain/images"
tplCommitImages base.TplName = "admin/cloudbrain/imagecommit"
EXCEL_DATE_FORMAT = "20060102150405" EXCEL_DATE_FORMAT = "20060102150405"
CREATE_TIME_FORMAT = "2006/01/02 15:04:05" CREATE_TIME_FORMAT = "2006/01/02 15:04:05"
) )
@@ -114,6 +115,12 @@ func Images(ctx *context.Context) {


} }


func CloudBrainCommitImageShow(ctx *context.Context) {
ctx.Data["PageIsAdminImages"] = true
ctx.HTML(200, tplCommitImages)

}

func DownloadCloudBrains(ctx *context.Context) { func DownloadCloudBrains(ctx *context.Context) {


page := 1 page := 1


+ 23
- 1
routers/admin/dataset.go View File

@@ -1,6 +1,8 @@
package admin package admin


import ( import (
"net/http"
"strconv"
"strings" "strings"


"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@@ -49,6 +51,8 @@ func Datasets(ctx *context.Context) {
orderBy = models.SearchOrderBySizeReverse orderBy = models.SearchOrderBySizeReverse
case "size": case "size":
orderBy = models.SearchOrderBySize orderBy = models.SearchOrderBySize
case "downloadtimes":
orderBy = models.SearchOrderByDownloadTimes
case "moststars": case "moststars":
orderBy = models.SearchOrderByStarsReverse orderBy = models.SearchOrderByStarsReverse
case "feweststars": case "feweststars":
@@ -70,6 +74,7 @@ func Datasets(ctx *context.Context) {
PageSize: setting.UI.ExplorePagingNum, PageSize: setting.UI.ExplorePagingNum,
}, },
Keyword: keyword, Keyword: keyword,
RecommendOnly: ctx.QueryBool("recommend"),
SearchOrderBy: orderBy, SearchOrderBy: orderBy,
}) })
if err != nil { if err != nil {
@@ -80,7 +85,7 @@ func Datasets(ctx *context.Context) {
ctx.Data["Keyword"] = keyword ctx.Data["Keyword"] = keyword
ctx.Data["Total"] = count ctx.Data["Total"] = count
ctx.Data["Datasets"] = datasets ctx.Data["Datasets"] = datasets
ctx.Data["Recommend"] = ctx.QueryBool("recommend")
pager := context.NewPagination(int(count), setting.UI.ExplorePagingNum, page, 5) pager := context.NewPagination(int(count), setting.UI.ExplorePagingNum, page, 5)
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
@@ -88,6 +93,23 @@ func Datasets(ctx *context.Context) {
ctx.HTML(200, tplDatasets) ctx.HTML(200, tplDatasets)
} }


func DatasetAction(ctx *context.Context) {
var err error
datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64)
switch ctx.Params(":action") {

case "recommend":
err = models.RecommendDataset(datasetId, true)
case "unrecommend":
err = models.RecommendDataset(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 DeleteDataset(ctx *context.Context) { func DeleteDataset(ctx *context.Context) {
dataset, err := models.GetDatasetByID(ctx.QueryInt64("id")) dataset, err := models.GetDatasetByID(ctx.QueryInt64("id"))
if err != nil { if err != nil {


+ 2
- 0
routers/home.go View File

@@ -331,6 +331,7 @@ func ExploreDatasets(ctx *context.Context) {
Task: task, Task: task,
License: license, License: license,
OwnerID: ownerID, OwnerID: ownerID,
RecommendOnly: ctx.QueryBool("recommend"),
ListOptions: models.ListOptions{ ListOptions: models.ListOptions{
Page: page, Page: page,
PageSize: 30, PageSize: 30,
@@ -357,6 +358,7 @@ func ExploreDatasets(ctx *context.Context) {
ctx.Data["Category"] = category ctx.Data["Category"] = category
ctx.Data["Task"] = task ctx.Data["Task"] = task
ctx.Data["License"] = license ctx.Data["License"] = license
ctx.Data["Recommend"] = ctx.QueryBool("recommend")
pager.SetDefaultParams(ctx) pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager ctx.Data["Page"] = pager




+ 2
- 2
routers/repo/attachment.go View File

@@ -855,13 +855,13 @@ func CompleteMultipart(ctx *context.Context) {
} }


if typeCloudBrain == models.TypeCloudBrainOne { if typeCloudBrain == models.TypeCloudBrainOne {
_, err = storage.CompleteMultiPartUpload(uuid, uploadID)
_, err = storage.CompleteMultiPartUpload(uuid, uploadID, fileChunk.TotalChunks)
if err != nil { if err != nil {
ctx.Error(500, fmt.Sprintf("CompleteMultiPartUpload failed: %v", err)) ctx.Error(500, fmt.Sprintf("CompleteMultiPartUpload failed: %v", err))
return return
} }
} else { } else {
err = storage.CompleteObsMultiPartUpload(uuid, uploadID, fileName)
err = storage.CompleteObsMultiPartUpload(uuid, uploadID, fileName, fileChunk.TotalChunks)
if err != nil { if err != nil {
ctx.Error(500, fmt.Sprintf("CompleteObsMultiPartUpload failed: %v", err)) ctx.Error(500, fmt.Sprintf("CompleteObsMultiPartUpload failed: %v", err))
return return


+ 47
- 0
routers/repo/cloudbrain.go View File

@@ -703,6 +703,53 @@ func CloudBrainCommitImageCheck(ctx *context.Context, form auth.CommitImageCloud


} }


func CloudBrainAdminCommitImage(ctx *context.Context, form auth.CommitAdminImageCloudBrainForm) {

if !NamePattern.MatchString(form.Tag) {
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.title_format_err")))
return
}

if utf8.RuneCountInString(form.Description) > 255 {
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("dataset.description_format_err", 255)))
return
}

validTopics, errMessage := checkTopics(form.Topics)
if errMessage != "" {
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr(errMessage)))
return
}

err := cloudbrain.CommitAdminImage(models.CommitImageParams{
CommitImageCloudBrainParams: models.CommitImageCloudBrainParams{
ImageDescription: form.Description,
ImageTag: form.Tag,
},
IsPrivate: form.IsPrivate,
CloudBrainType: form.Type,
Topics: validTopics,
UID: ctx.User.ID,
Type: models.GetRecommondType(form.IsRecommend),
Place: form.Place,
})
if err != nil {
log.Error("CommitImagefailed")
if models.IsErrImageTagExist(err) {
ctx.JSON(200, models.BaseErrorMessage(ctx.Tr("repo.image_exist")))

} else if models.IsErrorImageCommitting(err) {
ctx.JSON(200, models.BaseErrorMessage(ctx.Tr("repo.image_committing")))
} else {
ctx.JSON(200, models.BaseErrorMessage(ctx.Tr("repo.image_commit_fail")))
}

return
}

ctx.JSON(200, models.BaseOKMessage)
}

func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrainForm) { func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrainForm) {


if !NamePattern.MatchString(form.Tag) { if !NamePattern.MatchString(form.Tag) {


+ 3
- 0
routers/repo/dataset.go View File

@@ -358,6 +358,7 @@ func MyDatasets(ctx *context.Context) {
NeedIsPrivate: false, NeedIsPrivate: false,
JustNeedZipFile: true, JustNeedZipFile: true,
NeedRepoInfo: true, NeedRepoInfo: true,
RecommendOnly: ctx.QueryBool("recommend"),
}) })
if err != nil { if err != nil {
ctx.ServerError("datasets", err) ctx.ServerError("datasets", err)
@@ -398,6 +399,7 @@ func PublicDataset(ctx *context.Context) {
Type: cloudbrainType, Type: cloudbrainType,
JustNeedZipFile: true, JustNeedZipFile: true,
NeedRepoInfo: true, NeedRepoInfo: true,
RecommendOnly: ctx.QueryBool("recommend"),
}) })
if err != nil { if err != nil {
ctx.ServerError("datasets", err) ctx.ServerError("datasets", err)
@@ -454,6 +456,7 @@ func MyFavoriteDataset(ctx *context.Context) {
Type: cloudbrainType, Type: cloudbrainType,
JustNeedZipFile: true, JustNeedZipFile: true,
NeedRepoInfo: true, NeedRepoInfo: true,
RecommendOnly: ctx.QueryBool("recommend"),
}) })
if err != nil { if err != nil {
ctx.ServerError("datasets", err) ctx.ServerError("datasets", err)


+ 3
- 0
routers/routes/routes.go View File

@@ -525,6 +525,7 @@ func RegisterRoutes(m *macaron.Macaron) {


m.Group("/datasets", func() { m.Group("/datasets", func() {
m.Get("", admin.Datasets) m.Get("", admin.Datasets)
m.Put("/:id/action/:action", admin.DatasetAction)
// m.Post("/delete", admin.DeleteDataset) // m.Post("/delete", admin.DeleteDataset)
}) })
m.Group("/cloudbrains", func() { m.Group("/cloudbrains", func() {
@@ -534,6 +535,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/images", func() { m.Group("/images", func() {
m.Get("", admin.Images) m.Get("", admin.Images)
m.Get("/data", repo.GetAllImages) m.Get("/data", repo.GetAllImages)
m.Get("/commit_image", admin.CloudBrainCommitImageShow)
m.Post("/commit_image", bindIgnErr(auth.CommitAdminImageCloudBrainForm{}), repo.CloudBrainAdminCommitImage)
}) })
m.Put("/image/:id/action/:action", image.Action) m.Put("/image/:id/action/:action", image.Action)




+ 5
- 3
routers/user/profile.go View File

@@ -106,9 +106,9 @@ func Profile(ctx *context.Context) {


for _, org := range orgs { for _, org := range orgs {
_, repoCount, err := models.SearchRepository(&models.SearchRepoOptions{ _, repoCount, err := models.SearchRepository(&models.SearchRepoOptions{
OwnerID: org.ID,
Private: ctx.IsSigned,
Actor: ctx.User,
OwnerID: org.ID,
Private: ctx.IsSigned,
Actor: ctx.User,
}) })
if err != nil { if err != nil {
ctx.ServerError("SearchRepository", err) ctx.ServerError("SearchRepository", err)
@@ -175,6 +175,8 @@ func Profile(ctx *context.Context) {
orderBy = models.SearchOrderByAlphabeticallyReverse orderBy = models.SearchOrderByAlphabeticallyReverse
case "alphabetically": case "alphabetically":
orderBy = models.SearchOrderByAlphabetically orderBy = models.SearchOrderByAlphabetically
case "downloadtimes":
orderBy = models.SearchOrderByDownloadTimes
case "moststars": case "moststars":
orderBy = models.SearchOrderByStarsReverse orderBy = models.SearchOrderByStarsReverse
case "feweststars": case "feweststars":


+ 129
- 0
templates/admin/cloudbrain/imagecommit.tmpl View File

@@ -0,0 +1,129 @@
<style>
.label_color{
color:#505559 !important;
width: 6% !important;
text-align: center;
}
</style>
{{template "base/head" .}}
<div id="mask">
<div id="loadingPage">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
<div class="repository">
{{template "repo/header" .}}
<div class="alert"></div>
<div class="ui container">
<div>
<div class="ui negative message" style="display: none;">
</div>
<div class="ui info message" style="display: none;">
</div>
<div class="ui positive message" style="display: none;">
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.submit_image"}}
</h4>
<div class="submit-image-tmplvalue" style="display: none;" data-link="{{$.Link}}"></div>
<div class="ui attached segment" style="padding: 2em 3em;padding-bottom: 7rem;">
<div class="ui form" id="form_image">
<input type="hidden" name="edit" value="edit">
{{.CsrfTokenHtml}}
<div class="inline field">
<label class="label_color" for="">{{$.i18n.Tr "dataset.dataset_available_clusters"}}</label>
<div class="ui basic label" style="border: none !important;color:#3291f8;">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14"><path fill="none" d="M0 0h24v24H0z"></path><path d="M4 3h16a1 1 0 0 1 1 1v7H3V4a1 1 0 0 1 1-1zM3 13h18v7a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-7zm4 3v2h3v-2H7zM7 6v2h3V6H7z"></path></svg>
CPU/GPU
</div>
<input type="hidden" value="{{.Type}}" name="type">
</div>
<div class="inline required field">
<label class="label_color" for="">{{$.i18n.Tr "repo.images.name"}}</label>
<input type="text" name="tag" required placeholder="{{$.i18n.Tr "repo.images.name_placerholder"}}" style="width: 80%;" maxlength="100">
<span class="tooltips" style="display: block;padding-left: 0.5rem;">{{.i18n.Tr "repo.images.name_rule"}}</span>
</div>
<div class="inline required field">
<label class="label_color" for="">{{$.i18n.Tr "repo.images"}}</label>
<input type="text" name="place" required placeholder="{{$.i18n.Tr "cloudbrain.input_mirror"}}" style="width: 80%;" maxlength="100">
</div>
<div class="inline required field">
<label class="label_color" for="">{{$.i18n.Tr "dataset.description"}}</label>
<textarea style="width: 80%;" required id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
</div>
<div class="inline field" style="display: flex;align-items: center;">
<label class="label_color" for="">{{$.i18n.Tr "repo.model.manage.label"}}</label>&nbsp;
<div class="ui multiple search selection dropdown" id="dropdown_image" style="width: 80%;">
<input type="hidden" name="topics" value="" required>
<div class="default text" id="default_text">{{.i18n.Tr "repo.repo_label_helpe"}}</div>
<div class="menu" id="course_label_item"></div>
</div>
</div>
<span class="tooltips" style="display: block;padding-left: 0.5rem;margin-top: 0.5rem;margin-bottom: 1rem;">{{.i18n.Tr "repo.image.label_tooltips"}}</span>
<div class="inline fields">
<label class="label_color" for="" style="visibility: hidden;"></label>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="isRecommend" checked="checked" value="true">
<label>{{.i18n.Tr "admin.images.recommend"}}</label>
</div>
</div>
<div class="field" style="flex: 0.15;">
<div class="ui radio checkbox" >
<input type="radio" name="isRecommend" value="false">
<label>{{.i18n.Tr "admin.images.unrecommend"}}</label>
</div>
</div>
</div>
<div class="inline fields">
<label class="label_color" for="" style="visibility: hidden;"></label>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="isPrivate" checked="checked" value="false">
<label>{{.i18n.Tr "org.settings.visibility.public"}}</label>
</div>
</div>
<div class="field" style="flex: 0.15;">
<div class="ui radio checkbox" >
<input type="radio" name="isPrivate" value="true">
<label>{{.i18n.Tr "home.show_private"}}</label>
</div>
</div>
<div class="field">
<span class="label_color">{{.i18n.Tr "repo.images.public_tooltips"}}</span>
</div>
</div>
<div class="inline required field" style="padding-top: 2rem;">
<label class="label_color" for="" style="visibility: hidden;"></label>
<button class="ui create_image green button" type="button">
{{.i18n.Tr "repo.cloudbrain.commit_image"}}
</button>
<a class="ui button" id="cancel_submit_image">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</div>
</div>
</div>
</div>
</div>

<!-- 确认模态框 -->
<div>
<div class="ui modal image_confirm_submit">
<div class="header">{{.i18n.Tr "repo.submit_image"}}</div>
<div class="content text red center">
<p><i class="exclamation icon"></i>{{.i18n.Tr "repo.image_overwrite"}}</p>
</div>
<div class="actions">
<button class="ui deny small button">{{.i18n.Tr "cloudbrain.operate_cancel"}}</button>
<button class="ui green small approve button">{{.i18n.Tr "cloudbrain.operate_confirm"}}</button>
</div>
</div>
</div>
{{template "base/footer" .}}

+ 6
- 15
templates/admin/dataset/list.tmpl View File

@@ -3,6 +3,9 @@
{{template "admin/navbar" .}} {{template "admin/navbar" .}}
<div class="ui container"> <div class="ui container">
{{template "base/alert" .}} {{template "base/alert" .}}
<div class="ui negative message" style="display: none;">
</div>
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{.i18n.Tr "admin.datasets.dataset_manage_panel"}} ({{.i18n.Tr "admin.total" .Total}}) {{.i18n.Tr "admin.datasets.dataset_manage_panel"}} ({{.i18n.Tr "admin.total" .Total}})
</h4> </h4>
@@ -24,10 +27,10 @@
{{range .Datasets}} {{range .Datasets}}
<tr> <tr>
<td>{{.ID}}</td> <td>{{.ID}}</td>
<td><a href="{{AppSubUrl}}/">{{.Title}}</a></td>
<td style="display: flex;align-items: center;"><a href="{{AppSubUrl}}/">{{.Title}}</a>{{if .Recommend}}<img src="/img/jian.svg" style="margin-left: 0.5rem;">{{end}}</td>
<td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td>
<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> <td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td>
<td></td>
<td>{{if .Recommend}}<span class="set_dataset" style="color: rgb(250, 140, 22);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/unrecommend">{{$.i18n.Tr "admin.datasets.unrecommend"}}</span>{{else}}<span class="set_dataset" style="color: rgb(19, 194, 141);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/recommend">{{$.i18n.Tr "admin.datasets.recommend"}}</span>{{end}}</td>
</tr> </tr>
{{end}} {{end}}
</tbody> </tbody>
@@ -37,16 +40,4 @@
{{template "base/paginate" .}} {{template "base/paginate" .}}
</div> </div>
</div> </div>

<div class="ui small basic delete modal">
<div class="ui icon header">
<i class="trash icon"></i>
{{.i18n.Tr "dataset.settings.delete"}}
</div>
<div class="content">
<p>{{.i18n.Tr "dataset.settings.delete_desc"}}</p>
{{.i18n.Tr "dataset.settings.delete_notices_2" `<span class="name"></span>` | Safe}}<br>
</div>
{{template "base/delete_modal_actions" .}}
</div>
{{template "base/footer" .}}
{{template "base/footer" .}}

+ 4
- 4
templates/custom/select_dataset.tmpl View File

@@ -23,7 +23,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.current_project"}}" name="first"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name} </span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -49,7 +49,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.owner_dataset"}}" name="second"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -74,7 +74,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.public_dataset"}}" name="third"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -99,7 +99,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.I_liked"}}" name="fourth"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">


+ 4
- 4
templates/custom/select_dataset_train.tmpl View File

@@ -23,7 +23,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.current_project"}}" name="first"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias} </span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name} </span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -49,7 +49,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.owner_dataset"}}" name="second"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -74,7 +74,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.public_dataset"}}" name="third"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">
@@ -99,7 +99,7 @@
<el-tab-pane label="{{.i18n.Tr "dataset.I_liked"}}" name="fourth"> <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="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="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="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><img v-if="dataset.Recommend" src="/img/jian.svg" style="margin-left: 0.5rem;"><span class="panel_dataset_name">${dataset.Name}</span></div>
<div style="margin-top: 8px;display: flex;"> <div style="margin-top: 8px;display: flex;">
<a :title="dataset.UserName" style="cursor: default;"> <a :title="dataset.UserName" style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink">


+ 4
- 2
templates/explore/datasets.tmpl View File

@@ -125,7 +125,8 @@
<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> <a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.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}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a> <a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.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}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a> <a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.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> -->
<a class="{{if eq .SortType "downloadtimes"}}active{{end}} item" href="{{$.Link}}?sort=downloadtimes&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}</a>
<a class="{{if eq .SortType "moststars"}}active{{end}} item" href="{{$.Link}}?sort=moststars&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.moststars"}}</a>
</div> </div>
</div> </div>
</div> </div>
@@ -144,7 +145,8 @@
<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="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="content" style="border-bottom: none;">
<div class="repo_dataset_header" style="display: flex;align-items: center;justify-content: space-between;"> <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>
<a href="{{.Repo.Link}}/datasets" style="font-size: 12px;color: #3291F8;height: 24px;">{{.Repo.OwnerName}} / {{.Repo.Alias}}{{if .Recommend}}<img src="/img/jian.svg" style="margin-left: 0.5rem;">{{end}}</a>
{{if $.IsSigned}} {{if $.IsSigned}}
<span style="display: flex;align-items: center;justify-content: flex-end;cursor: pointer;" @click.stop="postSquareStar({{.ID}},'{{.Repo.Link}}/datasets',{{$k}})"> <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;"> <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;">


+ 20
- 1
templates/repo/cloudbrain/new.tmpl View File

@@ -179,7 +179,26 @@
</div> </div>
</div> </div>
<input id="store_category" type="hidden" name="get_benchmark_category"> <input id="store_category" type="hidden" name="get_benchmark_category">

<div class="inline required field">
<label>{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branch_name }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{else}}
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branchName }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{end}}
</select>
</div>
<div class="inline required field"> <div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type">


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

@@ -420,7 +420,13 @@ td, th {
</div> </div>
</div> </div>
<div class="ui tab" data-tab="second{{$k}}"> <div class="ui tab" data-tab="second{{$k}}">
<div>
<div style="position: relative;">
<span>
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" id="log_top"><i class="icon-to-top"></i></a>
</span>
<span>
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" id="log_bottom"><i class="icon-to-bottom"></i></a>
</span>
<div class="ui message message{{.VersionName}}" style="display: none;"> <div class="ui message message{{.VersionName}}" style="display: none;">
<div id="header"></div> <div id="header"></div>
</div> </div>
@@ -879,4 +885,57 @@ td, th {
}); });
} }
} }
function scrollAnimation(dom, currentY, targetY, currentX) {
let needScrollTop = targetY - currentY;
let _currentY = currentY;
setTimeout(() => {
// 一次调用滑动帧数,每次调用会不一样
//取总距离的十分之一
const dist = Math.ceil(needScrollTop / 10);
_currentY += dist;
//移动一个十分之一
console.log(_currentY, targetY)
dom.scrollTo(currentX || 0, _currentY);
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果
if (needScrollTop > 10 || needScrollTop < -10) {
scrollAnimation(dom, _currentY, targetY)
} else {
dom.scrollTo(0, targetY)
}
}, 1)
}

$('#log_top').click(function(){
let logContentDom = document.querySelector('.log')
if(!logContentDom)
return
scrollAnimation(logContentDom, logContentDom.scrollTop, 0);
})
$('#log_bottom').click(function(){
let logContentDom = document.querySelector('.log')
if(!logContentDom)
return
//如果内容撑大到可以滚动,则触发滚动
// if(!['10','11','12'].includes(context.taskInfo.statusCode)){
// context.getLogContent(0, context.lines, 'goDown')
// }
if(logContentDom.scrollHeight > logContentDom.clientHeight){
console.log("1111")
scrollAnimation(logContentDom, logContentDom.scrollTop, logContentDom.scrollHeight - logContentDom.clientHeight);
}
else{
logScroll(version_name)
logContentDom.scrollTo(0,logContentDom.scrollTop-1);
}
// if(this.checkCurrentCanScrollBottom()){
// // this.goDown();
// this.scrollAnimation(logContentDom, logContentDom.scrollTop, logContentDom.scrollHeight - logContentDom.clientHeight);
// }else{
// //如果内容不足,则往后追加内容
// this.goDown();
// logContentDom.scrollTo(0,logContentDom.scrollTop-1);
// }
})
</script> </script>

+ 3
- 0
web_src/js/components/MinioUploader.vue View File

@@ -193,6 +193,9 @@ export default {
const time = new Date().getTime(); const time = new Date().getTime();
this.status = this.dropzoneParams.data('md5-computing'); this.status = this.dropzoneParams.data('md5-computing');
file.totalChunkCounts = chunks; file.totalChunkCounts = chunks;
if (file.size==0) {
file.totalChunkCounts = 1
}
loadMd5Next(); loadMd5Next();


fileReader.onload = (e) => { fileReader.onload = (e) => {


+ 14
- 12
web_src/js/components/images/adminImages.vue View File

@@ -1,6 +1,7 @@
<template> <template>
<div>
<div >
<div class="ui container" style="width: 80%;"> <div class="ui container" style="width: 80%;">
<div class="ui grid">
<div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;">
<div class="ui attached segment"> <div class="ui attached segment">
@@ -11,12 +12,10 @@
</div> </div>
</div> </div>
</div> </div>
<el-row style="padding: 1rem;">
<el-col :span="2" style="margin-right: 1rem;">
<el-checkbox v-model="checked" style="padding: 0.5rem 1rem;">仅显示平台推荐</el-checkbox>
</el-col>
<el-col :span="6">
<el-dropdown @command="handleCommand" trigger="click" style="border: 1px solid rgba(34,36,38,.15);border-radius: 4px;padding: 0.5rem 1rem;">

<div class="ui ten wide column" style="margin: 1rem 0;">
<el-checkbox v-model="checked" style="padding: 0.5rem 1rem;">仅显示平台推荐</el-checkbox>
<el-dropdown @command="handleCommand" trigger="click" style="border: 1px solid rgba(34,36,38,.15);border-radius: 4px;padding: 0.5rem 1rem;">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
{{dropdownPrivate}}<i class="el-icon-caret-bottom el-icon--right"></i> {{dropdownPrivate}}<i class="el-icon-caret-bottom el-icon--right"></i>
</span> </span>
@@ -25,10 +24,12 @@
<el-dropdown-item :command="{label:'公开',private:false}">公开</el-dropdown-item> <el-dropdown-item :command="{label:'公开',private:false}">公开</el-dropdown-item>
<el-dropdown-item :command="{label:'公开',private:true}">私有</el-dropdown-item> <el-dropdown-item :command="{label:'公开',private:true}">私有</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<el-row>
</el-dropdown>
</div>
<div class="ui six wide column right aligned" style="margin: 1rem 0;">
<a class="ui blue small button" href="/admin/images/commit_image?from=imageAdmin">创建云脑镜像</a>
</div>
<div class="ui sixteen wide column" style="padding: 0;">
<el-table <el-table
:data="tableDataCustom" :data="tableDataCustom"
style="width: 100%" style="width: 100%"
@@ -138,7 +139,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-row>
</div>
<div class="ui container" style="padding:2rem 0;text-align:center"> <div class="ui container" style="padding:2rem 0;text-align:center">
<el-pagination <el-pagination
background background
@@ -152,6 +153,7 @@
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>




+ 21
- 2
web_src/js/features/images.js View File

@@ -26,6 +26,15 @@ export default async function initImage(){
} }
] ]
}, },
place:{
identifier : 'place',
rules: [
{
type: 'empty',
}
]
},
} }
}) })
} }
@@ -75,8 +84,9 @@ export default async function initImage(){
type:'POST', type:'POST',
data:formData, data:formData,
success:function(res){ success:function(res){
console.log(res)
if(res.Code===1){ if(res.Code===1){
$('.ui.info.message').text(res.Message).show().delay(1500).fadeOut();
$('.ui.negative.message').text(res.Message).show().delay(2500).fadeOut();
}else if(res.Code==0){ }else if(res.Code==0){
if(location.href.indexOf('imageAdmin')!==-1){ if(location.href.indexOf('imageAdmin')!==-1){
location.href = `${window.config.AppSubUrl}/admin/images` location.href = `${window.config.AppSubUrl}/admin/images`
@@ -105,6 +115,11 @@ export default async function initImage(){
$("textarea[name='description']").parent().addClass('error') $("textarea[name='description']").parent().addClass('error')
return false return false
} }
if($("input[name='place']").length>0&&!$("input[name='place']").val()){
console.log("1111111",$("input[name='place']"))
$("input[name='place']").parent().addClass('error')
return false
}
const postData = { const postData = {
_csrf:$("input[name='_csrf']").val(), _csrf:$("input[name='_csrf']").val(),
@@ -115,6 +130,10 @@ export default async function initImage(){
topics:$("input[name='topics']").val(), topics:$("input[name='topics']").val(),
id:$("input[name='id']").val() id:$("input[name='id']").val()
} }
if($("input[name='place']").val()&&$("input[name='isRecommend']:checked").val()){
postData.isRecommend = $("input[name='isRecommend']:checked").val()
postData.place = $("input[name='place']").val()
}
let formData = $params(postData) let formData = $params(postData)
if($("input[name='edit']").val()=="edit"){ if($("input[name='edit']").val()=="edit"){
postImage(formData) postImage(formData)
@@ -143,7 +162,7 @@ export default async function initImage(){
} }
}) })
} }
return false
}) })
$('#cancel_submit_image').click(()=>{ $('#cancel_submit_image').click(()=>{
if(link.includes('cloudbrain')){ if(link.includes('cloudbrain')){


+ 27
- 17
web_src/js/index.js View File

@@ -34,7 +34,6 @@ import {
} from './features/notification.js'; } from './features/notification.js';
import {createCodeEditor} from './features/codeeditor.js'; import {createCodeEditor} from './features/codeeditor.js';
import MinioUploader from './components/MinioUploader.vue'; import MinioUploader from './components/MinioUploader.vue';
import ObsUploader from './components/ObsUploader.vue';
import EditAboutInfo from './components/EditAboutInfo.vue'; import EditAboutInfo from './components/EditAboutInfo.vue';
// import Images from './components/Images.vue'; // import Images from './components/Images.vue';
import EditTopics from './components/EditTopics.vue'; import EditTopics from './components/EditTopics.vue';
@@ -2958,7 +2957,6 @@ $(document).ready(async () => {
initCodeView(); initCodeView();
initVueApp(); initVueApp();
initVueUploader(); initVueUploader();
initObsUploader();
initVueDataset(); initVueDataset();
initVueEditAbout(); initVueEditAbout();
initVueEditTopic(); initVueEditTopic();
@@ -3702,6 +3700,32 @@ function initVueEditAbout() {
} }


function initVueDataset() { function initVueDataset() {
$('.set_dataset').on('click', function(){
const $this = $(this);
let link = $this.data('url')
$.ajax({
url:link,
type:'PUT',
success:function(res){
console.log(res)
if(res.Code==0){
window.location.href = '/admin/datasets'
}else{
$('.ui.negative.message').text(res.Message).show().delay(1500).fadeOut();
}
},
error: function(xhr){
// 隐藏 loading
// 只有请求不正常(状态码不为200)才会执行
$('.ui.negative.message').html(xhr.responseText).show().delay(1500).fadeOut();
console.log(xhr)
},
complete:function(xhr){
// $("#mask").css({"display":"none","z-index":"1"})
}
})
});
const el = document.getElementById('dataset-base'); const el = document.getElementById('dataset-base');
if (!el) { if (!el) {
return; return;
@@ -3854,8 +3878,7 @@ function initVueDataset() {
}, },
}, },
components: { components: {
MinioUploader,
ObsUploader
MinioUploader
}, },
mounted(){ mounted(){
// if(document.getElementById('postPath')){ // if(document.getElementById('postPath')){
@@ -4380,19 +4403,6 @@ function initVueDataAnalysis() {
render: h => h(DataAnalysis) render: h => h(DataAnalysis)
}); });
} }
// 新增
function initObsUploader() {
const el = document.getElementById('obsUploader');
if (!el) {
return;
}

new Vue({
el: '#obsUploader',
components: {ObsUploader},
template: '<ObsUploader />'
});
}
function initVueWxAutorize() { function initVueWxAutorize() {
const el = document.getElementById('WxAutorize'); const el = document.getElementById('WxAutorize');
if (!el) { if (!el) {


Loading…
Cancel
Save