#1693 fix-1591

Merged
lewis merged 92 commits from fix-1591 into V20220328 2 years ago
  1. +132
    -0
      models/attachment.go
  2. +16
    -0
      models/base_message.go
  3. +70
    -28
      models/dataset.go
  4. +70
    -0
      models/dataset_star.go
  5. +1
    -0
      models/models.go
  6. +28
    -4
      models/repo.go
  7. +5
    -4
      models/user.go
  8. +17
    -6
      modules/auth/dataset.go
  9. +2
    -0
      modules/context/repo.go
  10. +17
    -0
      modules/dataset/dataset.go
  11. +5
    -3
      modules/setting/setting.go
  12. +26
    -20
      modules/templates/helper.go
  13. +50
    -6
      options/locale/locale_en-US.ini
  14. +47
    -1
      options/locale/locale_zh-CN.ini
  15. +29
    -6
      routers/home.go
  16. +63
    -12
      routers/repo/attachment.go
  17. +2
    -0
      routers/repo/cloudbrain.go
  18. +367
    -52
      routers/repo/dataset.go
  19. +5
    -0
      routers/repo/modelarts.go
  20. +0
    -4
      routers/repo/setting.go
  21. +20
    -1
      routers/routes/routes.go
  22. +134
    -0
      templates/custom/select_dataset.tmpl
  23. +69
    -0
      templates/explore/dataset_left.tmpl
  24. +1
    -1
      templates/explore/dataset_list.tmpl
  25. +210
    -9
      templates/explore/datasets.tmpl
  26. +45
    -0
      templates/repo/attachment/edit.tmpl
  27. +73
    -0
      templates/repo/attachment/upload.tmpl
  28. +5
    -11
      templates/repo/cloudbrain/new.tmpl
  29. +69
    -0
      templates/repo/datasets/create.tmpl
  30. +72
    -0
      templates/repo/datasets/edit.tmpl
  31. +321
    -125
      templates/repo/datasets/index.tmpl
  32. +1
    -1
      templates/repo/editor/upload.tmpl
  33. +1
    -1
      templates/repo/header.tmpl
  34. +13
    -19
      templates/repo/modelarts/notebook/new.tmpl
  35. +1
    -1
      templates/repo/modelmanage/index.tmpl
  36. +121
    -51
      web_src/js/components/MinioUploader.vue
  37. +4
    -1
      web_src/js/components/ObsUploader.vue
  38. +590
    -1
      web_src/js/index.js
  39. +35
    -0
      web_src/less/_dataset.less
  40. +4
    -0
      web_src/less/openi.less

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

+ 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),


+ 28
- 4
models/repo.go View File

@@ -1280,10 +1280,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
}

@@ -1601,6 +1597,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...


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

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

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

@@ -723,8 +723,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
@@ -743,7 +748,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
@@ -794,12 +800,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
@@ -829,7 +872,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)
@@ -885,7 +928,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
@@ -1095,6 +1138,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


+ 47
- 1
options/locale/locale_zh-CN.ini View File

@@ -726,8 +726,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=更新数据集
@@ -803,6 +809,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=拥有者
@@ -833,7 +877,7 @@ repo_label_helpe=输入完成后回车键完成标签确定。
issue_labels=任务标签
issue_labels_helper=选择一个任务标签集
license=授权许可
license_helper=选择授权许可文件
license_helper=选择授权许可文件
readme=自述
readme_helper=选择自述文件模板。
auto_init=初始化存储库 (添加. gitignore、许可证和自述文件)
@@ -1101,6 +1145,8 @@ unstar=取消点赞
star=点赞
fork=派生
download_archive=下载此项目
star_fail=%s失败。


no_desc=暂无描述
no_label = 暂无标签


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


+ 63
- 12
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 {
@@ -393,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"),
@@ -804,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)
@@ -841,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)



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

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



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

+ 5
- 0
routers/repo/modelarts.go View File

@@ -134,6 +134,8 @@ func notebookNewDataPrepare(ctx *context.Context) error {
}
ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo

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

return nil
}

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

return nil
}
@@ -751,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 {
@@ -1982,6 +1986,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

@@ -587,6 +587,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)
@@ -979,7 +981,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)


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


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

+ 5
- 11
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">
@@ -200,17 +202,8 @@
{{end}}
</datalist>
</div>

<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.dataset"}}</label>
<select id="cloudbrain_dataset" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}" 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="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="resource_spec_id">
@@ -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" .}}

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


+ 13
- 19
templates/repo/modelarts/notebook/new.tmpl View File

@@ -59,6 +59,9 @@
{{end}}
</select>
</div>
<<<<<<< HEAD
{{template "custom/select_dataset" .}}
=======

<div class="inline field">
<label>{{.i18n.Tr "cloudbrain.dataset"}}</label>
@@ -70,6 +73,7 @@
</datalist>
<input type="hidden" name="attachment" id="answerInput-hidden">
</div>
>>>>>>> V20220328

<!--<div class="inline required field">
<label>工作环境</label>
@@ -99,8 +103,8 @@
<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>
@@ -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
}
}
})
$(document).ready(function(){
$(document).keydown(function(event){
if(event.keyCode==13){
event.preventDefault();
}
});
});
</script>

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

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


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

+ 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