| @@ -50,14 +50,16 @@ const ( | |||||
| ActionRejectPullRequest // 22 | ActionRejectPullRequest // 22 | ||||
| ActionCommentPull // 23 | 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 | // Action represents user operation type and other information to | ||||
| @@ -107,6 +107,7 @@ const ( | |||||
| GrampusStatusSucceeded = "SUCCEEDED" | GrampusStatusSucceeded = "SUCCEEDED" | ||||
| GrampusStatusStopped = "STOPPED" | GrampusStatusStopped = "STOPPED" | ||||
| GrampusStatusUnknown = "UNKNOWN" | GrampusStatusUnknown = "UNKNOWN" | ||||
| GrampusStatusWaiting = "WAITING" | |||||
| ) | ) | ||||
| type Cloudbrain struct { | type Cloudbrain struct { | ||||
| @@ -1434,6 +1435,9 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) { | |||||
| cond = cond.And( | cond = cond.And( | ||||
| builder.Eq{"job_type": "TRAIN"}, | builder.Eq{"job_type": "TRAIN"}, | ||||
| ) | ) | ||||
| cond = cond.And( | |||||
| builder.In("type", 0, 1), | |||||
| ) | |||||
| cloudbrains := make([]*CloudbrainInfo, 0) | cloudbrains := make([]*CloudbrainInfo, 0) | ||||
| if err := sess.Select("job_id,display_job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | if err := sess.Select("job_id,display_job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | ||||
| @@ -1742,7 +1746,7 @@ func GetCloudbrainInferenceJobCountByUserID(userID int64) (int, error) { | |||||
| } | } | ||||
| func GetGrampusCountByUserID(userID int64, jobType, computeResource string) (int, error) { | func GetGrampusCountByUserID(userID int64, jobType, computeResource string) (int, error) { | ||||
| count, err := x.In("status", GrampusStatusPending, GrampusStatusRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeC2Net).And("compute_resource = ?", computeResource).Count(new(Cloudbrain)) | |||||
| 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 | return int(count), err | ||||
| } | } | ||||
| @@ -1910,3 +1914,44 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| return cloudbrains, count, nil | return cloudbrains, count, nil | ||||
| } | } | ||||
| func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| var cond = builder.NewCond() | |||||
| if (opts.Type) >= 0 { | |||||
| cond = cond.And( | |||||
| builder.Eq{"cloudbrain.type": opts.Type}, | |||||
| ) | |||||
| } | |||||
| if opts.BeginTimeUnix > 0 && opts.EndTimeUnix > 0 { | |||||
| cond = cond.And( | |||||
| builder.And(builder.Gte{"cloudbrain.created_unix": opts.BeginTimeUnix}, builder.Lte{"cloudbrain.created_unix": opts.EndTimeUnix}), | |||||
| ) | |||||
| } | |||||
| var count int64 | |||||
| var err error | |||||
| count, err = sess.Unscoped().Where(cond).Count(new(Cloudbrain)) | |||||
| if err != nil { | |||||
| return nil, 0, fmt.Errorf("Count: %v", err) | |||||
| } | |||||
| if opts.Page >= 0 && opts.PageSize > 0 { | |||||
| var start int | |||||
| if opts.Page == 0 { | |||||
| start = 0 | |||||
| } else { | |||||
| start = (opts.Page - 1) * opts.PageSize | |||||
| } | |||||
| sess.Limit(opts.PageSize, start) | |||||
| } | |||||
| sess.OrderBy("cloudbrain.created_unix DESC") | |||||
| cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | |||||
| if err := sess.Cols("status", "type", "job_type", "train_job_duration", "duration", "compute_resource", "created_unix", "start_time", "end_time").Table(&Cloudbrain{}).Unscoped().Where(cond). | |||||
| Find(&cloudbrains); err != nil { | |||||
| return nil, 0, fmt.Errorf("Find: %v", err) | |||||
| } | |||||
| return cloudbrains, count, nil | |||||
| } | |||||
| @@ -213,7 +213,7 @@ func GetWaittingTop() ([]*CloudbrainInfo, error) { | |||||
| cond = cond.And( | cond = cond.And( | ||||
| builder.Eq{"cloudbrain.status": string(JobWaiting)}, | builder.Eq{"cloudbrain.status": string(JobWaiting)}, | ||||
| ) | ) | ||||
| sess.OrderBy("(cloudbrain.start_time-cloudbrain.created_unix) DESC limit 10") | |||||
| sess.OrderBy("cloudbrain.created_unix ASC limit 10") | |||||
| cloudbrains := make([]*CloudbrainInfo, 0, 10) | cloudbrains := make([]*CloudbrainInfo, 0, 10) | ||||
| if err := sess.Table(&Cloudbrain{}).Where(cond). | if err := sess.Table(&Cloudbrain{}).Where(cond). | ||||
| Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
| @@ -228,7 +228,7 @@ func GetRunningTop() ([]*CloudbrainInfo, error) { | |||||
| cond = cond.And( | cond = cond.And( | ||||
| builder.Eq{"cloudbrain.status": string(JobRunning)}, | builder.Eq{"cloudbrain.status": string(JobRunning)}, | ||||
| ) | ) | ||||
| sess.OrderBy("(cloudbrain.end_time-cloudbrain.start_time) DESC limit 10") | |||||
| sess.OrderBy("cloudbrain.duration DESC limit 10") | |||||
| cloudbrains := make([]*CloudbrainInfo, 0, 10) | cloudbrains := make([]*CloudbrainInfo, 0, 10) | ||||
| if err := sess.Table(&Cloudbrain{}).Where(cond). | if err := sess.Table(&Cloudbrain{}).Where(cond). | ||||
| Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
| @@ -15,13 +15,9 @@ type CustomMigrationStatic struct { | |||||
| Migrate func(*xorm.Engine, *xorm.Engine) error | Migrate func(*xorm.Engine, *xorm.Engine) error | ||||
| } | } | ||||
| var customMigrations = []CustomMigration{ | |||||
| {"Custom v1 Topic struct change to support chinese", syncTopicStruct}, | |||||
| } | |||||
| var customMigrations []CustomMigration | |||||
| var customMigrationsStatic = []CustomMigrationStatic{ | |||||
| {"update issue_fixed_rate to 1 if num_issues is 0 ", updateIssueFixedRate}, | |||||
| } | |||||
| var customMigrationsStatic []CustomMigrationStatic | |||||
| func MigrateCustom(x *xorm.Engine) { | func MigrateCustom(x *xorm.Engine) { | ||||
| @@ -2749,15 +2749,10 @@ func ReadLatestFileInRepo(userName, repoName, refName, treePath string) (*RepoFi | |||||
| log.Error("ReadLatestFileInRepo: Close: %v", err) | log.Error("ReadLatestFileInRepo: Close: %v", err) | ||||
| } | } | ||||
| }() | }() | ||||
| buf := make([]byte, 1024) | |||||
| n, _ := reader.Read(buf) | |||||
| if n >= 0 { | |||||
| buf = buf[:n] | |||||
| } | |||||
| d, _ := ioutil.ReadAll(reader) | |||||
| commitId := "" | commitId := "" | ||||
| if blob != nil { | if blob != nil { | ||||
| commitId = fmt.Sprint(blob.ID) | commitId = fmt.Sprint(blob.ID) | ||||
| } | } | ||||
| return &RepoFile{CommitId: commitId, Content: buf}, nil | |||||
| return &RepoFile{CommitId: commitId, Content: d}, nil | |||||
| } | } | ||||
| @@ -6,7 +6,6 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/blockchain" | |||||
| "container/list" | "container/list" | ||||
| "context" | "context" | ||||
| "crypto/md5" | "crypto/md5" | ||||
| @@ -25,6 +24,8 @@ import ( | |||||
| "time" | "time" | ||||
| "unicode/utf8" | "unicode/utf8" | ||||
| "code.gitea.io/gitea/modules/blockchain" | |||||
| "code.gitea.io/gitea/modules/avatar" | "code.gitea.io/gitea/modules/avatar" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| "code.gitea.io/gitea/modules/generate" | "code.gitea.io/gitea/modules/generate" | ||||
| @@ -1498,6 +1499,17 @@ func GetUsersByIDs(ids []int64) (UserList, error) { | |||||
| return ous, err | return ous, err | ||||
| } | } | ||||
| func GetUsersByNames(names []string) (UserList, error) { | |||||
| ous := make([]*User, 0, len(names)) | |||||
| if len(names) == 0 { | |||||
| return ous, nil | |||||
| } | |||||
| err := x.In("name", names). | |||||
| Asc("name"). | |||||
| Find(&ous) | |||||
| return ous, err | |||||
| } | |||||
| // GetUserIDsByNames returns a slice of ids corresponds to names. | // GetUserIDsByNames returns a slice of ids corresponds to names. | ||||
| func GetUserIDsByNames(names []string, ignoreNonExistent bool) ([]int64, error) { | func GetUserIDsByNames(names []string, ignoreNonExistent bool) ([]int64, error) { | ||||
| ids := make([]int64, 0, len(names)) | ids := make([]int64, 0, len(names)) | ||||
| @@ -0,0 +1,139 @@ | |||||
| package wechat | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "encoding/json" | |||||
| "github.com/patrickmn/go-cache" | |||||
| "strings" | |||||
| "time" | |||||
| ) | |||||
| var WechatReplyCache = cache.New(2*time.Minute, 1*time.Minute) | |||||
| const ( | |||||
| WECHAT_REPLY_CACHE_KEY = "wechat_response" | |||||
| ) | |||||
| const ( | |||||
| ReplyTypeText = "text" | |||||
| ReplyTypeImage = "image" | |||||
| ReplyTypeVoice = "voice" | |||||
| ReplyTypeVideo = "video" | |||||
| ReplyTypeMusic = "music" | |||||
| ReplyTypeNews = "news" | |||||
| ) | |||||
| type ReplyConfigType string | |||||
| const ( | |||||
| SubscribeReply ReplyConfigType = "subscribe" | |||||
| AutoMsgReply ReplyConfigType = "autoMsg" | |||||
| ) | |||||
| func (r ReplyConfigType) Name() string { | |||||
| switch r { | |||||
| case SubscribeReply: | |||||
| return "subscribe" | |||||
| case AutoMsgReply: | |||||
| return "autoMsg" | |||||
| } | |||||
| return "" | |||||
| } | |||||
| func (r ReplyConfigType) TreePath() string { | |||||
| switch r { | |||||
| case SubscribeReply: | |||||
| return setting.TreePathOfSubscribe | |||||
| case AutoMsgReply: | |||||
| return setting.TreePathOfAutoMsgReply | |||||
| } | |||||
| return "" | |||||
| } | |||||
| type WechatReplyContent struct { | |||||
| Reply *ReplyContent | |||||
| ReplyType string | |||||
| KeyWords []string | |||||
| IsFullMatch int | |||||
| } | |||||
| type ReplyContent struct { | |||||
| Content string | |||||
| MediaId string | |||||
| Title string | |||||
| Description string | |||||
| MusicUrl string | |||||
| HQMusicUrl string | |||||
| ThumbMediaId string | |||||
| Articles []ArticlesContent | |||||
| } | |||||
| func GetAutomaticReply(msg string) *WechatReplyContent { | |||||
| r, err := LoadReplyFromCacheAndDisk(AutoMsgReply) | |||||
| if err != nil { | |||||
| return nil | |||||
| } | |||||
| if r == nil || len(r) == 0 { | |||||
| return nil | |||||
| } | |||||
| for i := 0; i < len(r); i++ { | |||||
| if r[i].IsFullMatch == 0 { | |||||
| for _, v := range r[i].KeyWords { | |||||
| if strings.Contains(msg, v) { | |||||
| return r[i] | |||||
| } | |||||
| } | |||||
| } else if r[i].IsFullMatch > 0 { | |||||
| for _, v := range r[i].KeyWords { | |||||
| if msg == v { | |||||
| return r[i] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| func loadReplyFromDisk(replyConfig ReplyConfigType) ([]*WechatReplyContent, error) { | |||||
| log.Info("LoadReply from disk") | |||||
| repo, err := models.GetRepositoryByOwnerAndAlias(setting.UserNameOfWechatReply, setting.RepoNameOfWechatReply) | |||||
| if err != nil { | |||||
| log.Error("get AutomaticReply repo failed, error=%v", err) | |||||
| return nil, err | |||||
| } | |||||
| repoFile, err := models.ReadLatestFileInRepo(setting.UserNameOfWechatReply, repo.Name, setting.RefNameOfWechatReply, replyConfig.TreePath()) | |||||
| if err != nil { | |||||
| log.Error("get AutomaticReply failed, error=%v", err) | |||||
| return nil, err | |||||
| } | |||||
| res := make([]*WechatReplyContent, 0) | |||||
| json.Unmarshal(repoFile.Content, &res) | |||||
| if res == nil || len(res) == 0 { | |||||
| return nil, err | |||||
| } | |||||
| return res, nil | |||||
| } | |||||
| func LoadReplyFromCacheAndDisk(replyConfig ReplyConfigType) ([]*WechatReplyContent, error) { | |||||
| v, success := WechatReplyCache.Get(replyConfig.Name()) | |||||
| if success { | |||||
| log.Info("LoadReply from cache,value = %v", v) | |||||
| if v == nil { | |||||
| return nil, nil | |||||
| } | |||||
| n := v.([]*WechatReplyContent) | |||||
| return n, nil | |||||
| } | |||||
| content, err := loadReplyFromDisk(replyConfig) | |||||
| if err != nil { | |||||
| log.Error("LoadReply failed, error=%v", err) | |||||
| WechatReplyCache.Set(replyConfig.Name(), nil, 30*time.Second) | |||||
| return nil, err | |||||
| } | |||||
| WechatReplyCache.Set(replyConfig.Name(), content, 60*time.Second) | |||||
| return content, nil | |||||
| } | |||||
| @@ -17,7 +17,8 @@ var ( | |||||
| const ( | const ( | ||||
| GRANT_TYPE = "client_credential" | GRANT_TYPE = "client_credential" | ||||
| ACCESS_TOKEN_PATH = "/cgi-bin/token" | ACCESS_TOKEN_PATH = "/cgi-bin/token" | ||||
| QR_CODE_Path = "/cgi-bin/qrcode/create" | |||||
| QR_CODE_PATH = "/cgi-bin/qrcode/create" | |||||
| GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material" | |||||
| ACTION_QR_STR_SCENE = "QR_STR_SCENE" | ACTION_QR_STR_SCENE = "QR_STR_SCENE" | ||||
| ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 | ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 | ||||
| @@ -40,6 +41,11 @@ type QRCodeRequest struct { | |||||
| Action_info ActionInfo `json:"action_info"` | Action_info ActionInfo `json:"action_info"` | ||||
| Expire_seconds int `json:"expire_seconds"` | Expire_seconds int `json:"expire_seconds"` | ||||
| } | } | ||||
| type MaterialRequest struct { | |||||
| Type string `json:"type"` | |||||
| Offset int `json:"offset"` | |||||
| Count int `json:"count"` | |||||
| } | |||||
| type ActionInfo struct { | type ActionInfo struct { | ||||
| Scene Scene `json:"scene"` | Scene Scene `json:"scene"` | ||||
| @@ -97,7 +103,7 @@ func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) { | |||||
| SetQueryParam("access_token", GetWechatAccessToken()). | SetQueryParam("access_token", GetWechatAccessToken()). | ||||
| SetBody(bodyJson). | SetBody(bodyJson). | ||||
| SetResult(&result). | SetResult(&result). | ||||
| Post(setting.WechatApiHost + QR_CODE_Path) | |||||
| Post(setting.WechatApiHost + QR_CODE_PATH) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("create QR code failed,e=%v", err) | log.Error("create QR code failed,e=%v", err) | ||||
| return nil, false | return nil, false | ||||
| @@ -113,6 +119,37 @@ func callQRCodeCreate(sceneStr string) (*QRCodeResponse, bool) { | |||||
| return &result, false | return &result, false | ||||
| } | } | ||||
| //getMaterial | |||||
| // api doc: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_materials_list.html | |||||
| func getMaterial(mType string, offset, count int) (interface{}, bool) { | |||||
| client := getWechatRestyClient() | |||||
| body := &MaterialRequest{ | |||||
| Type: mType, | |||||
| Offset: offset, | |||||
| Count: count, | |||||
| } | |||||
| bodyJson, _ := json.Marshal(body) | |||||
| r, err := client.R(). | |||||
| SetHeader("Content-Type", "application/json"). | |||||
| SetQueryParam("access_token", GetWechatAccessToken()). | |||||
| SetBody(bodyJson). | |||||
| Post(setting.WechatApiHost + GET_MATERIAL_PATH) | |||||
| if err != nil { | |||||
| log.Error("create QR code failed,e=%v", err) | |||||
| return nil, false | |||||
| } | |||||
| a := r.Body() | |||||
| resultMap := make(map[string]interface{}, 0) | |||||
| json.Unmarshal(a, &resultMap) | |||||
| errcode := resultMap["errcode"] | |||||
| if errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_EXPIRE) || errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_INVALID) { | |||||
| return nil, true | |||||
| } | |||||
| log.Info("%v", r) | |||||
| return &resultMap, false | |||||
| } | |||||
| func getErrorCodeFromResponse(r *resty.Response) int { | func getErrorCodeFromResponse(r *resty.Response) int { | ||||
| a := r.Body() | a := r.Body() | ||||
| resultMap := make(map[string]interface{}, 0) | resultMap := make(map[string]interface{}, 0) | ||||
| @@ -18,7 +18,7 @@ import ( | |||||
| // <EventKey><![CDATA[SCENE_VALUE]]></EventKey> | // <EventKey><![CDATA[SCENE_VALUE]]></EventKey> | ||||
| // <Ticket><![CDATA[TICKET]]></Ticket> | // <Ticket><![CDATA[TICKET]]></Ticket> | ||||
| //</xml> | //</xml> | ||||
| type WechatEvent struct { | |||||
| type WechatMsg struct { | |||||
| ToUserName string | ToUserName string | ||||
| FromUserName string | FromUserName string | ||||
| CreateTime int64 | CreateTime int64 | ||||
| @@ -26,9 +26,13 @@ type WechatEvent struct { | |||||
| Event string | Event string | ||||
| EventKey string | EventKey string | ||||
| Ticket string | Ticket string | ||||
| Content string | |||||
| MsgId string | |||||
| MsgDataId string | |||||
| Idx string | |||||
| } | } | ||||
| type EventReply struct { | |||||
| type MsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | XMLName xml.Name `xml:"xml"` | ||||
| ToUserName string | ToUserName string | ||||
| FromUserName string | FromUserName string | ||||
| @@ -37,16 +41,97 @@ type EventReply struct { | |||||
| Content string | Content string | ||||
| } | } | ||||
| type TextMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| Content string | |||||
| } | |||||
| type ImageMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| Image ImageContent | |||||
| } | |||||
| type VoiceMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| Voice VoiceContent | |||||
| } | |||||
| type VideoMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| Video VideoContent | |||||
| } | |||||
| type MusicMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| Music MusicContent | |||||
| } | |||||
| type NewsMsgReply struct { | |||||
| XMLName xml.Name `xml:"xml"` | |||||
| ToUserName string | |||||
| FromUserName string | |||||
| CreateTime int64 | |||||
| MsgType string | |||||
| ArticleCount int | |||||
| Articles ArticleItem | |||||
| } | |||||
| type ArticleItem struct { | |||||
| Item []ArticlesContent | |||||
| } | |||||
| type ImageContent struct { | |||||
| MediaId string | |||||
| } | |||||
| type VoiceContent struct { | |||||
| MediaId string | |||||
| } | |||||
| type VideoContent struct { | |||||
| MediaId string | |||||
| Title string | |||||
| Description string | |||||
| } | |||||
| type MusicContent struct { | |||||
| Title string | |||||
| Description string | |||||
| MusicUrl string | |||||
| HQMusicUrl string | |||||
| ThumbMediaId string | |||||
| } | |||||
| type ArticlesContent struct { | |||||
| XMLName xml.Name `xml:"item"` | |||||
| Title string | |||||
| Description string | |||||
| PicUrl string | |||||
| Url string | |||||
| } | |||||
| const ( | const ( | ||||
| WECHAT_EVENT_SUBSCRIBE = "subscribe" | WECHAT_EVENT_SUBSCRIBE = "subscribe" | ||||
| WECHAT_EVENT_SCAN = "SCAN" | WECHAT_EVENT_SCAN = "SCAN" | ||||
| ) | ) | ||||
| const ( | const ( | ||||
| WECHAT_MSG_TYPE_TEXT = "text" | |||||
| WECHAT_MSG_TYPE_TEXT = "text" | |||||
| WECHAT_MSG_TYPE_EVENT = "event" | |||||
| ) | ) | ||||
| func HandleSubscribeEvent(we WechatEvent) string { | |||||
| func HandleScanEvent(we WechatMsg) string { | |||||
| eventKey := we.EventKey | eventKey := we.EventKey | ||||
| if eventKey == "" { | if eventKey == "" { | ||||
| return "" | return "" | ||||
| @@ -74,3 +159,11 @@ func HandleSubscribeEvent(we WechatEvent) string { | |||||
| return BIND_REPLY_SUCCESS | return BIND_REPLY_SUCCESS | ||||
| } | } | ||||
| func HandleSubscribeEvent(we WechatMsg) *WechatReplyContent { | |||||
| r, err := LoadReplyFromCacheAndDisk(SubscribeReply) | |||||
| if err != nil || len(r) == 0 { | |||||
| return nil | |||||
| } | |||||
| return r[0] | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| package wechat | |||||
| import "code.gitea.io/gitea/modules/log" | |||||
| func GetWechatMaterial(mType string, offset, count int) interface{} { | |||||
| result, retryFlag := getMaterial(mType, offset, count) | |||||
| if retryFlag { | |||||
| log.Info("retryGetWechatMaterial calling") | |||||
| refreshAccessToken() | |||||
| result, _ = getMaterial(mType, offset, count) | |||||
| } | |||||
| return result | |||||
| } | |||||
| @@ -19,8 +19,8 @@ const ( | |||||
| ProcessorTypeNPU = "npu.huawei.com/NPU" | ProcessorTypeNPU = "npu.huawei.com/NPU" | ||||
| ProcessorTypeGPU = "nvidia.com/gpu" | ProcessorTypeGPU = "nvidia.com/gpu" | ||||
| CommandPrepareScript = "pwd;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;" | |||||
| 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;" + | //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;" + | // "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;" + | ||||
| @@ -101,7 +101,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| ImageUrl: req.ImageUrl, | ImageUrl: req.ImageUrl, | ||||
| CenterID: CenterID, | CenterID: CenterID, | ||||
| CenterName: CenterName, | CenterName: CenterName, | ||||
| ReplicaNum: 0, | |||||
| ReplicaNum: 1, | |||||
| }, | }, | ||||
| }, | }, | ||||
| }) | }) | ||||
| @@ -149,9 +149,9 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| var actionType models.ActionType | var actionType models.ActionType | ||||
| if req.ComputeResource == models.NPUResource { | if req.ComputeResource == models.NPUResource { | ||||
| actionType = models.ActionCreateTrainTask | |||||
| actionType = models.ActionCreateGrampusNPUTrainTask | |||||
| } else if req.ComputeResource == models.GPUResource { | } else if req.ComputeResource == models.GPUResource { | ||||
| actionType = models.ActionCreateGPUTrainTask | |||||
| actionType = models.ActionCreateGrampusGPUTrainTask | |||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, actionType) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, actionType) | ||||
| @@ -159,8 +159,8 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| } | } | ||||
| func TransTrainJobStatus(status string) string { | func TransTrainJobStatus(status string) string { | ||||
| if status == "pending" { | |||||
| status = "waiting" | |||||
| if status == models.GrampusStatusPending { | |||||
| status = models.GrampusStatusWaiting | |||||
| } | } | ||||
| return strings.ToUpper(status) | return strings.ToUpper(status) | ||||
| @@ -554,6 +554,13 @@ var ( | |||||
| WechatQRCodeExpireSeconds int | WechatQRCodeExpireSeconds int | ||||
| WechatAuthSwitch bool | WechatAuthSwitch bool | ||||
| //wechat auto reply config | |||||
| UserNameOfWechatReply string | |||||
| RepoNameOfWechatReply string | |||||
| RefNameOfWechatReply string | |||||
| TreePathOfAutoMsgReply string | |||||
| TreePathOfSubscribe string | |||||
| //nginx proxy | //nginx proxy | ||||
| PROXYURL string | PROXYURL string | ||||
| RadarMap = struct { | RadarMap = struct { | ||||
| @@ -1381,6 +1388,11 @@ func NewContext() { | |||||
| WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") | WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") | ||||
| WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) | WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) | ||||
| WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) | WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) | ||||
| UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG") | |||||
| RepoNameOfWechatReply = sec.Key("AUTO_REPLY_REPO_NAME").MustString("promote") | |||||
| RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master") | |||||
| TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json") | |||||
| TreePathOfSubscribe = sec.Key("SUBSCRIBE_TREE_PATH").MustString("wechat/subscribe_reply.json") | |||||
| SetRadarMapConfig() | SetRadarMapConfig() | ||||
| @@ -1177,7 +1177,7 @@ model.manage.model_manage = ModelManage | |||||
| model.manage.model_accuracy = Model Accuracy | model.manage.model_accuracy = Model Accuracy | ||||
| grampus.train_job.ai_center = AI Center | grampus.train_job.ai_center = AI Center | ||||
| grampus.dataset_path_rule = The code is storaged in /tmp/code;the dataset is storaged in /tmp/dataset;and please put your model into /tmp/output, then you can download it online。 | |||||
| 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。 | |||||
| grampus.no_operate_right = You have no right to do this operation. | grampus.no_operate_right = You have no right to do this operation. | ||||
| template.items = Template Items | template.items = Template Items | ||||
| @@ -2939,6 +2939,8 @@ task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s | |||||
| task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>` | task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>` | ||||
| task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
| task_gputrainjob=`created CPU/GPU training task<a href="%s/cloudbrain/train-job/%s">%s</a>` | task_gputrainjob=`created CPU/GPU training task<a href="%s/cloudbrain/train-job/%s">%s</a>` | ||||
| task_c2netnputrainjob=`created NPU training task<a href="%s/grampus/train-job/%s">%s</a>` | |||||
| task_c2netgputrainjob=`created CPU/GPU training task<a href="%s/grampus/train-job/%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago = %s ago | ago = %s ago | ||||
| @@ -1191,7 +1191,7 @@ model.manage.model_manage = 模型管理 | |||||
| model.manage.model_accuracy = 模型精度 | model.manage.model_accuracy = 模型精度 | ||||
| grampus.train_job.ai_center=智算中心 | grampus.train_job.ai_center=智算中心 | ||||
| grampus.dataset_path_rule = 训练脚本存储在/tmp/code中,数据集存储在/tmp/dataset中,训练输出请存储在/tmp/output中以供后续下载。 | |||||
| grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。 | |||||
| grampus.no_operate_right = 您没有权限创建这类任务。 | grampus.no_operate_right = 您没有权限创建这类任务。 | ||||
| @@ -1425,7 +1425,7 @@ issues.label_templates.helper=选择标签模板 | |||||
| issues.label_templates.use=使用标签集 | issues.label_templates.use=使用标签集 | ||||
| issues.label_templates.fail_to_load_file=加载标签模板文件 '%s' 时发生错误:%v | issues.label_templates.fail_to_load_file=加载标签模板文件 '%s' 时发生错误:%v | ||||
| issues.add_label_at=添加了标签 <div class="ui label" style="color: %s\; background-color: %s"> %s </div> %s | issues.add_label_at=添加了标签 <div class="ui label" style="color: %s\; background-color: %s"> %s </div> %s | ||||
| issues.remove_label_at=删除了 <div class="ui label" style="color: %s\; background-color: %s">%s</div> label %s 标签 | |||||
| issues.remove_label_at=删除了标签 <div class="ui label" style="color: %s\; background-color: %s">%s </div> %s | |||||
| issues.add_milestone_at=` %[2]s 添加了里程碑 <b>%[1]s</b>` | issues.add_milestone_at=` %[2]s 添加了里程碑 <b>%[1]s</b>` | ||||
| issues.change_milestone_at=`%[3]s 修改了里程碑从 <b>%[1]s</b> 到 <b>%[2]s</b>` | issues.change_milestone_at=`%[3]s 修改了里程碑从 <b>%[1]s</b> 到 <b>%[2]s</b>` | ||||
| issues.remove_milestone_at=`%[2]s 删除了里程碑 <b>%[1]s</b>` | issues.remove_milestone_at=`%[2]s 删除了里程碑 <b>%[1]s</b>` | ||||
| @@ -2955,6 +2955,8 @@ task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s" | |||||
| task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>` | ||||
| task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | ||||
| task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>` | task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>` | ||||
| task_c2netnputrainjob=`创建了NPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>` | |||||
| task_c2netgputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>` | |||||
| [tool] | [tool] | ||||
| ago=%s前 | ago=%s前 | ||||
| @@ -74,28 +74,30 @@ var swiperOrg = new Swiper(".homeorg-list", { | |||||
| }, | }, | ||||
| }); | }); | ||||
| var output = document.getElementById("newmessage"); | |||||
| var url = "ws://" + document.location.host + "/action/notification"; | |||||
| if(document.location.host == "git.openi.org.cn" || document.URL.startsWith("https")){ | |||||
| url = "wss://" + document.location.host + "/action/notification" | |||||
| } | |||||
| var socket = new WebSocket(url); | |||||
| socket.onopen = function () { | |||||
| messageQueue = []; | |||||
| console.log("message has connected."); | |||||
| }; | |||||
| var maxSize = 20; | var maxSize = 20; | ||||
| var html =document.documentElement; | var html =document.documentElement; | ||||
| var lang = html.attributes["lang"] | var lang = html.attributes["lang"] | ||||
| var isZh = true; | var isZh = true; | ||||
| if(lang != null && lang.nodeValue =="en-US" ){ | if(lang != null && lang.nodeValue =="en-US" ){ | ||||
| isZh=false; | isZh=false; | ||||
| }else{ | |||||
| } | } | ||||
| socket.onmessage = function (e) { | |||||
| document.onreadystatechange = function () { | |||||
| queryRecommendData(); | |||||
| var output = document.getElementById("newmessage"); | |||||
| var url = "ws://" + document.location.host + "/action/notification"; | |||||
| if(document.location.host == "git.openi.org.cn" || document.URL.startsWith("https")){ | |||||
| url = "wss://" + document.location.host + "/action/notification" | |||||
| } | |||||
| var socket = new WebSocket(url); | |||||
| socket.onopen = function () { | |||||
| messageQueue = []; | |||||
| console.log("message has connected."); | |||||
| }; | |||||
| socket.onmessage = function (e) { | |||||
| var data =JSON.parse(e.data) | var data =JSON.parse(e.data) | ||||
| var html = ""; | var html = ""; | ||||
| if (data != null){ | if (data != null){ | ||||
| @@ -176,7 +178,10 @@ socket.onmessage = function (e) { | |||||
| output.innerHTML = html; | output.innerHTML = html; | ||||
| swiperNewMessage.updateSlides(); | swiperNewMessage.updateSlides(); | ||||
| swiperNewMessage.updateProgress(); | swiperNewMessage.updateProgress(); | ||||
| }; | |||||
| }; | |||||
| } | |||||
| function getTaskLink(record){ | function getTaskLink(record){ | ||||
| var re = getRepoLink(record); | var re = getRepoLink(record); | ||||
| @@ -217,9 +222,9 @@ function refresh3DInfo(record){ | |||||
| //console.log("cloudbrain two line length=" + lines.length); | //console.log("cloudbrain two line length=" + lines.length); | ||||
| var span = $('.rotation3D__line').find("span")[1]; | var span = $('.rotation3D__line').find("span")[1]; | ||||
| //console.log(span); | //console.log(span); | ||||
| span.innerText =record.RefName; | |||||
| //$('.rotation3D__line').find("span").eq(1).text(record.RefName) | |||||
| //lines[1].find("span").text(record.RefName); | |||||
| if(span != null){ | |||||
| span.innerText =record.RefName; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -437,7 +442,9 @@ function getAction(opType,isZh){ | |||||
| } | } | ||||
| } | } | ||||
| queryRecommendData(); | |||||
| function queryRecommendData(){ | function queryRecommendData(){ | ||||
| $.ajax({ | $.ajax({ | ||||
| @@ -452,48 +459,12 @@ function queryRecommendData(){ | |||||
| displayOrg(json.org); | displayOrg(json.org); | ||||
| displayRepo(json.repo); | displayRepo(json.repo); | ||||
| displayActivity(json.image); | displayActivity(json.image); | ||||
| displayCloudBrain(json.cloudbrain) | |||||
| }, | }, | ||||
| error:function(response) { | error:function(response) { | ||||
| } | } | ||||
| }); | }); | ||||
| // $.ajax({ | |||||
| // type:"GET", | |||||
| // url:"/recommend/repo", | |||||
| // headers: { | |||||
| // authorization:token, | |||||
| // }, | |||||
| // dataType:"json", | |||||
| // async:false, | |||||
| // success:function(json){ | |||||
| // displayRepo(json); | |||||
| // }, | |||||
| // error:function(response) { | |||||
| // } | |||||
| // }); | |||||
| // $.ajax({ | |||||
| // type:"GET", | |||||
| // url:"/recommend/imageinfo", | |||||
| // headers: { | |||||
| // authorization:token, | |||||
| // }, | |||||
| // dataType:"json", | |||||
| // async:false, | |||||
| // success:function(json){ | |||||
| // displayActivity(json); | |||||
| // }, | |||||
| // error:function(response) { | |||||
| // } | |||||
| // }); | |||||
| } | } | ||||
| function displayCloudBrain(json){ | |||||
| $('#completed_task').text(json.completed_task); | |||||
| $('#running_task').text(json.running_task); | |||||
| $('#wait_task').text(json.wait_task); | |||||
| } | |||||
| function displayActivity(json){ | function displayActivity(json){ | ||||
| var activityDiv = document.getElementById("recommendactivity"); | var activityDiv = document.getElementById("recommendactivity"); | ||||
| @@ -1055,6 +1055,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/prd/event", authentication.ValidEventSource) | m.Get("/prd/event", authentication.ValidEventSource) | ||||
| m.Post("/prd/event", authentication.AcceptWechatEvent) | m.Post("/prd/event", authentication.AcceptWechatEvent) | ||||
| }) | }) | ||||
| m.Get("/wechat/material", authentication.GetMaterial) | |||||
| }, securityHeaders(), context.APIContexter(), sudo()) | }, securityHeaders(), context.APIContexter(), sudo()) | ||||
| } | } | ||||
| @@ -67,7 +67,7 @@ func GetAllCloudbrainsOverview(ctx *context.Context) { | |||||
| pagesize := 1000 | pagesize := 1000 | ||||
| count := pagesize | count := pagesize | ||||
| for count == pagesize && count != 0 { | for count == pagesize && count != 0 { | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: pagesize, | PageSize: pagesize, | ||||
| @@ -121,6 +121,13 @@ func GetAllCloudbrainsOverview(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| cloudBrainTypeList := []int{0, 1, 2} | |||||
| for _, v := range cloudBrainTypeList { | |||||
| if _, ok := cloudBrainNum[v]; !ok { | |||||
| cloudBrainNum[v] = 0 | |||||
| } | |||||
| } | |||||
| todayRunningCount := todayStatusResult[string(models.JobRunning)] | todayRunningCount := todayStatusResult[string(models.JobRunning)] | ||||
| todayCompletedCount := todayStatusResult[string(models.ModelArtsTrainJobCompleted)] + todayStatusResult[string(models.JobFailed)] + | todayCompletedCount := todayStatusResult[string(models.ModelArtsTrainJobCompleted)] + todayStatusResult[string(models.JobFailed)] + | ||||
| todayStatusResult[string(models.ModelArtsStartFailed)] + todayStatusResult[string(models.JobStopped)] + todayStatusResult[string(models.JobSucceeded)] + todayStatusResult[string(models.ModelArtsTrainJobKilled)] | todayStatusResult[string(models.ModelArtsStartFailed)] + todayStatusResult[string(models.JobStopped)] + todayStatusResult[string(models.JobSucceeded)] + todayStatusResult[string(models.ModelArtsTrainJobKilled)] | ||||
| @@ -504,7 +511,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) { | |||||
| count := pagesize | count := pagesize | ||||
| //Each time a maximum of 1000 pieces of data are detected to the memory, batch processing | //Each time a maximum of 1000 pieces of data are detected to the memory, batch processing | ||||
| for count == pagesize && count != 0 { | for count == pagesize && count != 0 { | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: pagesize, | PageSize: pagesize, | ||||
| @@ -613,7 +620,7 @@ func GetCloudbrainsStatusAnalysis(ctx *context.Context) { | |||||
| pagesize := 1000 | pagesize := 1000 | ||||
| count := pagesize | count := pagesize | ||||
| for count == pagesize && count != 0 { | for count == pagesize && count != 0 { | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: pagesize, | PageSize: pagesize, | ||||
| @@ -1021,7 +1028,7 @@ func getCloudbrainCount(beginTime time.Time, endTime time.Time, cloudbrains []*m | |||||
| func getDayCloudbrainNum(beginTime time.Time, endTime time.Time) ([]DateCloudbrainNum, error) { | func getDayCloudbrainNum(beginTime time.Time, endTime time.Time) ([]DateCloudbrainNum, error) { | ||||
| var endTimeTemp time.Time | var endTimeTemp time.Time | ||||
| endTimeTemp = beginTime.AddDate(0, 0, 1) | endTimeTemp = beginTime.AddDate(0, 0, 1) | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| Type: models.TypeCloudBrainAll, | Type: models.TypeCloudBrainAll, | ||||
| BeginTimeUnix: beginTime.Unix(), | BeginTimeUnix: beginTime.Unix(), | ||||
| EndTimeUnix: endTime.Unix(), | EndTimeUnix: endTime.Unix(), | ||||
| @@ -1057,7 +1064,7 @@ func getMonthCloudbrainNum(beginTime time.Time, endTime time.Time) ([]DateCloudb | |||||
| endTimeTemp = beginTime.AddDate(0, 1, 0) | endTimeTemp = beginTime.AddDate(0, 1, 0) | ||||
| endTimeTemp = time.Date(endTimeTemp.Year(), endTimeTemp.Month(), 1, 0, 0, 0, 0, now.Location()) | endTimeTemp = time.Date(endTimeTemp.Year(), endTimeTemp.Month(), 1, 0, 0, 0, 0, now.Location()) | ||||
| monthCloudbrainNum := make([]DateCloudbrainNum, 0) | monthCloudbrainNum := make([]DateCloudbrainNum, 0) | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| Type: models.TypeCloudBrainAll, | Type: models.TypeCloudBrainAll, | ||||
| BeginTimeUnix: beginTime.Unix(), | BeginTimeUnix: beginTime.Unix(), | ||||
| EndTimeUnix: endTime.Unix(), | EndTimeUnix: endTime.Unix(), | ||||
| @@ -1093,7 +1100,7 @@ func getDayCloudbrainInfo(beginTime time.Time, endTime time.Time) ([]DateCloudbr | |||||
| if endTimeTemp.Equal(endTime) { | if endTimeTemp.Equal(endTime) { | ||||
| endTimeTemp = endTimeTemp.AddDate(0, 0, -1) | endTimeTemp = endTimeTemp.AddDate(0, 0, -1) | ||||
| } | } | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| Type: models.TypeCloudBrainAll, | Type: models.TypeCloudBrainAll, | ||||
| BeginTimeUnix: beginTime.Unix(), | BeginTimeUnix: beginTime.Unix(), | ||||
| EndTimeUnix: endTime.Unix(), | EndTimeUnix: endTime.Unix(), | ||||
| @@ -1124,7 +1131,7 @@ func getMonthCloudbrainInfo(beginTime time.Time, endTime time.Time) ([]DateCloud | |||||
| if endTimeTemp.Equal(endTime) { | if endTimeTemp.Equal(endTime) { | ||||
| endTimeTemp = endTimeTemp.AddDate(0, -1, 0) | endTimeTemp = endTimeTemp.AddDate(0, -1, 0) | ||||
| } | } | ||||
| cloudbrains, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{ | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| Type: models.TypeCloudBrainAll, | Type: models.TypeCloudBrainAll, | ||||
| BeginTimeUnix: beginTime.Unix(), | BeginTimeUnix: beginTime.Unix(), | ||||
| EndTimeUnix: endTime.Unix(), | EndTimeUnix: endTime.Unix(), | ||||
| @@ -127,7 +127,8 @@ func GetModelArtsTrainJob(ctx *context.APIContext) { | |||||
| func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | ||||
| var ( | var ( | ||||
| err error | |||||
| err error | |||||
| aiCenterName string | |||||
| ) | ) | ||||
| jobID := ctx.Params(":jobid") | jobID := ctx.Params(":jobid") | ||||
| @@ -210,6 +211,20 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
| job.EndTime = job.StartTime.Add(job.Duration) | job.EndTime = job.StartTime.Add(job.Duration) | ||||
| } | } | ||||
| job.CorrectCreateUnix() | 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) | err = models.UpdateTrainJobVersion(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -220,6 +235,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
| "JobID": jobID, | "JobID": jobID, | ||||
| "JobStatus": job.Status, | "JobStatus": job.Status, | ||||
| "JobDuration": job.TrainJobDuration, | "JobDuration": job.TrainJobDuration, | ||||
| "AiCenter": aiCenterName, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -8,9 +8,11 @@ import ( | |||||
| "code.gitea.io/gitea/modules/redis/redis_client" | "code.gitea.io/gitea/modules/redis/redis_client" | ||||
| "code.gitea.io/gitea/modules/redis/redis_key" | "code.gitea.io/gitea/modules/redis/redis_key" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/routers/response" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| gouuid "github.com/satori/go.uuid" | gouuid "github.com/satori/go.uuid" | ||||
| "strconv" | |||||
| "time" | "time" | ||||
| ) | ) | ||||
| @@ -124,3 +126,23 @@ func createQRCode4Bind(userId int64) (*QRCodeResponse, error) { | |||||
| } | } | ||||
| return result, nil | return result, nil | ||||
| } | } | ||||
| // GetMaterial | |||||
| func GetMaterial(ctx *context.Context) { | |||||
| mType := ctx.Query("type") | |||||
| offsetStr := ctx.Query("offset") | |||||
| countStr := ctx.Query("count") | |||||
| var offset, count int | |||||
| if offsetStr == "" { | |||||
| offset = 0 | |||||
| } else { | |||||
| offset, _ = strconv.Atoi(offsetStr) | |||||
| } | |||||
| if countStr == "" { | |||||
| count = 20 | |||||
| } else { | |||||
| count, _ = strconv.Atoi(countStr) | |||||
| } | |||||
| r := wechat.GetWechatMaterial(mType, offset, count) | |||||
| ctx.JSON(200, response.SuccessWithData(r)) | |||||
| } | |||||
| @@ -14,24 +14,48 @@ import ( | |||||
| // https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html | // https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html | ||||
| func AcceptWechatEvent(ctx *context.Context) { | func AcceptWechatEvent(ctx *context.Context) { | ||||
| b, _ := ioutil.ReadAll(ctx.Req.Request.Body) | b, _ := ioutil.ReadAll(ctx.Req.Request.Body) | ||||
| we := wechat.WechatEvent{} | |||||
| we := wechat.WechatMsg{} | |||||
| xml.Unmarshal(b, &we) | xml.Unmarshal(b, &we) | ||||
| switch we.MsgType { | |||||
| case wechat.WECHAT_MSG_TYPE_EVENT: | |||||
| HandleEventMsg(ctx, we) | |||||
| case wechat.WECHAT_MSG_TYPE_TEXT: | |||||
| HandleTextMsg(ctx, we) | |||||
| } | |||||
| log.Info("accept wechat event= %+v", we) | log.Info("accept wechat event= %+v", we) | ||||
| var replyStr string | |||||
| switch we.Event { | |||||
| case wechat.WECHAT_EVENT_SUBSCRIBE, wechat.WECHAT_EVENT_SCAN: | |||||
| replyStr = wechat.HandleSubscribeEvent(we) | |||||
| break | |||||
| } | |||||
| // ValidEventSource | |||||
| func ValidEventSource(ctx *context.Context) { | |||||
| echostr := ctx.Query("echostr") | |||||
| ctx.Write([]byte(echostr)) | |||||
| return | |||||
| } | |||||
| func HandleEventMsg(ctx *context.Context, msg wechat.WechatMsg) { | |||||
| switch msg.Event { | |||||
| case wechat.WECHAT_EVENT_SCAN: | |||||
| HandleEventScan(ctx, msg) | |||||
| case wechat.WECHAT_EVENT_SUBSCRIBE: | |||||
| if msg.EventKey != "" { | |||||
| HandleEventScan(ctx, msg) | |||||
| } else { | |||||
| HandleEventSubscribe(ctx, msg) | |||||
| } | |||||
| } | } | ||||
| } | |||||
| func HandleEventScan(ctx *context.Context, msg wechat.WechatMsg) { | |||||
| replyStr := wechat.HandleScanEvent(msg) | |||||
| if replyStr == "" { | if replyStr == "" { | ||||
| log.Info("reply str is empty") | log.Info("reply str is empty") | ||||
| return | return | ||||
| } | } | ||||
| reply := &wechat.EventReply{ | |||||
| ToUserName: we.FromUserName, | |||||
| FromUserName: we.ToUserName, | |||||
| reply := &wechat.MsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | CreateTime: time.Now().Unix(), | ||||
| MsgType: wechat.WECHAT_MSG_TYPE_TEXT, | MsgType: wechat.WECHAT_MSG_TYPE_TEXT, | ||||
| Content: replyStr, | Content: replyStr, | ||||
| @@ -39,9 +63,99 @@ func AcceptWechatEvent(ctx *context.Context) { | |||||
| ctx.XML(200, reply) | ctx.XML(200, reply) | ||||
| } | } | ||||
| // ValidEventSource | |||||
| func ValidEventSource(ctx *context.Context) { | |||||
| echostr := ctx.Query("echostr") | |||||
| ctx.Write([]byte(echostr)) | |||||
| return | |||||
| func HandleEventSubscribe(ctx *context.Context, msg wechat.WechatMsg) { | |||||
| r := wechat.HandleSubscribeEvent(msg) | |||||
| if r == nil { | |||||
| return | |||||
| } | |||||
| reply := buildReplyContent(msg, r) | |||||
| ctx.XML(200, reply) | |||||
| } | |||||
| func HandleTextMsg(ctx *context.Context, msg wechat.WechatMsg) { | |||||
| r := wechat.GetAutomaticReply(msg.Content) | |||||
| if r == nil { | |||||
| log.Info("TextMsg reply is empty") | |||||
| return | |||||
| } | |||||
| reply := buildReplyContent(msg, r) | |||||
| ctx.XML(200, reply) | |||||
| } | |||||
| func buildReplyContent(msg wechat.WechatMsg, r *wechat.WechatReplyContent) interface{} { | |||||
| reply := &wechat.MsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| } | |||||
| switch r.ReplyType { | |||||
| case wechat.ReplyTypeText: | |||||
| return &wechat.TextMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| Content: r.Reply.Content, | |||||
| } | |||||
| case wechat.ReplyTypeImage: | |||||
| return &wechat.ImageMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| Image: wechat.ImageContent{ | |||||
| MediaId: r.Reply.MediaId, | |||||
| }, | |||||
| } | |||||
| case wechat.ReplyTypeVoice: | |||||
| return &wechat.VoiceMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| Voice: wechat.VoiceContent{ | |||||
| MediaId: r.Reply.MediaId, | |||||
| }, | |||||
| } | |||||
| case wechat.ReplyTypeVideo: | |||||
| return &wechat.VideoMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| Video: wechat.VideoContent{ | |||||
| MediaId: r.Reply.MediaId, | |||||
| Title: r.Reply.Title, | |||||
| Description: r.Reply.Description, | |||||
| }, | |||||
| } | |||||
| case wechat.ReplyTypeMusic: | |||||
| return &wechat.MusicMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| Music: wechat.MusicContent{ | |||||
| Title: r.Reply.Title, | |||||
| Description: r.Reply.Description, | |||||
| MusicUrl: r.Reply.MusicUrl, | |||||
| HQMusicUrl: r.Reply.HQMusicUrl, | |||||
| ThumbMediaId: r.Reply.ThumbMediaId, | |||||
| }, | |||||
| } | |||||
| case wechat.ReplyTypeNews: | |||||
| return &wechat.NewsMsgReply{ | |||||
| ToUserName: msg.FromUserName, | |||||
| FromUserName: msg.ToUserName, | |||||
| CreateTime: time.Now().Unix(), | |||||
| MsgType: r.ReplyType, | |||||
| ArticleCount: len(r.Reply.Articles), | |||||
| Articles: wechat.ArticleItem{ | |||||
| Item: r.Reply.Articles}, | |||||
| } | |||||
| } | |||||
| return reply | |||||
| } | } | ||||
| @@ -7,7 +7,6 @@ package routers | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "fmt" | |||||
| "net/http" | "net/http" | ||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| @@ -675,10 +674,19 @@ func getRecommendOrg() ([]map[string]interface{}, error) { | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| names := make([]string, 0) | |||||
| for _, userName := range result { | |||||
| names = append(names, userName) | |||||
| } | |||||
| users, _ := models.GetUsersByNames(names) | |||||
| userMap := make(map[string]*models.User, 0) | |||||
| for _, user := range users { | |||||
| userMap[user.Name] = user | |||||
| } | |||||
| resultOrg := make([]map[string]interface{}, 0) | resultOrg := make([]map[string]interface{}, 0) | ||||
| for _, userName := range result { | for _, userName := range result { | ||||
| user, err := models.GetUserByName(userName) | |||||
| if err == nil { | |||||
| user := userMap[userName] | |||||
| if user != nil { | |||||
| userMap := make(map[string]interface{}) | userMap := make(map[string]interface{}) | ||||
| userMap["Name"] = user.Name | userMap["Name"] = user.Name | ||||
| userMap["Description"] = user.Description | userMap["Description"] = user.Description | ||||
| @@ -691,7 +699,7 @@ func getRecommendOrg() ([]map[string]interface{}, error) { | |||||
| userMap["NumMembers"] = user.NumMembers | userMap["NumMembers"] = user.NumMembers | ||||
| resultOrg = append(resultOrg, userMap) | resultOrg = append(resultOrg, userMap) | ||||
| } else { | } else { | ||||
| log.Info("query user error," + err.Error()) | |||||
| log.Info("the user not exist," + userName) | |||||
| } | } | ||||
| } | } | ||||
| return resultOrg, nil | return resultOrg, nil | ||||
| @@ -760,15 +768,6 @@ func GetRankUser(index string) ([]map[string]interface{}, error) { | |||||
| return resultOrg, nil | return resultOrg, nil | ||||
| } | } | ||||
| // func GetImageInfoFromPromote(ctx *context.Context) { | |||||
| // imageInfo, err := GetImageInfo() | |||||
| // if err != nil { | |||||
| // ctx.ServerError("500", err) | |||||
| // return | |||||
| // } | |||||
| // ctx.JSON(200, imageInfo) | |||||
| // } | |||||
| func GetUserRankFromPromote(ctx *context.Context) { | func GetUserRankFromPromote(ctx *context.Context) { | ||||
| index := ctx.Params("index") | index := ctx.Params("index") | ||||
| resultUserRank, err := GetRankUser(index) | resultUserRank, err := GetRankUser(index) | ||||
| @@ -792,45 +791,15 @@ func RecommendHomeInfo(ctx *context.Context) { | |||||
| if err != nil { | if err != nil { | ||||
| log.Info("error." + err.Error()) | log.Info("error." + err.Error()) | ||||
| } | } | ||||
| resultCloudBrain, err := getCloudbrainNums() | |||||
| if err != nil { | |||||
| log.Info("error." + err.Error()) | |||||
| } | |||||
| mapInterface := make(map[string]interface{}) | mapInterface := make(map[string]interface{}) | ||||
| mapInterface["org"] = resultOrg | mapInterface["org"] = resultOrg | ||||
| mapInterface["repo"] = resultRepo | mapInterface["repo"] = resultRepo | ||||
| mapInterface["image"] = resultImage | mapInterface["image"] = resultImage | ||||
| mapInterface["cloudbrain"] = resultCloudBrain | |||||
| //mapInterface["cloudbrain"] = resultCloudBrain | |||||
| ctx.JSON(http.StatusOK, mapInterface) | ctx.JSON(http.StatusOK, mapInterface) | ||||
| } | } | ||||
| func getCloudbrainNums() (map[string]string, error) { | |||||
| result := make(map[string]string) | |||||
| cloudStatusMap := models.GetAllStatusCloudBrain() | |||||
| result["completed_task"] = fmt.Sprint(cloudStatusMap["COMPLETED"]) | |||||
| result["running_task"] = fmt.Sprint(cloudStatusMap["RUNNING"]) | |||||
| result["wait_task"] = fmt.Sprint(cloudStatusMap["WAITING"]) | |||||
| return result, nil | |||||
| } | |||||
| // func RecommendOrgFromPromote(ctx *context.Context) { | |||||
| // resultOrg, err := GetRecommendOrg() | |||||
| // if err != nil { | |||||
| // ctx.ServerError("500", err) | |||||
| // return | |||||
| // } | |||||
| // ctx.JSON(200, resultOrg) | |||||
| // } | |||||
| func RecommendRepoFromPromote(ctx *context.Context) { | |||||
| result, err := repository.GetRecommendRepoFromPromote("projects") | |||||
| if err != nil { | |||||
| ctx.ServerError("500", err) | |||||
| } else { | |||||
| ctx.JSON(200, result) | |||||
| } | |||||
| } | |||||
| func HomeTerm(ctx *context.Context) { | func HomeTerm(ctx *context.Context) { | ||||
| ctx.HTML(200, tplHomeTerm) | ctx.HTML(200, tplHomeTerm) | ||||
| } | } | ||||
| @@ -172,8 +172,8 @@ func DatasetIndex(ctx *context.Context) { | |||||
| for _, attachment := range pageAttachments { | for _, attachment := range pageAttachments { | ||||
| uploader, _ := models.GetUserByID(attachment.UploaderID) | uploader, _ := models.GetUserByID(attachment.UploaderID) | ||||
| attachment.Uploader = uploader | attachment.Uploader = uploader | ||||
| if !strings.HasSuffix(attachment.Name, ".zip") { | |||||
| attachment.DecompressState = -1 //非zip文件 | |||||
| if !strings.HasSuffix(attachment.Name, ".zip") && !strings.HasSuffix(attachment.Name, ".tar.gz") { | |||||
| attachment.DecompressState = -1 //非压缩文件 | |||||
| } | } | ||||
| } | } | ||||
| @@ -616,8 +616,14 @@ func DatasetIsCollaborator(ctx *context.Context, dataset *models.Dataset) bool { | |||||
| repo.GetOwner() | repo.GetOwner() | ||||
| if ctx.User != nil { | if ctx.User != nil { | ||||
| if repo.Owner.IsOrganization() { | if repo.Owner.IsOrganization() { | ||||
| if repo.Owner.IsUserPartOfOrg(ctx.User.ID) { | |||||
| for _, t := range repo.Owner.Teams { | |||||
| org := repo.Owner | |||||
| org.Teams, err = org.GetUserTeams(ctx.User.ID) | |||||
| if err != nil { | |||||
| log.Error("GetUserTeams error:", err.Error()) | |||||
| return false | |||||
| } | |||||
| if org.IsUserPartOfOrg(ctx.User.ID) { | |||||
| for _, t := range org.Teams { | |||||
| if t.IsMember(ctx.User.ID) && t.HasRepository(repo.ID) { | if t.IsMember(ctx.User.ID) && t.HasRepository(repo.ID) { | ||||
| return true | return true | ||||
| } | } | ||||
| @@ -108,11 +108,17 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err | |||||
| ctx.Data["branchName"] = ctx.Repo.BranchName | 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 | return nil | ||||
| } | } | ||||
| func grampusParamCheckCreateTrainJob(form auth.CreateGrampusTrainJobForm) error { | func grampusParamCheckCreateTrainJob(form auth.CreateGrampusTrainJobForm) error { | ||||
| if !strings.HasSuffix(form.BootFile, ".py") { | |||||
| if !strings.HasSuffix(strings.TrimSpace(form.BootFile), ".py") { | |||||
| log.Error("the boot file(%s) must be a python file", form.BootFile) | log.Error("the boot file(%s) must be a python file", form.BootFile) | ||||
| return errors.New("启动文件必须是python文件") | return errors.New("启动文件必须是python文件") | ||||
| } | } | ||||
| @@ -130,7 +136,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | ||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| bootFile := form.BootFile | |||||
| bootFile := strings.TrimSpace(form.BootFile) | |||||
| params := form.Params | params := form.Params | ||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| codeLocalPath := setting.JobPath + jobName + cloudbrain.CodeMountPath + "/" | codeLocalPath := setting.JobPath + jobName + cloudbrain.CodeMountPath + "/" | ||||
| @@ -310,7 +316,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | ||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| bootFile := form.BootFile | |||||
| bootFile := strings.TrimSpace(form.BootFile) | |||||
| params := form.Params | params := form.Params | ||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| codeLocalPath := setting.JobPath + jobName + modelarts.CodePath | codeLocalPath := setting.JobPath + jobName + modelarts.CodePath | ||||
| @@ -619,6 +625,7 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||||
| ctx.Data["version_list_task"] = taskList | ctx.Data["version_list_task"] = taskList | ||||
| ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | ||||
| ctx.Data["displayJobName"] = task.DisplayJobName | |||||
| aiCenterInfo := strings.Split(task.AiCenter, "+") | aiCenterInfo := strings.Split(task.AiCenter, "+") | ||||
| if len(aiCenterInfo) == 2 { | if len(aiCenterInfo) == 2 { | ||||
| @@ -665,14 +672,24 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||||
| command += commandDownload | command += commandDownload | ||||
| } | } | ||||
| //check download result | |||||
| commandCheckRes := "bash -c \"[[ $? -eq 0 ]] && exit 0 || exit -1;\";" | |||||
| command += commandCheckRes | |||||
| //unzip code & dataset | //unzip code & dataset | ||||
| toolUnzip := "unzip -q " | toolUnzip := "unzip -q " | ||||
| if strings.HasSuffix(datasetName, ".tar.gz") { | if strings.HasSuffix(datasetName, ".tar.gz") { | ||||
| toolUnzip = "tar -zxvf " | toolUnzip = "tar -zxvf " | ||||
| } | } | ||||
| commandUnzip := "cd /tmp/dataset;" + toolUnzip + datasetName + ";cd /tmp/code;unzip -q master.zip;" | |||||
| commandUnzip := "cd /cache/code;unzip -q master.zip;echo \"start to unzip dataset\";cd /cache/dataset;" + toolUnzip + datasetName + ";" | |||||
| command += commandUnzip | 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 | //exec code | ||||
| var parameters models.Parameters | var parameters models.Parameters | ||||
| var paramCode string | var paramCode string | ||||
| @@ -693,7 +710,7 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||||
| } | } | ||||
| } | } | ||||
| commandCode := "cd /tmp/code/" + strings.ToLower(repoName) + ";python " + bootFile + paramCode + ";" | |||||
| commandCode := "cd /cache/code/" + strings.ToLower(repoName) + ";python " + bootFile + paramCode + ";" | |||||
| command += commandCode | command += commandCode | ||||
| //get exec result | //get exec result | ||||
| @@ -702,15 +719,15 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||||
| //upload models | //upload models | ||||
| if processorType == grampus.ProcessorTypeNPU { | if processorType == grampus.ProcessorTypeNPU { | ||||
| commandUpload := "cd /tmp/script_for_grampus/;./uploader_for_obs " + setting.Bucket + " " + outputRemotePath + " " + "/tmp/output/;" | |||||
| commandUpload := "cd /cache/script_for_grampus/;./uploader_for_obs " + setting.Bucket + " " + outputRemotePath + " " + "/cache/output/;" | |||||
| command += commandUpload | command += commandUpload | ||||
| } else if processorType == grampus.ProcessorTypeGPU { | } else if processorType == grampus.ProcessorTypeGPU { | ||||
| commandUpload := "cd /tmp/script_for_grampus/;./uploader_for_minio " + setting.Grampus.Env + " " + outputRemotePath + " " + "/tmp/output/;" | |||||
| commandUpload := "cd /cache/script_for_grampus/;./uploader_for_minio " + setting.Grampus.Env + " " + outputRemotePath + " " + "/cache/output/;" | |||||
| command += commandUpload | command += commandUpload | ||||
| } | } | ||||
| //check exec result | //check exec result | ||||
| commandCheckRes := "bash -c \"[[ $result -eq 0 ]] && exit 0 || exit -1;\"" | |||||
| commandCheckRes = "bash -c \"[[ $result -eq 0 ]] && exit 0 || exit -1;\"" | |||||
| command += commandCheckRes | command += commandCheckRes | ||||
| return command, nil | return command, nil | ||||
| @@ -769,12 +769,6 @@ func Cloudbrains(ctx *context.Context) { | |||||
| if page <= 0 { | if page <= 0 { | ||||
| page = 1 | page = 1 | ||||
| } | } | ||||
| debugType := models.TypeCloudBrainAll | |||||
| if listType == models.GPUResource { | |||||
| debugType = models.TypeCloudBrainOne | |||||
| } else if listType == models.NPUResource { | |||||
| debugType = models.TypeCloudBrainTwo | |||||
| } | |||||
| var jobTypes []string | var jobTypes []string | ||||
| jobTypeNot := false | jobTypeNot := false | ||||
| @@ -821,7 +815,6 @@ func Cloudbrains(ctx *context.Context) { | |||||
| }, | }, | ||||
| Keyword: keyword, | Keyword: keyword, | ||||
| UserID: ctxUser.ID, | UserID: ctxUser.ID, | ||||
| Type: debugType, | |||||
| JobTypeNot: jobTypeNot, | JobTypeNot: jobTypeNot, | ||||
| JobStatusNot: jobStatusNot, | JobStatusNot: jobStatusNot, | ||||
| JobStatus: jobStatuses, | JobStatus: jobStatuses, | ||||
| @@ -829,6 +822,8 @@ func Cloudbrains(ctx *context.Context) { | |||||
| NeedRepoInfo: true, | NeedRepoInfo: true, | ||||
| IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
| RepoIDList: repoIDList, | RepoIDList: repoIDList, | ||||
| ComputeResource: listType, | |||||
| Type: models.TypeCloudBrainAll, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("Get job failed:", err) | ctx.ServerError("Get job failed:", err) | ||||
| @@ -131,11 +131,6 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err | |||||
| repoMap["ID"] = fmt.Sprint(repo.ID) | repoMap["ID"] = fmt.Sprint(repo.ID) | ||||
| repoMap["Name"] = repo.Name | repoMap["Name"] = repo.Name | ||||
| repoMap["Alias"] = repo.Alias | repoMap["Alias"] = repo.Alias | ||||
| if repo.RepoType == models.RepoCourse { | |||||
| //Load creator | |||||
| repo.GetCreator() | |||||
| repoMap["Creator"] = repo.Creator | |||||
| } | |||||
| repoMap["OwnerName"] = repo.OwnerName | repoMap["OwnerName"] = repo.OwnerName | ||||
| repoMap["NumStars"] = repo.NumStars | repoMap["NumStars"] = repo.NumStars | ||||
| @@ -18,7 +18,7 @@ | |||||
| .ui.list .list>.item>img.image+.content, | .ui.list .list>.item>img.image+.content, | ||||
| .ui.list>.item>img.image+.content { | .ui.list>.item>img.image+.content { | ||||
| width: calc(100% - 30px); | |||||
| width: calc(100% - 34px); | |||||
| margin-left: 0; | margin-left: 0; | ||||
| } | } | ||||
| @@ -107,9 +107,9 @@ | |||||
| {{range .Repos}} | {{range .Repos}} | ||||
| <div class="item"> | <div class="item"> | ||||
| {{if .RelAvatarLink}} | {{if .RelAvatarLink}} | ||||
| <img class="ui avatar image" src="{{.RelAvatarLink}}"> | |||||
| <img class="ui avatar image" style="width: 28px;height: 28px;" src="{{.RelAvatarLink}}"> | |||||
| {{else}} | {{else}} | ||||
| <img class="ui avatar image" avatar="{{.Owner.Name}}"> | |||||
| <img class="ui avatar image" style="width: 28px;height: 28px;" avatar="{{.Owner.Name}}"> | |||||
| {{end}} | {{end}} | ||||
| <div class="content"> | <div class="content"> | ||||
| <div class="ui header"> | <div class="ui header"> | ||||
| @@ -97,7 +97,7 @@ | |||||
| </a> | </a> | ||||
| <a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> | <a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> | ||||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | ||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}} | |||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -91,7 +91,7 @@ | |||||
| </a> | </a> | ||||
| <a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create"> | <a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create"> | ||||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | ||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}} | |||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -85,10 +85,9 @@ | |||||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | ||||
| {{.i18n.Tr "cloudbrain.resource_cluster_openi"}} | {{.i18n.Tr "cloudbrain.resource_cluster_openi"}} | ||||
| </a> | </a> | ||||
| <a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create"> | <a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create"> | ||||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | ||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}} | |||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -205,7 +204,7 @@ | |||||
| <button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
| <a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
| </div> | </div> | ||||
| <!-- 模态框 --> | <!-- 模态框 --> | ||||
| @@ -217,8 +216,7 @@ | |||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | <script> | ||||
| let url_href = window.location.pathname.split('create')[0] | |||||
| $(".ui.button").attr('href',url_href) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| @@ -430,7 +430,7 @@ | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | |||||
| <div class="text-span text-span-w" id="{{.VersionName}}-ai_center"> | |||||
| {{$.ai_center}} | {{$.ai_center}} | ||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| @@ -679,6 +679,7 @@ | |||||
| // detail status and duration | // detail status and duration | ||||
| $('#' + version_name + '-duration').text(data.JobDuration) | $('#' + version_name + '-duration').text(data.JobDuration) | ||||
| $('#' + version_name + '-status').text(data.JobStatus) | $('#' + version_name + '-status').text(data.JobStatus) | ||||
| $('#' + version_name + '-ai_center').text(data.AiCenter) | |||||
| loadLog(version_name) | loadLog(version_name) | ||||
| @@ -157,7 +157,7 @@ | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button"> | |||||
| <a class="ui basic disabled button"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -1,67 +1,72 @@ | |||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||
| <style> | <style> | ||||
| .unite { | |||||
| font-family: SourceHanSansSC-medium !important; | |||||
| color: rgba(16, 16, 16, 100) !important; | |||||
| } | |||||
| .title { | |||||
| font-size: 16px !important; | |||||
| padding-left: 3rem !important; | |||||
| } | |||||
| .min_title { | |||||
| font-size: 14px !important; | |||||
| padding-left: 6rem !important; | |||||
| margin-bottom: 2rem !important; | |||||
| } | |||||
| .width { | |||||
| width: 100% !important; | |||||
| } | |||||
| .width80 { | |||||
| width: 80.7% !important; | |||||
| margin-left: 10px; | |||||
| } | |||||
| .unite{ | |||||
| font-family: SourceHanSansSC-medium !important; | |||||
| color: rgba(16, 16, 16, 100) !important; | |||||
| } | |||||
| .title{ | |||||
| font-size: 16px !important; | |||||
| padding-left: 3rem !important; | |||||
| } | |||||
| .min_title{ | |||||
| font-size: 14px !important; | |||||
| padding-left: 6rem !important; | |||||
| margin-bottom: 2rem !important; | |||||
| } | |||||
| .width{ | |||||
| width:100% !important; | |||||
| } | |||||
| .width80{ | |||||
| width: 80.7% !important; | |||||
| margin-left: 10px; | |||||
| } | |||||
| .width85{ | |||||
| width: 85% !important; | |||||
| margin-left: 4.5rem !important; | |||||
| } | |||||
| .width81{ | |||||
| margin-left: 1.5rem; | |||||
| width: 81% !important; | |||||
| } | |||||
| .add{font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 0px 5px 5px 0px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| .min{ | |||||
| font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 5px 0px 0px 5px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| .width85 { | |||||
| width: 85% !important; | |||||
| margin-left: 4.5rem !important; | |||||
| } | |||||
| .width81 { | |||||
| margin-left: 1.5rem; | |||||
| width: 81% !important; | |||||
| } | |||||
| .add { | |||||
| font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 0px 5px 5px 0px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| .min { | |||||
| font-size: 18px; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(187, 187, 187, 100); | |||||
| border-radius: 5px 0px 0px 5px; | |||||
| line-height: 21px; | |||||
| text-align: center; | |||||
| color: #C2C7CC; | |||||
| } | |||||
| </style> | </style> | ||||
| <!-- <div class="ui page dimmer"> | <!-- <div class="ui page dimmer"> | ||||
| <div class="ui text loader">{{.i18n.Tr "loading"}}</div> | <div class="ui text loader">{{.i18n.Tr "loading"}}</div> | ||||
| </div> --> | </div> --> | ||||
| <div id="mask"> | <div id="mask"> | ||||
| <div id="loadingPage"> | |||||
| <div class="rect1"></div> | |||||
| <div class="rect2"></div> | |||||
| <div class="rect3"></div> | |||||
| <div class="rect4"></div> | |||||
| <div class="rect5"></div> | |||||
| </div> | |||||
| <div id="loadingPage"> | |||||
| <div class="rect1"></div> | |||||
| <div class="rect2"></div> | |||||
| <div class="rect3"></div> | |||||
| <div class="rect4"></div> | |||||
| <div class="rect5"></div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="repository"> | <div class="repository"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| @@ -87,7 +92,7 @@ | |||||
| </a> | </a> | ||||
| <a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> | <a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> | ||||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | ||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}} | |||||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -95,29 +100,41 @@ | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | ||||
| <div class="ui blue mini menu compact selectcloudbrain"> | <div class="ui blue mini menu compact selectcloudbrain"> | ||||
| <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> | ||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||||
| height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z" /> | |||||
| <path | |||||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||||
| </svg> | </svg> | ||||
| CPU/GPU | CPU/GPU | ||||
| </a> | </a> | ||||
| <a class="active item" href="{{.RepoLink}}/modelarts/train-job/create"> | <a class="active item" href="{{.RepoLink}}/modelarts/train-job/create"> | ||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z"/> | |||||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||||
| height="16"> | |||||
| <path fill="none" d="M0 0h24v24H0z" /> | |||||
| <path | |||||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||||
| </svg> | </svg> | ||||
| Ascend NPU</a> | Ascend NPU</a> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" | |||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||||
| tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required | |||||
| maxlength="64"> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | ||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
| <label style="font-weight: normal;" | |||||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" | |||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||||
| onchange="this.value=this.value.substring(0, 255)" | |||||
| onkeydown="this.value=this.value.substring(0, 255)" | |||||
| onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -125,43 +142,45 @@ | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
| <select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
| {{if .branch_name}} | |||||
| <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branch_name }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| <option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branchName }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| </select> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
| <select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
| {{if .branch_name}} | |||||
| <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branch_name }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| <option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
| {{range $k, $v :=.Branches}} | |||||
| {{ if ne $v $.branchName }} | |||||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline fields" style="width: 90%;"> | <div class="required unite min_title inline fields" style="width: 90%;"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}} </label> | |||||
| <label | |||||
| style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}} </label> | |||||
| <div class="field" style="flex: 1.5;"> | <div class="field" style="flex: 1.5;"> | ||||
| <select class="ui dropdown width" id="trainjob_engines" > | |||||
| <select class="ui dropdown width" id="trainjob_engines"> | |||||
| {{range .engines}} | {{range .engines}} | ||||
| <option value="{{.Value}}">{{.Value}}</option> | |||||
| <option value="{{.Value}}">{{.Value}}</option> | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="field" style="flex: 2;" id="engine_name"> | <div class="field" style="flex: 2;" id="engine_name"> | ||||
| <select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id"> | |||||
| {{range .engine_versions}} | |||||
| <option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| <select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' | |||||
| name="engine_id"> | |||||
| {{range .engine_versions}} | |||||
| <option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -169,41 +188,49 @@ | |||||
| </div> | </div> | ||||
| <div class="inline unite min_title field required"> | <div class="inline unite min_title field required"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
| {{end}} | |||||
| <span> | |||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
| </span> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" | |||||
| tabindex="3" autofocus required maxlength="255"> | |||||
| {{else}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" | |||||
| autofocus required maxlength="255"> | |||||
| {{end}} | |||||
| <span> | |||||
| <i class="question circle icon link" | |||||
| data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} | |||||
| data-position="right center" data-variation="mini"></i> | |||||
| </span> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" | |||||
| target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | </div> | ||||
| {{template "custom/select_dataset_train" .}} | {{template "custom/select_dataset_train" .}} | ||||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
| <span class="tooltips" | |||||
| style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||||
| <span id="add_run_para" | |||||
| style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i | |||||
| class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||||
| <div class="dynamic field" style="margin-top: 1rem;"> | <div class="dynamic field" style="margin-top: 1rem;"> | ||||
| {{if ne 0 (len .params)}} | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | {{range $k ,$v := .params}} | ||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | </div> | ||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -212,13 +239,14 @@ | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | ||||
| <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | ||||
| {{range .resource_pools}} | {{range .resource_pools}} | ||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="required grouped fields" style="display: none;"> | <div class="required grouped fields" style="display: none;"> | ||||
| <label style="font-weight: normal;" for="resource_type">{{.i18n.Tr "repo.modelarts.train_job.resource_type"}}</label> | |||||
| <label style="font-weight: normal;" | |||||
| for="resource_type">{{.i18n.Tr "repo.modelarts.train_job.resource_type"}}</label> | |||||
| <div class="field"> | <div class="field"> | ||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="column"> | <div class="column"> | ||||
| @@ -237,29 +265,31 @@ | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | ||||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
| {{range .flavor_infos}} | {{range .flavor_infos}} | ||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="inline required unite min_title field"> | <div class="inline required unite min_title field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||||
| <label | |||||
| style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||||
| <div class="ui labeled input" style="width: 5%;"> | <div class="ui labeled input" style="width: 5%;"> | ||||
| <input style="border-radius: 0;text-align: center;"type="hidden" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | |||||
| <div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | |||||
| <select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
| <option name="server_id" value="1">1</option> | |||||
| <option name="server_id" value="2">2</option> | |||||
| </select> | |||||
| </div> | |||||
| <input style="border-radius: 0;text-align: center;" type="hidden" name="work_server_number" | |||||
| id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" | |||||
| readonly> | |||||
| <div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | |||||
| <select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
| <option name="server_id" value="1">1</option> | |||||
| </select> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="inline unite min_title field"> | <div class="inline unite min_title field"> | ||||
| <button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||||
| </button> | </button> | ||||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
| </div> | </div> | ||||
| @@ -274,7 +304,7 @@ | |||||
| <script> | <script> | ||||
| let url_href = window.location.pathname.split('create')[0] | let url_href = window.location.pathname.split('create')[0] | ||||
| $(".ui.button").attr('href',url_href) | |||||
| $(".ui.button").attr('href', url_href) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| @@ -296,182 +326,182 @@ | |||||
| // } | // } | ||||
| // }) | // }) | ||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | |||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>'+ | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| function Add_parameter(i) { | |||||
| value = '<div class="two fields width85" id= "para' + i + '">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>' + | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | } | ||||
| $('#add_run_para').click(function(){ | |||||
| $('#add_run_para').click(function () { | |||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| Add_parameter(len) | Add_parameter(len) | ||||
| }); | }); | ||||
| $(".dynamic.field").on("click",".trash.icon", function() { | |||||
| $(".dynamic.field").on("click", ".trash.icon", function () { | |||||
| var index = $(this).parent().parent().index() | var index = $(this).parent().parent().index() | ||||
| $(this).parent().parent().remove() | $(this).parent().parent().remove() | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var cur_index = $(this).index() | var cur_index = $(this).index() | ||||
| $(this).attr('id', 'para' + cur_index) | $(this).attr('id', 'para' + cur_index) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.green.button').click(function(){ | |||||
| $('.ui.parameter.green.button').click(function () { | |||||
| var parameters = []; | var parameters = []; | ||||
| $('table tr').each(function() { | |||||
| $(this).find('td:eq(1)').each(function(){ | |||||
| $('table tr').each(function () { | |||||
| $(this).find('td:eq(1)').each(function () { | |||||
| parameters.push($(this).text()); | parameters.push($(this).text()); | ||||
| }) | }) | ||||
| $(this).find('input').each(function(){ | |||||
| $(this).find('input').each(function () { | |||||
| parameters.push($(this).text()) | parameters.push($(this).text()) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.modal') | $('.ui.parameter.modal') | ||||
| .modal('hide'); | .modal('hide'); | ||||
| for(var i = 2; i < parameters.length; i++){ | |||||
| switch(i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for(var j = 0; j < para.length; j++){ | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| // $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| for (var i = 2; i < parameters.length; i++) { | |||||
| switch (i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for (var j = 0; j < para.length; j++) { | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field" + " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field" + " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| // $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| }) | }) | ||||
| $('.ui.save.checkbox').click(function(){ | |||||
| $('.ui.save.checkbox').click(function () { | |||||
| $(this).checkbox({ | $(this).checkbox({ | ||||
| onChange: function(){ | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
| onChange: function () { | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')) { | |||||
| $('#save_para').removeClass("disabled") | $('#save_para').removeClass("disabled") | ||||
| }else{ | |||||
| } else { | |||||
| $('#save_para').addClass("disabled") | $('#save_para').addClass("disabled") | ||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| }) | }) | ||||
| $('.question.circle.icon').hover(function(){ | |||||
| $('.question.circle.icon').hover(function () { | |||||
| $(this).popup('show') | $(this).popup('show') | ||||
| }); | }); | ||||
| $(".item.active.parameter_config").click(function(){ | |||||
| $(".item.active.parameter_config").click(function () { | |||||
| $('.ui.parameter.modal') | $('.ui.parameter.modal') | ||||
| .modal('setting', 'closable', false) | .modal('setting', 'closable', false) | ||||
| .modal('show'); | .modal('show'); | ||||
| }) | }) | ||||
| $('.ui.deny.button').click(function(){ | |||||
| $('.ui.deny.button').click(function () { | |||||
| $('.ui.parameter.modal') | $('.ui.parameter.modal') | ||||
| .modal('hide'); | .modal('hide'); | ||||
| }) | }) | ||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| function validate(){ | |||||
| function validate() { | |||||
| $('.ui.form') | $('.ui.form') | ||||
| .form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| boot_file: { | |||||
| identifier : 'boot_file', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/.+\.py$/g]', | |||||
| .form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| boot_file: { | |||||
| identifier: 'boot_file', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/.+\.py$/g]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| display_job_name: { | |||||
| identifier: 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment: { | |||||
| identifier: 'attachment', | |||||
| rules: [ | |||||
| { | |||||
| type: 'empty', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| work_server_number: { | |||||
| identifier: 'work_server_number', | |||||
| rules: [ | |||||
| { | |||||
| type: 'integer[1..25]', | |||||
| } | |||||
| ] | |||||
| } | } | ||||
| ] | |||||
| }, | }, | ||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | |||||
| ] | |||||
| onSuccess: function () { | |||||
| // $('.ui.page.dimmer').dimmer('show') | |||||
| document.getElementById("mask").style.display = "block" | |||||
| }, | }, | ||||
| attachment:{ | |||||
| identifier : 'attachment', | |||||
| rules: [ | |||||
| { | |||||
| type: 'empty', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| work_server_number: { | |||||
| identifier : 'work_server_number', | |||||
| rules: [ | |||||
| { | |||||
| type : 'integer[1..25]', | |||||
| } | |||||
| ] | |||||
| onFailure: function (e) { | |||||
| return false; | |||||
| } | } | ||||
| }, | |||||
| onSuccess: function(){ | |||||
| // $('.ui.page.dimmer').dimmer('show') | |||||
| document.getElementById("mask").style.display = "block" | |||||
| }, | |||||
| onFailure: function(e){ | |||||
| return false; | |||||
| } | |||||
| }) | |||||
| }) | |||||
| } | } | ||||
| document.onreadystatechange = function() { | |||||
| document.onreadystatechange = function () { | |||||
| if (document.readyState === "complete") { | if (document.readyState === "complete") { | ||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| function send_run_para(){ | |||||
| function send_run_para() { | |||||
| var run_parameters = [] | var run_parameters = [] | ||||
| var msg = {} | var msg = {} | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | var para_name = $(this).find('input[name=shipping_first-name]').val() | ||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | var para_value = $(this).find('input[name=shipping_last-name]').val() | ||||
| run_parameters.push({"label": para_name, "value": para_value}) | |||||
| run_parameters.push({ "label": para_name, "value": para_value }) | |||||
| }) | }) | ||||
| msg["parameter"] = run_parameters | msg["parameter"] = run_parameters | ||||
| msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
| $('#store_run_para').val(msg) | $('#store_run_para').val(msg) | ||||
| } | } | ||||
| function get_name(){ | |||||
| let name1=$("#engine_name .text").text() | |||||
| let name2=$("#flaver_name .text").text() | |||||
| function get_name() { | |||||
| let name1 = $("#engine_name .text").text() | |||||
| let name2 = $("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | $("input#ai_engine_name").val(name1) | ||||
| $("input#ai_flaver_name").val(name2) | $("input#ai_flaver_name").val(name2) | ||||
| @@ -480,9 +510,9 @@ | |||||
| $("input#trainjob_work_server_num").val(val_server_num_select) | $("input#trainjob_work_server_num").val(val_server_num_select) | ||||
| } | } | ||||
| $('.ui.create_train_job.green.button').click(function(e) { | |||||
| $('.ui.create_train_job.green.button').click(function (e) { | |||||
| get_name() | get_name() | ||||
| send_run_para() | send_run_para() | ||||
| validate() | validate() | ||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -597,8 +597,12 @@ | |||||
| </div> | </div> | ||||
| <div class="required inline field" id="verionname"> | <div class="required inline field" id="verionname"> | ||||
| <label>模型版本</label> | <label>模型版本</label> | ||||
| <input style="width: 45%;" id="version" name="Version" value="" readonly required | |||||
| maxlength="255"> | |||||
| <input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255"> | |||||
| </div> | |||||
| <div class="unite min_title inline field required"> | |||||
| <label>模型框架</label> | |||||
| <input type="hidden" id="Engine" name="Engine" required> | |||||
| <input style="width: 45%;" id="Engine_name" name="Engine_name" readonly required maxlength="255"> | |||||
| </div> | </div> | ||||
| <div class="inline field"> | <div class="inline field"> | ||||
| <label>模型标签</label> | <label>模型标签</label> | ||||
| @@ -671,6 +675,14 @@ | |||||
| $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | ||||
| $('input[name="JobId"]').val(obj.JobID) | $('input[name="JobId"]').val(obj.JobID) | ||||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | ||||
| if(obj.EngineID ==122 || obj.EngineID ==35){ | |||||
| $('input[name="Engine_name"]').val("MindSpore").addClass('model_disabled'); | |||||
| $('input[name="Engine"]').val(2); | |||||
| } | |||||
| if(obj.EngineID ==121){ | |||||
| $('input[name="Engine_name"]').val("TensorFlow").addClass('model_disabled'); | |||||
| $('input[name="Engine"]').val(1); | |||||
| } | |||||
| $('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" }) | $('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" }) | ||||
| createModelName() | createModelName() | ||||
| }, | }, | ||||
| @@ -692,6 +704,8 @@ | |||||
| type: 'POST', | type: 'POST', | ||||
| data: data, | data: data, | ||||
| success: function (res) { | success: function (res) { | ||||
| $('input[name="Engine_name"]').val(""); | |||||
| $('input[name="Engine"]').val(""); | |||||
| location.href = `/${userName}/${repoPath}/modelmanage/show_model` | location.href = `/${userName}/${repoPath}/modelmanage/show_model` | ||||
| $('.ui.modal.second').modal('hide') | $('.ui.modal.second').modal('hide') | ||||
| }, | }, | ||||
| @@ -266,17 +266,20 @@ | |||||
| $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | ||||
| const n_length = data.length | const n_length = data.length | ||||
| let train_html = '' | |||||
| for (let i = 0; i < n_length; i++) { | |||||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].DisplayJobName}</div>` | |||||
| train_html += '</div>' | |||||
| if(n_length > 0){ | |||||
| let train_html = '' | |||||
| for (let i = 0; i < n_length; i++) { | |||||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].DisplayJobName}</div>` | |||||
| train_html += '</div>' | |||||
| } | |||||
| $("#job-name").append(train_html) | |||||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | |||||
| $('#choice_model .default.text').text(data[0].DisplayJobName) | |||||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | |||||
| loadTrainVersion() | |||||
| }else{ | |||||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | |||||
| } | } | ||||
| $("#job-name").append(train_html) | |||||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | |||||
| $('#choice_model .default.text').text(data[0].DisplayJobName) | |||||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | |||||
| loadTrainVersion() | |||||
| }) | }) | ||||
| } | } | ||||
| function loadTrainVersion(value) { | function loadTrainVersion(value) { | ||||
| @@ -298,7 +301,6 @@ | |||||
| } | } | ||||
| $('#choice_version .default.text').text(versionName) | $('#choice_version .default.text').text(versionName) | ||||
| $('#choice_version input[name="VersionName"]').val(versionName) | $('#choice_version input[name="VersionName"]').val(versionName) | ||||
| console.log("1111111111"); | |||||
| setEngine(data[0]) | setEngine(data[0]) | ||||
| } | } | ||||
| @@ -94,7 +94,7 @@ | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .ComputeResource "NPU"}}modelarts{{else}}cloudbrain{{end}}/train-job/{{$JobID}}" | |||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{else if eq .Cloudbrain.Type 2}}grampus{{end}}/train-job/{{$JobID}}" | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | title="{{.DisplayJobName}}" style="font-size: 14px;"> | ||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| @@ -186,7 +186,7 @@ | |||||
| {{else}} | {{else}} | ||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | ||||
| class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' | class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' | ||||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}modelarts/train-job{{else}}cloudbrain/train-job{{end}}{{end}}' | |||||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}modelarts/train-job{{else if eq .Cloudbrain.Type 0}}cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}grampus/train-job{{end}}{{end}}' | |||||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | ||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| @@ -203,7 +203,7 @@ | |||||
| {{end}} | {{end}} | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" | <form class="ui compact buttons" id="delForm-{{$JobID}}" | ||||
| action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' | |||||
| action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' | |||||
| method="post"> | method="post"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | ||||
| @@ -86,6 +86,10 @@ | |||||
| {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 31}} | {{else if eq .GetOpType 31}} | ||||
| {{$.i18n.Tr "action.task_gputrainjob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_gputrainjob" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 32}} | |||||
| {{$.i18n.Tr "action.task_c2netnputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{else if eq .GetOpType 33}} | |||||
| {{$.i18n.Tr "action.task_c2netgputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{end}} | {{end}} | ||||
| </p> | </p> | ||||
| {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | ||||
| @@ -353,7 +353,7 @@ export default { | |||||
| return "Pytorch"; | return "Pytorch"; | ||||
| }else if(model.Engine == 1 || model.Engine == 121){ | }else if(model.Engine == 1 || model.Engine == 121){ | ||||
| return "TensorFlow"; | return "TensorFlow"; | ||||
| }else if(model.Engine == 2 || model.Engine == 122){ | |||||
| }else if(model.Engine == 2 || model.Engine == 122 || model.Engine == 35){ | |||||
| return "MindSpore"; | return "MindSpore"; | ||||
| }else{ | }else{ | ||||
| return "Other" | return "Other" | ||||
| @@ -1,74 +1,100 @@ | |||||
| /** | /** | ||||
| * LetterAvatar | * LetterAvatar | ||||
| * | |||||
| * | |||||
| * Artur Heinze | * Artur Heinze | ||||
| * Create Letter avatar based on Initials | * Create Letter avatar based on Initials | ||||
| * based on https://gist.github.com/leecrossley/6027780 | * based on https://gist.github.com/leecrossley/6027780 | ||||
| */ | */ | ||||
| (function(w, d){ | |||||
| 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; | |||||
| (function (w, d) { | |||||
| 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); | |||||
| } | |||||
| let initials1 = initials.toUpperCase(); | |||||
| if (w.devicePixelRatio) { | |||||
| size = size * w.devicePixelRatio; | |||||
| } | } | ||||
| 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); | |||||
| }); | |||||
| }; | |||||
| // AMD support | |||||
| if (typeof define === 'function' && define.amd) { | |||||
| define(function () { return LetterAvatar; }); | |||||
| 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(initials1, 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); | |||||
| } | |||||
| ); | |||||
| }; | |||||
| // AMD support | |||||
| if (typeof define === "function" && define.amd) { | |||||
| define(function () { | |||||
| return LetterAvatar; | |||||
| }); | |||||
| // CommonJS and Node.js module support. | // CommonJS and Node.js module support. | ||||
| } else if (typeof exports !== 'undefined') { | |||||
| // Support Node.js specific `module.exports` (which can be a function) | |||||
| if (typeof module != 'undefined' && module.exports) { | |||||
| exports = module.exports = LetterAvatar; | |||||
| } | |||||
| // But always support CommonJS module 1.1.1 spec (`exports` cannot be a function) | |||||
| exports.LetterAvatar = LetterAvatar; | |||||
| } else { | |||||
| window.LetterAvatar = LetterAvatar; | |||||
| d.addEventListener('DOMContentLoaded', function(event) { | |||||
| LetterAvatar.transform(); | |||||
| }); | |||||
| } else if (typeof exports !== "undefined") { | |||||
| // Support Node.js specific `module.exports` (which can be a function) | |||||
| if (typeof module != "undefined" && module.exports) { | |||||
| exports = module.exports = LetterAvatar; | |||||
| } | } | ||||
| })(window, document); | |||||
| // But always support CommonJS module 1.1.1 spec (`exports` cannot be a function) | |||||
| exports.LetterAvatar = LetterAvatar; | |||||
| } else { | |||||
| window.LetterAvatar = LetterAvatar; | |||||
| d.addEventListener("DOMContentLoaded", function (event) { | |||||
| LetterAvatar.transform(); | |||||
| }); | |||||
| } | |||||
| })(window, document); | |||||