diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index d294c8823..7a4298f6b 100755 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -1141,3 +1141,9 @@ growth_issue=0.2 growth_contributors=0.2 growth_commit=0.2 growth_comments=0.2 + + +[grampus] +USERNAME = +PASSWORD = +SERVER_HOST = diff --git a/models/action.go b/models/action.go index 9b92b4192..288186b2c 100755 --- a/models/action.go +++ b/models/action.go @@ -50,14 +50,16 @@ const ( ActionRejectPullRequest // 22 ActionCommentPull // 23 - ActionUploadAttachment //24 - ActionCreateDebugGPUTask //25 - ActionCreateDebugNPUTask //26 - ActionCreateTrainTask //27 - ActionCreateInferenceTask // 28 - ActionCreateBenchMarkTask //29 - ActionCreateNewModelTask //30 - ActionCreateGPUTrainTask //31 + ActionUploadAttachment //24 + ActionCreateDebugGPUTask //25 + ActionCreateDebugNPUTask //26 + ActionCreateTrainTask //27 + ActionCreateInferenceTask // 28 + ActionCreateBenchMarkTask //29 + ActionCreateNewModelTask //30 + ActionCreateGPUTrainTask //31 + ActionCreateGrampusNPUTrainTask //32 + ActionCreateGrampusGPUTrainTask //33 ) // Action represents user operation type and other information to diff --git a/models/cloudbrain.go b/models/cloudbrain.go index 4b4c2c099..4c7bf76a2 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -24,7 +24,7 @@ type ModelArtsJobStatus string const ( TypeCloudBrainOne int = iota TypeCloudBrainTwo - TypeIntelligentNet + TypeC2Net //智算网络 TypeCloudBrainAll = -1 ) @@ -99,6 +99,15 @@ const ( ModelArtsTrainJobCheckFailed ModelArtsJobStatus = "CHECK_FAILED" //审核作业失败 DURATION_STR_ZERO = "00:00:00" + + //grampus + GrampusStatusPending = "pending" + GrampusStatusRunning = "RUNNING" + GrampusStatusFailed = "FAILED" + GrampusStatusSucceeded = "SUCCEEDED" + GrampusStatusStopped = "STOPPED" + GrampusStatusUnknown = "UNKNOWN" + GrampusStatusWaiting = "WAITING" ) type Cloudbrain struct { @@ -138,6 +147,8 @@ type Cloudbrain struct { PreVersionName string //父版本名称 ComputeResource string //计算资源,例如npu EngineID int64 //引擎id + ImageID string //grampus image_id + AiCenter string //grampus ai center: center_id+center_name TrainUrl string //输出模型的obs路径 BranchName string //分支名称 @@ -206,7 +217,7 @@ func ConvertDurationToStr(duration int64) string { } func IsTrainJobTerminal(status string) bool { - return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) + return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) || status == GrampusStatusFailed || status == GrampusStatusStopped || status == GrampusStatusSucceeded } func IsModelArtsDebugJobTerminal(status string) bool { @@ -1156,6 +1167,84 @@ type LogFile struct { Name string } +//Grampus +type GrampusResult struct { + ErrorCode int `json:"errorCode"` + ErrorMsg string `json:"errorMsg"` +} + +type GrampusJobInfo struct { + StartedAt int64 `json:"startedAt"` + RunSec int64 `json:"runSec"` + CompletedAt int64 `json:"completedAt"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` + Desc string `json:"desc"` + JobID string `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + UserID string `json:"userId"` + Tasks []GrampusTasks `json:"tasks"` +} + +type GrampusSpec struct { + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` + ID string `json:"id"` + Name string `json:"name"` + ProcessorType string `json:"processorType"` +} + +type GetGrampusResourceSpecsResult struct { + GrampusResult + Infos []GrampusSpec `json:"resourceSpecs"` +} + +type GrampusImage struct { + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` + ID string `json:"id"` + Name string `json:"name"` + ProcessorType string `json:"processorType"` +} + +type GetGrampusImagesResult struct { + GrampusResult + TotalSize int `json:"totalSize"` + Infos []GrampusImage `json:"images"` +} + +type CreateGrampusJobResponse struct { + GrampusResult + JobInfo GrampusJobInfo `json:"otJob"` +} + +type GetGrampusJobResponse struct { + GrampusResult + JobInfo GrampusJobInfo `json:"otJob"` +} + +type GrampusStopJobResponse struct { + GrampusResult + StoppedAt int64 `json:"stoppedAt"` +} + +type GrampusTasks struct { + Command string `json:"command"` + Name string `json:"name"` + ImageId string `json:"imageId"` + ResourceSpecId string `json:"resourceSpecId"` + ImageUrl string `json:"imageUrl"` + CenterID []string `json:"centerID"` + CenterName []string `json:"centerName"` + ReplicaNum int `json:"replicaNum"` +} + +type CreateGrampusJobRequest struct { + Name string `json:"name"` + Tasks []GrampusTasks `json:"tasks"` +} + type GetTrainJobMetricStatisticResult struct { TrainJobResult Interval int `json:"interval"` //查询的时间间隔,单位为分钟 @@ -1201,6 +1290,12 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { ) } + if len(opts.ComputeResource) > 0 { + cond = cond.And( + builder.Eq{"cloudbrain.compute_resource": opts.ComputeResource}, + ) + } + if len(opts.JobTypes) > 0 { if opts.JobTypeNot { cond = cond.And( @@ -1456,6 +1551,11 @@ func GetCloudbrainByJobID(jobID string) (*Cloudbrain, error) { return getRepoCloudBrain(cb) } +func GetCloudbrainByJobIDWithDeleted(jobID string) (*Cloudbrain, error) { + cb := &Cloudbrain{JobID: jobID} + return getRepoCloudBrainWithDeleted(cb) +} + func GetCloudbrainByID(id string) (*Cloudbrain, error) { idInt64, _ := strconv.ParseInt(id, 10, 64) cb := &Cloudbrain{ID: idInt64} @@ -1634,6 +1734,11 @@ func GetCloudbrainInferenceJobCountByUserID(userID int64) (int, error) { return int(count), err } +func GetGrampusCountByUserID(userID int64, jobType, computeResource string) (int, error) { + count, err := x.In("status", GrampusStatusWaiting, GrampusStatusRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeC2Net).And("compute_resource = ?", computeResource).Count(new(Cloudbrain)) + return int(count), err +} + func UpdateInferenceJob(job *Cloudbrain) error { return updateInferenceJob(x, job) } diff --git a/models/cloudbrain_image.go b/models/cloudbrain_image.go old mode 100644 new mode 100755 index f72c6a27c..71f0c2c94 --- a/models/cloudbrain_image.go +++ b/models/cloudbrain_image.go @@ -68,6 +68,7 @@ type SearchImageOptions struct { IncludeCustom bool IncludeOwnerOnly bool Topics string + CloudbrainType int ListOptions SearchOrderBy } @@ -411,6 +412,10 @@ func SearchImageCondition(opts *SearchImageOptions) builder.Cond { } + if opts.CloudbrainType > 0 { + cond = cond.And(builder.Eq{"cloudbrain_type": opts.CloudbrainType}) + } + return cond } diff --git a/modules/auth/grampus.go b/modules/auth/grampus.go new file mode 100755 index 000000000..ebf0defde --- /dev/null +++ b/modules/auth/grampus.go @@ -0,0 +1,26 @@ +package auth + +import ( + "gitea.com/macaron/binding" + "gitea.com/macaron/macaron" +) + +type CreateGrampusTrainJobForm struct { + DisplayJobName string `form:"display_job_name" binding:"Required"` + JobName string `form:"job_name" binding:"Required"` + Attachment string `form:"attachment" binding:"Required"` + BootFile string `form:"boot_file" binding:"Required"` + ImageID string `form:"image_id" binding:"Required"` + FlavorID string `form:"flavor" binding:"Required"` + Params string `form:"run_para_list" binding:"Required"` + Description string `form:"description"` + BranchName string `form:"branch_name" binding:"Required"` + FlavorName string `form:"flavor_name" binding:"Required"` + EngineName string `form:"engine_name" binding:"Required"` + WorkServerNumber int `form:"work_server_number" binding:"Required"` + Image string `form:"image"` +} + +func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { + return validate(errs, ctx.Data, f, ctx.Locale) +} diff --git a/modules/cloudbrain/cloudbrain.go b/modules/cloudbrain/cloudbrain.go index 8fb13ca4c..dea3f2768 100755 --- a/modules/cloudbrain/cloudbrain.go +++ b/modules/cloudbrain/cloudbrain.go @@ -48,13 +48,10 @@ func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, er if !ctx.IsSigned { return false } - log.Info("is repo owner:" + strconv.FormatBool(ctx.IsUserRepoOwner())) - log.Info("is user admin:" + strconv.FormatBool(ctx.IsUserSiteAdmin())) if err != nil { return ctx.IsUserRepoOwner() || ctx.IsUserSiteAdmin() } else { - log.Info("is job creator:" + strconv.FormatBool(ctx.User.ID == job.UserID)) return ctx.IsUserRepoOwner() || ctx.IsUserSiteAdmin() || ctx.User.ID == job.UserID } diff --git a/modules/grampus/grampus.go b/modules/grampus/grampus.go new file mode 100755 index 000000000..57d65a593 --- /dev/null +++ b/modules/grampus/grampus.go @@ -0,0 +1,138 @@ +package grampus + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/timeutil" + "strings" +) + +const ( + JobPath = "job/" + + ProcessorTypeNPU = "npu.huawei.com/NPU" + ProcessorTypeGPU = "nvidia.com/gpu" + + CommandPrepareScript = "pwd;cd /cache;mkdir -p output;mkdir -p code;mkdir -p dataset;echo \"start loading script\";wget -q https://git.openi.org.cn/OpenIOSSG/script_for_grampus/archive/master.zip;" + + "echo \"finish loading script\";unzip -q master.zip;cd script_for_grampus;chmod 777 downloader_for_obs uploader_for_obs downloader_for_minio uploader_for_minio;" + + //CommandPrepareScript = "bash;pwd;apt-get -y update;apt-get -y upgrade;apt-get -y install wget;apt-get -y install unzip;" + + // "cd /tmp;mkdir -p output;mkdir -p code;mkdir -p dataset;wget -q https://git.openi.org.cn/OpenIOSSG/script_for_grampus/archive/master.zip;" + + // "unzip -q master.zip;cd script_for_grampus;chmod 777 downloader_for_obs uploader_for_obs downloader_for_minio uploader_for_minio;" + CodeArchiveName = "master.zip" +) + +var ( + poolInfos *models.PoolInfos + FlavorInfos *models.FlavorInfos + ImageInfos *models.ImageInfosModelArts +) + +type GenerateTrainJobReq struct { + JobName string + Command string + ResourceSpecId string + ImageUrl string //与image_id二选一,都有的情况下优先image_url + ImageId string + + DisplayJobName string + Uuid string + Description string + CodeObsPath string + BootFile string + BootFileUrl string + DataUrl string + TrainUrl string + WorkServerNumber int + EngineID int64 + CommitID string + IsLatestVersion string + BranchName string + PreVersionId int64 + PreVersionName string + FlavorName string + VersionCount int + EngineName string + TotalVersionCount int + ComputeResource string + DatasetName string + Params string +} + +func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) { + createTime := timeutil.TimeStampNow() + jobResult, err := createJob(models.CreateGrampusJobRequest{ + Name: req.JobName, + Tasks: []models.GrampusTasks{ + { + Name: req.JobName, + Command: req.Command, + ResourceSpecId: req.ResourceSpecId, + ImageId: req.ImageId, + ImageUrl: req.ImageUrl, + ReplicaNum: 1, + }, + }, + }) + if err != nil { + log.Error("createJob failed: %v", err.Error()) + return err + } + + jobID := jobResult.JobInfo.JobID + err = models.CreateCloudbrain(&models.Cloudbrain{ + Status: TransTrainJobStatus(jobResult.JobInfo.Status), + UserID: ctx.User.ID, + RepoID: ctx.Repo.Repository.ID, + JobID: jobID, + JobName: req.JobName, + DisplayJobName: req.DisplayJobName, + JobType: string(models.JobTypeTrain), + Type: models.TypeC2Net, + Uuid: req.Uuid, + DatasetName: req.DatasetName, + CommitID: req.CommitID, + IsLatestVersion: req.IsLatestVersion, + ComputeResource: req.ComputeResource, + ImageID: req.ImageId, + TrainUrl: req.TrainUrl, + BranchName: req.BranchName, + Parameters: req.Params, + BootFile: req.BootFile, + DataUrl: req.DataUrl, + FlavorCode: req.ResourceSpecId, + Description: req.Description, + WorkServerNumber: req.WorkServerNumber, + FlavorName: req.FlavorName, + EngineName: req.EngineName, + VersionCount: req.VersionCount, + TotalVersionCount: req.TotalVersionCount, + CreatedUnix: createTime, + UpdatedUnix: createTime, + }) + + if err != nil { + log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error()) + return err + } + + var actionType models.ActionType + if req.ComputeResource == models.NPUResource { + actionType = models.ActionCreateGrampusNPUTrainTask + } else if req.ComputeResource == models.GPUResource { + actionType = models.ActionCreateGrampusGPUTrainTask + } + notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, actionType) + + return nil +} + +func TransTrainJobStatus(status string) string { + if status == models.GrampusStatusPending { + status = models.GrampusStatusWaiting + } + + return strings.ToUpper(status) +} diff --git a/modules/grampus/resty.go b/modules/grampus/resty.go new file mode 100755 index 000000000..5e8722b4b --- /dev/null +++ b/modules/grampus/resty.go @@ -0,0 +1,277 @@ +package grampus + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "crypto/tls" + "encoding/json" + "fmt" + "github.com/go-resty/resty/v2" + "net/http" +) + +var ( + restyClient *resty.Client + HOST string + TOKEN string +) + +const ( + urlOpenApiV1 = "/openapi/v1/" + + urlGetToken = urlOpenApiV1 + "token" + urlTrainJob = urlOpenApiV1 + "trainjob" + urlGetResourceSpecs = urlOpenApiV1 + "resourcespec" + urlGetImages = urlOpenApiV1 + "image" + + errorIllegalToken = 1005 +) + +type GetTokenParams struct { + UserName string `json:"username"` + Password string `json:"password"` +} + +type GetTokenResult struct { + Token string `json:"token"` + Expiration int64 `json:"expiration"` +} + +func getRestyClient() *resty.Client { + if restyClient == nil { + restyClient = resty.New() + restyClient.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + } + return restyClient +} + +func checkSetting() { + if len(HOST) != 0 && len(TOKEN) != 0 && restyClient != nil { + return + } + + err := getToken() + if err != nil { + log.Error("getToken failed:%v", err) + } +} + +func getToken() error { + HOST = setting.Grampus.Host + + client := getRestyClient() + params := GetTokenParams{ + UserName: setting.Grampus.UserName, + Password: setting.Grampus.Password, + } + + var result GetTokenResult + res, err := client.R(). + SetHeader("Content-Type", "application/json"). + SetBody(params). + SetResult(&result). + Post(HOST + urlGetToken) + if err != nil { + return fmt.Errorf("resty getToken: %v", err) + } + + if res.StatusCode() != http.StatusOK { + return fmt.Errorf("getToken failed:%s", res.String()) + } + + TOKEN = result.Token + + return nil +} + +func createJob(req models.CreateGrampusJobRequest) (*models.CreateGrampusJobResponse, error) { + checkSetting() + client := getRestyClient() + var result models.CreateGrampusJobResponse + + retry := 0 + +sendjob: + _, err := client.R(). + SetHeader("Content-Type", "application/json"). + SetAuthToken(TOKEN). + SetBody(req). + SetResult(&result). + Post(HOST + urlTrainJob) + + if err != nil { + return nil, fmt.Errorf("resty CreateJob: %s", err) + } + + if result.ErrorCode == errorIllegalToken && retry < 1 { + retry++ + _ = getToken() + goto sendjob + } + + if result.ErrorCode != 0 { + log.Error("CreateJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + return &result, fmt.Errorf("CreateJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + } + + return &result, nil +} + +func GetJob(jobID string) (*models.GetGrampusJobResponse, error) { + checkSetting() + client := getRestyClient() + var result models.GetGrampusJobResponse + + retry := 0 + +sendjob: + _, err := client.R(). + SetAuthToken(TOKEN). + SetResult(&result). + Get(HOST + urlTrainJob + "/" + jobID) + + if err != nil { + return nil, fmt.Errorf("resty GetJob: %v", err) + } + + if result.ErrorCode == errorIllegalToken && retry < 1 { + retry++ + log.Info("retry get token") + _ = getToken() + goto sendjob + } + + if result.ErrorCode != 0 { + log.Error("GetJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + return nil, fmt.Errorf("GetJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + } + + return &result, nil +} + +func GetResourceSpecs(processorType string) (*models.GetGrampusResourceSpecsResult, error) { + checkSetting() + client := getRestyClient() + var result models.GetGrampusResourceSpecsResult + + retry := 0 + +sendjob: + _, err := client.R(). + SetAuthToken(TOKEN). + SetResult(&result). + Get(HOST + urlGetResourceSpecs + "?processorType=" + processorType) + + if err != nil { + return nil, fmt.Errorf("resty GetResourceSpecs: %v", err) + } + + if result.ErrorCode == errorIllegalToken && retry < 1 { + retry++ + log.Info("retry get token") + _ = getToken() + goto sendjob + } + + if result.ErrorCode != 0 { + log.Error("GetResourceSpecs failed(%d): %s", result.ErrorCode, result.ErrorMsg) + return &result, fmt.Errorf("GetResourceSpecs failed(%d): %s", result.ErrorCode, result.ErrorMsg) + } + + return &result, nil +} + +func GetImages(processorType string) (*models.GetGrampusImagesResult, error) { + checkSetting() + client := getRestyClient() + var result models.GetGrampusImagesResult + + retry := 0 + +sendjob: + _, err := client.R(). + SetAuthToken(TOKEN). + SetResult(&result). + Get(HOST + urlGetImages + "?processorType=" + processorType) + + if err != nil { + return nil, fmt.Errorf("resty GetImages: %v", err) + } + + if result.ErrorCode == errorIllegalToken && retry < 1 { + retry++ + log.Info("retry get token") + _ = getToken() + goto sendjob + } + + if result.ErrorCode != 0 { + log.Error("GetImages failed(%d): %s", result.ErrorCode, result.ErrorMsg) + return &result, fmt.Errorf("GetImages failed(%d): %s", result.ErrorCode, result.ErrorMsg) + } + + return &result, nil +} + +func GetTrainJobLog(jobID string) (string, error) { + checkSetting() + client := getRestyClient() + var logContent string + + res, err := client.R(). + SetAuthToken(TOKEN). + SetResult(&logContent). + Get(HOST + urlTrainJob + "/" + jobID + "/task/0/replica/0/log") + + if err != nil { + return logContent, fmt.Errorf("resty GetTrainJobLog: %v", err) + } + + if res.StatusCode() != http.StatusOK { + var temp models.GrampusResult + if err = json.Unmarshal([]byte(res.String()), &temp); err != nil { + log.Error("json.Unmarshal failed(%s): %v", res.String(), err.Error()) + return logContent, fmt.Errorf("json.Unmarshal failed(%s): %v", res.String(), err.Error()) + } + log.Error("GetTrainJobLog failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) + return logContent, fmt.Errorf("GetTrainJobLog failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) + } + + logContent = res.String() + + return logContent, nil +} + +func StopJob(jobID string) (*models.GrampusStopJobResponse, error) { + checkSetting() + client := getRestyClient() + var result models.GrampusStopJobResponse + + retry := 0 + +sendjob: + _, err := client.R(). + //SetHeader("Content-Type", "application/json"). + SetAuthToken(TOKEN). + SetResult(&result). + Post(HOST + urlTrainJob + "/" + jobID + "/stop") + + if err != nil { + return &result, fmt.Errorf("resty StopTrainJob: %v", err) + } + + if result.ErrorCode == errorIllegalToken && retry < 1 { + retry++ + log.Info("retry get token") + _ = getToken() + goto sendjob + } + + if result.ErrorCode != 0 { + log.Error("GetJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + return &result, fmt.Errorf("GetJob failed(%d): %s", result.ErrorCode, result.ErrorMsg) + } + + return &result, nil +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 5c87b68c5..abee77579 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -528,6 +528,14 @@ var ( FlavorInfos string TrainJobFLAVORINFOS string + //grampus config + Grampus = struct { + Env string + Host string + UserName string + Password string + }{} + //elk config ElkUrl string ElkUser string @@ -1382,6 +1390,16 @@ func NewContext() { Course.OrgName = sec.Key("org_name").MustString("") Course.TeamName = sec.Key("team_name").MustString("") + GetGrampusConfig() +} + +func GetGrampusConfig() { + sec := Cfg.Section("grampus") + + Grampus.Env = sec.Key("ENV").MustString("TEST") + Grampus.Host = sec.Key("SERVER_HOST").MustString("") + Grampus.UserName = sec.Key("USERNAME").MustString("") + Grampus.Password = sec.Key("PASSWORD").MustString("") } func SetRadarMapConfig() { diff --git a/modules/util/path.go b/modules/util/path.go old mode 100644 new mode 100755 index 2b198eb6d..1db6e4379 --- a/modules/util/path.go +++ b/modules/util/path.go @@ -31,3 +31,13 @@ func GetDirectorySize(path string) (int64, error) { }) return size, err } + +// check whether the path is dir +func IsDir(path string) bool { + s, err := os.Stat(path) + if err != nil { + return false + } + + return s.IsDir() +} diff --git a/modules/util/util.go b/modules/util/util.go index 134fd1296..87dd5b700 100755 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -115,7 +115,7 @@ func AddZero(t int64) (m string) { func ConvertDisplayJobNameToJobName(DisplayName string) (JobName string) { t := time.Now() - JobName = "openi" + strings.ToLower(cutNameString(DisplayName, 15)) + "t" + t.Format("20060102150405")[4:] + strconv.Itoa(int(rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000))) + JobName = strings.ToLower(cutNameString(DisplayName, 15)) + "t" + t.Format("20060102150405")[10:] + strconv.Itoa(int(rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000))) return JobName } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b04534636..ce96c669f 100755 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1176,6 +1176,9 @@ model.manage.sava_model = Sava Model model.manage.model_manage = ModelManage model.manage.model_accuracy = Model Accuracy +grampus.train_job.ai_center = AI Center +grampus.dataset_path_rule = The code is storaged in /cache/code;the dataset is storaged in /cache/dataset;and please put your model into /cache/output, then you can download it online。 + template.items = Template Items template.git_content = Git Content (Default Branch) template.git_hooks = Git Hooks @@ -2935,6 +2938,8 @@ task_inferencejob=`created reasoning task %s` task_createmodel=`created new model %s` task_gputrainjob=`created CPU/GPU training task%s` +task_c2netnputrainjob=`created NPU training task%s` +task_c2netgputrainjob=`created CPU/GPU training task%s` [tool] ago = %s ago @@ -3023,6 +3028,9 @@ Platform_Tutorial = Tutorial foot.advice_feedback = Feedback [cloudbrain] +resource_cluster = Resource Cluster +resource_cluster_openi = OpenI Resource Cluster +resource_cluster_c2net = China Computing NET compute_resource = Computing resources task_name = Task name task_type = Task type diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 6c305d296..4de0fa209 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1190,6 +1190,9 @@ model.manage.sava_model = 保存模型 model.manage.model_manage = 模型管理 model.manage.model_accuracy = 模型精度 +grampus.train_job.ai_center=智算中心 +grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。 + template.items=模板选项 template.git_content=Git数据(默认分支) template.git_hooks=Git 钩子 @@ -2950,6 +2953,8 @@ task_inferencejob=`创建了推理任务 %s` task_createmodel=`导入了新模型 %s` task_gputrainjob=`创建了CPU/GPU类型训练任务 %s` +task_c2netnputrainjob=`创建了NPU类型训练任务 %s` +task_c2netgputrainjob=`创建了CPU/GPU类型训练任务 %s` [tool] ago=%s前 @@ -3038,6 +3043,9 @@ Platform_Tutorial=新手指引 foot.advice_feedback = 意见反馈 [cloudbrain] +resource_cluster = 算力集群 +resource_cluster_openi = 启智集群 +resource_cluster_c2net = 智算网络集群 compute_resource = 计算资源 task_name = 任务名称 task_type = 任务类型 diff --git a/public/home/search.js b/public/home/search.js index 2fac95358..ea6006fba 100644 --- a/public/home/search.js +++ b/public/home/search.js @@ -1,118 +1,114 @@ var token; -if(isEmpty(token)){ - var meta = $("meta[name=_uid]"); - if(!isEmpty(meta)){ - token = meta.attr("content"); - console.log("token is uid:" + token); - } +if (isEmpty(token)) { + var meta = $("meta[name=_uid]"); + if (!isEmpty(meta)) { + token = meta.attr("content"); + } } -var html =document.documentElement; +var html = document.documentElement; var lang = html.attributes["lang"] var isZh = true; -if(lang != null && lang.nodeValue =="en-US" ){ - console.log("the language is " + lang.nodeValue); - isZh=false; -}else{ - console.log("default lang=zh"); +if (lang != null && lang.nodeValue == "en-US") { + isZh = false; +} else { } -function isEmpty(str){ - if(typeof str == "undefined" || str == null || str == ""){ - return true; +function isEmpty(str) { + if (typeof str == "undefined" || str == null || str == "") { + return true; } return false; } -var itemType={ - "1":"repository", - "2":"issue", - "3":"user", - "4":"org", - "5":"dataset", - "6":"pr" +var itemType = { + "1": "repository", + "2": "issue", + "3": "user", + "4": "org", + "5": "dataset", + "6": "pr" }; -var sortBy={ - "10":"default", - "11":"updated_unix.keyword", - "12":"num_watches", - "13":"num_stars", - "14":"num_forks", - "20":"default", - "21":"updated_unix.keyword", - "30":"default", - "31":"name.keyword", - "32":"name.keyword", - "33":"created_unix.keyword", - "34":"created_unix.keyword", - "40":"default", - "41":"name.keyword", - "42":"name.keyword", - "43":"created_unix.keyword", - "44":"created_unix.keyword", - "50":"default", - "51":"download_times", - "60":"default", - "61":"updated_unix.keyword" +var sortBy = { + "10": "default", + "11": "updated_unix.keyword", + "12": "num_watches", + "13": "num_stars", + "14": "num_forks", + "20": "default", + "21": "updated_unix.keyword", + "30": "default", + "31": "name.keyword", + "32": "name.keyword", + "33": "created_unix.keyword", + "34": "created_unix.keyword", + "40": "default", + "41": "name.keyword", + "42": "name.keyword", + "43": "created_unix.keyword", + "44": "created_unix.keyword", + "50": "default", + "51": "download_times", + "60": "default", + "61": "updated_unix.keyword" }; -var sortAscending={ - "10":"false", - "11":"false", - "12":"false", - "13":"false", - "14":"false", - "20":"false", - "21":"false", - "30":"false", - "31":"true", - "32":"false", - "33":"false", - "34":"true", - "40":"false", - "41":"true", - "42":"false", - "43":"false", - "44":"true", - "50":"false", - "51":"false", - "60":"false", - "61":"false" +var sortAscending = { + "10": "false", + "11": "false", + "12": "false", + "13": "false", + "14": "false", + "20": "false", + "21": "false", + "30": "false", + "31": "true", + "32": "false", + "33": "false", + "34": "true", + "40": "false", + "41": "true", + "42": "false", + "43": "false", + "44": "true", + "50": "false", + "51": "false", + "60": "false", + "61": "false" }; var currentPage = 1; var pageSize = 15; -var currentSearchTableName ="repository"; -var currentSearchKeyword=""; -var currentSearchSortBy=""; -var currentSearchAscending="false"; -var OnlySearchLabel=false; -var startIndex =1; +var currentSearchTableName = "repository"; +var currentSearchKeyword = ""; +var currentSearchSortBy = ""; +var currentSearchAscending = "false"; +var OnlySearchLabel = false; +var startIndex = 1; var endIndex = 5; var totalPage = 1; var totalNum = 0; var privateTotal = 0; -function initPageInfo(){ +function initPageInfo() { currentPage = 1; - startIndex =1; + startIndex = 1; endIndex = 5; } -function searchItem(type,sortType){ - console.log("enter item 2."); - if(OnlySearchLabel){ - doSearchLabel(currentSearchTableName,currentSearchKeyword,sortBy[sortType],sortAscending[sortType]) - }else{ +function searchItem(type, sortType) { + if (OnlySearchLabel) { + doSearchLabel(currentSearchTableName, currentSearchKeyword, sortBy[sortType], sortAscending[sortType]) + } else { currentSearchKeyword = document.getElementById("keyword_input").value; - if(!isEmpty(currentSearchKeyword)){ + if (!isEmpty(currentSearchKeyword)) { initPageInfo(); currentSearchTableName = itemType[type]; currentSearchSortBy = sortBy[sortType]; currentSearchAscending = sortAscending[sortType]; - OnlySearchLabel =false; + OnlySearchLabel = false; page(currentPage); - }else{ + } else { emptySearch(); } } @@ -120,28 +116,27 @@ function searchItem(type,sortType){ -function search(){ - console.log("enter here 1."); +function search() { currentSearchKeyword = document.getElementById("keyword_input").value; - if(!isEmpty(currentSearchKeyword)){ + if (!isEmpty(currentSearchKeyword)) { currentSearchKeyword = currentSearchKeyword.trim(); } - if(!isEmpty(currentSearchKeyword)){ - doSpcifySearch(currentSearchTableName,currentSearchKeyword,sortBy[10],"false"); - }else{ + if (!isEmpty(currentSearchKeyword)) { + doSpcifySearch(currentSearchTableName, currentSearchKeyword, sortBy[10], "false"); + } else { emptySearch(); } } -function emptySearch(){ +function emptySearch() { initDiv(false); initPageInfo(); $('#searchForm').addClass("hiddenSearch"); - document.getElementById("find_id").innerHTML=getLabel(isZh,"search_empty"); + document.getElementById("find_id").innerHTML = getLabel(isZh, "search_empty"); $('#find_title').html(""); - document.getElementById("sort_type").innerHTML=""; - document.getElementById("child_search_item").innerHTML=""; - document.getElementById("page_menu").innerHTML=""; + document.getElementById("sort_type").innerHTML = ""; + document.getElementById("child_search_item").innerHTML = ""; + document.getElementById("page_menu").innerHTML = ""; $('#repo_total').text(""); $('#pr_total').text(""); $('#issue_total').text(""); @@ -151,790 +146,822 @@ function emptySearch(){ setActivate(null); } -function initDiv(isSearchLabel=false){ - if(isSearchLabel){ - document.getElementById("search_div").style.display="none"; - document.getElementById("search_label_div").style.display="block"; - document.getElementById("dataset_item").style.display="none"; - document.getElementById("issue_item").style.display="none"; - document.getElementById("pr_item").style.display="none"; - document.getElementById("user_item").style.display="none"; - document.getElementById("org_item").style.display="none"; - document.getElementById("find_id").innerHTML=""; - }else{ - document.getElementById("search_div").style.display="block"; - document.getElementById("search_label_div").style.display="none"; - document.getElementById("dataset_item").style.display="block"; - document.getElementById("issue_item").style.display="block"; - document.getElementById("pr_item").style.display="block"; - document.getElementById("user_item").style.display="block"; - document.getElementById("org_item").style.display="block"; - document.getElementById("find_id").innerHTML=getLabel(isZh,"search_finded"); +function initDiv(isSearchLabel = false) { + if (isSearchLabel) { + document.getElementById("search_div").style.display = "none"; + document.getElementById("search_label_div").style.display = "block"; + document.getElementById("dataset_item").style.display = "none"; + document.getElementById("issue_item").style.display = "none"; + document.getElementById("pr_item").style.display = "none"; + document.getElementById("user_item").style.display = "none"; + document.getElementById("org_item").style.display = "none"; + document.getElementById("find_id").innerHTML = ""; + } else { + document.getElementById("search_div").style.display = "block"; + document.getElementById("search_label_div").style.display = "none"; + document.getElementById("dataset_item").style.display = "block"; + document.getElementById("issue_item").style.display = "block"; + document.getElementById("pr_item").style.display = "block"; + document.getElementById("user_item").style.display = "block"; + document.getElementById("org_item").style.display = "block"; + document.getElementById("find_id").innerHTML = getLabel(isZh, "search_finded"); } } -function doSpcifySearch(tableName,keyword,sortBy="",ascending="false"){ +function doSpcifySearch(tableName, keyword, sortBy = "", ascending = "false") { initDiv(false); $('#searchForm').addClass("hiddenSearch"); - document.getElementById("find_id").innerHTML=getLabel(isZh,"search_finded"); + document.getElementById("find_id").innerHTML = getLabel(isZh, "search_finded"); currentSearchKeyword = keyword; initPageInfo(); currentSearchTableName = tableName; currentSearchSortBy = sortBy; currentSearchAscending = ascending; - OnlySearchLabel =false; - + OnlySearchLabel = false; + page(currentPage); - if(currentSearchTableName != "repository"){ - doSearch("repository",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "repository") { + doSearch("repository", currentSearchKeyword, 1, pageSize, true, "", false); } - if(currentSearchTableName != "issue"){ - doSearch("issue",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "issue") { + doSearch("issue", currentSearchKeyword, 1, pageSize, true, "", false); } - if(currentSearchTableName != "user"){ - doSearch("user",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "user") { + doSearch("user", currentSearchKeyword, 1, pageSize, true, "", false); } - if(currentSearchTableName != "org"){ - doSearch("org",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "org") { + doSearch("org", currentSearchKeyword, 1, pageSize, true, "", false); } - if(currentSearchTableName != "dataset"){ - doSearch("dataset",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "dataset") { + doSearch("dataset", currentSearchKeyword, 1, pageSize, true, "", false); } - if(currentSearchTableName != "pr"){ - doSearch("pr",currentSearchKeyword,1,pageSize,true,"",false); + if (currentSearchTableName != "pr") { + doSearch("pr", currentSearchKeyword, 1, pageSize, true, "", false); } } -function doSearchLabel(tableName,keyword,sortBy="",ascending="false"){ +function doSearchLabel(tableName, keyword, sortBy = "", ascending = "false") { initDiv(true); //document.getElementById("search_div").style.display="none"; //document.getElementById("search_label_div").style.display="block"; - document.getElementById("search_label_div").innerHTML="

#" + keyword + "

"; - + document.getElementById("search_label_div").innerHTML = "

#" + keyword + "

"; + currentSearchKeyword = keyword; initPageInfo(); currentSearchTableName = tableName; currentSearchSortBy = sortBy; currentSearchAscending = ascending; - OnlySearchLabel =true; - + OnlySearchLabel = true; + page(currentPage); } -function searchLabel(tableName,keyword,sortBy="",ascending="false"){ +function searchLabel(tableName, keyword, sortBy = "", ascending = "false") { - sessionStorage.setItem("keyword",keyword); - sessionStorage.setItem("tableName",tableName); - sessionStorage.setItem("searchLabel",true); - sessionStorage.setItem("sortBy",sortBy); - sessionStorage.setItem("ascending",ascending); - console.log("enter label search."); + sessionStorage.setItem("keyword", keyword); + sessionStorage.setItem("tableName", tableName); + sessionStorage.setItem("searchLabel", true); + sessionStorage.setItem("sortBy", sortBy); + sessionStorage.setItem("ascending", ascending); window.open("/all/search/"); } -function doSearch(tableName,keyword,page,pageSize=15,onlyReturnNum=true,sortBy="",OnlySearchLabel=false){ +function doSearch(tableName, keyword, page, pageSize = 15, onlyReturnNum = true, sortBy = "", OnlySearchLabel = false) { var language = "zh-CN"; - if(!isZh){ - language="en-US"; + if (!isZh) { + language = "en-US"; } $.ajax({ - type:"GET", - url:"/all/dosearch/", + type: "GET", + url: "/all/dosearch/", headers: { - authorization:token, - }, - dataType:"json", - data:{ + authorization: token, + }, + dataType: "json", + data: { 'TableName': tableName, 'Key': keyword, 'Page': page, 'PageSize': pageSize, - 'OnlyReturnNum':onlyReturnNum, - 'SortBy':sortBy, - 'OnlySearchLabel':OnlySearchLabel, - 'Ascending':currentSearchAscending, - 'WebTotal':totalNum, - 'PrivateTotal':privateTotal, - 'language':language - }, - async:true, - success:function(json){ - console.log("tableName=" + tableName); - console.log(json); - displayResult(tableName,page,json,onlyReturnNum,keyword); + 'OnlyReturnNum': onlyReturnNum, + 'SortBy': sortBy, + 'OnlySearchLabel': OnlySearchLabel, + 'Ascending': currentSearchAscending, + 'WebTotal': totalNum, + 'PrivateTotal': privateTotal, + 'language': language + }, + async: true, + success: function (json) { + displayResult(tableName, page, json, onlyReturnNum, keyword); }, - error:function(response) { - console.log(response); + error: function (response) { } }); } -function displayResult(tableName,page,jsonResult,onlyReturnNum,keyword){ - if(tableName == "repository") { - displayRepoResult(page,jsonResult,onlyReturnNum,keyword); - } else if (tableName == "issue") { - displayIssueResult(page,jsonResult,onlyReturnNum,keyword); - } else if (tableName == "user") { - displayUserResult(page,jsonResult,onlyReturnNum,keyword); - } else if (tableName == "org") { - displayOrgResult(page,jsonResult,onlyReturnNum,keyword); - } else if (tableName == "dataset") { - displayDataSetResult(page,jsonResult,onlyReturnNum,keyword); - } else if (tableName == "pr") { - displayPrResult(page,jsonResult,onlyReturnNum,keyword); - } - if(!onlyReturnNum){ - console.log("set total num." + tableName); - totalPage =Math.ceil(jsonResult.Total/pageSize); +function displayResult(tableName, page, jsonResult, onlyReturnNum, keyword) { + if (tableName == "repository") { + displayRepoResult(page, jsonResult, onlyReturnNum, keyword); + } else if (tableName == "issue") { + displayIssueResult(page, jsonResult, onlyReturnNum, keyword); + } else if (tableName == "user") { + displayUserResult(page, jsonResult, onlyReturnNum, keyword); + } else if (tableName == "org") { + displayOrgResult(page, jsonResult, onlyReturnNum, keyword); + } else if (tableName == "dataset") { + displayDataSetResult(page, jsonResult, onlyReturnNum, keyword); + } else if (tableName == "pr") { + displayPrResult(page, jsonResult, onlyReturnNum, keyword); + } + if (!onlyReturnNum) { + totalPage = Math.ceil(jsonResult.Total / pageSize); totalNum = jsonResult.Total; privateTotal = jsonResult.PrivateTotal; setPage(page); } - + } -function displayPrResult(page,jsonResult,onlyReturnNum,keyword){ +function displayPrResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#pr_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("pr_item"); //$('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_pr")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_pr")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_pr")).replace('{total}', total)); - setIssueOrPrInnerHtml(data,"pulls"); + setIssueOrPrInnerHtml(data, "pulls"); } } -var categoryDesc={ - "computer_vision":"计算机视觉", - "natural_language_processing":"自然语言处理", - "speech_processing":"语音处理", - "computer_vision_natural_language_processing":"计算机视觉、自然语言处理" +var categoryDesc = { + "computer_vision": "计算机视觉", + "natural_language_processing": "自然语言处理", + "speech_processing": "语音处理", + "computer_vision_natural_language_processing": "计算机视觉、自然语言处理" }; -var categoryENDesc={ - "computer_vision":"computer vision", - "natural_language_processing":"natural language processing", - "speech_processing":"speech processing", - "computer_vision_natural_language_processing":"computer vision and natural language processing" +var categoryENDesc = { + "computer_vision": "computer vision", + "natural_language_processing": "natural language processing", + "speech_processing": "speech processing", + "computer_vision_natural_language_processing": "computer vision and natural language processing" }; -var taskDesc={ - "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":"VR/AR", - "2_d_vision":"2-D视觉", - "2_5_d_vision":"2.5-D视觉", - "3_d_reconstruction":"3D重构", - "image_processing":"图像处理", - "video_processing":"视频处理", - "visual_input_system":"视觉输入系统", - "speech_coding":"语音编码", - "speech_enhancement":"语音增强", - "speech_recognition":"语音识别", - "speech_synthesis":"语音合成" +var taskDesc = { + "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": "VR/AR", + "2_d_vision": "2-D视觉", + "2_5_d_vision": "2.5-D视觉", + "3_d_reconstruction": "3D重构", + "image_processing": "图像处理", + "video_processing": "视频处理", + "visual_input_system": "视觉输入系统", + "speech_coding": "语音编码", + "speech_enhancement": "语音增强", + "speech_recognition": "语音识别", + "speech_synthesis": "语音合成" }; -var taskENDesc={ - "machine_translation":"machine translation", - "question_answering_system":"question answering system", - "information_retrieval":"information retrieval", - "knowledge_graph":"knowledge graph", - "text_annotation":"text annotation", - "text_categorization":"text categorization", - "emotion_analysis":"emotion analysis", - "language_modeling":"language modeling", - "speech_recognition":"speech recognition", - "automatic_digest":"automatic digest", - "information_extraction":"information extraction", - "description_generation":"description generation", - "image_classification":"image classification", - "face_recognition":"face recognition", - "image_search":"image search", - "target_detection":"target detection", - "image_description_generation":"image description generation", - "vehicle_license_plate_recognition":"vehicle license plate recognition", - "medical_image_analysis":"medical image analysis", - "unmanned":"unmanned", - "unmanned_security":"unmanned security", - "drone":"drone", - "vr_ar":"VR/AR", - "2_d_vision":"2.D vision", - "2.5_d_vision":"2.5D vision", - "3_d_reconstruction":"3Dreconstruction", - "image_processing":"image processing", - "video_processing":"video processing", - "visual_input_system":"visual input system", - "speech_coding":"speech coding", - "speech_enhancement":"speech enhancement", - "speech_recognition":"speech recognition", - "speech_synthesis":"speech synthesis" +var taskENDesc = { + "machine_translation": "machine translation", + "question_answering_system": "question answering system", + "information_retrieval": "information retrieval", + "knowledge_graph": "knowledge graph", + "text_annotation": "text annotation", + "text_categorization": "text categorization", + "emotion_analysis": "emotion analysis", + "language_modeling": "language modeling", + "speech_recognition": "speech recognition", + "automatic_digest": "automatic digest", + "information_extraction": "information extraction", + "description_generation": "description generation", + "image_classification": "image classification", + "face_recognition": "face recognition", + "image_search": "image search", + "target_detection": "target detection", + "image_description_generation": "image description generation", + "vehicle_license_plate_recognition": "vehicle license plate recognition", + "medical_image_analysis": "medical image analysis", + "unmanned": "unmanned", + "unmanned_security": "unmanned security", + "drone": "drone", + "vr_ar": "VR/AR", + "2_d_vision": "2.D vision", + "2.5_d_vision": "2.5D vision", + "3_d_reconstruction": "3Dreconstruction", + "image_processing": "image processing", + "video_processing": "video processing", + "visual_input_system": "visual input system", + "speech_coding": "speech coding", + "speech_enhancement": "speech enhancement", + "speech_recognition": "speech recognition", + "speech_synthesis": "speech synthesis" }; -function getCategoryDesc(isZh,key){ +function getCategoryDesc(isZh, key) { var re = key; - if(isZh){ + if (isZh) { re = categoryDesc[key]; - }else{ + } else { re = categoryENDesc[key]; } - if(isEmpty(re)){ + if (isEmpty(re)) { return key; } return re; } -function getTaskDesc(isZh,key){ +function getTaskDesc(isZh, key) { var re = key; - if(isZh){ + if (isZh) { re = taskDesc[key]; - }else{ + } else { re = taskENDesc[key]; } - if(isEmpty(re)){ + if (isEmpty(re)) { return key; } return re; } -function getActiveItem(sort_type){ - console.log("currentSearchSortBy=" + currentSearchSortBy + " sort_type=" + sortBy[sort_type]); - if(currentSearchSortBy == sortBy[sort_type] && currentSearchAscending == sortAscending[sort_type]){ +function getActiveItem(sort_type) { + if (currentSearchSortBy == sortBy[sort_type] && currentSearchAscending == sortAscending[sort_type]) { return "active "; - }else{ + } else { return ""; } } -function displayDataSetResult(page,jsonResult,onlyReturnNum,keyword){ +function displayDataSetResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#dataset_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("dataset_item"); //$('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_dataset")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_dataset")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_dataset")).replace('{total}', total)); var sortHtml = ""; - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_matched_download") + ""; - document.getElementById("sort_type").innerHTML=sortHtml; + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_matched_download") + ""; + document.getElementById("sort_type").innerHTML = sortHtml; var html = ""; var currentTime = new Date().getTime(); - for(var i = 0; i < data.length;i++){ + for (var i = 0; i < data.length; i++) { var recordMap = data[i]; - html += "
"; - html += "
"; - html += "
" ; - if(!isEmpty(recordMap["category"])){ - html += " " + getCategoryDesc(isZh,recordMap["category"]) + ""; + html += "
"; + html += "
"; + html += "
"; + if (!isEmpty(recordMap["category"])) { + html += " " + getCategoryDesc(isZh, recordMap["category"]) + ""; } - if(!isEmpty(recordMap["task"])){ - html += " " + getTaskDesc(isZh,recordMap["task"]) + ""; + if (!isEmpty(recordMap["task"])) { + html += " " + getTaskDesc(isZh, recordMap["task"]) + ""; } - html += " " +recordMap["download_times"] + " "; - html +="
"; + html += " " + recordMap["download_times"] + " "; + html += "
"; html += "
"; - html += " " + recordMap["title"] + ""; - html +=" "; - html +="
"; + html += " " + recordMap["title"] + ""; + html += " "; + html += "
"; html += "
"; html += "

" + recordMap["description"] + "

"; - if(!isEmpty(recordMap["file_name"])){ + if (!isEmpty(recordMap["file_name"])) { html += "

" + recordMap["file_name"] + "

"; } - html +="

"; - html +=" "+ getLabel(isZh,"search_lasted_update") + " " + recordMap["updated_html"]; - html +="

"; - html +="
"; - html +="
"; - html +="
"; + html += "

"; + html += " " + getLabel(isZh, "search_lasted_update") + " " + recordMap["updated_html"]; + html += "

"; + html += "
"; + html += " "; + html += ""; } - document.getElementById("child_search_item").innerHTML=html; + document.getElementById("child_search_item").innerHTML = html; } } -function displayOrgResult(page,jsonResult,onlyReturnNum,keyword){ +function displayOrgResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#org_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("org_item"); //$('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_org")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_org")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_org")).replace('{total}', total)); var sortHtml = ""; - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_letter_asc") + ""; - sortHtml +=""+ getLabel(isZh,"search_letter_desc") + ""; - sortHtml +=""+ getLabel(isZh,"search_lasted_create") + ""; - sortHtml +=""+ getLabel(isZh,"search_early_create") + ""; - document.getElementById("sort_type").innerHTML=sortHtml; + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_letter_asc") + ""; + sortHtml += "" + getLabel(isZh, "search_letter_desc") + ""; + sortHtml += "" + getLabel(isZh, "search_lasted_create") + ""; + sortHtml += "" + getLabel(isZh, "search_early_create") + ""; + document.getElementById("sort_type").innerHTML = sortHtml; var html = ""; var currentTime = new Date().getTime(); - for(var i = 0; i < data.length;i++){ + for (var i = 0; i < data.length; i++) { var recordMap = data[i]; - html += "
"; + html += "
"; html += ""; - html += "
"; + html += " "; html += "
"; html += "

" + recordMap["description"] + "

"; - html +="

"; - if(!isEmpty(recordMap["location"]) && recordMap["location"] != "null"){ - html +=" " + recordMap["location"]; + html += "

"; + if (!isEmpty(recordMap["location"]) && recordMap["location"] != "null") { + html += " " + recordMap["location"]; } - html +=" "; - if(!isEmpty(recordMap["website"]) && recordMap["website"] != "null"){ - html +=" " + "" + recordMap["website"] + ""; + html += " "; + if (!isEmpty(recordMap["website"]) && recordMap["website"] != "null") { + html += " " + "" + recordMap["website"] + ""; } - html +=" "+ getLabel(isZh,"search_add_by") + " "; + html += " " + getLabel(isZh, "search_add_by") + " "; html += recordMap["add_time"] - html +="

"; - html +="
"; - html +="
"; - html +="
"; + html += "

"; + html += "
"; + html += " "; + html += ""; } - document.getElementById("child_search_item").innerHTML=html; + document.getElementById("child_search_item").innerHTML = html; } } -var monthDisplay=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Spt","Oct","Nov","Dec"); -function displayUserResult(page,jsonResult,onlyReturnNum,keyword){ +var monthDisplay = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Spt", "Oct", "Nov", "Dec"); +function displayUserResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#user_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("user_item"); //$('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_user")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_user")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_user")).replace('{total}', total)); var sortHtml = "";//equal user sort by - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_letter_asc") + ""; - sortHtml +=""+ getLabel(isZh,"search_letter_desc") + ""; - sortHtml +=""+ getLabel(isZh,"search_lasted_create") + ""; - sortHtml +=""+ getLabel(isZh,"search_early_create") + ""; + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_letter_asc") + ""; + sortHtml += "" + getLabel(isZh, "search_letter_desc") + ""; + sortHtml += "" + getLabel(isZh, "search_lasted_create") + ""; + sortHtml += "" + getLabel(isZh, "search_early_create") + ""; - document.getElementById("sort_type").innerHTML=sortHtml; + document.getElementById("sort_type").innerHTML = sortHtml; var html = ""; var currentTime = new Date().getTime(); - for(var i = 0; i < data.length;i++){ + for (var i = 0; i < data.length; i++) { var recordMap = data[i]; - html += "
"; + html += "
"; html += ""; - html += "
"; + html += " "; html += "
"; html += "

" + recordMap["description"] + "

"; - html +="

"; - if(!isEmpty(recordMap["email"]) && recordMap["email"] != "null"){ - html +="  " + recordMap["email"] + ""; - } - html +=" "+ getLabel(isZh,"search_add_by") + " "; + html += "

"; + if (!isEmpty(recordMap["email"]) && recordMap["email"] != "null") { + html += "  " + recordMap["email"] + ""; + } + html += " " + getLabel(isZh, "search_add_by") + " "; html += recordMap["add_time"] - html +="

"; - html +="
"; - html +="
"; - html +="
"; + html += "

"; + html += "
"; + html += " "; + html += ""; } - document.getElementById("child_search_item").innerHTML=html; + document.getElementById("child_search_item").innerHTML = html; } } -function setIssueOrPrInnerHtml(data,path){ +function setIssueOrPrInnerHtml(data, path) { var sortHtml = ""; - if(path =="issues"){ - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_lasted") + ""; - }else{ - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_lasted") + ""; + if (path == "issues") { + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_lasted") + ""; + } else { + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_lasted") + ""; } - - document.getElementById("sort_type").innerHTML=sortHtml; + + document.getElementById("sort_type").innerHTML = sortHtml; var html = ""; var currentTime = new Date().getTime(); - for(var i = 0; i < data.length;i++){ + for (var i = 0; i < data.length; i++) { var recordMap = data[i]; - html += "
"; - html += "
"; + html += "
"; + html += "
"; html += "
"; - html += " " + recordMap["name"] + ""; - html +="
"; + html += " " + recordMap["name"] + ""; + html += "
"; html += "
"; html += "

" + recordMap["content"] + "

"; - html +="

"; - html +=" "; - html +=" " + addBlank(recordMap["repoUrl"]) +" #" + recordMap["index"] + "    "; - html +="  "; - if(recordMap["is_closed"] != null && (!(recordMap["is_closed"]) || recordMap["is_closed"]=="f")){ - html += getLabel(isZh,"search_open"); - }else{ - html += getLabel(isZh,"search_closed"); + html += "

"; + html += " "; + html += " " + addBlank(recordMap["repoUrl"]) + " #" + recordMap["index"] + "    "; + html += "  "; + if (recordMap["is_closed"] != null && (!(recordMap["is_closed"]) || recordMap["is_closed"] == "f")) { + html += getLabel(isZh, "search_open"); + } else { + html += getLabel(isZh, "search_closed"); } - html +="      " + recordMap["num_comments"]; - - html +="     "+ getLabel(isZh,"search_lasted_update") + " "+ recordMap["updated_html"]; - - html +="

"; - html +="
"; - html +="
"; - html +="
"; + html += "      " + recordMap["num_comments"]; + + html += "     " + getLabel(isZh, "search_lasted_update") + " " + recordMap["updated_html"]; + + html += "

"; + html += "
"; + html += " "; + html += ""; } - document.getElementById("child_search_item").innerHTML=html; + document.getElementById("child_search_item").innerHTML = html; } -function addBlank(url){ - if(url == null){ +function addBlank(url) { + if (url == null) { return url; - } - var tmps = url.split("/"); - if(tmps.length == 2){ - return tmps[0] + " / " + tmps[1]; - } - return url; + } + var tmps = url.split("/"); + if (tmps.length == 2) { + return tmps[0] + " / " + tmps[1]; + } + return url; } -function displayIssueResult(page,jsonResult,onlyReturnNum,keyword){ +function displayIssueResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#issue_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("issue_item"); //$('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_issue")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_issue")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_issue")).replace('{total}', total)); - setIssueOrPrInnerHtml(data,"issues"); + setIssueOrPrInnerHtml(data, "issues"); } } -function setActivate(name){ +function setActivate(name) { $('#repo_item').removeClass("active"); $('#user_item').removeClass("active"); $('#issue_item').removeClass("active"); $('#dataset_item').removeClass("active"); $('#org_item').removeClass("active"); $('#pr_item').removeClass("active"); - if(name==null){ + if (name == null) { return; } var tmp = "#" + name; $(tmp).addClass("active"); } -function displayRepoResult(page,jsonResult,onlyReturnNum,keyword){ + +function LetterAvatar(name, size, color) { + name = name || ''; + size = size || 60; + var colours = [ + "#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50", + "#f1c40f", "#e67e22", "#e74c3c", "#00bcd4", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d" + ], + nameSplit = String(name).split(' '), + initials, charIndex, colourIndex, canvas, context, dataURI; + if (nameSplit.length == 1) { + initials = nameSplit[0] ? nameSplit[0].charAt(0) : '?'; + } else { + initials = nameSplit[0].charAt(0) + nameSplit[1].charAt(0); + } + if (w.devicePixelRatio) { + size = (size * w.devicePixelRatio); + } + + charIndex = (initials == '?' ? 72 : initials.charCodeAt(0)) - 64; + colourIndex = charIndex % 20; + canvas = d.createElement('canvas'); + canvas.width = size; + canvas.height = size; + context = canvas.getContext("2d"); + + context.fillStyle = color ? color : colours[colourIndex - 1]; + context.fillRect(0, 0, canvas.width, canvas.height); + context.font = Math.round(canvas.width / 2) + "px 'Microsoft Yahei'"; + context.textAlign = "center"; + context.fillStyle = "#FFF"; + context.fillText(initials, size / 2, size / 1.5); + dataURI = canvas.toDataURL(); + canvas = null; + return dataURI; +} +LetterAvatar.transform = function () { + Array.prototype.forEach.call(d.querySelectorAll('img[avatar]'), function (img, name, color) { + name = img.getAttribute('avatar'); + color = img.getAttribute('color'); + img.src = LetterAvatar(name, img.getAttribute('width'), color); + img.removeAttribute('avatar'); + img.setAttribute('alt', name); + }); +}; + +function displayRepoResult(page, jsonResult, onlyReturnNum, keyword) { var data = jsonResult.Result; var total = jsonResult.Total; $('#repo_total').text(total); - if(!onlyReturnNum){ + if (!onlyReturnNum) { setActivate("repo_item"); - // $('#keyword_desc').text(keyword); + // $('#keyword_desc').text(keyword); //$('#obj_desc').text(getLabel(isZh,"search_repo")); //$('#child_total').text(total); - $('#find_title').html(getLabel(isZh,"find_title").replace('{keyword}',keyword).replace('{tablename}',getLabel(isZh,"search_repo")).replace('{total}',total)); + $('#find_title').html(getLabel(isZh, "find_title").replace('{keyword}', keyword).replace('{tablename}', getLabel(isZh, "search_repo")).replace('{total}', total)); var sortHtml = ""; - sortHtml +=""+ getLabel(isZh,"search_matched") + ""; - sortHtml +=""+ getLabel(isZh,"search_lasted") + ""; - sortHtml +=""+ getLabel(isZh,"search_watched") + ""; - sortHtml +=""+ getLabel(isZh,"search_star") + ""; - sortHtml +=""+ getLabel(isZh,"search_fork") + ""; + sortHtml += "" + getLabel(isZh, "search_matched") + ""; + sortHtml += "" + getLabel(isZh, "search_lasted") + ""; + sortHtml += "" + getLabel(isZh, "search_watched") + ""; + sortHtml += "" + getLabel(isZh, "search_star") + ""; + sortHtml += "" + getLabel(isZh, "search_fork") + ""; - document.getElementById("sort_type").innerHTML=sortHtml; + document.getElementById("sort_type").innerHTML = sortHtml; var html = ""; var currentTime = new Date().getTime(); - for(var i = 0; i < data.length;i++){ + for (var i = 0; i < data.length; i++) { var recordMap = data[i]; - html += "
"; - if(!isEmpty(recordMap['avatar'])){ - html += ""; + html += "
"; + if (recordMap['avatar']) { + html += `` + } else { + html += `` } - html += "
"; + + html += "
"; html += "
"; - html += " " + recordMap["owner_name"] +" / " + recordMap["alias"] + ""; - if(recordMap["is_private"]){ - html +=" "; + html += " " + recordMap["owner_name"] + " / " + recordMap["alias"] + ""; + if (recordMap["is_private"]) { + html += " "; } - html +="
"; + html += "
"; html += "
"; html += "

" + recordMap["description"] + "

"; html += "
"; - if(!isEmpty(recordMap["topics"]) && recordMap["topics"] !="null"){ - for(var j = 0; j < recordMap["topics"].length;j++){ + if (!isEmpty(recordMap["topics"]) && recordMap["topics"] != "null") { + for (var j = 0; j < recordMap["topics"].length; j++) { //function searchLabel(tableName,keyword,sortBy="",ascending=false) - html +="
"+ recordMap["hightTopics"][j] + "
"; + html += "
" + recordMap["hightTopics"][j] + "
"; } } - html +="
"; - html +="

"; - html +="  " + recordMap["num_watches"] + "   " + recordMap["num_stars"] + "   " + recordMap["num_forks"] +"  "; - html +="    "+ getLabel(isZh,"search_lasted_update") + " " + recordMap["updated_html"]; - if(!isEmpty(recordMap["lang"])){ + html += "

"; + html += "

"; + html += "  " + recordMap["num_watches"] + "   " + recordMap["num_stars"] + "   " + recordMap["num_forks"] + "  "; + html += "    " + getLabel(isZh, "search_lasted_update") + " " + recordMap["updated_html"]; + if (!isEmpty(recordMap["lang"])) { var lang = recordMap["lang"] var tmpLang = recordMap["lang"].split(","); - if(tmpLang.length>0){ + if (tmpLang.length > 0) { lang = tmpLang[0] } var backColor = "#3572A5"; - if(LanguagesColor[lang] != null){ + if (LanguagesColor[lang] != null) { backColor = LanguagesColor[lang]; } - html +="  " + lang + ""; + html += "  " + lang + ""; } - html +="

"; - html +="
"; - html +="
"; - html +="
"; + html += "

"; + html += " "; + html += " "; + html += ""; } - document.getElementById("child_search_item").innerHTML=html; + document.getElementById("child_search_item").innerHTML = html; + LetterAvatar.transform() } } -function getTime(UpdatedUnix,currentTime){ +function getTime(UpdatedUnix, currentTime) { UpdatedUnix = UpdatedUnix; currentTime = currentTime / 1000; var timeEscSecond = currentTime - UpdatedUnix; - if( timeEscSecond < 0){ + if (timeEscSecond < 0) { timeEscSecond = 1; } - console.log("currentTime=" + currentTime + " updateUnix=" + UpdatedUnix); - - var hours= Math.floor(timeEscSecond / 3600); + + var hours = Math.floor(timeEscSecond / 3600); //计算相差分钟数 var leave2 = Math.floor(timeEscSecond % (3600)); //计算小时数后剩余的秒数 - var minutes= Math.floor(leave2 / 60);//计算相差分钟数 - - var leave3=Math.floor(leave2 % 60); //计算分钟数后剩余的秒数 - var seconds= leave3; - - if(hours == 0 && minutes == 0){ - return seconds + getRepoOrOrg(6,isZh); - }else{ - if(hours > 0){ - if(hours >= 24){ - var days = Math.ceil(hours/24) - if (days >= 30 && days <365){ - return Math.ceil(days/30) + getRepoOrOrg(8,isZh); - }else if(days >= 365){ - return Math.ceil(days/365) + getRepoOrOrg(9,isZh); + var minutes = Math.floor(leave2 / 60);//计算相差分钟数 + + var leave3 = Math.floor(leave2 % 60); //计算分钟数后剩余的秒数 + var seconds = leave3; + + if (hours == 0 && minutes == 0) { + return seconds + getRepoOrOrg(6, isZh); + } else { + if (hours > 0) { + if (hours >= 24) { + var days = Math.ceil(hours / 24) + if (days >= 30 && days < 365) { + return Math.ceil(days / 30) + getRepoOrOrg(8, isZh); + } else if (days >= 365) { + return Math.ceil(days / 365) + getRepoOrOrg(9, isZh); } - return Math.ceil(hours/24) + getRepoOrOrg(7,isZh); - }else{ - return hours + getRepoOrOrg(4,isZh); + return Math.ceil(hours / 24) + getRepoOrOrg(7, isZh); + } else { + return hours + getRepoOrOrg(4, isZh); } - }else{ - return minutes + getRepoOrOrg(5,isZh); + } else { + return minutes + getRepoOrOrg(5, isZh); } } } -function getRepoOrOrg(key,isZhLang){ - if(isZhLang){ +function getRepoOrOrg(key, isZhLang) { + if (isZhLang) { return repoAndOrgZH[key]; - }else{ + } else { return repoAndOrgEN[key]; } } -var repoAndOrgZH={ - "1":"项目", - "2":"成员", - "3":"团队", - "4":"小时前", - "5":"分钟前", - "6":"秒前", - "7":"天前", - "8":"个月前", - "9":"年前" +var repoAndOrgZH = { + "1": "项目", + "2": "成员", + "3": "团队", + "4": "小时前", + "5": "分钟前", + "6": "秒前", + "7": "天前", + "8": "个月前", + "9": "年前" }; -var repoAndOrgEN={ - "1":"repository", - "2":"Members ", - "3":"Teams", - "4":" hours ago", - "5":" minutes ago", - "6":" seconds ago", - "7":" day ago", - "8":" month ago", - "9":" year ago" +var repoAndOrgEN = { + "1": "repository", + "2": "Members ", + "3": "Teams", + "4": " hours ago", + "5": " minutes ago", + "6": " seconds ago", + "7": " day ago", + "8": " month ago", + "9": " year ago" }; -function page(current){ - - currentPage=current; - - doSearch(currentSearchTableName,currentSearchKeyword,current,pageSize,false,currentSearchSortBy,OnlySearchLabel); - } - - function nextPage(){ - currentPage = currentPage+1; - console.log("currentPage=" + currentPage); - +function page(current) { + + currentPage = current; + + doSearch(currentSearchTableName, currentSearchKeyword, current, pageSize, false, currentSearchSortBy, OnlySearchLabel); +} + +function nextPage() { + currentPage = currentPage + 1; page(currentPage); - } - - function prePage(){ - console.log("currentPage=" + currentPage); - if(currentPage > 1){ - currentPage = currentPage-1; - console.log("currentPage=" + (currentPage)); - page(currentPage); - } - } - -function getXPosition(e){ - var x=e.offsetLeft; - while(e=e.offsetParent) - { - x+=e.offsetLeft; - } - return x+20;//-260防止屏幕超出 +} + +function prePage() { + if (currentPage > 1) { + currentPage = currentPage - 1; + page(currentPage); + } +} + +function getXPosition(e) { + var x = e.offsetLeft; + while (e = e.offsetParent) { + x += e.offsetLeft; + } + return x + 20;//-260防止屏幕超出 } //获取y坐标 -function getYPosition(e){ - var y=e.offsetTop; - while(e=e.offsetParent) - { - y+=e.offsetTop; - } - return y+20;//80为input高度 +function getYPosition(e) { + var y = e.offsetTop; + while (e = e.offsetParent) { + y += e.offsetTop; + } + return y + 20;//80为input高度 } - function goPage(event){ - - var inputpage = document.getElementById("inputpage_div") - var left = getXPosition(event.target); - var top = getYPosition(event.target); - var goNum = $('#inputpage').val(); - if (goNum<=0){ - showTip(getLabel(isZh,"search_input_large_0"),"warning",left+5,top); - } - else if(goNum<=totalPage){ - page(parseInt(goNum,10)); - } - else{ - showTip(getLabel(isZh,"search_input_maxed"),"warning",left+5,top); - } - } - - function showTip(tip, type,left,top) { +function goPage(event) { + + var inputpage = document.getElementById("inputpage_div") + var left = getXPosition(event.target); + var top = getYPosition(event.target); + var goNum = $('#inputpage').val(); + if (goNum <= 0) { + showTip(getLabel(isZh, "search_input_large_0"), "warning", left + 5, top); + } + else if (goNum <= totalPage) { + page(parseInt(goNum, 10)); + } + else { + showTip(getLabel(isZh, "search_input_maxed"), "warning", left + 5, top); + } +} + +function showTip(tip, type, left, top) { var $tip = $('#tipmsg'); var tipmsg = document.getElementById("tipmsg") - var style="z-index:10024;top:" + top + "px;left:" + left + "px;position:absolute;width:200px;height:60px;vertical-align:middle;"; - console.log(style); + var style = "z-index:10024;top:" + top + "px;left:" + left + "px;position:absolute;width:200px;height:60px;vertical-align:middle;"; tipmsg.style = style; - var html ="

" + tip + "

" + var html = "

" + tip + "

" $tip.stop(true).prop('class', 'alert alert-' + type).html(html).fadeIn(500).delay(2000).fadeOut(500); - } - - function setPage(currentPage){ - console.log("totalPage=" + totalPage); - var html =""; - console.log("currentPage=" + currentPage); - console.log("privateTotal=" + privateTotal); - startIndex = currentPage -1; - if(startIndex < 1){ +} + +function setPage(currentPage) { + var html = ""; + startIndex = currentPage - 1; + if (startIndex < 1) { startIndex = 1; } endIndex = currentPage + 2; - if(endIndex >= totalPage){ + if (endIndex >= totalPage) { endIndex = totalPage; } - html += "" + getLabel(isZh,"search_input_total") + " " + totalNum + " " + getLabel(isZh,"search_srtip") + "" - if(currentPage > 1){ - html += "" + getLabel(isZh,"search_home_page") + ""; + html += "" + getLabel(isZh, "search_input_total") + " " + totalNum + " " + getLabel(isZh, "search_srtip") + "" + if (currentPage > 1) { + html += "" + getLabel(isZh, "search_home_page") + ""; html += ""; - }else{ - html += "" + getLabel(isZh,"search_home_page") + ""; + } else { + html += "" + getLabel(isZh, "search_home_page") + ""; html += ""; } - - for(var i=startIndex; i <= endIndex; i++){ - var page_i = i; - if(page_i > totalPage){ + + for (var i = startIndex; i <= endIndex; i++) { + var page_i = i; + if (page_i > totalPage) { break; } - if( page_i == currentPage){ - html += "" + page_i + ""; - }else{ - html += "" + page_i + ""; + if (page_i == currentPage) { + html += "" + page_i + ""; + } else { + html += "" + page_i + ""; } } - if (endIndex < totalPage-1){ + if (endIndex < totalPage - 1) { html += "..."; - html += "" + totalPage + ""; + html += "" + totalPage + ""; } - if(currentPage >=totalPage){ + if (currentPage >= totalPage) { html += ""; - html += "" + getLabel(isZh,"search_last_page") + ""; - }else{ + html += "" + getLabel(isZh, "search_last_page") + ""; + } else { html += ""; - html += "" + getLabel(isZh,"search_last_page") + ""; + html += "" + getLabel(isZh, "search_last_page") + ""; } - html +="
" + getLabel(isZh,"search_go_to") + "
" + getLabel(isZh,"search_go_page") + "
"; - console.log("html=" + html) - document.getElementById("page_menu").innerHTML=html; - $('#inputpage').on('keypress',function(event){ - if(event.keyCode == 13){ + html += "
" + getLabel(isZh, "search_go_to") + "
" + getLabel(isZh, "search_go_page") + "
"; + document.getElementById("page_menu").innerHTML = html; + $('#inputpage').on('keypress', function (event) { + if (event.keyCode == 13) { goPage(event); } - }); - } + }); +} -$('#keyword_input').on('keypress',function(event){ - if(event.keyCode == 13){ +$('#keyword_input').on('keypress', function (event) { + if (event.keyCode == 13) { search(); } }); @@ -944,369 +971,365 @@ $('#keyword_input').on('keypress',function(event){ var LanguagesColor = { - "1C Enterprise": "#814CCC", - "ABAP": "#E8274B", - "AGS Script": "#B9D9FF", - "AMPL": "#E6EFBB", - "ANTLR": "#9DC3FF", - "API Blueprint": "#2ACCA8", - "APL": "#5A8164", - "ASP": "#6a40fd", - "ATS": "#1ac620", - "ActionScript": "#882B0F", - "Ada": "#02f88c", - "Agda": "#315665", - "Alloy": "#64C800", - "AngelScript": "#C7D7DC", - "AppleScript": "#101F1F", - "Arc": "#aa2afe", - "AspectJ": "#a957b0", - "Assembly": "#6E4C13", - "Asymptote": "#4a0c0c", - "AutoHotkey": "#6594b9", - "AutoIt": "#1C3552", - "Ballerina": "#FF5000", - "Batchfile": "#C1F12E", - "BlitzMax": "#cd6400", - "Boo": "#d4bec1", - "Brainfuck": "#2F2530", - "C": "#555555", - "C#": "#178600", - "C++": "#f34b7d", - "CSS": "#563d7c", - "Ceylon": "#dfa535", - "Chapel": "#8dc63f", - "Cirru": "#ccccff", - "Clarion": "#db901e", - "Clean": "#3F85AF", - "Click": "#E4E6F3", - "Clojure": "#db5855", - "CoffeeScript": "#244776", - "ColdFusion": "#ed2cd6", - "Common Lisp": "#3fb68b", - "Common Workflow Language": "#B5314C", - "Component Pascal": "#B0CE4E", - "Crystal": "#000100", - "Cuda": "#3A4E3A", - "D": "#ba595e", - "DM": "#447265", - "Dart": "#00B4AB", - "DataWeave": "#003a52", - "Dhall": "#dfafff", - "Dockerfile": "#384d54", - "Dogescript": "#cca760", - "Dylan": "#6c616e", - "E": "#ccce35", - "ECL": "#8a1267", - "EQ": "#a78649", - "Eiffel": "#946d57", - "Elixir": "#6e4a7e", - "Elm": "#60B5CC", - "Emacs Lisp": "#c065db", - "EmberScript": "#FFF4F3", - "Erlang": "#B83998", - "F#": "#b845fc", - "F*": "#572e30", - "FLUX": "#88ccff", - "Factor": "#636746", - "Fancy": "#7b9db4", - "Fantom": "#14253c", - "Faust": "#c37240", - "Forth": "#341708", - "Fortran": "#4d41b1", - "FreeMarker": "#0050b2", - "Frege": "#00cafe", - "G-code": "#D08CF2", - "GAML": "#FFC766", - "GDScript": "#355570", - "Game Maker Language": "#71b417", - "Genie": "#fb855d", - "Gherkin": "#5B2063", - "Glyph": "#c1ac7f", - "Gnuplot": "#f0a9f0", - "Go": "#00ADD8", - "Golo": "#88562A", - "Gosu": "#82937f", - "Grammatical Framework": "#79aa7a", - "Groovy": "#e69f56", - "HTML": "#e34c26", - "Hack": "#878787", - "Harbour": "#0e60e3", - "Haskell": "#5e5086", - "Haxe": "#df7900", - "HiveQL": "#dce200", - "HolyC": "#ffefaf", - "Hy": "#7790B2", - "IDL": "#a3522f", - "IGOR Pro": "#0000cc", - "Idris": "#b30000", - "Io": "#a9188d", - "Ioke": "#078193", - "Isabelle": "#FEFE00", - "J": "#9EEDFF", - "JSONiq": "#40d47e", - "Java": "#b07219", - "JavaScript": "#f1e05a", - "Jolie": "#843179", - "Jsonnet": "#0064bd", - "Julia": "#a270ba", - "Jupyter Notebook": "#DA5B0B", - "KRL": "#28430A", - "Kotlin": "#F18E33", - "LFE": "#4C3023", - "LLVM": "#185619", - "LOLCODE": "#cc9900", - "LSL": "#3d9970", - "Lasso": "#999999", - "Lex": "#DBCA00", - "LiveScript": "#499886", - "LookML": "#652B81", - "Lua": "#000080", - "MATLAB": "#e16737", - "MAXScript": "#00a6a6", - "MLIR": "#5EC8DB", - "MQL4": "#62A8D6", - "MQL5": "#4A76B8", - "MTML": "#b7e1f4", - "Makefile": "#427819", - "Mask": "#f97732", - "Max": "#c4a79c", - "Mercury": "#ff2b2b", - "Meson": "#007800", - "Metal": "#8f14e9", - "Mirah": "#c7a938", - "Modula-3": "#223388", - "NCL": "#28431f", - "Nearley": "#990000", - "Nemerle": "#3d3c6e", - "NetLinx": "#0aa0ff", - "NetLinx+ERB": "#747faa", - "NetLogo": "#ff6375", - "NewLisp": "#87AED7", - "Nextflow": "#3ac486", - "Nim": "#37775b", - "Nit": "#009917", - "Nix": "#7e7eff", - "Nu": "#c9df40", - "OCaml": "#3be133", - "ObjectScript": "#424893", - "Objective-C": "#438eff", - "Objective-C++": "#6866fb", - "Objective-J": "#ff0c5a", - "Odin": "#60AFFE", - "Omgrofl": "#cabbff", - "Opal": "#f7ede0", - "OpenQASM": "#AA70FF", - "Oxygene": "#cdd0e3", - "Oz": "#fab738", - "P4": "#7055b5", - "PHP": "#4F5D95", - "PLSQL": "#dad8d8", - "Pan": "#cc0000", - "Papyrus": "#6600cc", - "Parrot": "#f3ca0a", - "Pascal": "#E3F171", - "Pawn": "#dbb284", - "Pep8": "#C76F5B", - "Perl": "#0298c3", - "PigLatin": "#fcd7de", - "Pike": "#005390", - "PogoScript": "#d80074", - "PostScript": "#da291c", - "PowerBuilder": "#8f0f8d", - "PowerShell": "#012456", - "Processing": "#0096D8", - "Prolog": "#74283c", - "Propeller Spin": "#7fa2a7", - "Puppet": "#302B6D", - "PureBasic": "#5a6986", - "PureScript": "#1D222D", - "Python": "#3572A5", - "QML": "#44a51c", - "Quake": "#882233", - "R": "#198CE7", - "RAML": "#77d9fb", - "RUNOFF": "#665a4e", - "Racket": "#3c5caa", - "Ragel": "#9d5200", - "Raku": "#0000fb", - "Rascal": "#fffaa0", - "Reason": "#ff5847", - "Rebol": "#358a5b", - "Red": "#f50000", - "Ren'Py": "#ff7f7f", - "Ring": "#2D54CB", - "Riot": "#A71E49", - "Roff": "#ecdebe", - "Rouge": "#cc0088", - "Ruby": "#701516", - "Rust": "#dea584", - "SAS": "#B34936", - "SQF": "#3F3F3F", - "SRecode Template": "#348a34", - "SaltStack": "#646464", - "Scala": "#c22d40", - "Scheme": "#1e4aec", - "Self": "#0579aa", - "Shell": "#89e051", - "Shen": "#120F14", - "Slash": "#007eff", - "Slice": "#003fa2", - "SmPL": "#c94949", - "Smalltalk": "#596706", - "Solidity": "#AA6746", - "SourcePawn": "#5c7611", - "Squirrel": "#800000", - "Stan": "#b2011d", - "Standard ML": "#dc566d", - "Starlark": "#76d275", - "SuperCollider": "#46390b", - "Swift": "#ffac45", - "SystemVerilog": "#DAE1C2", - "TI Program": "#A0AA87", - "Tcl": "#e4cc98", - "TeX": "#3D6117", - "Terra": "#00004c", - "Turing": "#cf142b", - "TypeScript": "#2b7489", - "UnrealScript": "#a54c4d", - "V": "#5d87bd", - "VBA": "#867db1", - "VBScript": "#15dcdc", - "VCL": "#148AA8", - "VHDL": "#adb2cb", - "Vala": "#fbe5cd", - "Verilog": "#b2b7f8", - "Vim script": "#199f4b", - "Visual Basic .NET": "#945db7", - "Volt": "#1F1F1F", - "Vue": "#2c3e50", - "WebAssembly": "#04133b", - "Wollok": "#a23738", - "X10": "#4B6BEF", - "XC": "#99DA07", - "XQuery": "#5232e7", - "XSLT": "#EB8CEB", - "YARA": "#220000", - "YASnippet": "#32AB90", - "Yacc": "#4B6C4B", - "ZAP": "#0d665e", - "ZIL": "#dc75e5", - "ZenScript": "#00BCD1", - "Zephir": "#118f9e", - "Zig": "#ec915c", - "eC": "#913960", - "mIRC Script": "#926059", - "mcfunction": "#E22837", - "nesC": "#94B0C7", - "ooc": "#b0b77e", - "q": "#0040cd", - "sed": "#64b970", - "wdl": "#42f1f4", - "wisp": "#7582D1", - "xBase": "#403a40", + "1C Enterprise": "#814CCC", + "ABAP": "#E8274B", + "AGS Script": "#B9D9FF", + "AMPL": "#E6EFBB", + "ANTLR": "#9DC3FF", + "API Blueprint": "#2ACCA8", + "APL": "#5A8164", + "ASP": "#6a40fd", + "ATS": "#1ac620", + "ActionScript": "#882B0F", + "Ada": "#02f88c", + "Agda": "#315665", + "Alloy": "#64C800", + "AngelScript": "#C7D7DC", + "AppleScript": "#101F1F", + "Arc": "#aa2afe", + "AspectJ": "#a957b0", + "Assembly": "#6E4C13", + "Asymptote": "#4a0c0c", + "AutoHotkey": "#6594b9", + "AutoIt": "#1C3552", + "Ballerina": "#FF5000", + "Batchfile": "#C1F12E", + "BlitzMax": "#cd6400", + "Boo": "#d4bec1", + "Brainfuck": "#2F2530", + "C": "#555555", + "C#": "#178600", + "C++": "#f34b7d", + "CSS": "#563d7c", + "Ceylon": "#dfa535", + "Chapel": "#8dc63f", + "Cirru": "#ccccff", + "Clarion": "#db901e", + "Clean": "#3F85AF", + "Click": "#E4E6F3", + "Clojure": "#db5855", + "CoffeeScript": "#244776", + "ColdFusion": "#ed2cd6", + "Common Lisp": "#3fb68b", + "Common Workflow Language": "#B5314C", + "Component Pascal": "#B0CE4E", + "Crystal": "#000100", + "Cuda": "#3A4E3A", + "D": "#ba595e", + "DM": "#447265", + "Dart": "#00B4AB", + "DataWeave": "#003a52", + "Dhall": "#dfafff", + "Dockerfile": "#384d54", + "Dogescript": "#cca760", + "Dylan": "#6c616e", + "E": "#ccce35", + "ECL": "#8a1267", + "EQ": "#a78649", + "Eiffel": "#946d57", + "Elixir": "#6e4a7e", + "Elm": "#60B5CC", + "Emacs Lisp": "#c065db", + "EmberScript": "#FFF4F3", + "Erlang": "#B83998", + "F#": "#b845fc", + "F*": "#572e30", + "FLUX": "#88ccff", + "Factor": "#636746", + "Fancy": "#7b9db4", + "Fantom": "#14253c", + "Faust": "#c37240", + "Forth": "#341708", + "Fortran": "#4d41b1", + "FreeMarker": "#0050b2", + "Frege": "#00cafe", + "G-code": "#D08CF2", + "GAML": "#FFC766", + "GDScript": "#355570", + "Game Maker Language": "#71b417", + "Genie": "#fb855d", + "Gherkin": "#5B2063", + "Glyph": "#c1ac7f", + "Gnuplot": "#f0a9f0", + "Go": "#00ADD8", + "Golo": "#88562A", + "Gosu": "#82937f", + "Grammatical Framework": "#79aa7a", + "Groovy": "#e69f56", + "HTML": "#e34c26", + "Hack": "#878787", + "Harbour": "#0e60e3", + "Haskell": "#5e5086", + "Haxe": "#df7900", + "HiveQL": "#dce200", + "HolyC": "#ffefaf", + "Hy": "#7790B2", + "IDL": "#a3522f", + "IGOR Pro": "#0000cc", + "Idris": "#b30000", + "Io": "#a9188d", + "Ioke": "#078193", + "Isabelle": "#FEFE00", + "J": "#9EEDFF", + "JSONiq": "#40d47e", + "Java": "#b07219", + "JavaScript": "#f1e05a", + "Jolie": "#843179", + "Jsonnet": "#0064bd", + "Julia": "#a270ba", + "Jupyter Notebook": "#DA5B0B", + "KRL": "#28430A", + "Kotlin": "#F18E33", + "LFE": "#4C3023", + "LLVM": "#185619", + "LOLCODE": "#cc9900", + "LSL": "#3d9970", + "Lasso": "#999999", + "Lex": "#DBCA00", + "LiveScript": "#499886", + "LookML": "#652B81", + "Lua": "#000080", + "MATLAB": "#e16737", + "MAXScript": "#00a6a6", + "MLIR": "#5EC8DB", + "MQL4": "#62A8D6", + "MQL5": "#4A76B8", + "MTML": "#b7e1f4", + "Makefile": "#427819", + "Mask": "#f97732", + "Max": "#c4a79c", + "Mercury": "#ff2b2b", + "Meson": "#007800", + "Metal": "#8f14e9", + "Mirah": "#c7a938", + "Modula-3": "#223388", + "NCL": "#28431f", + "Nearley": "#990000", + "Nemerle": "#3d3c6e", + "NetLinx": "#0aa0ff", + "NetLinx+ERB": "#747faa", + "NetLogo": "#ff6375", + "NewLisp": "#87AED7", + "Nextflow": "#3ac486", + "Nim": "#37775b", + "Nit": "#009917", + "Nix": "#7e7eff", + "Nu": "#c9df40", + "OCaml": "#3be133", + "ObjectScript": "#424893", + "Objective-C": "#438eff", + "Objective-C++": "#6866fb", + "Objective-J": "#ff0c5a", + "Odin": "#60AFFE", + "Omgrofl": "#cabbff", + "Opal": "#f7ede0", + "OpenQASM": "#AA70FF", + "Oxygene": "#cdd0e3", + "Oz": "#fab738", + "P4": "#7055b5", + "PHP": "#4F5D95", + "PLSQL": "#dad8d8", + "Pan": "#cc0000", + "Papyrus": "#6600cc", + "Parrot": "#f3ca0a", + "Pascal": "#E3F171", + "Pawn": "#dbb284", + "Pep8": "#C76F5B", + "Perl": "#0298c3", + "PigLatin": "#fcd7de", + "Pike": "#005390", + "PogoScript": "#d80074", + "PostScript": "#da291c", + "PowerBuilder": "#8f0f8d", + "PowerShell": "#012456", + "Processing": "#0096D8", + "Prolog": "#74283c", + "Propeller Spin": "#7fa2a7", + "Puppet": "#302B6D", + "PureBasic": "#5a6986", + "PureScript": "#1D222D", + "Python": "#3572A5", + "QML": "#44a51c", + "Quake": "#882233", + "R": "#198CE7", + "RAML": "#77d9fb", + "RUNOFF": "#665a4e", + "Racket": "#3c5caa", + "Ragel": "#9d5200", + "Raku": "#0000fb", + "Rascal": "#fffaa0", + "Reason": "#ff5847", + "Rebol": "#358a5b", + "Red": "#f50000", + "Ren'Py": "#ff7f7f", + "Ring": "#2D54CB", + "Riot": "#A71E49", + "Roff": "#ecdebe", + "Rouge": "#cc0088", + "Ruby": "#701516", + "Rust": "#dea584", + "SAS": "#B34936", + "SQF": "#3F3F3F", + "SRecode Template": "#348a34", + "SaltStack": "#646464", + "Scala": "#c22d40", + "Scheme": "#1e4aec", + "Self": "#0579aa", + "Shell": "#89e051", + "Shen": "#120F14", + "Slash": "#007eff", + "Slice": "#003fa2", + "SmPL": "#c94949", + "Smalltalk": "#596706", + "Solidity": "#AA6746", + "SourcePawn": "#5c7611", + "Squirrel": "#800000", + "Stan": "#b2011d", + "Standard ML": "#dc566d", + "Starlark": "#76d275", + "SuperCollider": "#46390b", + "Swift": "#ffac45", + "SystemVerilog": "#DAE1C2", + "TI Program": "#A0AA87", + "Tcl": "#e4cc98", + "TeX": "#3D6117", + "Terra": "#00004c", + "Turing": "#cf142b", + "TypeScript": "#2b7489", + "UnrealScript": "#a54c4d", + "V": "#5d87bd", + "VBA": "#867db1", + "VBScript": "#15dcdc", + "VCL": "#148AA8", + "VHDL": "#adb2cb", + "Vala": "#fbe5cd", + "Verilog": "#b2b7f8", + "Vim script": "#199f4b", + "Visual Basic .NET": "#945db7", + "Volt": "#1F1F1F", + "Vue": "#2c3e50", + "WebAssembly": "#04133b", + "Wollok": "#a23738", + "X10": "#4B6BEF", + "XC": "#99DA07", + "XQuery": "#5232e7", + "XSLT": "#EB8CEB", + "YARA": "#220000", + "YASnippet": "#32AB90", + "Yacc": "#4B6C4B", + "ZAP": "#0d665e", + "ZIL": "#dc75e5", + "ZenScript": "#00BCD1", + "Zephir": "#118f9e", + "Zig": "#ec915c", + "eC": "#913960", + "mIRC Script": "#926059", + "mcfunction": "#E22837", + "nesC": "#94B0C7", + "ooc": "#b0b77e", + "q": "#0040cd", + "sed": "#64b970", + "wdl": "#42f1f4", + "wisp": "#7582D1", + "xBase": "#403a40", } -function getLabel(isZh,key){ - if(isZh){ +function getLabel(isZh, key) { + if (isZh) { return zhCN[key] - }else{ + } else { return esUN[key] } } -var zhCN={ - "search":"搜索", - "search_repo":"项目", - "search_dataset":"数据集", - "search_issue":"任务", - "search_pr":"合并请求", - "search_user":"用户", - "search_org":"组织", - "search_finded":"找到", - "search_matched":"最佳匹配", - "search_matched_download":"下载次数", - "search_lasted_update":"最后更新于", - "search_letter_asc":"字母顺序排序", - "search_letter_desc":"字母逆序排序", - "search_lasted_create":"最近创建", - "search_early_create":"最早创建", - "search_add_by":"加入于", - "search_lasted":"最近更新", - "search_open":"开启中", - "search_closed":"已关闭", - "search_watched":"关注数", - "search_star":"点赞数", - "search_fork":"Fork数", - "search_input_large_0":"请输入大于0的数值。", - "search_input_maxed":"不能超出总页数。", - "search_input_total":"共", - "search_srtip":"条", - "search_home_page":"首页", - "search_last_page":"末页", - "search_go_to":"前往", - "search_go_page":"页", - "find_title":"“{keyword}”相关{tablename}约为{total}个", - "search_empty":"请输入任意关键字开始搜索。" - } - - var esUN={ - "search":"Search", - "search_repo":"Repository", - "search_dataset":"DataSet", - "search_issue":"Issue", - "search_pr":"Pull Request", - "search_user":"User", - "search_org":"Organization", - "search_finded":"Find", - "search_matched":"Best Match", - "search_matched_download":"Most downloads", - "search_lasted_update":"Updated ", - "search_letter_asc":"Alphabetically", - "search_letter_desc":"Reverse alphabetically", - "search_lasted_create":"Recently created", - "search_early_create":"First created", - "search_add_by":"Joined on", - "search_lasted":"Recently updated", - "search_open":"Open", - "search_closed":"Closed", - "search_watched":"Watches", - "search_star":"Stars", - "search_fork":"Forks", - "search_input_large_0":"Please enter a value greater than 0.", - "search_input_maxed":"Cannot exceed total pages.", - "search_input_total":"Total", - "search_srtip":"", - "search_home_page":"First", - "search_last_page":"Last", - "search_go_to":"Go", - "search_go_page":"Page", - "find_title":" {total} \"{keyword}\" related {tablename}", - "search_empty":"Please enter any keyword to start the search." - } - initDiv(false); - document.onreadystatechange = function() { - if (document.readyState === "complete") { - var tmpSearchLabel = sessionStorage.getItem("searchLabel"); - console.log("tmpSearchLabel=" + tmpSearchLabel); - if(tmpSearchLabel){ - console.log("search label...."); - sessionStorage.removeItem("searchLabel"); - doSearchLabel(sessionStorage.getItem("tableName"),sessionStorage.getItem("keyword"),sessionStorage.getItem("sortBy"),sessionStorage.getItem("ascending")); - }else{ - var specifySearch = sessionStorage.getItem("specifySearch"); - if(specifySearch){ - sessionStorage.removeItem("specifySearch"); - console.log("search sepcial keyword=...." + sessionStorage.getItem("keyword")); - document.getElementById("keyword_input").value = sessionStorage.getItem("keyword"); - doSpcifySearch(sessionStorage.getItem("tableName"),sessionStorage.getItem("keyword"),sessionStorage.getItem("sortBy"),sessionStorage.getItem("ascending")); - }else{ - console.log("normal search...."); - search(); - } - +var zhCN = { + "search": "搜索", + "search_repo": "项目", + "search_dataset": "数据集", + "search_issue": "任务", + "search_pr": "合并请求", + "search_user": "用户", + "search_org": "组织", + "search_finded": "找到", + "search_matched": "最佳匹配", + "search_matched_download": "下载次数", + "search_lasted_update": "最后更新于", + "search_letter_asc": "字母顺序排序", + "search_letter_desc": "字母逆序排序", + "search_lasted_create": "最近创建", + "search_early_create": "最早创建", + "search_add_by": "加入于", + "search_lasted": "最近更新", + "search_open": "开启中", + "search_closed": "已关闭", + "search_watched": "关注数", + "search_star": "点赞数", + "search_fork": "Fork数", + "search_input_large_0": "请输入大于0的数值。", + "search_input_maxed": "不能超出总页数。", + "search_input_total": "共", + "search_srtip": "条", + "search_home_page": "首页", + "search_last_page": "末页", + "search_go_to": "前往", + "search_go_page": "页", + "find_title": "“{keyword}”相关{tablename}约为{total}个", + "search_empty": "请输入任意关键字开始搜索。" +} + +var esUN = { + "search": "Search", + "search_repo": "Repository", + "search_dataset": "DataSet", + "search_issue": "Issue", + "search_pr": "Pull Request", + "search_user": "User", + "search_org": "Organization", + "search_finded": "Find", + "search_matched": "Best Match", + "search_matched_download": "Most downloads", + "search_lasted_update": "Updated ", + "search_letter_asc": "Alphabetically", + "search_letter_desc": "Reverse alphabetically", + "search_lasted_create": "Recently created", + "search_early_create": "First created", + "search_add_by": "Joined on", + "search_lasted": "Recently updated", + "search_open": "Open", + "search_closed": "Closed", + "search_watched": "Watches", + "search_star": "Stars", + "search_fork": "Forks", + "search_input_large_0": "Please enter a value greater than 0.", + "search_input_maxed": "Cannot exceed total pages.", + "search_input_total": "Total", + "search_srtip": "", + "search_home_page": "First", + "search_last_page": "Last", + "search_go_to": "Go", + "search_go_page": "Page", + "find_title": " {total} \"{keyword}\" related {tablename}", + "search_empty": "Please enter any keyword to start the search." +} +initDiv(false); +document.onreadystatechange = function () { + if (document.readyState === "complete") { + var tmpSearchLabel = sessionStorage.getItem("searchLabel"); + if (tmpSearchLabel) { + sessionStorage.removeItem("searchLabel"); + doSearchLabel(sessionStorage.getItem("tableName"), sessionStorage.getItem("keyword"), sessionStorage.getItem("sortBy"), sessionStorage.getItem("ascending")); + } else { + var specifySearch = sessionStorage.getItem("specifySearch"); + if (specifySearch) { + sessionStorage.removeItem("specifySearch"); + document.getElementById("keyword_input").value = sessionStorage.getItem("keyword"); + doSpcifySearch(sessionStorage.getItem("tableName"), sessionStorage.getItem("keyword"), sessionStorage.getItem("sortBy"), sessionStorage.getItem("ascending")); + } else { + search(); } + } } +} + - diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 0c280b0cb..a37d23158 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -947,6 +947,15 @@ func RegisterRoutes(m *macaron.Macaron) { }) }) }, reqRepoReader(models.UnitTypeCloudBrain)) + m.Group("/grampus", func() { + m.Group("/train-job", func() { + m.Group("/:jobid", func() { + m.Get("", repo.GetModelArtsTrainJobVersion) + m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.GrampusStopJob) + m.Get("/log", repo_ext.GrampusGetLog) + }) + }) + }, reqRepoReader(models.UnitTypeCloudBrain)) }, repoAssignment()) }) diff --git a/routers/api/v1/repo/cloudbrain_dashboard.go b/routers/api/v1/repo/cloudbrain_dashboard.go old mode 100644 new mode 100755 index f102a0f05..cc125c97f --- a/routers/api/v1/repo/cloudbrain_dashboard.go +++ b/routers/api/v1/repo/cloudbrain_dashboard.go @@ -103,7 +103,7 @@ func GetAllCloudbrainsOverview(ctx *context.Context) { if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo { cloudBrainTwoDuration = cloudBrainTwoDuration + cloudbrain.Cloudbrain.Duration } - if cloudbrain.Cloudbrain.Type == models.TypeIntelligentNet { + if cloudbrain.Cloudbrain.Type == models.TypeC2Net { intelligentNetDuration = intelligentNetDuration + cloudbrain.Cloudbrain.Duration } @@ -540,7 +540,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) { cloudTwoJobTypeRes[cloudbrain.JobType] += 1 } } - if cloudbrain.Cloudbrain.Type == models.TypeIntelligentNet { + if cloudbrain.Cloudbrain.Type == models.TypeC2Net { if _, ok := intelligentNetJobTypeRes[cloudbrain.JobType]; !ok { intelligentNetJobTypeRes[cloudbrain.JobType] = 1 } else { @@ -1287,7 +1287,7 @@ func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string { return ctx.Tr("repo.cloudbrain1") } else if rs.Cloudbrain.Type == models.TypeCloudBrainTwo { return ctx.Tr("repo.cloudbrain2") - } else if rs.Cloudbrain.Type == models.TypeIntelligentNet { + } else if rs.Cloudbrain.Type == models.TypeC2Net { return ctx.Tr("repo.intelligent_net") } else { return ctx.Tr("repo.cloudbrain_untype") diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go index c14976282..2a0ce19db 100755 --- a/routers/api/v1/repo/modelarts.go +++ b/routers/api/v1/repo/modelarts.go @@ -6,6 +6,8 @@ package repo import ( + "code.gitea.io/gitea/modules/grampus" + "encoding/json" "net/http" "strconv" "strings" @@ -125,7 +127,8 @@ func GetModelArtsTrainJob(ctx *context.APIContext) { func GetModelArtsTrainJobVersion(ctx *context.APIContext) { var ( - err error + err error + aiCenterName string ) jobID := ctx.Params(":jobid") @@ -167,7 +170,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { log.Error("UpdateJob failed:", err) } } - } else { + } else if job.Type == models.TypeCloudBrainTwo { result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10)) if err != nil { ctx.NotFound(err) @@ -189,12 +192,50 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { if err != nil { log.Error("UpdateJob failed:", err) } + } else if job.Type == models.TypeC2Net { + result, err := grampus.GetJob(jobID) + if err != nil { + log.Error("GetJob(%s) failed:%v", job.JobName, err) + ctx.NotFound(err) + return + } + + if job.StartTime == 0 && result.JobInfo.StartedAt > 0 { + job.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt) + } + job.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) + job.Duration = result.JobInfo.RunSec + job.TrainJobDuration = models.ConvertDurationToStr(job.Duration) + + if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 { + job.EndTime = job.StartTime.Add(job.Duration) + } + job.CorrectCreateUnix() + + if len(job.AiCenter) == 0 { + if len(result.JobInfo.Tasks) > 0 { + if len(result.JobInfo.Tasks[0].CenterID) > 0 && len(result.JobInfo.Tasks[0].CenterName) > 0 { + job.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0] + aiCenterName = result.JobInfo.Tasks[0].CenterName[0] + } + } + } else { + temp := strings.Split(job.AiCenter, "+") + if len(temp) > 1 { + aiCenterName = temp[1] + } + } + err = models.UpdateTrainJobVersion(job) + if err != nil { + log.Error("UpdateJob failed:", err) + } } ctx.JSON(http.StatusOK, map[string]interface{}{ "JobID": jobID, "JobStatus": job.Status, "JobDuration": job.TrainJobDuration, + "AiCenter": aiCenterName, }) } @@ -373,11 +414,29 @@ func ModelList(ctx *context.APIContext) { log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error()) return } - models, err := storage.GetObsListObject(task.JobName, "output/", parentDir, versionName) - if err != nil { - log.Info("get TrainJobListModel failed:", err) - ctx.ServerError("GetObsListObject:", err) - return + + var fileInfos []storage.FileInfo + if task.ComputeResource == models.NPUResource { + fileInfos, err = storage.GetObsListObject(task.JobName, "output/", parentDir, versionName) + if err != nil { + log.Info("get TrainJobListModel failed:", err) + ctx.ServerError("GetObsListObject:", err) + return + } + } else if task.ComputeResource == models.GPUResource { + files, err := routerRepo.GetModelDirs(task.JobName, parentDir) + if err != nil { + log.Info("GetModelDirs failed:", err) + ctx.ServerError("GetModelDirs:", err) + return + } + + err = json.Unmarshal([]byte(files), &fileInfos) + if err != nil { + log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) + ctx.ServerError("json.Unmarshal failed:", err) + return + } } ctx.JSON(http.StatusOK, map[string]interface{}{ @@ -385,7 +444,7 @@ func ModelList(ctx *context.APIContext) { "VersionName": versionName, "StatusOK": 0, "Path": dirArray, - "Dirs": models, + "Dirs": fileInfos, "task": task, "PageIsCloudBrain": true, }) diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index eb2ddc93b..24a5df821 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -2,6 +2,7 @@ package repo import ( "bufio" + "code.gitea.io/gitea/modules/grampus" "encoding/json" "errors" "fmt" @@ -186,7 +187,7 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled - ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne + ctx.Data["datasetType"] = models.TypeCloudBrainOne ctx.Data["benchmarkMode"] = ctx.Query("benchmarkMode") @@ -1036,6 +1037,7 @@ func GetPublicImages(ctx *context.Context) { IncludeOfficialOnly: ctx.QueryBool("recommend"), SearchOrderBy: "type desc, num_stars desc,id desc", Status: models.IMAGE_STATUS_SUCCESS, + CloudbrainType: ctx.QueryInt("cloudbrainType"), } getImages(ctx, &opts) @@ -1471,7 +1473,34 @@ func SyncCloudbrainStatus() { } else { log.Error("task.JobType(%s) is error:%s", task.JobName, task.JobType) } + } else if task.Type == models.TypeC2Net { + result, err := grampus.GetJob(task.JobID) + if err != nil { + log.Error("GetTrainJob(%s) failed:%v", task.JobName, err) + continue + } + + if result != nil { + if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 { + task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0] + } + task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) + task.Duration = result.JobInfo.RunSec + task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) + if task.StartTime == 0 && result.JobInfo.StartedAt > 0 { + task.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt) + } + if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 { + task.EndTime = task.StartTime.Add(task.Duration) + } + task.CorrectCreateUnix() + err = models.UpdateJob(task) + if err != nil { + log.Error("UpdateJob(%s) failed:%v", task.JobName, err) + continue + } + } } else { log.Error("task.Type(%s) is error:%d", task.JobName, task.Type) } diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go new file mode 100755 index 000000000..48957387f --- /dev/null +++ b/routers/repo/grampus.go @@ -0,0 +1,724 @@ +package repo + +import ( + "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/grampus" + "code.gitea.io/gitea/modules/modelarts" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + "encoding/json" + "errors" + "github.com/unknwon/com" + "io/ioutil" + "net/http" + "os" + "path" + "strconv" + "strings" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/cloudbrain" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +const ( + tplGrampusTrainJobShow base.TplName = "repo/grampus/trainjob/show" + + //GPU + tplGrampusTrainJobGPUNew base.TplName = "repo/grampus/trainjob/gpu/new" + + //NPU + tplGrampusTrainJobNPUNew base.TplName = "repo/grampus/trainjob/npu/new" +) + +func GrampusTrainJobGPUNew(ctx *context.Context) { + ctx.Data["datasetType"] = models.TypeCloudBrainOne + err := grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + if err != nil { + ctx.ServerError("get new train-job info failed", err) + return + } + ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew) +} + +func GrampusTrainJobNPUNew(ctx *context.Context) { + ctx.Data["datasetType"] = models.TypeCloudBrainTwo + err := grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + if err != nil { + ctx.ServerError("get new train-job info failed", err) + return + } + ctx.HTML(200, tplGrampusTrainJobNPUNew) +} + +func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) error { + ctx.Data["PageIsCloudBrain"] = true + + t := time.Now() + var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + ctx.Data["display_job_name"] = displayJobName + + //get valid images + images, err := grampus.GetImages(processType) + if err != nil { + log.Error("GetImages failed:", err.Error()) + } else { + ctx.Data["images"] = images.Infos + } + + //get valid resource specs + specs, err := grampus.GetResourceSpecs(processType) + if err != nil { + log.Error("GetResourceSpecs failed:", err.Error()) + } else { + ctx.Data["flavor_infos"] = specs.Infos + } + + //get branches + branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0) + if err != nil { + log.Error("GetBranches error:", err.Error()) + } else { + ctx.Data["branches"] = branches + } + + ctx.Data["branchName"] = ctx.Repo.BranchName + + if processType == grampus.ProcessorTypeGPU { + ctx.Data["datasetType"] = models.TypeCloudBrainOne + } else if processType == grampus.ProcessorTypeNPU { + ctx.Data["datasetType"] = models.TypeCloudBrainTwo + } + + return nil +} + +func grampusParamCheckCreateTrainJob(form auth.CreateGrampusTrainJobForm) error { + if !strings.HasSuffix(strings.TrimSpace(form.BootFile), ".py") { + log.Error("the boot file(%s) must be a python file", form.BootFile) + return errors.New("启动文件必须是python文件") + } + + if form.BranchName == "" { + log.Error("the branch must not be null!", form.BranchName) + return errors.New("代码分支不能为空!") + } + + return nil +} + +func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrainJobForm) { + displayJobName := form.DisplayJobName + jobName := util.ConvertDisplayJobNameToJobName(displayJobName) + uuid := form.Attachment + description := form.Description + bootFile := strings.TrimSpace(form.BootFile) + params := form.Params + repo := ctx.Repo.Repository + codeLocalPath := setting.JobPath + jobName + cloudbrain.CodeMountPath + "/" + codeMinioPath := setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/" + dataMinioPath := setting.Attachment.Minio.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + branchName := form.BranchName + flavorName := form.FlavorName + image := strings.TrimSpace(form.Image) + + if !jobNamePattern.MatchString(displayJobName) { + ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplGrampusTrainJobGPUNew, &form) + return + } + + //check count limit + count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.GPUResource) + if err != nil { + log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("system error", tplGrampusTrainJobGPUNew, &form) + return + } else { + if count >= 1 { + log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplGrampusTrainJobGPUNew, &form) + return + } + } + + //check param + if err := grampusParamCheckCreateTrainJob(form); err != nil { + log.Error("paramCheckCreateTrainJob failed:(%v)", err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr(err.Error(), tplGrampusTrainJobGPUNew, &form) + return + } + + //check whether the task name in the project is duplicated + tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) + if err == nil { + if len(tasks) != 0 { + log.Error("the job name did already exist", ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("the job name did already exist", tplGrampusTrainJobGPUNew, &form) + return + } + } else { + if !models.IsErrJobNotExist(err) { + log.Error("system error, %v", err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("system error", tplGrampusTrainJobGPUNew, &form) + return + } + } + + //check dataset + attachment, err := models.GetAttachmentByUUID(uuid) + if err != nil { + log.Error("GetAttachmentByUUID failed:", err.Error(), ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("dataset is not exist", tplGrampusTrainJobGPUNew, &form) + return + } + + //prepare code and out path + _, err = ioutil.ReadDir(codeLocalPath) + if err == nil { + os.RemoveAll(codeLocalPath) + } + + if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil { + log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form) + return + } + + //todo: upload code (send to file_server todo this work?) + //upload code + if err := uploadCodeToMinio(codeLocalPath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil { + log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form) + return + } + + modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" + if err := mkModelPath(modelPath); err != nil { + log.Error("Failed to mkModelPath: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form) + return + } + + //init model readme + if err := uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/"); err != nil { + log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form) + return + } + + //prepare command + command, err := generateCommand(repo.Name, grampus.ProcessorTypeGPU, codeMinioPath+cloudbrain.DefaultBranchName+".zip", dataMinioPath, bootFile, params, setting.CBCodePathPrefix+jobName+cloudbrain.ModelMountPath+"/", attachment.Name) + if err != nil { + log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form) + return + } + + commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName) + + req := &grampus.GenerateTrainJobReq{ + JobName: jobName, + DisplayJobName: displayJobName, + ComputeResource: models.GPUResource, + Command: command, + ResourceSpecId: form.FlavorID, + ImageUrl: image, + Description: description, + BootFile: bootFile, + Uuid: uuid, + CommitID: commitID, + BranchName: branchName, + Params: form.Params, + FlavorName: flavorName, + EngineName: image, + DatasetName: attachment.Name, + IsLatestVersion: modelarts.IsLatestVersion, + VersionCount: modelarts.VersionCount, + WorkServerNumber: 1, + } + + err = grampus.GenerateTrainJob(ctx, req) + if err != nil { + log.Error("GenerateTrainJob failed:%v", err.Error(), ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + ctx.RenderWithErr(err.Error(), tplGrampusTrainJobGPUNew, &form) + return + } + ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") +} + +func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrainJobForm) { + displayJobName := form.DisplayJobName + jobName := util.ConvertDisplayJobNameToJobName(displayJobName) + uuid := form.Attachment + description := form.Description + bootFile := strings.TrimSpace(form.BootFile) + params := form.Params + repo := ctx.Repo.Repository + codeLocalPath := setting.JobPath + jobName + modelarts.CodePath + codeObsPath := grampus.JobPath + jobName + modelarts.CodePath + dataObsPath := setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/" + branchName := form.BranchName + isLatestVersion := modelarts.IsLatestVersion + flavorName := form.FlavorName + versionCount := modelarts.VersionCount + engineName := form.EngineName + + if !jobNamePattern.MatchString(displayJobName) { + ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplGrampusTrainJobNPUNew, &form) + return + } + + //check count limit + count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.NPUResource) + if err != nil { + log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("system error", tplGrampusTrainJobNPUNew, &form) + return + } else { + if count >= 1 { + log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplGrampusTrainJobNPUNew, &form) + return + } + } + + //check param + if err := grampusParamCheckCreateTrainJob(form); err != nil { + log.Error("paramCheckCreateTrainJob failed:(%v)", err) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr(err.Error(), tplGrampusTrainJobNPUNew, &form) + return + } + + //check whether the task name in the project is duplicated + tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) + if err == nil { + if len(tasks) != 0 { + log.Error("the job name did already exist", ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("the job name did already exist", tplGrampusTrainJobNPUNew, &form) + return + } + } else { + if !models.IsErrJobNotExist(err) { + log.Error("system error, %v", err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("system error", tplGrampusTrainJobNPUNew, &form) + return + } + } + + //check dataset + attachment, err := models.GetAttachmentByUUID(uuid) + if err != nil { + log.Error("GetAttachmentByUUID failed:", err.Error(), ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("dataset is not exist", tplGrampusTrainJobNPUNew, &form) + return + } + + //prepare code and out path + _, err = ioutil.ReadDir(codeLocalPath) + if err == nil { + os.RemoveAll(codeLocalPath) + } + + if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil { + log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("Create task failed, server timed out", tplGrampusTrainJobNPUNew, &form) + return + } + + //todo: upload code (send to file_server todo this work?) + if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil { + log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form) + return + } + + if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil { + log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("Failed to uploadCodeToObs", tplGrampusTrainJobNPUNew, &form) + return + } + + //prepare command + command, err := generateCommand(repo.Name, grampus.ProcessorTypeNPU, codeObsPath+cloudbrain.DefaultBranchName+".zip", dataObsPath+attachment.Name, bootFile, params, setting.CodePathPrefix+jobName+modelarts.OutputPath, attachment.Name) + if err != nil { + log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"]) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobNPUNew, &form) + return + } + + commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName) + + req := &grampus.GenerateTrainJobReq{ + JobName: jobName, + DisplayJobName: displayJobName, + ComputeResource: models.NPUResource, + Command: command, + ResourceSpecId: form.FlavorID, + ImageId: form.ImageID, + DataUrl: dataObsPath, + Description: description, + CodeObsPath: codeObsPath, + BootFileUrl: codeObsPath + bootFile, + BootFile: bootFile, + WorkServerNumber: form.WorkServerNumber, + Uuid: uuid, + CommitID: commitID, + IsLatestVersion: isLatestVersion, + BranchName: branchName, + Params: form.Params, + FlavorName: flavorName, + EngineName: engineName, + VersionCount: versionCount, + TotalVersionCount: modelarts.TotalVersionCount, + DatasetName: attachment.Name, + } + + err = grampus.GenerateTrainJob(ctx, req) + if err != nil { + log.Error("GenerateTrainJob failed:%v", err.Error()) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + ctx.RenderWithErr(err.Error(), tplGrampusTrainJobNPUNew, &form) + return + } + ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") +} + +func GrampusStopJob(ctx *context.Context) { + var ID = ctx.Params(":jobid") + var resultCode = "0" + var errorMsg = "" + var status = "" + + task := ctx.Cloudbrain + for { + if task.Status == string(models.GrampusStatusStopped) || task.Status == string(models.GrampusStatusFailed) || task.Status == string(models.GrampusStatusSucceeded) { + log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"]) + resultCode = "-1" + errorMsg = "system error" + break + } + + res, err := grampus.StopJob(task.JobID) + if err != nil { + log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) + resultCode = strconv.Itoa(res.ErrorCode) + errorMsg = res.ErrorMsg + break + } + + task.Status = string(models.GrampusStatusStopped) + if task.EndTime == 0 { + task.EndTime = timeutil.TimeStampNow() + } + task.ComputeAndSetDuration() + err = models.UpdateJob(task) + if err != nil { + log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) + resultCode = "-1" + errorMsg = "system error" + break + } + + status = task.Status + break + } + + ctx.JSON(200, map[string]interface{}{ + "result_code": resultCode, + "error_msg": errorMsg, + "status": status, + "id": ID, + "StatusOK": 0, + }) +} + +func GrampusTrainJobDel(ctx *context.Context) { + var listType = ctx.Query("listType") + if err := deleteGrampusJob(ctx); err != nil { + log.Error("deleteGrampusJob failed: %v", err, ctx.Data["msgID"]) + ctx.ServerError(err.Error(), err) + return + } + + var isAdminPage = ctx.Query("isadminpage") + var isHomePage = ctx.Query("ishomepage") + if ctx.IsUserSiteAdmin() && isAdminPage == "true" { + ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains") + } else if isHomePage == "true" { + ctx.Redirect(setting.AppSubURL + "/cloudbrains") + } else { + ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job?listType=" + listType) + } +} + +func deleteGrampusJob(ctx *context.Context) error { + task := ctx.Cloudbrain + + if task.Status != string(models.GrampusStatusStopped) && task.Status != string(models.GrampusStatusSucceeded) && task.Status != string(models.GrampusStatusFailed) { + log.Error("the job(%s) has not been stopped", task.JobName, ctx.Data["msgID"]) + return errors.New("the job has not been stopped") + } + + err := models.DeleteJob(task) + if err != nil { + log.Error("DeleteJob failed: %v", err, ctx.Data["msgID"]) + return err + } + + storageType := models.TypeCloudBrainOne + if task.ComputeResource == models.NPUResource { + storageType = models.TypeCloudBrainTwo + } + deleteJobStorage(task.JobName, storageType) + + return nil +} + +func GrampusTrainJobShow(ctx *context.Context) { + ctx.Data["PageIsCloudBrain"] = true + + var task *models.Cloudbrain + task, err := models.GetCloudbrainByJobIDWithDeleted(ctx.Params(":jobid")) + if err != nil { + log.Error("GetCloudbrainByJobID failed:" + err.Error()) + ctx.ServerError("system error", err) + return + } + + if task.DeletedAt.IsZero() { //normal record + result, err := grampus.GetJob(task.JobID) + if err != nil { + log.Error("GetJob failed:" + err.Error()) + //ctx.ServerError("GetJob failed", err) + //return + } + + if result != nil { + if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 { + task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0] + } + task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) + if task.Status != result.JobInfo.Status || result.JobInfo.Status == models.GrampusStatusRunning { + task.Duration = result.JobInfo.RunSec + task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) + + if task.StartTime == 0 && result.JobInfo.StartedAt > 0 { + task.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt) + } + if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 { + task.EndTime = task.StartTime.Add(task.Duration) + } + task.CorrectCreateUnix() + err = models.UpdateJob(task) + if err != nil { + log.Error("UpdateJob failed:" + err.Error()) + } + } + } + } + + if len(task.Parameters) > 0 { + var parameters models.Parameters + err := json.Unmarshal([]byte(task.Parameters), ¶meters) + if err != nil { + log.Error("Failed to Unmarshal Parameters: %s (%v)", task.Parameters, err) + ctx.ServerError("system error", err) + return + } + + if len(parameters.Parameter) > 0 { + paramTemp := "" + for _, Parameter := range parameters.Parameter { + param := Parameter.Label + " = " + Parameter.Value + "; " + paramTemp = paramTemp + param + } + task.Parameters = paramTemp[:len(paramTemp)-2] + } else { + task.Parameters = "" + } + } + + taskList := make([]*models.Cloudbrain, 0) + taskList = append(taskList, task) + ctx.Data["version_list_task"] = taskList + + ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) + ctx.Data["displayJobName"] = task.DisplayJobName + + aiCenterInfo := strings.Split(task.AiCenter, "+") + if len(aiCenterInfo) == 2 { + ctx.Data["ai_center"] = aiCenterInfo[1] + } + + ctx.HTML(http.StatusOK, tplGrampusTrainJobShow) +} + +func GrampusGetLog(ctx *context.Context) { + jobID := ctx.Params(":jobid") + job, err := models.GetCloudbrainByJobID(jobID) + if err != nil { + log.Error("GetCloudbrainByJobID failed: %v", err, ctx.Data["MsgID"]) + ctx.ServerError(err.Error(), err) + return + } + + content, err := grampus.GetTrainJobLog(job.JobID) + if err != nil { + log.Error("GetTrainJobLog failed: %v", err, ctx.Data["MsgID"]) + ctx.ServerError(err.Error(), err) + return + } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "JobName": job.JobName, + "Content": content, + }) + + return +} + +func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bootFile, paramSrc, outputRemotePath, datasetName string) (string, error) { + var command string + + command += grampus.CommandPrepareScript + //download code & dataset + if processorType == grampus.ProcessorTypeNPU { + commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " " + datasetName + ";" + command += commandDownload + } else if processorType == grampus.ProcessorTypeGPU { + commandDownload := "./downloader_for_minio " + setting.Grampus.Env + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " " + datasetName + ";" + command += commandDownload + } + + //check download result + commandCheckRes := "bash -c \"[[ $? -eq 0 ]] && exit 0 || exit -1;\";" + command += commandCheckRes + + //unzip code & dataset + toolUnzip := "unzip -q " + if strings.HasSuffix(datasetName, ".tar.gz") { + toolUnzip = "tar -zxvf " + } + commandUnzip := "cd /cache/code;unzip -q master.zip;echo \"start to unzip dataset\";cd /cache/dataset;" + toolUnzip + datasetName + ";" + command += commandUnzip + + //check unzip result + commandCheckRes = "bash -c \"[[ $? -eq 0 ]] && exit 0 || exit -1;\";" + command += commandCheckRes + + command += "echo \"unzip finished;start to exec code;\";" + + //exec code + var parameters models.Parameters + var paramCode string + param := make([]models.Parameter, 0) + if len(paramSrc) != 0 { + err := json.Unmarshal([]byte(paramSrc), ¶meters) + if err != nil { + log.Error("Failed to Unmarshal params: %s (%v)", paramSrc, err) + return command, err + } + + for _, parameter := range parameters.Parameter { + param = append(param, models.Parameter{ + Label: parameter.Label, + Value: parameter.Value, + }) + paramCode += " --" + parameter.Label + "=" + parameter.Value + } + } + + commandCode := "cd /cache/code/" + strings.ToLower(repoName) + ";python " + bootFile + paramCode + ";" + command += commandCode + + //get exec result + commandGetRes := "result=$?;" + command += commandGetRes + + //upload models + if processorType == grampus.ProcessorTypeNPU { + commandUpload := "cd /cache/script_for_grampus/;./uploader_for_obs " + setting.Bucket + " " + outputRemotePath + " " + "/cache/output/;" + command += commandUpload + } else if processorType == grampus.ProcessorTypeGPU { + commandUpload := "cd /cache/script_for_grampus/;./uploader_for_minio " + setting.Grampus.Env + " " + outputRemotePath + " " + "/cache/output/;" + command += commandUpload + } + + //check exec result + commandCheckRes = "bash -c \"[[ $result -eq 0 ]] && exit 0 || exit -1;\"" + command += commandCheckRes + + return command, nil +} + +func downloadZipCode(ctx *context.Context, codePath, branchName string) error { + archiveType := git.ZIP + archivePath := codePath + + if !com.IsDir(archivePath) { + if err := os.MkdirAll(archivePath, os.ModePerm); err != nil { + log.Error("MkdirAll failed:" + err.Error()) + return err + } + } + + // Get corresponding commit. + var ( + commit *git.Commit + err error + ) + + gitRepo := ctx.Repo.GitRepo + if err != nil { + log.Error("OpenRepository failed:" + err.Error()) + return err + } + + if gitRepo.IsBranchExist(branchName) { + commit, err = gitRepo.GetBranchCommit(branchName) + if err != nil { + log.Error("GetBranchCommit failed:" + err.Error()) + return err + } + } + + archivePath = path.Join(archivePath, grampus.CodeArchiveName) + if !com.IsFile(archivePath) { + if err := commit.CreateArchive(archivePath, git.CreateArchiveOpts{ + Format: archiveType, + Prefix: setting.Repository.PrefixArchiveFiles, + }); err != nil { + log.Error("CreateArchive failed:" + err.Error()) + return err + } + } + + return nil +} diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 12a5a0623..1fb9ec5c5 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -146,7 +146,7 @@ func notebookNewDataPrepare(ctx *context.Context) error { } ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -559,24 +559,11 @@ func TrainJobIndex(ctx *context.Context) { } listType := ctx.Query("listType") - if len(listType) == 0 { - listType = models.AllResource - } ctx.Data["ListType"] = listType - typeCloudBrain := models.TypeCloudBrainAll - if listType == models.GPUResource { - typeCloudBrain = models.TypeCloudBrainOne - } else if listType == models.NPUResource { - typeCloudBrain = models.TypeCloudBrainTwo - } else if listType == models.AllResource { - typeCloudBrain = models.TypeCloudBrainAll + if listType == models.AllResource { + listType = "" } - //else { - // log.Error("listType(%s) error", listType) - // ctx.ServerError("listType error", errors.New("listType error")) - // return - //} var jobTypes []string jobTypes = append(jobTypes, string(models.JobTypeTrain)) @@ -586,10 +573,11 @@ func TrainJobIndex(ctx *context.Context) { PageSize: setting.UI.IssuePagingNum, }, RepoID: repo.ID, - Type: typeCloudBrain, JobTypeNot: false, JobTypes: jobTypes, IsLatestVersion: modelarts.IsLatestVersion, + ComputeResource: listType, + Type: models.TypeCloudBrainAll, }) if err != nil { ctx.ServerError("Cloudbrain", err) @@ -599,11 +587,6 @@ func TrainJobIndex(ctx *context.Context) { for i, task := range tasks { tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) - if task.Cloudbrain.Type == models.TypeCloudBrainOne { - tasks[i].ComputeResource = models.GPUResource - } else if task.Cloudbrain.Type == models.TypeCloudBrainTwo { - tasks[i].ComputeResource = models.NPUResource - } } pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) @@ -690,7 +673,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { return err } ctx.Data["config_list"] = configList.ParaConfigs - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -764,7 +747,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts ctx.Data["bootFile"] = form.BootFile ctx.Data["uuid"] = form.Attachment ctx.Data["branch_name"] = form.BranchName - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -858,7 +841,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 + ctx.Data["datasetType"] = models.TypeCloudBrainTwo configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) if err != nil { @@ -955,7 +938,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai return err } ctx.Data["config_list"] = configList.ParaConfigs - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -2111,7 +2094,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { New: MODEL_LATEST, }) ctx.Data["MODEL_COUNT"] = model_count - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -2177,7 +2160,7 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel ctx.Data["model_version"] = form.ModelVersion ctx.Data["ckpt_name"] = form.CkptName ctx.Data["train_url"] = form.TrainUrl - ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo + ctx.Data["datasetType"] = models.TypeCloudBrainTwo return nil } @@ -2247,24 +2230,35 @@ func ModelDownload(ctx *context.Context) { err error ) - var jobID = ctx.Params(":jobid") + jobID := ctx.Params(":jobid") versionName := ctx.Query("version_name") parentDir := ctx.Query("parent_dir") fileName := ctx.Query("file_name") task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName) if err != nil { - log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error()) + log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", task.JobName, err.Error()) return } - path := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, task.JobName, setting.OutPutPath, versionName, parentDir, fileName), "/") - - url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path) - if err != nil { - log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"]) - ctx.ServerError("GetObsCreateSignedUrl", err) - return + var url string + if task.ComputeResource == models.NPUResource { + path := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, task.JobName, setting.OutPutPath, versionName, parentDir, fileName), "/") + url, err = storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path) + if err != nil { + log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"]) + ctx.ServerError("GetObsCreateSignedUrl", err) + return + } + } else if task.ComputeResource == models.GPUResource { + filePath := setting.CBCodePathPrefix + task.JobName + cloudbrain.ModelMountPath + "/" + parentDir + url, err = storage.Attachments.PresignedGetURL(filePath, fileName) + if err != nil { + log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"]) + ctx.ServerError("PresignedGetURL", err) + return + } } + ctx.Resp.Header().Set("Cache-Control", "max-age=0") http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) } diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 7732ff217..1198953c6 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -1086,6 +1086,24 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) }) }, context.RepoRef()) + m.Group("/grampus", func() { + m.Group("/train-job", func() { + m.Group("/:jobid", func() { + m.Get("", reqRepoCloudBrainReader, repo.GrampusTrainJobShow) + m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.GrampusStopJob) + m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GrampusTrainJobDel) + m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload) + }) + m.Group("/gpu", func() { + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobGPUNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateGrampusTrainJobForm{}), repo.GrampusTrainJobGpuCreate) + }) + m.Group("/npu", func() { + m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobNPUNew) + m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateGrampusTrainJobForm{}), repo.GrampusTrainJobNpuCreate) + }) + }) + }, context.RepoRef()) m.Group("/modelmanage", func() { m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) m.Post("/create_new_model", repo.SaveNewNameModel) diff --git a/routers/search.go b/routers/search.go index fe1643c80..05074df55 100644 --- a/routers/search.go +++ b/routers/search.go @@ -489,7 +489,7 @@ func makeRepoResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool, if recordSource["avatar"] != nil { avatarstr := recordSource["avatar"].(string) if len(avatarstr) == 0 { - record["avatar"] = setting.RepositoryAvatarFallbackImage + // record["avatar"] = setting.RepositoryAvatarFallbackImage } else { record["avatar"] = setting.AppSubURL + "/repo-avatars/" + avatarstr } diff --git a/routers/user/home.go b/routers/user/home.go index 53aff19b8..ab64e707f 100755 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -769,12 +769,6 @@ func Cloudbrains(ctx *context.Context) { if page <= 0 { page = 1 } - debugType := models.TypeCloudBrainAll - if listType == models.GPUResource { - debugType = models.TypeCloudBrainOne - } else if listType == models.NPUResource { - debugType = models.TypeCloudBrainTwo - } var jobTypes []string jobTypeNot := false @@ -821,7 +815,6 @@ func Cloudbrains(ctx *context.Context) { }, Keyword: keyword, UserID: ctxUser.ID, - Type: debugType, JobTypeNot: jobTypeNot, JobStatusNot: jobStatusNot, JobStatus: jobStatuses, @@ -829,6 +822,8 @@ func Cloudbrains(ctx *context.Context) { NeedRepoInfo: true, IsLatestVersion: modelarts.IsLatestVersion, RepoIDList: repoIDList, + ComputeResource: listType, + Type: models.TypeCloudBrainAll, }) if err != nil { ctx.ServerError("Get job failed:", err) diff --git a/templates/custom/select_dataset.tmpl b/templates/custom/select_dataset.tmpl old mode 100644 new mode 100755 index d545f487e..0108327d5 --- a/templates/custom/select_dataset.tmpl +++ b/templates/custom/select_dataset.tmpl @@ -1,9 +1,9 @@ -
+ data-dataset-type="{{.datasetType}}">
+
- {{if eq .cloudbraintype 0}} + {{if eq .datasetType 0}} {{else}} @@ -18,7 +18,7 @@
- +
diff --git a/templates/custom/select_dataset_train.tmpl b/templates/custom/select_dataset_train.tmpl old mode 100644 new mode 100755 index f1d2abaf3..e96bfa3a8 --- a/templates/custom/select_dataset_train.tmpl +++ b/templates/custom/select_dataset_train.tmpl @@ -1,5 +1,5 @@ + data-dataset-type="{{.datasetType}}">
{{if or (.benchmarkMode) (.newInference)}}
- +
diff --git a/templates/explore/repo_list.tmpl b/templates/explore/repo_list.tmpl index b6bb49da9..758fea14e 100755 --- a/templates/explore/repo_list.tmpl +++ b/templates/explore/repo_list.tmpl @@ -1,38 +1,46 @@ + +
+
+
+
+
+
+
+
+
+
+ {{template "repo/header" .}} +
+ {{template "base/alert" .}} +

+ {{.i18n.Tr "repo.modelarts.train_job.new"}} +

+
+ +
+ {{.CsrfTokenHtml}} + + + +

{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:

+ +
+ + +
+
+ + + {{.i18n.Tr "cloudbrain.job_name_rule"}} +
+ +
+ + +
+
+ +

{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:

+ + +
+ + +
+ +
+
+ +
+ + {{if .bootFile}} + + {{else}} + + {{end}} + + + + 查看样例 +
+ + + {{template "custom/select_dataset_train" .}} + {{.i18n.Tr "repo.grampus.dataset_path_rule"}} +
+ + {{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}} + +
+ {{if .params}} + {{if ne 0 (len .params)}} + {{range $k ,$v := .params}} +
+
+ +
+
+ +
+ + + + +
+ {{end}} + {{end}} + {{end}} +
+
+ +
+ + +
+ +
+ + {{.i18n.Tr "repo.cloudbrain.cancel"}} +
+ + + +
+
+
+
+{{template "base/footer" .}} + + \ No newline at end of file diff --git a/templates/repo/grampus/trainjob/npu/new.tmpl b/templates/repo/grampus/trainjob/npu/new.tmpl new file mode 100755 index 000000000..3b7c7843b --- /dev/null +++ b/templates/repo/grampus/trainjob/npu/new.tmpl @@ -0,0 +1,430 @@ +{{template "base/head" .}} + + +
+
+
+
+
+
+
+
+
+
+ {{template "repo/header" .}} +
+ {{template "base/alert" .}} +

+ {{.i18n.Tr "repo.modelarts.train_job.new"}} +

+
+ +
+ {{.CsrfTokenHtml}} + + + +

{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:

+ +
+ + +
+
+ + + {{.i18n.Tr "cloudbrain.job_name_rule"}} +
+ +
+ + +
+
+ +

{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:

+ + +
+ + +
+ +
+ + +
+ +
+ + {{if .bootFile}} + + {{else}} + + {{end}} + + + + {{.i18n.Tr "cloudbrain.view_sample"}} +
+ + {{template "custom/select_dataset_train" .}} + {{.i18n.Tr "repo.grampus.dataset_path_rule"}} +
+ + {{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}} + +
+
+
+ +
+ + +
+
+ + +
+ + +
+ +
+ +
+
+ +
+ + {{.i18n.Tr "repo.cloudbrain.cancel"}} +
+ + + +
+
+
+
+{{template "base/footer" .}} + + diff --git a/templates/repo/grampus/trainjob/show.tmpl b/templates/repo/grampus/trainjob/show.tmpl new file mode 100755 index 000000000..579e83693 --- /dev/null +++ b/templates/repo/grampus/trainjob/show.tmpl @@ -0,0 +1,982 @@ +{{template "base/head" .}} + +
+
+
+
+
+
+
+
+
+
+ {{template "repo/header" .}} +
+

+ +

+ {{range $k ,$v := .version_list_task}} +
+
+
+
+ + + +
+ {{$.CsrfTokenHtml}} + +
+
+ + + {{if not (eq .StartTime 0)}} + {{TimeSinceUnix1 .StartTime}} + {{else}} + {{TimeSinceUnix1 .CreatedUnix}} + {{end}} + + {{$.i18n.Tr "repo.modelarts.current_version"}}:{{.VersionName}} + + {{$.i18n.Tr "repo.modelarts.parent_version"}}:{{.PreVersionName}} + {{$.i18n.Tr "repo.modelarts.status"}}: + {{.Status}} + + {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}: + {{.TrainJobDuration}} + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{$.i18n.Tr "repo.cloudbrain_task"}} + +
+ {{.DisplayJobName}} +
+
+ {{$.i18n.Tr "repo.modelarts.status"}} + +
+ {{.Status}} +
+
+ {{$.i18n.Tr "repo.modelarts.run_version"}} + +
+ {{.VersionName}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} + +
+ + {{if not (eq .StartTime 0)}} + {{TimeSinceUnix1 .StartTime}} + {{else}} + {{TimeSinceUnix1 .CreatedUnix}} + {{end}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} + +
+ {{.TrainJobDuration}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.standard"}} + +
+ {{.FlavorName}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} + +
+ {{.WorkServerNumber}} +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} + +
+ {{.EngineName}} +
+
+ {{$.i18n.Tr "repo.modelarts.code_version"}} + +
+ {{.BranchName}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} + +
+ {{.BootFile}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} + +
+ {{.DatasetName}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} + +
+ {{.Parameters}} +
+
+ {{$.i18n.Tr "repo.grampus.train_job.ai_center"}} + +
+ {{$.ai_center}} +
+
+ {{$.i18n.Tr "repo.modelarts.train_job.description"}} + +
+ {{.Description}} +
+
+
+
+
+ +
+
+
+
+ +
+ + +

+                            
+ +
+ +
+
+ + + +
+ +
+
+ +
+
+
+ {{end}} {{template "base/paginate" .}} +
+ +
+ +
+ +
+ +
+
+{{template "base/footer" .}} + + \ No newline at end of file diff --git a/templates/repo/modelarts/trainjob/index.tmpl b/templates/repo/modelarts/trainjob/index.tmpl index edb146d7e..3e6645727 100755 --- a/templates/repo/modelarts/trainjob/index.tmpl +++ b/templates/repo/modelarts/trainjob/index.tmpl @@ -112,7 +112,7 @@
- + {{.DisplayJobName}} @@ -153,18 +153,18 @@
{{$.CsrfTokenHtml}} {{if .CanDel}} - + {{$.i18n.Tr "repo.stop"}} {{else}} - + {{$.i18n.Tr "repo.stop"}} {{end}}
-
+ {{$.CsrfTokenHtml}} {{if .CanDel}} diff --git a/templates/repo/modelarts/trainjob/new.tmpl b/templates/repo/modelarts/trainjob/new.tmpl index 9d6a45e83..d6e5ba157 100755 --- a/templates/repo/modelarts/trainjob/new.tmpl +++ b/templates/repo/modelarts/trainjob/new.tmpl @@ -84,6 +84,19 @@

{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:

+