diff --git a/custom/public/css/git.openi.css b/custom/public/css/git.openi.css
index 3d7e15ada..3a4eff8e4 100755
--- a/custom/public/css/git.openi.css
+++ b/custom/public/css/git.openi.css
@@ -72,9 +72,7 @@
z-index: 10;
}
.ui.secondary.c2net.segment{
- /* background: #f8faff;
- border: none;*/
- margin-bottom: 5em;
+ padding-bottom: 3em;
padding-top: 2em;
color: rgba(0,0,0,.87);
background-image: linear-gradient(to bottom left,var(--tw-gradient-stops));
@@ -176,7 +174,7 @@
}
.homeorg, .homepro, .homemodel, .i-env{
position: relative;
- padding-bottom: 5em;
+ padding-bottom: 3em;
}
.homenews::before{
content: '';
@@ -203,7 +201,7 @@
padding: 0;
}
.newslist{
- height: 300px;
+ height: 260px;
overflow: hidden;
}
@@ -278,7 +276,7 @@
z-index: 9;
}
.homeorg-list .card{
- background-image: linear-gradient(#FFF, #FFF 60%, #DFF0EF) !important;
+ /* background-image: linear-gradient(#FFF, #FFF 60%, #DFF0EF) !important; */
box-shadow: none !important;
}
.homeorg-list .card .ui.small.header .content{
@@ -299,7 +297,7 @@
background-color: #FFF;
box-shadow: 0px 5px 10px 0px rgba(105, 192, 255, .3);
border: 1px solid rgba(105, 192, 255, .4);
- min-height: 10.8em;
+ /* min-height: 10.8em; */
}
.homepro-list .ui.card>.content>.header{
line-height: 40px !important;
@@ -307,7 +305,7 @@
.homepro-list .swiper-pagination-bullet-active, .homeorg-list .swiper-pagination-bullet-active{
width: 40px;
- border-radius: 4px;
+ border-radius: 4px;
}
.i-env > div{
position: relative;
@@ -317,6 +315,15 @@
}
@media only screen and (max-width: 767px) {
+ .mobile-margin-left-20 {
+ margin-left: 20px !important;
+ }
+ .mobile-text-align-center {
+ text-align: center !important;
+ }
+ .mobile-justify-content-center {
+ justify-content: center !important;
+ }
.am-mt-30{ margin-top: 1.5rem !important;}
.ui.secondary.hometop.segment{
margin-bottom: 5.0rem;
@@ -341,7 +348,7 @@
background: #FFF;
}
.homeorg{
- padding-left: 3.5em;
+ /* padding-left: 3.5em; */
}
.homeorg-tit::after {
left: -2.3em;
diff --git a/custom/public/img/home-banner-01-en.jpg b/custom/public/img/home-banner-01-en.jpg
new file mode 100644
index 000000000..59001d4f0
Binary files /dev/null and b/custom/public/img/home-banner-01-en.jpg differ
diff --git a/custom/public/img/home-banner-01.jpg b/custom/public/img/home-banner-01.jpg
new file mode 100644
index 000000000..1aa0563c4
Binary files /dev/null and b/custom/public/img/home-banner-01.jpg differ
diff --git a/custom/public/img/home-bg-ps.png b/custom/public/img/home-bg-ps.png
new file mode 100644
index 000000000..27e6ae1a1
Binary files /dev/null and b/custom/public/img/home-bg-ps.png differ
diff --git a/custom/public/img/logo-footer.svg b/custom/public/img/logo-footer.svg
new file mode 100644
index 000000000..3be0e5b18
--- /dev/null
+++ b/custom/public/img/logo-footer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/custom/public/img/logo-w.svg b/custom/public/img/logo-w.svg
index 867acc1e2..133f63d23 100644
--- a/custom/public/img/logo-w.svg
+++ b/custom/public/img/logo-w.svg
@@ -1 +1,45 @@
-logo-w
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/models/dataset.go b/models/dataset.go
index 972503641..4c1dc24db 100755
--- a/models/dataset.go
+++ b/models/dataset.go
@@ -122,22 +122,22 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions)
for i := range datasets {
if attachment.DatasetID == datasets[i].ID {
- if !attachment.IsPrivate{
+ if !attachment.IsPrivate {
datasets[i].Attachments = append(datasets[i].Attachments, attachment)
- }else{
+ } else {
permission, ok := permissionMap[datasets[i].ID]
if !ok {
permission = false
datasets[i].Repo.GetOwner()
if !permission {
- if datasets[i].Repo.OwnerID==opts.User.ID{
+ if datasets[i].Repo.OwnerID == opts.User.ID {
permission = true
- }else{
+ } else {
isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID)
- isInRepoTeam,_:=datasets[i].Repo.IsInRepoTeam(opts.User.ID)
+ isInRepoTeam, _ := datasets[i].Repo.IsInRepoTeam(opts.User.ID)
- if isCollaborator ||isInRepoTeam {
+ if isCollaborator || isInRepoTeam {
permission = true
}
}
@@ -603,3 +603,11 @@ func UpdateDatasetCreateUser(ID int64, user *User) error {
}
return nil
}
+
+func QueryDatasetGroupByTask() ([]map[string]interface{}, error) {
+ rows, err := x.QueryInterface("SELECT count(*) as total,task FROM public.dataset where task <>'' group by task order by total desc limit 7")
+ if err != nil {
+ return nil, err
+ }
+ return rows, nil
+}
diff --git a/models/repo_activity_custom.go b/models/repo_activity_custom.go
index b6fffca0e..26b2ea14f 100644
--- a/models/repo_activity_custom.go
+++ b/models/repo_activity_custom.go
@@ -263,7 +263,11 @@ func GetAllUserKPIStats(startTime time.Time, endTime time.Time) (map[string]*git
log.Warn("get user kpi status err:"+repository.RepoPath(), err1.Error())
continue
}
-
+ // if repository.Name == "yolov5" {
+ // log.Info("repoName=" + repository.Name + " owner=" + repository.RepoPath())
+ // authorsOneRepoJson, _ := json.Marshal(authorsOneRepo)
+ // log.Info("authorsOneRepoJson=" + string(authorsOneRepoJson))
+ // }
for key, value := range authorsOneRepo {
if _, ok := authors[key]; !ok {
authors[key] = &git.UserKPIStats{
diff --git a/models/resource_specification.go b/models/resource_specification.go
index 7a11edd05..2f815818b 100644
--- a/models/resource_specification.go
+++ b/models/resource_specification.go
@@ -298,6 +298,15 @@ func ResourceSpecOffShelf(id int64) (int64, error) {
return n, err
}
+func GetResourceSpecificationByIds(ids []int64) ([]*Specification, error) {
+ r := make([]*Specification, 0)
+ err := x.In("resource_specification.id", ids).
+ Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id").
+ Find(&r)
+ return r, err
+
+}
+
func GetResourceSpecification(r *ResourceSpecification) (*ResourceSpecification, error) {
has, err := x.Get(r)
if err != nil {
diff --git a/models/user.go b/models/user.go
index b21858e37..c421455bc 100755
--- a/models/user.go
+++ b/models/user.go
@@ -346,7 +346,7 @@ func (u *User) DashboardLink() string {
if u.IsOrganization() {
return setting.AppSubURL + "/org/" + u.Name + "/dashboard/"
}
- return setting.AppSubURL + "/"
+ return setting.AppSubURL + "/dashboard"
}
// HomeLink returns the user or organization home page link.
diff --git a/modules/cloudbrain/cloudbrain.go b/modules/cloudbrain/cloudbrain.go
index 8d4e57670..f8a6525d2 100755
--- a/modules/cloudbrain/cloudbrain.go
+++ b/modules/cloudbrain/cloudbrain.go
@@ -145,7 +145,7 @@ func isAdminOrImageCreater(ctx *context.Context, image *models.Image, err error)
func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {
var id = ctx.Params(":id")
- job, err := models.GetCloudbrainByID(id)
+ job, err := GetCloudBrainByIdOrJobId(id)
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -161,7 +161,7 @@ func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {
func AdminOrJobCreaterRight(ctx *context.Context) {
var id = ctx.Params(":id")
- job, err := models.GetCloudbrainByID(id)
+ job, err := GetCloudBrainByIdOrJobId(id)
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -177,7 +177,7 @@ func AdminOrJobCreaterRight(ctx *context.Context) {
func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- job, err := models.GetCloudbrainByJobID(jobID)
+ job, err := GetCloudBrainByIdOrJobId(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -193,7 +193,7 @@ func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {
func AdminOrJobCreaterRightForTrain(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
- job, err := models.GetCloudbrainByJobID(jobID)
+ job, err := GetCloudBrainByIdOrJobId(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -652,3 +652,16 @@ func IsElementExist(s []string, str string) bool {
}
return false
}
+
+func GetCloudBrainByIdOrJobId(id string) (*models.Cloudbrain,error) {
+ _, err := strconv.ParseInt(id, 10, 64)
+ var job *models.Cloudbrain
+ if err != nil {
+
+ job, err = models.GetCloudbrainByJobID(id)
+ } else {
+ job, err = models.GetCloudbrainByID(id)
+
+ }
+ return job,err
+}
diff --git a/modules/modelarts/modelarts.go b/modules/modelarts/modelarts.go
index dd502dfd0..b59be307b 100755
--- a/modules/modelarts/modelarts.go
+++ b/modules/modelarts/modelarts.go
@@ -1,13 +1,18 @@
package modelarts
import (
+ "encoding/base64"
"encoding/json"
"errors"
"fmt"
+ "io/ioutil"
+ "net/http"
"path"
"strconv"
"strings"
+ "code.gitea.io/gitea/modules/cloudbrain"
+
"code.gitea.io/gitea/modules/modelarts_cd"
"code.gitea.io/gitea/models"
@@ -23,7 +28,7 @@ const (
//notebook
storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
- autoStopDurationMs = 4 * 60 * 60 * 1000
+ AutoStopDurationMs = 4 * 60 * 60 * 1000
MORDELART_USER_IMAGE_ENGINE_ID = -1
DataSetMountPath = "/home/ma-user/work"
NotebookEnv = "Python3"
@@ -276,7 +281,7 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin
return nil
}
-func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error {
+func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string,autoStopDurationInMs int64) (string, error) {
if poolInfos == nil {
json.Unmarshal([]byte(setting.PoolInfos), &poolInfos)
}
@@ -284,14 +289,14 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
imageName, err := GetNotebookImageName(imageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
- return err
+ return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook2(models.CreateNotebook2Params{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
- Duration: autoStopDurationMs,
+ Duration: autoStopDurationInMs,
ImageID: imageId,
PoolID: poolInfos.PoolInfo[0].PoolId,
Feature: models.NotebookFeature,
@@ -316,10 +321,10 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
})
if errTemp != nil {
log.Error("InsertCloudbrainTemp failed: %v", errTemp.Error())
- return errTemp
+ return "", errTemp
}
}
- return err
+ return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
@@ -334,6 +339,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
Uuid: uuid,
ComputeResource: models.NPUResource,
Image: imageName,
+ BootFile: bootFile,
Description: description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
@@ -342,12 +348,12 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
err = models.CreateCloudbrain(task)
if err != nil {
- return err
+ return "", err
}
stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
- return nil
+ return jobResult.ID, nil
}
func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId string, err error) {
@@ -907,6 +913,11 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
if task.FlavorCode == "" {
task.FlavorCode = result.Flavor
}
+
+ if oldStatus != task.Status && task.Status == string(models.ModelArtsRunning) && task.BootFile != "" {
+ uploadNoteBookFile(task, result)
+
+ }
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
@@ -917,6 +928,81 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
return nil
}
+func uploadNoteBookFile(task *models.Cloudbrain, result *models.GetNotebook2Result) {
+ jupyterUrl := result.Url + "?token=" + result.Token
+
+ cookies, xsrf := getCookiesAndCsrf(jupyterUrl)
+ if xsrf == "" {
+ log.Error("browser jupyterUrl failed:%v", task.DisplayJobName)
+ } else {
+
+ codePath := setting.JobPath + task.JobName + cloudbrain.CodeMountPath
+ fileContents, err := ioutil.ReadFile(codePath + "/" + task.BootFile)
+ if err != nil {
+ log.Error("read jupyter file failed:%v", task.DisplayJobName, err)
+ }
+
+ base64Content := base64.StdEncoding.EncodeToString(fileContents)
+ client := getRestyClient()
+ uploadUrl := getJupyterBaseUrl(result.Url) + "api/contents/" + path.Base(task.BootFile)
+ res, err := client.R().
+ SetCookies(cookies).
+ SetHeader("X-XSRFToken", xsrf).
+ SetBody(map[string]interface{}{
+ "type": "file",
+ "format": "base64",
+ "name": path.Base(task.BootFile),
+ "path": path.Base(task.BootFile),
+ "content": base64Content}).
+ Put(uploadUrl)
+ if err != nil {
+ log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
+ } else if res.StatusCode() != http.StatusCreated {
+ log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
+ }
+
+ }
+
+}
+
+func getJupyterBaseUrl(url string) string {
+ jupyterUrlLength := len(url)
+ baseUrl := url[0 : jupyterUrlLength-len(path.Base(url))]
+ return baseUrl
+}
+
+func getCookiesAndCsrf(jupyterUrl string) ([]*http.Cookie, string) {
+ log.Info("jupyter url:"+jupyterUrl)
+ var cookies []*http.Cookie
+ const retryTimes = 10
+ for i := 0; i < retryTimes; i++ {
+ res, err := http.Get(jupyterUrl)
+ if err != nil {
+ log.Error("browser jupyterUrl failed.",err)
+ if i==retryTimes-1{
+ return cookies, ""
+ }
+
+ } else {
+ cookies = res.Cookies()
+ xsrf := ""
+ for _, cookie := range cookies {
+ if cookie.Name == "_xsrf" {
+ xsrf = cookie.Value
+ break
+ }
+
+ }
+ if xsrf != "" {
+ return cookies, xsrf
+ }
+
+ }
+ }
+ return cookies, ""
+
+}
+
func SyncTempStatusJob() {
jobs, err := models.GetCloudBrainTempJobs()
if err != nil {
diff --git a/modules/modelarts/resty.go b/modules/modelarts/resty.go
index c38300606..3ccba9011 100755
--- a/modules/modelarts/resty.go
+++ b/modules/modelarts/resty.go
@@ -280,7 +280,7 @@ sendjob:
SetHeader("Content-Type", "application/json").
SetAuthToken(TOKEN).
SetResult(&result).
- Post(HOST + "/v1/" + setting.ProjectID + urlNotebook2 + "/" + jobID + "/" + param.Action + "?duration=" + strconv.Itoa(autoStopDurationMs))
+ Post(HOST + "/v1/" + setting.ProjectID + urlNotebook2 + "/" + jobID + "/" + param.Action + "?duration=" + strconv.Itoa(AutoStopDurationMs))
if err != nil {
return &result, fmt.Errorf("resty ManageNotebook2: %v", err)
diff --git a/modules/modelarts_cd/modelarts.go b/modules/modelarts_cd/modelarts.go
index 330b048ca..93032fa89 100755
--- a/modules/modelarts_cd/modelarts.go
+++ b/modules/modelarts_cd/modelarts.go
@@ -88,18 +88,18 @@ type Parameters struct {
} `json:"parameter"`
}
-func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error {
+func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string,autoStopDurationInMs int64) (string, error) {
imageName, err := GetNotebookImageName(imageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
- return err
+ return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook(models.CreateNotebookWithoutPoolParams{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
- Duration: autoStopDurationMs,
+ Duration: autoStopDurationInMs,
ImageID: imageId,
Feature: models.NotebookFeature,
Volume: models.VolumeReq{
@@ -123,10 +123,10 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
})
if errTemp != nil {
log.Error("InsertCloudbrainTemp failed: %v", errTemp.Error())
- return errTemp
+ return "", errTemp
}
}
- return err
+ return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
@@ -145,16 +145,17 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
+ BootFile: bootFile,
}
err = models.CreateCloudbrain(task)
if err != nil {
- return err
+ return "", err
}
stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
- return nil
+ return jobResult.ID, nil
}
func GetNotebookImageName(imageId string) (string, error) {
@@ -175,41 +176,3 @@ func GetNotebookImageName(imageId string) (string, error) {
return imageName, nil
}
-
-/*
-func HandleNotebookInfo(task *models.Cloudbrain) error {
-
- result, err := GetNotebook(task.JobID)
- if err != nil {
- log.Error("GetNotebook2(%s) failed:%v", task.DisplayJobName, err)
- return err
- }
-
- if result != nil {
- oldStatus := task.Status
- task.Status = result.Status
- if task.StartTime == 0 && result.Lease.UpdateTime > 0 {
- task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000)
- }
- if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) {
- task.EndTime = timeutil.TimeStampNow()
- }
- task.CorrectCreateUnix()
- task.ComputeAndSetDuration()
- if oldStatus != task.Status {
- notification.NotifyChangeCloudbrainStatus(task, oldStatus)
- }
- if task.FlavorCode == "" {
- task.FlavorCode = result.Flavor
- }
- err = models.UpdateJob(task)
- if err != nil {
- log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
- return err
- }
- }
-
- return nil
-}
-
-*/
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 8da1bab91..ee3dfd90c 100755
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -717,6 +717,21 @@ var (
TeamName string
}{}
+ FileNoteBook = struct {
+ ProjectName string
+ ImageGPU string
+ SpecIdGPU int64
+ SpecIdCPU int64
+ ImageIdNPU string
+ SpecIdNPU int64
+ ImageIdNPUCD string
+ SpecIdNPUCD int64
+ ImageCPUDescription string
+ ImageGPUDescription string
+ ImageNPUDescription string
+ ImageNPUCDDescription string
+ }{}
+
ModelConvert = struct {
GPU_PYTORCH_IMAGE string
GpuQueue string
@@ -1582,6 +1597,20 @@ func NewContext() {
Course.OrgName = sec.Key("org_name").MustString("")
Course.TeamName = sec.Key("team_name").MustString("")
+ sec = Cfg.Section("file_notebook")
+ FileNoteBook.ProjectName = sec.Key("project_name").MustString("openi-notebook")
+ FileNoteBook.ImageIdNPU = sec.Key("imageid_npu").MustString("")
+ FileNoteBook.ImageGPU = sec.Key("image_gpu").MustString("")
+ FileNoteBook.SpecIdCPU = sec.Key("specid_cpu").MustInt64(-1)
+ FileNoteBook.SpecIdGPU = sec.Key("specid_gpu").MustInt64(-1)
+ FileNoteBook.SpecIdNPU = sec.Key("specid_npu").MustInt64(-1)
+ FileNoteBook.ImageIdNPUCD = sec.Key("imageid_npu_cd").MustString("")
+ FileNoteBook.SpecIdNPUCD = sec.Key("specid_npu_cd").MustInt64(-1)
+ FileNoteBook.ImageCPUDescription = sec.Key("image_cpu_desc").MustString("")
+ FileNoteBook.ImageGPUDescription = sec.Key("image_gpu_desc").MustString("")
+ FileNoteBook.ImageNPUDescription = sec.Key("image_npu_desc").MustString("")
+ FileNoteBook.ImageNPUCDDescription = sec.Key("image_npu_cd_desc").MustString("")
+
sec = Cfg.Section("kanban")
IsCloudbrainTimingEnabled = sec.Key("ENABLED").MustBool(false)
diff --git a/modules/structs/cloudbrain.go b/modules/structs/cloudbrain.go
index 866c85dad..9ea5601c9 100644
--- a/modules/structs/cloudbrain.go
+++ b/modules/structs/cloudbrain.go
@@ -41,6 +41,14 @@ type CreateTrainJobOption struct {
SpecId int64 `json:"spec_id" binding:"Required"`
}
+type CreateFileNotebookJobOption struct {
+ Type int `json:"type"` //0 CPU 1 GPU 2 NPU
+ File string `json:"file" binding:"Required"`
+ BranchName string `json:"branch_name" binding:"Required"`
+ OwnerName string `json:"owner_name" binding:"Required"`
+ ProjectName string `json:"project_name" binding:"Required"`
+}
+
type Cloudbrain struct {
ID int64 `json:"id"`
JobID string `json:"job_id"`
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 3e424454b..c314127f1 100755
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -151,6 +151,9 @@ func NewFuncMap() []template.FuncMap {
"EscapePound": func(str string) string {
return strings.NewReplacer("%", "%25", "#", "%23", " ", "%20", "?", "%3F").Replace(str)
},
+ "IpynbBool":func(str string) bool{
+ return strings.Contains(str, ".ipynb")
+ },
"nl2br": func(text string) template.HTML {
return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", " ", -1))
},
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 1e03d5cd3..92f490c51 100755
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -24,6 +24,7 @@ enable_javascript = This website works better with JavaScript.
toc = Table of Contents
return=Back OpenI
calculation_points = Calculation Points
+notice_announcement = Notice Announcement
username = Username
email = Email Address
@@ -236,7 +237,7 @@ page_title=Explore Better AI
page_small_title=OpenI AI Development Cooperation Platform
page_description=The one-stop collaborative development environment for AI field provides AI development pipeline integrating code development, data management, model debugging, reasoning and evaluation
page_use=Use Now
-page_only_dynamic=Only show the dynamics of open source projects
+page_only_dynamic=The dynamics of open source projects
page_recommend_org=Recommended Organizations
page_recommend_org_desc=These excellent organizations are using the OpenI AI Collaboration Platform for collaborative development of projects. To show your organization here,
page_recommend_org_commit=Click here to submit.
@@ -260,7 +261,7 @@ page_dev_env_desc3_title=Once Configuration, Multiple Reuse
page_dev_env_desc3_desc=Provide execution environment sharing, Once Configuration, Multiple Reuse. Lower the threshold of model development, and avoid spending repetitive time configuring complex environments.
page_dev_yunlao=OpenI AI Collaboration Platform
page_dev_yunlao_desc1=OpenI AI collaboration platform has cooperated with Pengcheng cloud brain and China computing power network (C²NET) can be used to complete AI development tasks by using the rich computing resources of Pengcheng cloud brain and China computing network.
-page_dev_yunlao_desc2=Pengcheng CloudBrain's existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure consists of GPU servers equipped with NVIDIA Tesla V100 and A100, and Atlas 900 AI clusters equipped with Kunpeng and shengteng processors.
+page_dev_yunlao_desc2=Pengcheng CloudBrain is existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure consists of GPU servers equipped with NVIDIA Tesla V100 and A100, and Atlas 900 AI clusters equipped with Kunpeng and shengteng processors.
page_dev_yunlao_desc3=China computing power network (C²NET) phase I can realize high-speed network interconnection between different artificial intelligence computing centers, and realize reasonable scheduling of computing power and flexible allocation of resources. At present, 11 intelligent computing centers have been connected, and the total scale of computing power is 1924p OPS@FP16. OpenI AI collaboration platform has been connected to Pengcheng Cloud Computing Institute, Chengdu Intelligent Computing Center, Zhongyuan Intelligent Computing Center, Hefei brain and other nodes.
page_dev_yunlao_desc4=Developers can freely select the corresponding computing resources according to the use needs, and can test the adaptability, performance, stability, etc. of the model in different hardware environments.
page_dev_yunlao_desc5=If your model requires more computing resources, you can also apply for it separately.
@@ -283,6 +284,7 @@ search_ge=
wecome_AI_plt = Welcome to OpenI AI Collaboration Platform!
explore_AI = Explore better AI, come here to find more interesting
datasets = Datasets
+datasets_descr = Open source dataset base, seamlessly integrated with your project. View all
repositories = Repositories
use_plt__fuction = To use the AI collaboration functions provided by this platform, such as: hosting code, sharing data, debugging algorithms or training models, start with
provide_resoure = Computing resources of CPU/GPU/NPU are provided freely for various types of AI tasks.
@@ -290,6 +292,12 @@ activity = Activity
no_events = There are no events related
or_t = or
powerdby=Powered_by Pengcheng CloudBrain、China Computing NET(C²NET)、
+experience_officer=Experience Officer
+openi_experience_officer_plan=OpenI AI experience officer growth plan
+more_benefits=, More benefits
+org_see=See
+more_notice=More notices
+vedio_detail=Video details
[explore]
repos = Repositories
@@ -345,8 +353,10 @@ account_activated = Account has been activated
prohibit_login = Sign In Prohibited
prohibit_login_desc = Your account is prohibited to sign in, please contact your site administrator.
resent_limit_prompt = You have already requested an activation email recently. Please wait 3 minutes and try again.
-has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (%s ). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
-resend_mail = Click here to resend your activation email
+has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (%s ).
+has_unconfirmed_mail_resend = If you did not receive the activation email, or need to resend it, please click the "Resend Confirmation Email" button below.
+has_unconfirmed_mail_change=If you need to change the mailbox and then activate the mail, please click the "Modify Mailbox" button below.
+resend_mail = Resend your activation email
email_not_associate = The email address is not associated with any account.
email_not_main=The email address is wrong, please input your primary email address.
email_not_right=The email address is not associated with any account, please input the right email address.
@@ -1010,6 +1020,8 @@ readme = README
readme_helper = Select a README file template.
auto_init = Initialize Repository (Adds .gitignore, License and README)
create_repo = Create Repository
+failed_to_create_repo=Failed to create repository, please try again later.
+failed_to_create_notebook_repo=Failed to create %s repository, please check whether you have the same name project, if yes please update or delete it first.
create_course = Publish Course
failed_to_create_course=Failed to publish course, please try again later.
default_branch = Default Branch
@@ -1044,6 +1056,10 @@ model_experience = Model Experience
model_noright=You have no right to do the operation.
model_rename=Duplicate model name, please modify model name.
+notebook_file_not_exist=Notebook file does not exist.
+notebook_select_wrong=Please select a Notebook(.ipynb) file first.
+notebook_file_no_right=You have no right to access the Notebook(.ipynb) file.
+
date=Date
repo_add=Project Increment
repo_total=Project Total
@@ -1223,7 +1239,7 @@ cloudbrain.benchmark.evaluate_test=Test Script
cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"Target detection","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"Target re-identification","second":[{"id":1,"value":"Vehicle re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"Image-based person re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"Multi-target tracking","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.morethanonejob=You already have a running or waiting task, create it after that task is over.
cloudbrain.morethanonejob1=You have created an equivalent task that is waiting or running, please wait for the task to finish before creating it.
-cloudbrain.morethanonejob2=You can view all your Cloud Brain tasks in Home > Cloudbrain Task .
+cloudbrain.morethanonejob2=You can view all your Cloud Brain tasks in Home > Cloudbrain Task .
modelarts.infer_job_model = Model
modelarts.infer_job_model_file = Model File
@@ -1443,6 +1459,7 @@ blame = Blame
normal_view = Normal View
line = line
lines = lines
+notebook_open = Open in Notebook
editor.new_file = New File
editor.upload_file = Upload File
@@ -3196,6 +3213,9 @@ foot.copyright= Copyright: New Generation Artificial Intelligence Open Source Op
Platform_Tutorial = Tutorial
foot.advice_feedback = Feedback
resource_description = Resource Note
+foot.openi_subscription_number = OpenI subscription number
+foot.user_communication_group = User communication group
+
[cloudbrain]
all_resource_cluster=All Cluster
all_ai_center=All Computing NET
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index b01fbad01..63c7f93b3 100755
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -24,6 +24,7 @@ enable_javascript=使用 JavaScript能使本网站更好的工作。
toc=目录
return=返回OpenI
calculation_points=算力积分
+notice_announcement=通知公告
username=用户名
email=电子邮件地址
@@ -238,7 +239,7 @@ page_title=探索更好的AI
page_small_title=启智AI协作平台
page_description=面向AI领域的一站式协同开发环境,提供集代码开发、数据管理、模型调试、推理和评测为一体的AI开发流水线
page_use=立即使用
-page_only_dynamic=仅展示开源项目动态
+page_only_dynamic=社区开源项目动态
page_recommend_org=推荐组织
page_recommend_org_desc=这些优秀的组织正在使用启智AI开发协作平台;你的组织也想展示到这里,
page_recommend_org_commit=点此提交
@@ -285,6 +286,7 @@ search_ge=个
wecome_AI_plt=欢迎来到启智AI协作平台!
explore_AI = 探索更好的AI,来这里发现更有意思的
datasets = 数据集
+datasets_descr=开源数据集大本营,同你的项目无缝集成。查看所有
repositories = 项目
use_plt__fuction = 使用本平台提供的AI协作功能,如:托管代码、共享数据、调试算法或训练模型,请先
provide_resoure = 平台目前提供CPU、GPU、NPU的普惠算力资源,可进行多种类型的AI任务。
@@ -293,7 +295,12 @@ activity = 活动
no_events = 还没有与您相关的活动
or_t = 或
powerdby=Powered_by 鹏城实验室云脑、中国算力网(C²NET)、
-
+experience_officer=体验官
+openi_experience_officer_plan=启智社区体验官成长计划
+more_benefits=,超多福利大放送
+org_see=。查看
+more_notice=更多通知
+vedio_detail=详细介绍视频
[explore]
repos=项目
@@ -349,8 +356,10 @@ account_activated=帐户已激活
prohibit_login=禁止登录
prohibit_login_desc=您的帐户被禁止登录,请与网站管理员联系。
resent_limit_prompt=您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
-has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 %s 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
-resend_mail=单击此处重新发送确认邮件
+has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 %s 但未被确认的邮件。
+has_unconfirmed_mail_resend=如果您未收到激活邮件,或需要重新发送,请单击下方的 "重新发送确认邮件 " 按钮。
+has_unconfirmed_mail_change=如果需要更改邮箱后再激活邮件,请单击下方的 "修改邮箱" 按钮
+resend_mail=重新发送确认邮件
email_not_associate=您输入的邮箱地址未被关联到任何帐号!
email_not_main=电子邮箱地址不正确,请输入您设置的主要邮箱地址。
email_not_right=您输入了不存在的邮箱地址,请输入正确的邮箱地址。
@@ -1016,6 +1025,8 @@ readme=自述
readme_helper=选择自述文件模板。
auto_init=初始化存储库 (添加. gitignore、许可证和自述文件)
create_repo=创建项目
+failed_to_create_repo=创建项目失败,请稍后再试。
+failed_to_create_notebook_repo=创建项目%s失败,请检查您是否有同名的项目,如果有请先手工修改或删除后重试。
create_course=发布课程
failed_to_create_course=发布课程失败,请稍后再试。
default_branch=默认分支
@@ -1044,6 +1055,9 @@ model_experience = 模型体验
model_noright=您没有操作权限。
model_rename=模型名称重复,请修改模型名称
+notebook_file_not_exist=Notebook文件不存在。
+notebook_select_wrong=请先选择Notebook(.ipynb)文件。
+notebook_file_no_right=您没有这个Notebook文件的读权限。
date=日期
repo_add=新增项目
@@ -1462,6 +1476,8 @@ normal_view=普通视图
line=行
lines=行
+notebook_open = 在Notebook中打开
+
editor.new_file=新建文件
editor.upload_file=上传文件
editor.edit_file=编辑文件
@@ -3214,6 +3230,8 @@ foot.copyright= 版权所有:新一代人工智能开源开放平台(OpenI
Platform_Tutorial=新手指引
foot.advice_feedback = 意见反馈
resource_description = 资源说明
+foot.openi_subscription_number = 启智社区订阅号
+foot.user_communication_group = 用户交流群
[cloudbrain]
all_resource_cluster=全部集群
diff --git a/public/home/home.js b/public/home/home.js
index 853c3ef23..43eab17e0 100755
--- a/public/home/home.js
+++ b/public/home/home.js
@@ -9,16 +9,20 @@ if(isEmpty(token)){
var swiperNewMessage = new Swiper(".newslist", {
direction: "vertical",
- slidesPerView: 9,
+ slidesPerView: 6,
loop: true,
+ spaceBetween: 8,
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
});
-var swiperEvent = new Swiper(".event-list", {
- slidesPerView: 3,
- spaceBetween: 30,
+
+var swiperRepo = new Swiper(".homepro-list", {
+ slidesPerView: 1,
+ // slidesPerColumn: 2,
+ // slidesPerColumnFill:'row',
+ spaceBetween: 20,
pagination: {
el: ".swiper-pagination",
clickable: true,
@@ -27,49 +31,130 @@ var swiperEvent = new Swiper(".event-list", {
delay: 2500,
disableOnInteraction: false,
},
+ breakpoints: {
+ 768: {
+ slidesPerView: 2,
+ },
+ 1024: {
+ slidesPerView: 2,
+ },
+ 1200: {
+ slidesPerView: 3,
+ },
+ 1440: {
+ slidesPerView: 3,
+ },
+ 1840: {
+ slidesPerView: 3,
+ },
+ 1920: {
+ slidesPerView: 3,
+ },
+ },
});
-var swiperRepo = new Swiper(".homepro-list", {
+
+var swiperOrg = new Swiper(".homeorg-list", {
slidesPerView: 1,
slidesPerColumn: 2,
slidesPerColumnFill:'row',
- spaceBetween: 30,
+ spaceBetween: 25,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
- delay: 2500,
+ delay: 4500,
disableOnInteraction: false,
},
breakpoints: {
768: {
- slidesPerView: 2,
+ slidesPerView: 3,
+ slidesPerColumn: 2,
},
1024: {
slidesPerView: 3,
+ slidesPerColumn: 2,
+ },
+ 1200: {
+ slidesPerView: 4,
+ slidesPerColumn: 2,
+ },
+ 1440: {
+ slidesPerView: 4,
+ slidesPerColumn: 2,
+ },
+ 1840: {
+ slidesPerView: 4,
+ slidesPerColumn: 2,
+ },
+ 1920: {
+ slidesPerView: 4,
+ slidesPerColumn: 2,
},
},
});
-var swiperOrg = new Swiper(".homeorg-list", {
+var swiperUserExp = new Swiper(".home-user-exp-list", {
slidesPerView: 1,
- slidesPerColumn: 4,
+ spaceBetween: 0,
+ navigation: {
+ nextEl: '.homeuserexp .swiper-prev',
+ prevEl: '.homeuserexp .swiper-next',
+ },
+ autoplay: {
+ delay: 2500,
+ disableOnInteraction: false,
+ },
+ breakpoints: {
+ 768: {
+ slidesPerView: 2,
+ },
+ 1200: {
+ slidesPerView: 3,
+ },
+ 1440: {
+ slidesPerView: 4,
+ },
+ 1840: {
+ slidesPerView: 4,
+ },
+ 1920: {
+ slidesPerView: 5,
+ },
+ },
+});
+
+var swiperDataset = new Swiper(".home-dataset-list", {
+ slidesPerView: 2,
+ slidesPerColumn: 1,
slidesPerColumnFill:'row',
- spaceBetween: 15,
+ spaceBetween: 30,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
- delay: 4500,
+ delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
+ 676: {
+ slidesPerView: 3,
+ },
768: {
- slidesPerView: 2,
+ slidesPerView: 4,
},
- 1024: {
- slidesPerView: 3,
+ 1320: {
+ slidesPerView: 5,
+ },
+ 1520: {
+ slidesPerView: 6,
+ },
+ 1720: {
+ slidesPerView: 7,
+ },
+ 1920: {
+ slidesPerView: 7,
},
},
});
@@ -85,7 +170,7 @@ document.onreadystatechange = function () {
if(document.readyState != "complete"){
return;
}
- console.log("Start to open WebSocket." + document.readyState);
+ console.log("Start to open WebSocket." + document.readyState);
queryRecommendData();
var output = document.getElementById("newmessage");
@@ -101,6 +186,7 @@ document.onreadystatechange = function () {
};
socket.onmessage = function (e) {
+ if (!output) return;
var data =JSON.parse(e.data)
var html = "";
if (data != null){
@@ -177,18 +263,17 @@ document.onreadystatechange = function () {
var time = getTime(record.CreatedUnix,currentTime);
html += " " + time;
}
- html += "";
+ html += "";
html += "";
}
}
output.innerHTML = html;
+ $('#homenews p').show();
swiperNewMessage.updateSlides();
swiperNewMessage.updateProgress();
};
}
-
-
function getTaskLink(record){
var re = getRepoLink(record);
if(record.OpType == 24){
@@ -223,7 +308,7 @@ function getMsg(record){
}else{
console.log("act user is null.");
}
- html += " "
+ html += "
"
html += "
"
html += "
" + name + " "
return html;
@@ -236,6 +321,7 @@ function getRepotext(record){
return record.Repo.OwnerName + "/" + record.Repo.Name;
}
}
+
function getRepoLink(record){
return encodeURI(record.Repo.OwnerName + "/" + record.Repo.Name);
@@ -437,10 +523,6 @@ function getAction(opType,isZh){
}
}
-
-
-
-
function queryRecommendData(){
$.ajax({
type:"GET",
@@ -453,7 +535,10 @@ function queryRecommendData(){
success:function(json){
displayOrg(json.org);
displayRepo(json.repo);
- displayActivity(json.image);
+ displayActivity(json.activity);
+ displayDataset(json.dataset);
+ displayUserExp(json.user_experience);
+ LetterAvatar && LetterAvatar.transform();
},
error:function(response) {
}
@@ -463,49 +548,99 @@ function queryRecommendData(){
function displayActivity(json){
var activityDiv = document.getElementById("recommendactivity");
+ if (!activityDiv) return;
var html = "";
if (json != null && json.length > 0){
for(var i = 0; i < json.length;i++){
- var record = json[i]
- html += "
";
- html += "
";
- html += " "
+ var record = json[i];
+ var name = isZh ? (record["name"] || '') : (record["name_en"] || record["name"]);
+ html += "";
}
+ var swiperEvent = new Swiper(".event-list", {
+ slidesPerView: 1,
+ spaceBetween: 30,
+ // pagination: {
+ // el: ".swiper-pagination",
+ // clickable: true,
+ // },
+ autoplay: {
+ delay: 2500,
+ disableOnInteraction: false,
+ },
+ breakpoints: {
+ 768: {
+ slidesPerView: Math.min(2, json.length),
+ },
+ 1024: {
+ slidesPerView: Math.min(3, json.length),
+ },
+ 1200: {
+ slidesPerView: Math.min(3, json.length),
+ },
+ 1440: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ 1840: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ 1920: {
+ slidesPerView: Math.min(4, json.length),
+ },
+ },
+ });
+ activityDiv.innerHTML = html;
+ swiperEvent.updateSlides();
+ swiperEvent.updateProgress();
}
- activityDiv.innerHTML = html;
- swiperEvent.updateSlides();
- swiperEvent.updateProgress();
}
function displayRepo(json){
var orgRepo = document.getElementById("recommendrepo");
var html = "";
if (json != null && json.length > 0){
- for(var i = 0; i < json.length;i++){
- var record = json[i]
- html += "";
- html += "
";
- html += "
";
- html += "
";
- html += " " + record["NumStars"] + " " + record["NumForks"];
- html += " ";
- html += "
";
- html += " ";
- html += "
" + record["Description"] + "
";
- html += "
"
- if(record["Topics"] != null){
- for(var j = 0; j < record["Topics"].length; j++){
- topic = record["Topics"][j];
- url = "/explore/repos?q=" + (topic) + "&topic="
- html += "
" + topic + " ";
- }
+ var repoMap = {};
+ for (var i = 0, iLen = json.length; i < iLen; i++) {
+ var repo = json[i];
+ var labelSearch = repo.Label;
+ var label = isZh ? repo.Label : repo.Label_en;
+ if (repoMap[label]) {
+ repoMap[label].push(repo);
+ } else {
+ repoMap[label] = [repo];
}
- html += "
";
- html += "
";
- html += "
";
- html += "
";
+ }
+
+ for (var label in repoMap) {
+ var repos = repoMap[label];
+ html += ``;
+ for (var i = 0, iLen = repos.length; i < iLen; i++) {
+ if (i >= 4) break;
+ var repo = repos[i];
+ //
${repo["NumStars"]}
${repo["NumForks"]}
+ html += `
+
+ ${repo["Avatar"] ? `
` : `
`}
+
+
${repo["Description"]}
+ `;
+ // if (repo["Topics"] != null) {
+ // for(var j = 0; j < repo["Topics"].length; j++){
+ // var topic = repo["Topics"][j];
+ // var url = "/explore/repos?q=" + (topic) + "&topic="
+ // html += `
${topic} `;
+ // }
+ // }
+ html += `
+
+
`;
+ }
+ html += '
'
}
}
orgRepo.innerHTML = html;
@@ -513,7 +648,6 @@ function displayRepo(json){
swiperRepo.updateProgress();
}
-
function getRepoOrOrg(key,isZhLang,numbers=1){
if(numbers > 1){
key+="1";
@@ -537,7 +671,7 @@ function displayOrg(json){
html += " ";
html += " ";
html += "
" + record["Name"] + " " + record["FullName"];
- html += "
" + record["NumRepos"] +" " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ " + record["NumMembers"] +" " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ " + record["NumTeams"] + " " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "
";
+ html += "
" + record["NumRepos"] +" " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ " + record["NumMembers"] +" " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ " + record["NumTeams"] + " " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "
";
html += "
";
html += " ";
html += "
";
@@ -548,3 +682,173 @@ function displayOrg(json){
orgDiv.innerHTML = html;
swiperOrg.updateSlides();
}
+
+function displayDataset(data) {
+ var homeDatasetEl = document.getElementById("home_dataset");
+ if (!homeDatasetEl) return;
+ var html = '';
+ var svgStrMap = {
+ '0': '
',
+ '1': '
',
+ '2': '
',
+ '3': '
',
+ '4': '
',
+ '5': '
',
+ '6': '
',
+ }
+ for (var i = 0, iLen = data.length; i < iLen; i++) {
+ var dataI = data[i];
+ html += `
`
+ }
+ homeDatasetEl.innerHTML = html;
+ swiperDataset.updateSlides();
+ swiperDataset.updateProgress();
+}
+
+function displayUserExp(data) {
+ var homeUserExpEl = document.getElementById("home_user-exp");
+ if (!homeUserExpEl) return;
+ var html = '';
+ for (var i = 0, iLen = data.length; i < iLen; i++) {
+ var dataI = data[i];
+ html += `
+
+
+
${dataI.fullname || dataI.name}
+
+
+
`
+ }
+ homeUserExpEl.innerHTML = html;
+ swiperUserExp.updateSlides();
+ swiperUserExp.updateProgress();
+}
+
+function getNotice() {
+ $.ajax({
+ type:"GET",
+ url:"/dashboard/invitation",
+ headers: { authorization:token, },
+ dataType:"json",
+ data: {
+ filename: 'notice/notice.json',
+ },
+ success:function(json){
+ if (json) {
+ try {
+ var noticeList = JSON.parse(json).Notices || [];
+ var noticeEls = $('._hm-recommend-info-area-1 a._hm-notice');
+ for (var i = 0, iLen = noticeEls.length; i < iLen; i++) {
+ var noticeEl = noticeEls.eq(i);
+ var noticeObj = noticeList[i];
+ if (noticeObj) {
+ var title = isZh ? noticeObj.Title : (noticeObj.Title_en || noticeObj.Title);
+ noticeEl.attr('href', noticeObj.Link);
+ noticeEl.find('span').text(title).attr('title', title);
+ noticeEl.show();
+ } else {
+ noticeEl.hide();
+ }
+ }
+ } catch (e) {
+ console.info(e);
+ }
+ }
+ },
+ error:function(response) {
+ }
+ });
+}
+
+function getRecommendModule() {
+ $.ajax({
+ type:"GET",
+ url:"/dashboard/invitation",
+ headers: { authorization:token, },
+ dataType:"json",
+ data: {
+ filename: 'home/newfunction',
+ },
+ success:function(json){
+ if (json) {
+ try {
+ var recommendModuleList = JSON.parse(json) || [];
+ var recommendModuleEls = $('._hm-recommend-info-area a._hm-link');
+ for (var i = 0, iLen = recommendModuleEls.length; i < iLen; i++) {
+ var recommendModuleEl = recommendModuleEls.eq(i);
+ var recommendModuleObj = recommendModuleList[i];
+ if (recommendModuleObj) {
+ recommendModuleEl.attr('href', recommendModuleObj.image_link);
+ recommendModuleEl.text(isZh ? recommendModuleObj.name : (recommendModuleObj.name_en || recommendModuleObj.name));
+ } else {
+ }
+ }
+ } catch (e) {
+ console.info(e);
+ }
+ }
+ },
+ error:function(response) {
+ }
+ });
+}
+
+function initHomeTopBanner() {
+ var homeSlideTimer = null;
+ var homeSlideDuration = 8000;
+ function homeSlide(direction) {
+ var slidePages = $('._hm-pg-c ._hm-pg');
+ var currentPage = slidePages.filter('._hm-pg-show');
+ var currentIndex = currentPage.index();
+ var next = direction == 'left' ? currentIndex - 1 : currentIndex + 1;
+ if (next < 0) next = slidePages.length - 1;
+ if (next == slidePages.length) next = 0;
+ slidePages.removeClass('_hm-pg-show');
+ slidePages.eq(next).addClass('_hm-pg-show');
+ }
+
+ function startSlide() {
+ homeSlideTimer && clearTimeout(homeSlideTimer);
+ homeSlideTimer = setTimeout(function() {
+ homeSlide('right');
+ startSlide();
+ }, homeSlideDuration);
+ }
+
+ function stopSlide() {
+ homeSlideTimer && clearTimeout(homeSlideTimer);
+ }
+
+ $('._hm-slide-btn').on('click', function () {
+ if ($(this).hasClass('_hm-slide-btn-left')) {
+ homeSlide('left');
+ } else {
+ homeSlide('right');
+ }
+ startSlide();
+ });
+ $('._hm-pg #homenews').on('mouseenter', function() {
+ stopSlide();
+ }).on('mouseleave', function() {
+ startSlide();
+ });
+ setTimeout(function() { startSlide(); }, 500);
+}
+
+initHomeTopBanner();
+getNotice();
+getRecommendModule();
diff --git a/public/img/search.svg b/public/img/search.svg
index ec91b07dd..a4d965f9a 100644
--- a/public/img/search.svg
+++ b/public/img/search.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 2afbb9b7d..14badfdb4 100755
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -737,6 +737,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/my_favorite", repo.MyFavoriteDatasetMultiple)
}, reqToken(), repoAssignment())
+ m.Group("/file_notebook", func() {
+ m.Get("", reqToken(), repo.GetFileNoteBookInfo)
+ m.Post("/create", reqToken(), reqWeChat(), bind(api.CreateFileNotebookJobOption{}), repo.CreateFileNoteBook)
+
+ })
+
m.Group("/repos", func() {
m.Get("/search", repo.Search)
diff --git a/routers/api/v1/repo/cloudbrain.go b/routers/api/v1/repo/cloudbrain.go
index 68baf3287..f1b2751f8 100755
--- a/routers/api/v1/repo/cloudbrain.go
+++ b/routers/api/v1/repo/cloudbrain.go
@@ -79,6 +79,75 @@ func CloudBrainShow(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)})
}
+func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) {
+ cloudbrainTask.FileNotebookCreate(ctx.Context, option)
+}
+
+func GetFileNoteBookInfo(ctx *context.APIContext) {
+ //image description spec description waiting count
+
+ specs, err := models.GetResourceSpecificationByIds([]int64{setting.FileNoteBook.SpecIdCPU, setting.FileNoteBook.SpecIdGPU, setting.FileNoteBook.SpecIdNPU, setting.FileNoteBook.SpecIdNPUCD})
+ if err != nil {
+ log.Error("Fail to query specifications", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
+ return
+ }
+
+ var specCPU, specGpu, specNPU, specNPUCD *api.SpecificationShow
+ var specGpuQueueCode string
+ for _, spec := range specs {
+ if spec.ID == setting.FileNoteBook.SpecIdCPU {
+ specCPU = convert.ToSpecification(spec)
+ } else if spec.ID == setting.FileNoteBook.SpecIdGPU {
+ specGpu = convert.ToSpecification(spec)
+ specGpuQueueCode = spec.QueueCode
+ } else if spec.ID == setting.FileNoteBook.SpecIdNPU {
+ specNPU = convert.ToSpecification(spec)
+ } else if spec.ID == setting.FileNoteBook.SpecIdNPUCD {
+ specNPUCD = convert.ToSpecification(spec)
+ }
+ }
+
+ waitCountNpu := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+
+ queuesMap, err := cloudbrain.GetQueuesDetail()
+ if err != nil {
+ log.Error("Fail to query gpu queues waiting count", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
+ return
+ }
+ waitCountGPU := (*queuesMap)[specGpuQueueCode]
+ if !setting.ModelartsCD.Enabled{
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "code": 0,
+ "projectName":setting.FileNoteBook.ProjectName,
+ "specCpu": specCPU,
+ "specGpu": specGpu,
+ "specNpu": specNPU,
+ "waitCountGpu": waitCountGPU,
+ "waitCountNpu": waitCountNpu,
+ "imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
+ "imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
+ "imageNpuDescription": setting.FileNoteBook.ImageNPUDescription,
+
+ })
+ } else{
+ ctx.JSON(http.StatusOK, map[string]interface{}{
+ "code": 0,
+ "projectName":setting.FileNoteBook.ProjectName,
+ "specCpu": specCPU,
+ "specGpu": specGpu,
+ "specNpu": specNPUCD,
+ "waitCountGpu": waitCountGPU,
+ "waitCountNpu": waitCountNpu,
+ "imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
+ "imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
+ "imageNpuDescription": setting.FileNoteBook.ImageNPUCDDescription,
+ })
+
+ }
+
+}
func CreateCloudBrain(ctx *context.APIContext, option api.CreateTrainJobOption) {
if option.Type == cloudbrainTask.TaskTypeCloudbrainOne {
@@ -141,10 +210,11 @@ func GetCloudbrainTask(ctx *context.APIContext) {
)
ID := ctx.Params(":id")
- job, err := models.GetCloudbrainByID(ID)
+
+ job,err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
+
if err != nil {
ctx.NotFound(err)
- log.Error("GetCloudbrainByID failed:", err)
return
}
if job.JobType == string(models.JobTypeModelSafety) {
@@ -566,7 +636,6 @@ func CloudbrainDownloadLogFile(ctx *context.Context) {
url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName)
if err != nil {
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
- ctx.ServerError("Get minio get SignedUrl failed", err)
return
}
log.Info("fileName=" + fileName)
@@ -650,7 +719,7 @@ func CloudbrainGetLog(ctx *context.APIContext) {
result = getLogFromModelDir(job.JobName, startLine, endLine, resultPath)
if result == nil {
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"])
- ctx.ServerError(err.Error(), err)
+ //ctx.ServerError(err.Error(), err)
return
}
}
@@ -865,7 +934,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
- ctx.ServerError("json.Unmarshal failed:", err)
+ //ctx.ServerError("json.Unmarshal failed:", err)
return
}
@@ -896,7 +965,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
models, err := storage.GetObsListObject(job.ID, "output/", parentDir, versionName)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
- ctx.ServerError("GetObsListObject:", err)
+ //ctx.ServerError("GetObsListObject:", err)
return
}
@@ -941,7 +1010,7 @@ func CloudBrainModelList(ctx *context.APIContext) {
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
- ctx.ServerError("json.Unmarshal failed:", err)
+ //ctx.ServerError("json.Unmarshal failed:", err)
return
}
diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go
index e0db9eda3..127ddd835 100755
--- a/routers/api/v1/repo/modelarts.go
+++ b/routers/api/v1/repo/modelarts.go
@@ -6,6 +6,7 @@
package repo
import (
+ "code.gitea.io/gitea/modules/cloudbrain"
"encoding/json"
"net/http"
"path"
@@ -37,11 +38,14 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {
)
ID := ctx.Params(":id")
- job, err := models.GetCloudbrainByID(ID)
+
+ job,err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
+
if err != nil {
ctx.NotFound(err)
return
}
+
err = modelarts.HandleNotebookInfo(job)
if err != nil {
ctx.NotFound(err)
diff --git a/routers/home.go b/routers/home.go
index aab760611..092b30fe3 100755
--- a/routers/home.go
+++ b/routers/home.go
@@ -7,6 +7,7 @@ package routers
import (
"bytes"
+ "encoding/json"
"net/http"
"strconv"
"strings"
@@ -672,7 +673,7 @@ func NotFound(ctx *context.Context) {
}
func getRecommendOrg() ([]map[string]interface{}, error) {
- url := setting.RecommentRepoAddr + "organizations"
+ url := setting.RecommentRepoAddr + "home/organizations"
result, err := repository.RecommendFromPromote(url)
if err != nil {
@@ -745,7 +746,7 @@ func GetMapInfo(ctx *context.Context) {
}
func GetRankUser(index string) ([]map[string]interface{}, error) {
- url := setting.RecommentRepoAddr + "user_rank_" + index
+ url := setting.RecommentRepoAddr + "user_rank/user_rank_" + index
result, err := repository.RecommendFromPromote(url)
if err != nil {
@@ -756,13 +757,25 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
tmpIndex := strings.Index(userRank, " ")
userName := userRank
score := 0
+ label := ""
if tmpIndex != -1 {
userName = userRank[0:tmpIndex]
- tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:])
- if err != nil {
- log.Info("convert to int error.")
+ left := userRank[tmpIndex+1:]
+ tmpIndex1 := strings.Index(left, " ")
+ if tmpIndex1 != -1 {
+ tmpScore, err := strconv.Atoi(left[0:tmpIndex1])
+ if err != nil {
+ log.Info("convert to int error.")
+ }
+ score = tmpScore
+ label = left[tmpIndex1+1:]
+ } else {
+ tmpScore, err := strconv.Atoi(left[tmpIndex+1:])
+ if err != nil {
+ log.Info("convert to int error.")
+ }
+ score = tmpScore
}
- score = tmpScore
}
user, err := models.GetUserByName(userName)
if err == nil {
@@ -772,6 +785,7 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
userMap["FullName"] = user.FullName
userMap["HomeLink"] = user.HomeLink()
userMap["ID"] = user.ID
+ userMap["Label"] = label
userMap["Avatar"] = user.RelAvatarLink()
userMap["Score"] = score
resultOrg = append(resultOrg, userMap)
@@ -792,25 +806,54 @@ func GetUserRankFromPromote(ctx *context.Context) {
ctx.JSON(200, resultUserRank)
}
+func getMapContent(fileName string) []map[string]string {
+ url := setting.RecommentRepoAddr + fileName
+ result, err := repository.RecommendContentFromPromote(url)
+ remap := make([]map[string]string, 0)
+ if err == nil {
+ json.Unmarshal([]byte(result), &remap)
+ }
+ return remap
+}
+
+func HomeNoticeTmpl(ctx *context.Context) {
+ ctx.Data["url_params"] = ""
+ ctx.HTML(200, "notice")
+}
+
func RecommendHomeInfo(ctx *context.Context) {
resultOrg, err := getRecommendOrg()
if err != nil {
log.Info("error." + err.Error())
}
- resultRepo, err := repository.GetRecommendRepoFromPromote("projects")
+ repoMap := getMapContent("home/projects")
+ resultRepo, err := repository.GetRecommendRepoFromPromote(repoMap)
if err != nil {
log.Info("error." + err.Error())
}
- resultImage, err := getImageInfo("picture_info")
- if err != nil {
- log.Info("error." + err.Error())
- }
-
+ resultActivityInfo := getMapContent("home/activity_info")
mapInterface := make(map[string]interface{})
mapInterface["org"] = resultOrg
mapInterface["repo"] = resultRepo
- mapInterface["image"] = resultImage
- //mapInterface["cloudbrain"] = resultCloudBrain
+ mapInterface["activity"] = resultActivityInfo
+
+ user_experience := getMapContent("home/user_experience")
+ for _, amap := range user_experience {
+ userId := amap["userid"]
+ userIntId, _ := strconv.Atoi(userId)
+ user, err := models.GetUserByID(int64(userIntId))
+ if err == nil {
+ amap["name"] = user.Name
+ amap["fullname"] = user.FullName
+ amap["detail"] = user.Description
+ amap["avatar"] = user.AvatarLink()
+ }
+ }
+ mapInterface["user_experience"] = user_experience
+ dataset, err := models.QueryDatasetGroupByTask()
+ if err == nil {
+ mapInterface["dataset"] = dataset
+ }
ctx.JSON(http.StatusOK, mapInterface)
}
@@ -824,4 +867,4 @@ func HomePrivacy(ctx *context.Context) {
func HomeResoruceDesc(ctx *context.Context) {
ctx.HTML(200, tplResoruceDesc)
-}
\ No newline at end of file
+}
diff --git a/routers/repo/ai_model_convert.go b/routers/repo/ai_model_convert.go
index 962c76aae..405f0ef89 100644
--- a/routers/repo/ai_model_convert.go
+++ b/routers/repo/ai_model_convert.go
@@ -828,5 +828,4 @@ func ModelConvertDownloadModel(ctx *context.Context) {
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
}
}
-
}
diff --git a/routers/repo/aisafety.go b/routers/repo/aisafety.go
index b638a486b..6176fcda5 100644
--- a/routers/repo/aisafety.go
+++ b/routers/repo/aisafety.go
@@ -11,7 +11,8 @@ import (
"os"
"strconv"
"strings"
- "time"
+
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/aisafety"
@@ -483,7 +484,6 @@ func isTaskNotFinished(status string) bool {
}
func AiSafetyCreateForGetGPU(ctx *context.Context) {
- t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainOne
@@ -497,7 +497,7 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
log.Info("GPUBaseDataSetUUID=" + setting.ModelSafetyTest.GPUBaseDataSetUUID)
log.Info("GPUCombatDataSetName=" + setting.ModelSafetyTest.GPUCombatDataSetName)
log.Info("GPUCombatDataSetUUID=" + setting.ModelSafetyTest.GPUCombatDataSetUUID)
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
prepareCloudbrainOneSpecs(ctx)
queuesDetail, _ := cloudbrain.GetQueuesDetail()
@@ -514,12 +514,11 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
}
func AiSafetyCreateForGetNPU(ctx *context.Context) {
- t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainTwo
ctx.Data["compute_resource"] = models.NPUResource
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
ctx.Data["BaseDataSetName"] = setting.ModelSafetyTest.NPUBaseDataSetName
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index 7d96d1b58..d3d76f440 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+
"code.gitea.io/gitea/modules/urfs_client/urchin"
"code.gitea.io/gitea/modules/dataset"
@@ -92,28 +94,9 @@ func MustEnableCloudbrain(ctx *context.Context) {
}
}
-func cutString(str string, lens int) string {
- if len(str) < lens {
- return str
- }
- return str[:lens]
-}
-
-func jobNamePrefixValid(s string) string {
- lowStr := strings.ToLower(s)
- re := regexp.MustCompile(`[^a-z0-9_\\-]+`)
-
- removeSpecial := re.ReplaceAllString(lowStr, "")
-
- re = regexp.MustCompile(`^[_\\-]+`)
- return re.ReplaceAllString(removeSpecial, "")
-
-}
-
func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
ctx.Data["command"] = cloudbrain.GetCloudbrainDebugCommand()
@@ -696,7 +679,7 @@ func CloudBrainRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
- resultCode = "-1"
+ resultCode = "2"
errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
@@ -759,43 +742,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
return
}
if task.Status == string(models.JobWaiting) || task.Status == string(models.JobRunning) {
- result, err := cloudbrain.GetJob(task.JobID)
+ task, err = cloudbrainTask.SyncCloudBrainOneStatus(task)
if err != nil {
log.Info("error:" + err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
- if result != nil {
- jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
- taskRoles := jobRes.TaskRoles
- taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
- ctx.Data["taskRes"] = taskRes
- ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
- oldStatus := task.Status
- task.Status = taskRes.TaskStatuses[0].State
- task.ContainerIp = ""
- task.ContainerID = taskRes.TaskStatuses[0].ContainerID
- models.ParseAndSetDurationFromCloudBrainOne(jobRes, task)
-
- if task.DeletedAt.IsZero() { //normal record
- if oldStatus != task.Status {
- notification.NotifyChangeCloudbrainStatus(task, oldStatus)
- }
- err = models.UpdateJob(task)
- if err != nil {
- ctx.Data["error"] = err.Error()
- return
- }
- } else { //deleted record
-
- }
-
- ctx.Data["result"] = jobRes
- } else {
- log.Info("error:" + err.Error())
- return
- }
}
user, err := models.GetUserByID(task.UserID)
@@ -889,7 +842,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
func CloudBrainDebug(ctx *context.Context) {
task := ctx.Cloudbrain
debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
- ctx.Redirect(debugUrl)
+ if task.BootFile!=""{
+ ctx.Redirect(getFileUrl(debugUrl,task.BootFile))
+
+ }else{
+ ctx.Redirect(debugUrl)
+ }
+
}
func prepareSpec4Show(ctx *context.Context, task *models.Cloudbrain) {
diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go
index de7bb454d..8f3182758 100755
--- a/routers/repo/grampus.go
+++ b/routers/repo/grampus.go
@@ -10,7 +10,6 @@ import (
"path"
"strconv"
"strings"
- "time"
"code.gitea.io/gitea/modules/urfs_client/urchin"
"code.gitea.io/gitea/routers/response"
@@ -77,8 +76,7 @@ func GrampusTrainJobNPUNew(ctx *context.Context) {
func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
//get valid images
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index fabf7e555..b992734e4 100755
--- a/routers/repo/modelarts.go
+++ b/routers/repo/modelarts.go
@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+
"code.gitea.io/gitea/services/cloudbrain/cloudbrainTask"
"code.gitea.io/gitea/modules/dataset"
@@ -128,8 +130,7 @@ func NotebookNew(ctx *context.Context) {
func notebookNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
@@ -239,9 +240,9 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
}
if setting.ModelartsCD.Enabled {
- err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec)
+ _, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec, "",modelarts.AutoStopDurationMs)
} else {
- err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec)
+ _, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec, "",modelarts.AutoStopDurationMs)
}
if err != nil {
@@ -387,8 +388,33 @@ func NotebookDebug2(ctx *context.Context) {
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
return
}
+ if task.BootFile!=""{
+ ctx.Redirect(getFileUrl(result.Url,task.BootFile) + "?token="+ result.Token)
+ }else{
+ ctx.Redirect(result.Url + "?token=" + result.Token)
+ }
+
- ctx.Redirect(result.Url + "?token=" + result.Token)
+}
+
+func getFileUrl(url string,filename string) string{
+ middle:=""
+ if url[len(url)-3:]=="lab" || url[len(url)-4:]=="lab/" {
+ if url[len(url)-1] == '/' {
+ middle="tree/"
+ } else {
+ middle= "/tree/"
+ }
+ }else{
+ if url[len(url)-1] == '/' {
+ middle = "lab/tree/"
+ } else {
+ middle= "/lab/tree/"
+ }
+ }
+
+
+ return url+middle+path.Base(filename)
}
func NotebookRestart(ctx *context.Context) {
@@ -420,7 +446,8 @@ func NotebookRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
- errorMsg = "you have already a running or waiting task, can not create more"
+ resultCode="2"
+ errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
}
@@ -714,8 +741,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
// return
//}
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
@@ -2351,8 +2377,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["newInference"] = true
- t := time.Now()
- var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+ var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index a988e4849..60f0365ea 100755
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -359,6 +359,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/all/dosearch/", routers.SearchApi)
m.Post("/user/login/kanban", user.SignInPostAPI)
m.Get("/home/term", routers.HomeTerm)
+ m.Get("/home/notice", routers.HomeNoticeTmpl)
m.Get("/home/privacy", routers.HomePrivacy)
m.Get("/extension/tuomin/upload", modelapp.ProcessImageUI)
m.Post("/extension/tuomin/upload", reqSignIn, modelapp.ProcessImage)
@@ -1273,8 +1274,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/modelsafety", func() {
m.Group("/:id", func() {
- m.Get("/show", reqRepoCloudBrainWriter, repo.GetAiSafetyTaskTmpl)
- m.Get("", reqRepoCloudBrainWriter, repo.GetAiSafetyTask)
+ m.Get("/show", reqRepoCloudBrainReader, repo.GetAiSafetyTaskTmpl)
+ m.Get("", reqRepoCloudBrainReader, repo.GetAiSafetyTask)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.StopAiSafetyTask)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelAiSafetyTask)
})
diff --git a/services/cloudbrain/cloudbrainTask/notebook.go b/services/cloudbrain/cloudbrainTask/notebook.go
new file mode 100644
index 000000000..6b2fcf707
--- /dev/null
+++ b/services/cloudbrain/cloudbrainTask/notebook.go
@@ -0,0 +1,362 @@
+package cloudbrainTask
+
+import (
+ "fmt"
+ "net/http"
+ "path"
+
+ "code.gitea.io/gitea/modules/modelarts"
+ "code.gitea.io/gitea/modules/modelarts_cd"
+
+ "code.gitea.io/gitea/modules/git"
+
+ "code.gitea.io/gitea/modules/cloudbrain"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/redis/redis_key"
+ "code.gitea.io/gitea/modules/redis/redis_lock"
+ "code.gitea.io/gitea/modules/storage"
+ "code.gitea.io/gitea/services/cloudbrain/resource"
+ "code.gitea.io/gitea/services/reward/point/account"
+
+ "code.gitea.io/gitea/modules/setting"
+ cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
+ repo_service "code.gitea.io/gitea/services/repository"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
+)
+
+const NoteBookExtension = ".ipynb"
+
+func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption) {
+
+ if ctx.Written() {
+ return
+ }
+
+ if path.Ext(option.File) != NoteBookExtension {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
+ return
+ }
+
+ isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
+ if !isNotebookFileExist {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+
+ sourceRepo, err := models.GetRepositoryByOwnerAndName(option.OwnerName, option.ProjectName)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+
+ permission, err := models.GetUserRepoPermission(sourceRepo, ctx.User)
+ if err != nil {
+ log.Error("Get permission failed", err)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
+ return
+ }
+
+ if !permission.CanRead(models.UnitTypeCode) {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
+ return
+ }
+
+ //create repo if not exist
+ repo, err := models.GetRepositoryByName(ctx.User.ID, setting.FileNoteBook.ProjectName)
+ if repo == nil {
+ repo, err = repo_service.CreateRepository(ctx.User, ctx.User, models.CreateRepoOptions{
+ Name: setting.FileNoteBook.ProjectName,
+ Alias: "",
+ Description: "",
+ IssueLabels: "",
+ Gitignores: "",
+ License: "",
+ Readme: "Default",
+ IsPrivate: false,
+ AutoInit: true,
+ DefaultBranch: "master",
+ })
+ }
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo",setting.FileNoteBook.ProjectName)))
+ return
+ }
+ if option.Type <= 1 {
+ cloudBrainFileNoteBookCreate(ctx, option, repo, sourceRepo)
+ } else {
+ modelartsFileNoteBookCreate(ctx, option, repo, sourceRepo)
+ }
+
+}
+
+func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
+
+ displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
+ jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
+ jobType := string(models.JobTypeDebug)
+
+ lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), jobType, displayJobName))
+ defer lock.UnLock()
+ isOk, err := lock.Lock(models.CloudbrainKeyDuration)
+ if !isOk {
+ log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+
+ tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName)
+ if err == nil {
+ if len(tasks) != 0 {
+ log.Error("the job name did already exist", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ } else {
+ if !models.IsErrJobNotExist(err) {
+ log.Error("system error, %v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ }
+ }
+
+ count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType)
+ if err != nil {
+ log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK,models.BaseMessageApi{
+ Code: 2,
+ Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
+ })
+ return
+ }
+ }
+
+ errStr := uploadCodeFile(sourceRepo, getCodePath(jobName), option.BranchName, option.File, jobName)
+ if errStr != "" {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
+ return
+ }
+ command := cloudbrain.GetCloudbrainDebugCommand()
+ specId := setting.FileNoteBook.SpecIdGPU
+ if option.Type == 0 {
+ specId = setting.FileNoteBook.SpecIdCPU
+ }
+ spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
+ JobType: models.JobType(jobType),
+ ComputeResource: models.GPU,
+ Cluster: models.OpenICluster,
+ AiCenterCode: models.AICenterOfCloudBrainOne})
+ if err != nil || spec == nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
+ return
+ }
+
+ if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
+ log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
+ return
+ }
+ ctx.Repo = &context.Repository{
+ Repository: repo,
+ }
+
+ req := cloudbrain.GenerateCloudBrainTaskReq{
+ Ctx: ctx,
+ DisplayJobName: displayJobName,
+ JobName: jobName,
+ Image: setting.FileNoteBook.ImageGPU,
+ Command: command,
+ Uuids: "",
+ DatasetNames: "",
+ DatasetInfos: nil,
+ CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
+ ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
+ BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
+ Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
+ BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
+ JobType: jobType,
+ Description: getDescription(option),
+ BranchName: option.BranchName,
+ BootFile: option.File,
+ Params: "{\"parameter\":[]}",
+ CommitID: "",
+ BenchmarkTypeID: 0,
+ BenchmarkChildTypeID: 0,
+ ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"),
+ Spec: spec,
+ }
+
+ jobId, err := cloudbrain.GenerateTask(req)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
+ return
+ }
+ ctx.JSON(http.StatusOK, models.BaseMessageApi{
+ Code: 0,
+ Message: jobId,
+ })
+
+}
+
+func getCodePath(jobName string) string {
+ return setting.JobPath + jobName + cloudbrain.CodeMountPath
+}
+
+func getDescription(option api.CreateFileNotebookJobOption) string {
+ return option.OwnerName + "/" + option.ProjectName + "/" + option.File
+}
+
+func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
+ displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
+ jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
+
+ lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), string(models.JobTypeDebug), displayJobName))
+ isOk, err := lock.Lock(models.CloudbrainKeyDuration)
+ if !isOk {
+ log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ defer lock.UnLock()
+
+ count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug))
+
+ if err != nil {
+ log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
+
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ } else {
+ if count >= 1 {
+ log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK,models.BaseMessageApi{
+ Code: 2,
+ Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
+ })
+ return
+ }
+ }
+
+ tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName)
+ if err == nil {
+ if len(tasks) != 0 {
+ log.Error("the job name did already exist", ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
+ return
+ }
+ } else {
+ if !models.IsErrJobNotExist(err) {
+ log.Error("system error, %v", err, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
+ return
+ }
+ }
+
+ err = downloadCode(sourceRepo, getCodePath(jobName), option.BranchName)
+ if err != nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
+ return
+ }
+
+ var aiCenterCode = models.AICenterOfCloudBrainTwo
+ var specId = setting.FileNoteBook.SpecIdNPU
+ if setting.ModelartsCD.Enabled {
+ aiCenterCode = models.AICenterOfChengdu
+ specId = setting.FileNoteBook.SpecIdNPUCD
+ }
+ spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
+ JobType: models.JobTypeDebug,
+ ComputeResource: models.NPU,
+ Cluster: models.OpenICluster,
+ AiCenterCode: aiCenterCode})
+ if err != nil || spec == nil {
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
+ return
+ }
+ if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
+ log.Error("point balance is not enough,userId=%d specId=%d ", ctx.User.ID, spec.ID)
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
+ return
+ }
+ ctx.Repo = &context.Repository{
+ Repository: repo,
+ }
+
+ var jobId string
+ if setting.ModelartsCD.Enabled {
+ jobId, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPUCD, spec, option.File,modelarts.AutoStopDurationMs/4)
+ } else {
+ jobId, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPU, spec, option.File,modelarts.AutoStopDurationMs/4)
+ }
+
+ if err != nil {
+ log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"])
+
+ ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
+
+ return
+ }
+
+ ctx.JSON(http.StatusOK, models.BaseMessageApi{
+ Code: 0,
+ Message: jobId,
+ })
+
+}
+
+func isNoteBookFileExist(ctx *context.Context, option api.CreateFileNotebookJobOption) (bool, error) {
+ repoPathOfNoteBook := models.RepoPath(option.OwnerName, option.ProjectName)
+
+ gitRepoOfNoteBook, err := git.OpenRepository(repoPathOfNoteBook)
+ if err != nil {
+ log.Error("RepoRef Invalid repo "+repoPathOfNoteBook, err.Error())
+ return false, err
+ }
+ // We opened it, we should close it
+ defer func() {
+ // If it's been set to nil then assume someone else has closed it.
+ if gitRepoOfNoteBook != nil {
+ gitRepoOfNoteBook.Close()
+ }
+ }()
+ fileExist, err := fileExists(gitRepoOfNoteBook, option.File, option.BranchName)
+ if err != nil || !fileExist {
+ log.Error("Get file error:", err, ctx.Data["MsgID"])
+
+ return false, err
+ }
+ return true, nil
+}
+
+func uploadCodeFile(repo *models.Repository, codePath string, branchName string, filePath string, jobName string) string {
+ err := downloadCode(repo, codePath, branchName)
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+
+ err = uploadOneFileToMinio(codePath, filePath, jobName, cloudbrain.CodeMountPath+"/")
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+ return ""
+}
+
+func fileExists(gitRepo *git.Repository, path string, branch string) (bool, error) {
+
+ commit, err := gitRepo.GetBranchCommit(branch)
+ if err != nil {
+ return false, err
+ }
+ if _, err := commit.GetTreeEntryByPath(path); err != nil {
+ return false, err
+ }
+ return true, nil
+}
diff --git a/services/cloudbrain/cloudbrainTask/sync_status.go b/services/cloudbrain/cloudbrainTask/sync_status.go
index 67dc4d3b7..973b9bbc2 100644
--- a/services/cloudbrain/cloudbrainTask/sync_status.go
+++ b/services/cloudbrain/cloudbrainTask/sync_status.go
@@ -1,20 +1,21 @@
package cloudbrainTask
import (
- "net/http"
-
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
- "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
+ "net/http"
+ "strconv"
)
var noteBookOKMap = make(map[int64]int, 20)
+var noteBookFailMap = make(map[int64]int, 20)
-//if a task notebook url can get two times, the notebook can browser.
+//if a task notebook url can get successfulCount times, the notebook can browser.
const successfulCount = 3
+const maxSuccessfulCount=10
func SyncCloudBrainOneStatus(task *models.Cloudbrain) (*models.Cloudbrain, error) {
jobResult, err := cloudbrain.GetJob(task.JobID)
@@ -62,21 +63,29 @@ func isNoteBookReady(task *models.Cloudbrain) bool {
return true
}
noteBookUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
- r := httplib.Get(noteBookUrl)
- res, err := r.Response()
+ res,err := http.Get(noteBookUrl)
if err != nil {
return false
}
+ log.Info("notebook success count:"+strconv.Itoa(noteBookOKMap[task.ID])+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
if res.StatusCode == http.StatusOK {
count := noteBookOKMap[task.ID]
- if count < successfulCount-1 {
+ if count==0{ //如果是第一次成功,把失败数重置为0
+ noteBookFailMap[task.ID]=0
+ }
+
+ if count < successfulCount-1 || (noteBookFailMap[task.ID]==0 && count < maxSuccessfulCount-1) {
noteBookOKMap[task.ID] = count + 1
return false
} else {
+ log.Info("notebook success count:"+strconv.Itoa(count)+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
delete(noteBookOKMap, task.ID)
+ delete(noteBookFailMap, task.ID)
return true
}
+ }else{
+ noteBookFailMap[task.ID]+=1
}
return false
diff --git a/services/cloudbrain/cloudbrainTask/train.go b/services/cloudbrain/cloudbrainTask/train.go
index 8e4673d66..00d01a7ce 100644
--- a/services/cloudbrain/cloudbrainTask/train.go
+++ b/services/cloudbrain/cloudbrainTask/train.go
@@ -810,6 +810,18 @@ func uploadCodeToMinio(codePath, jobName, parentDir string) error {
return nil
}
+func uploadOneFileToMinio(codePath, filePath, jobName, parentDir string) error {
+ destObject := setting.CBCodePathPrefix + jobName + parentDir + path.Base(filePath)
+ sourceFile := codePath + "/" + filePath
+ err := storage.Attachments.UploadObject(destObject, sourceFile)
+ if err != nil {
+ log.Error("UploadObject(%s) failed: %s", filePath, err.Error())
+ return err
+ }
+ return nil
+
+}
+
func readDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
diff --git a/services/cloudbrain/util.go b/services/cloudbrain/util.go
index dc9177ecf..0a3096e3f 100644
--- a/services/cloudbrain/util.go
+++ b/services/cloudbrain/util.go
@@ -1,7 +1,11 @@
package cloudbrain
import (
+ "regexp"
+ "strconv"
"strings"
+ "time"
+
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@@ -33,6 +37,28 @@ func GetAiCenterShow(aiCenter string, ctx *context.Context) string {
}
+func GetDisplayJobName(username string) string {
+ t := time.Now()
+ return jobNamePrefixValid(cutString(username, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
+}
+
+func cutString(str string, lens int) string {
+ if len(str) < lens {
+ return str
+ }
+ return str[:lens]
+}
+
+func jobNamePrefixValid(s string) string {
+ lowStr := strings.ToLower(s)
+ re := regexp.MustCompile(`[^a-z0-9_\\-]+`)
+
+ removeSpecial := re.ReplaceAllString(lowStr, "")
+
+ re = regexp.MustCompile(`^[_\\-]+`)
+ return re.ReplaceAllString(removeSpecial, "")
+}
+
func GetAiCenterInfoByCenterCode(aiCenterCode string) *setting.C2NetSequenceInfo {
if setting.AiCenterCodeAndNameMapInfo != nil {
if info, ok := setting.AiCenterCodeAndNameMapInfo[aiCenterCode]; ok {
diff --git a/services/repository/repository.go b/services/repository/repository.go
index b4c047392..db25010ea 100644
--- a/services/repository/repository.go
+++ b/services/repository/repository.go
@@ -107,18 +107,13 @@ func GetRecommendCourseKeyWords() ([]string, error) {
}
-func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, error) {
+func GetRecommendRepoFromPromote(repoMap []map[string]string) ([]map[string]interface{}, error) {
resultRepo := make([]map[string]interface{}, 0)
- url := setting.RecommentRepoAddr + filename
- result, err := RecommendFromPromote(url)
-
- if err != nil {
-
- return resultRepo, err
- }
//resultRepo := make([]*models.Repository, 0)
- for _, repoName := range result {
+ for _, record := range repoMap {
+ repoName := record["project_url"]
+ //log.Info("repoName=" + repoName + " tmpIndex1=" + fmt.Sprint(tmpIndex1) + " len(repoName)=" + fmt.Sprint(len(repoName)))
tmpIndex := strings.Index(repoName, "/")
if tmpIndex == -1 {
log.Info("error repo name format.")
@@ -131,7 +126,8 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err
repoMap["ID"] = fmt.Sprint(repo.ID)
repoMap["Name"] = repo.Name
repoMap["Alias"] = repo.Alias
-
+ repoMap["Label"] = record["class"]
+ repoMap["Label_en"] = record["class_en"]
repoMap["OwnerName"] = repo.OwnerName
repoMap["NumStars"] = repo.NumStars
repoMap["NumForks"] = repo.NumForks
diff --git a/templates/admin/cloudbrain/list.tmpl b/templates/admin/cloudbrain/list.tmpl
index 20e704a4d..94f80c0fa 100755
--- a/templates/admin/cloudbrain/list.tmpl
+++ b/templates/admin/cloudbrain/list.tmpl
@@ -238,6 +238,7 @@
{{$.i18n.Tr "repo.debug"}}
{{else}}
+ {{if not .BootFile}}
{{end}}
+ {{end}}
{{end}}
diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl
index b4c8518c4..94940e7a9 100755
--- a/templates/base/footer_content.tmpl
+++ b/templates/base/footer_content.tmpl
@@ -1,15 +1,17 @@
-
+
-
+
+
+
+
-
+
+
+
+
+
{{.i18n.Tr "custom.foot.openi_subscription_number"}}
+
+
+
+
{{.i18n.Tr "custom.foot.user_communication_group"}}
+
+
+
+
+
{{.i18n.Tr "custom.foot.copyright"}}
京ICP备18004880号
{{.i18n.Tr "home.powerdby"}}
Trustie确实 {{.i18n.Tr "、Gitea"}}
@@ -69,4 +104,9 @@
+
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index 4ab9da231..f4766bc9d 100755
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -240,6 +240,7 @@ var _hmt = _hmt || [];
}
}
if (isShowNoticeTag){
+ if (!document.getElementById("notic_content")) return;
if(isNewNotice){
document.getElementById("notic_content").style.display='block'
}else{
diff --git a/templates/base/head_home.tmpl b/templates/base/head_home.tmpl
index a77d7b00a..6456e2a4a 100644
--- a/templates/base/head_home.tmpl
+++ b/templates/base/head_home.tmpl
@@ -247,6 +247,7 @@ var _hmt = _hmt || [];
}
}
if (isShowNoticeTag){
+ if (!document.getElementById("notic_content")) return;
if(isNewNotice){
document.getElementById("notic_content").style.display='block'
}else{
diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl
index 50521516f..e598d7ca4 100755
--- a/templates/base/head_navbar.tmpl
+++ b/templates/base/head_navbar.tmpl
@@ -1,5 +1,5 @@
-
+
@@ -7,15 +7,18 @@
-
-
+
-
-
-
{{if .IsSigned}}
{{else}}
@@ -224,14 +234,14 @@
diff --git a/templates/base/head_notice.tmpl b/templates/base/head_notice.tmpl
index 43c581e6e..9bd35bcb6 100644
--- a/templates/base/head_notice.tmpl
+++ b/templates/base/head_notice.tmpl
@@ -1,5 +1,5 @@
{{if not .IsCourse}}
- {{ if .notices}}
+ {{ if (and .notices (not .PageIsHome)) }}
diff --git a/templates/custom/home/home_activity.tmpl b/templates/custom/home/home_activity.tmpl
new file mode 100644
index 000000000..447aaafe7
--- /dev/null
+++ b/templates/custom/home/home_activity.tmpl
@@ -0,0 +1,36 @@
+
+
+
+
{{.page_recommend_activity}}
+
{{.page_recommend_activity_desc}}
+
+
+
diff --git a/templates/custom/home/home_dataset.tmpl b/templates/custom/home/home_dataset.tmpl
new file mode 100644
index 000000000..9fb1a04f0
--- /dev/null
+++ b/templates/custom/home/home_dataset.tmpl
@@ -0,0 +1,85 @@
+
+
diff --git a/templates/custom/home/home_org.tmpl b/templates/custom/home/home_org.tmpl
new file mode 100644
index 000000000..14c976cb1
--- /dev/null
+++ b/templates/custom/home/home_org.tmpl
@@ -0,0 +1,20 @@
+
+
diff --git a/templates/custom/home/home_repo.tmpl b/templates/custom/home/home_repo.tmpl
new file mode 100644
index 000000000..0a5e45f25
--- /dev/null
+++ b/templates/custom/home/home_repo.tmpl
@@ -0,0 +1,21 @@
+
+
diff --git a/templates/custom/home/home_top.tmpl b/templates/custom/home/home_top.tmpl
new file mode 100644
index 000000000..3d5b58167
--- /dev/null
+++ b/templates/custom/home/home_top.tmpl
@@ -0,0 +1,1942 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* {{.page_only_dynamic}}
+
+
+
+
+
+
{{.i18n.Tr "home.page_title"}}
+
{{.i18n.Tr "home.page_description"}}
+
+
+
+
+
+
+
+
+
+
{{.i18n.Tr "home.c2net_title"}}
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/custom/home/home_user_experience.tmpl b/templates/custom/home/home_user_experience.tmpl
new file mode 100644
index 000000000..edee8993d
--- /dev/null
+++ b/templates/custom/home/home_user_experience.tmpl
@@ -0,0 +1,133 @@
+
+
diff --git a/templates/explore/repos.tmpl b/templates/explore/repos.tmpl
index 23170b3d6..e55f0987e 100644
--- a/templates/explore/repos.tmpl
+++ b/templates/explore/repos.tmpl
@@ -1,9 +1,7 @@
-{{template "base/head_pro" .}}
+{{template "base/head_home" .}}
-
{{template "explore/repo_search" .}}
{{template "explore/repo_orgtop" .}}
-
{{template "explore/repo_left" .}}
diff --git a/templates/home.tmpl b/templates/home.tmpl
index c7485a214..c103bf1fc 100755
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -1,91 +1,25 @@
{{template "base/head_home" .}}
-
+
+ {{template "custom/home/home_top" .}}
+
-
-
-
-
+ {{template "custom/home/home_org" .}}
-
-
{{.page_recommend_activity}}
-
{{.page_recommend_activity_desc}}
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {{template "custom/home/home_repo" .}}
-
-
-
+
+ {{template "custom/home/home_dataset" .}}
+
+
+ {{template "custom/home/home_user_experience" .}}
+
+ {{template "custom/home/home_activity" .}}
+
+
+
-
+
+
-
-
+
{{.page_dev_env}}
{{.page_dev_env_desc}}
@@ -193,8 +127,10 @@
+
+
+
+
diff --git a/templates/notice.tmpl b/templates/notice.tmpl
new file mode 100644
index 000000000..564c96dd3
--- /dev/null
+++ b/templates/notice.tmpl
@@ -0,0 +1,81 @@
+
+{{template "base/head_home" .}}
+
+
+
{{.i18n.Tr "notice_announcement"}}
+
+
+
+{{template "base/footer" .}}
+
diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl
index 20aacfb01..7345fa9bc 100755
--- a/templates/repo/debugjob/index.tmpl
+++ b/templates/repo/debugjob/index.tmpl
@@ -221,7 +221,7 @@
+ data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}" data-bootfile="{{.BootFile}}">
{{.Status}}
@@ -266,6 +266,7 @@
{{$.i18n.Tr "repo.debug"}}
{{else}}
+ {{if not .BootFile}}
{{end}}
+ {{end}}
{{else}}
{{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}}
@@ -294,7 +296,9 @@
+ data-jobid="{{.Cloudbrain.ID}}"
+ {{if .BootFile}}data-bootfile="{{.BootFile}}"{{end}}>
+
{{$.i18n.Tr "repo.stop"}}
{{else}}
@@ -322,6 +326,7 @@
{{end}}
+ {{if not .BootFile}}
+ {{end}}
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index f501fafa4..5bac6504c 100755
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -52,13 +52,13 @@
{{if not .IsBeingCreated}}