@@ -33,6 +33,7 @@ type AiModelManage struct { | |||||
CodeBranch string `xorm:"varchar(400) NULL" json:"codeBranch"` | CodeBranch string `xorm:"varchar(400) NULL" json:"codeBranch"` | ||||
CodeCommitID string `xorm:"NULL" json:"codeCommitID"` | CodeCommitID string `xorm:"NULL" json:"codeCommitID"` | ||||
UserId int64 `xorm:"NOT NULL" json:"userId"` | UserId int64 `xorm:"NOT NULL" json:"userId"` | ||||
IsPrivate bool `xorm:"DEFAULT true" json:"isPrivate"` | |||||
UserName string `json:"userName"` | UserName string `json:"userName"` | ||||
UserRelAvatarLink string `json:"userRelAvatarLink"` | UserRelAvatarLink string `json:"userRelAvatarLink"` | ||||
TrainTaskInfo string `xorm:"text NULL" json:"trainTaskInfo"` | TrainTaskInfo string `xorm:"text NULL" json:"trainTaskInfo"` | ||||
@@ -40,6 +41,7 @@ type AiModelManage struct { | |||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated" json:"updatedUnix"` | UpdatedUnix timeutil.TimeStamp `xorm:"updated" json:"updatedUnix"` | ||||
IsCanOper bool `json:"isCanOper"` | IsCanOper bool `json:"isCanOper"` | ||||
IsCanDelete bool `json:"isCanDelete"` | IsCanDelete bool `json:"isCanDelete"` | ||||
IsCanDownload bool `json:"isCanDownload"` | |||||
} | } | ||||
type AiModelConvert struct { | type AiModelConvert struct { | ||||
@@ -84,8 +86,10 @@ type AiModelQueryOptions struct { | |||||
SortType string | SortType string | ||||
New int | New int | ||||
// JobStatus CloudbrainStatus | // JobStatus CloudbrainStatus | ||||
Type int | |||||
Status int | |||||
Type int | |||||
Status int | |||||
IsOnlyThisRepo bool | |||||
IsQueryPrivate bool | |||||
} | } | ||||
func (a *AiModelConvert) IsGpuTrainTask() bool { | func (a *AiModelConvert) IsGpuTrainTask() bool { | ||||
@@ -217,6 +221,19 @@ func SaveModelToDb(model *AiModelManage) error { | |||||
return nil | return nil | ||||
} | } | ||||
func QueryModelConvertByName(name string, repoId int64) ([]*AiModelConvert, error) { | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
sess.Select("*").Table(new(AiModelConvert)). | |||||
Where("name='" + name + "' and repo_id=" + fmt.Sprint(repoId)).OrderBy("created_unix desc") | |||||
aiModelManageConvertList := make([]*AiModelConvert, 0) | |||||
err := sess.Find(&aiModelManageConvertList) | |||||
if err == nil { | |||||
return aiModelManageConvertList, nil | |||||
} | |||||
return nil, err | |||||
} | |||||
func QueryModelConvertById(id string) (*AiModelConvert, error) { | func QueryModelConvertById(id string) (*AiModelConvert, error) { | ||||
sess := x.NewSession() | sess := x.NewSession() | ||||
defer sess.Close() | defer sess.Close() | ||||
@@ -288,15 +305,30 @@ func ModifyModelDescription(id string, description string) error { | |||||
return nil | return nil | ||||
} | } | ||||
func ModifyLocalModel(id string, name, label, description string, engine int) error { | |||||
func ModifyModelPrivate(id string, isPrivate bool) error { | |||||
var sess *xorm.Session | |||||
sess = x.ID(id) | |||||
defer sess.Close() | |||||
re, err := sess.Cols("is_private").Update(&AiModelManage{ | |||||
IsPrivate: isPrivate, | |||||
}) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
log.Info("success to update isPrivate from db.re=" + fmt.Sprint((re))) | |||||
return nil | |||||
} | |||||
func ModifyLocalModel(id string, name, label, description string, engine int, isPrivate bool) error { | |||||
var sess *xorm.Session | var sess *xorm.Session | ||||
sess = x.ID(id) | sess = x.ID(id) | ||||
defer sess.Close() | defer sess.Close() | ||||
re, err := sess.Cols("name", "label", "description", "engine").Update(&AiModelManage{ | |||||
re, err := sess.Cols("name", "label", "description", "engine", "is_private").Update(&AiModelManage{ | |||||
Description: description, | Description: description, | ||||
Name: name, | Name: name, | ||||
Label: label, | Label: label, | ||||
Engine: int64(engine), | Engine: int64(engine), | ||||
IsPrivate: isPrivate, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
@@ -411,7 +443,11 @@ func QueryModel(opts *AiModelQueryOptions) ([]*AiModelManage, int64, error) { | |||||
builder.Eq{"ai_model_manage.status": opts.Status}, | builder.Eq{"ai_model_manage.status": opts.Status}, | ||||
) | ) | ||||
} | } | ||||
if !opts.IsQueryPrivate { | |||||
cond = cond.And( | |||||
builder.Eq{"ai_model_manage.is_private": false}, | |||||
) | |||||
} | |||||
count, err := sess.Where(cond).Count(new(AiModelManage)) | count, err := sess.Where(cond).Count(new(AiModelManage)) | ||||
if err != nil { | if err != nil { | ||||
return nil, 0, fmt.Errorf("Count: %v", err) | return nil, 0, fmt.Errorf("Count: %v", err) | ||||
@@ -204,6 +204,7 @@ type Cloudbrain struct { | |||||
BenchmarkTypeRankLink string `xorm:"-"` | BenchmarkTypeRankLink string `xorm:"-"` | ||||
StartTime timeutil.TimeStamp | StartTime timeutil.TimeStamp | ||||
EndTime timeutil.TimeStamp | EndTime timeutil.TimeStamp | ||||
Cleared bool `xorm:"DEFAULT false"` | |||||
Spec *Specification `xorm:"-"` | Spec *Specification `xorm:"-"` | ||||
} | } | ||||
@@ -1905,6 +1906,12 @@ func GetCloudbrainByID(id string) (*Cloudbrain, error) { | |||||
return getRepoCloudBrain(cb) | return getRepoCloudBrain(cb) | ||||
} | } | ||||
func IsCloudbrainExistByJobName(jobName string)(bool,error){ | |||||
return x.Unscoped().Exist(&Cloudbrain{ | |||||
JobName: jobName, | |||||
}) | |||||
} | |||||
func GetCloudbrainByIDWithDeleted(id string) (*Cloudbrain, error) { | func GetCloudbrainByIDWithDeleted(id string) (*Cloudbrain, error) { | ||||
idInt64, _ := strconv.ParseInt(id, 10, 64) | idInt64, _ := strconv.ParseInt(id, 10, 64) | ||||
cb := &Cloudbrain{ID: idInt64} | cb := &Cloudbrain{ID: idInt64} | ||||
@@ -2050,6 +2057,83 @@ func GetCloudBrainUnStoppedJob() ([]*Cloudbrain, error) { | |||||
Find(&cloudbrains) | Find(&cloudbrains) | ||||
} | } | ||||
func GetCloudBrainOneStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) { | |||||
cloudbrains := make([]*Cloudbrain, 0, 10) | |||||
endTimeBefore := time.Now().Unix() - int64(days)*24*3600 | |||||
missEndTimeBefore := endTimeBefore - 24*3600 | |||||
return cloudbrains, x.Unscoped().Cols("id,job_name,job_id"). | |||||
In("status", | |||||
JobStopped, JobSucceeded, JobFailed, ModelArtsCreateFailed, ModelArtsStartFailed, ModelArtsUnavailable, ModelArtsResizFailed, ModelArtsDeleted, | |||||
ModelArtsStopped, ModelArtsTrainJobCanceled, ModelArtsTrainJobCheckFailed, ModelArtsTrainJobCompleted, ModelArtsTrainJobDeleteFailed, ModelArtsTrainJobDeployServiceFailed, | |||||
ModelArtsTrainJobFailed, ModelArtsTrainJobImageFailed, ModelArtsTrainJobKilled, ModelArtsTrainJobLost, ModelArtsTrainJobSubmitFailed, ModelArtsTrainJobSubmitModelFailed). | |||||
Where("(((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false and type=0 and job_type != 'DEBUG'", missEndTimeBefore, endTimeBefore). | |||||
Limit(limit). | |||||
Find(&cloudbrains) | |||||
} | |||||
/** | |||||
本方法考虑了再次调试的情况,多次调试取最后一次的任务的结束时间 | |||||
*/ | |||||
func GetCloudBrainOneStoppedDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) { | |||||
cloudbrains := make([]*Cloudbrain, 0, 10) | |||||
endTimeBefore := time.Now().Unix() - int64(days)*24*3600 | |||||
missEndTimeBefore := endTimeBefore - 24*3600 | |||||
sql:=`SELECT id,job_name,job_id from (SELECT DISTINCT ON (job_name) | |||||
id, job_name, job_id,status,end_time,updated_unix,cleared | |||||
FROM cloudbrain | |||||
where type=0 and job_type='DEBUG' | |||||
ORDER BY job_name, updated_unix DESC) a | |||||
where status in ('STOPPED','SUCCEEDED','FAILED') and (((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false` | |||||
return cloudbrains, x.Unscoped().SQL(sql,missEndTimeBefore, endTimeBefore).Limit(limit).Find(&cloudbrains) | |||||
} | |||||
func UpdateCloudBrainRecordsCleared(ids []int64) error { | |||||
pageSize := 150 | |||||
n := len(ids) / pageSize | |||||
var err error | |||||
for i := 1; i <= n+1; i++ { | |||||
tempIds := getPageIds(ids, i, pageSize) | |||||
if len(tempIds) > 0 { | |||||
idsIn := "" | |||||
for i, id := range tempIds { | |||||
if i == 0 { | |||||
idsIn += strconv.FormatInt(id, 10) | |||||
} else { | |||||
idsIn += "," + strconv.FormatInt(id, 10) | |||||
} | |||||
} | |||||
_, errTemp := x.Unscoped().Exec("update cloudbrain set cleared=true where id in (" + idsIn + ")") | |||||
if errTemp != nil { | |||||
err = errTemp | |||||
} | |||||
} | |||||
} | |||||
return err | |||||
} | |||||
func getPageIds(ids []int64, page int, pagesize int) []int64 { | |||||
begin := (page - 1) * pagesize | |||||
end := (page) * pagesize | |||||
if begin > len(ids)-1 { | |||||
return []int64{} | |||||
} | |||||
if end > len(ids)-1 { | |||||
return ids[begin:] | |||||
} else { | |||||
return ids[begin:end] | |||||
} | |||||
} | |||||
func GetStoppedJobWithNoDurationJob() ([]*Cloudbrain, error) { | func GetStoppedJobWithNoDurationJob() ([]*Cloudbrain, error) { | ||||
cloudbrains := make([]*Cloudbrain, 0) | cloudbrains := make([]*Cloudbrain, 0) | ||||
return cloudbrains, x. | return cloudbrains, x. | ||||
@@ -183,6 +183,17 @@ func GetWaittingTop() ([]*CloudbrainInfo, error) { | |||||
Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
log.Info("find error.") | log.Info("find error.") | ||||
} | } | ||||
var ids []int64 | |||||
for _, task := range cloudbrains { | |||||
ids = append(ids, task.RepoID) | |||||
} | |||||
repositoryMap, err := GetRepositoriesMapByIDs(ids) | |||||
if err == nil { | |||||
for _, task := range cloudbrains { | |||||
task.Repo = repositoryMap[task.RepoID] | |||||
} | |||||
} | |||||
return cloudbrains, nil | return cloudbrains, nil | ||||
} | } | ||||
@@ -199,6 +210,16 @@ func GetRunningTop() ([]*CloudbrainInfo, error) { | |||||
Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
log.Info("find error.") | log.Info("find error.") | ||||
} | } | ||||
var ids []int64 | |||||
for _, task := range cloudbrains { | |||||
ids = append(ids, task.RepoID) | |||||
} | |||||
repositoryMap, err := GetRepositoriesMapByIDs(ids) | |||||
if err == nil { | |||||
for _, task := range cloudbrains { | |||||
task.Repo = repositoryMap[task.RepoID] | |||||
} | |||||
} | |||||
return cloudbrains, nil | return cloudbrains, nil | ||||
} | } | ||||
@@ -3,6 +3,7 @@ package models | |||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
"fmt" | "fmt" | ||||
"strings" | |||||
"xorm.io/builder" | "xorm.io/builder" | ||||
) | ) | ||||
@@ -197,12 +198,104 @@ type Specification struct { | |||||
AiCenterName string | AiCenterName string | ||||
IsExclusive bool | IsExclusive bool | ||||
ExclusiveOrg string | ExclusiveOrg string | ||||
//specs that have the same sourceSpecId, computeResource and cluster as current spec | |||||
RelatedSpecs []*Specification | |||||
} | } | ||||
func (Specification) TableName() string { | func (Specification) TableName() string { | ||||
return "resource_specification" | return "resource_specification" | ||||
} | } | ||||
func (s *Specification) loadRelatedSpecs() { | |||||
if s.RelatedSpecs != nil { | |||||
return | |||||
} | |||||
defaultSpecs := make([]*Specification, 0) | |||||
if s.SourceSpecId == "" { | |||||
s.RelatedSpecs = defaultSpecs | |||||
return | |||||
} | |||||
r, err := FindSpecs(FindSpecsOptions{ | |||||
ComputeResource: s.ComputeResource, | |||||
Cluster: s.Cluster, | |||||
SourceSpecId: s.SourceSpecId, | |||||
RequestAll: true, | |||||
SpecStatus: SpecOnShelf, | |||||
}) | |||||
if err != nil { | |||||
s.RelatedSpecs = defaultSpecs | |||||
return | |||||
} | |||||
s.RelatedSpecs = r | |||||
} | |||||
func (s *Specification) GetAvailableCenterIds(userIds ...int64) []string { | |||||
s.loadRelatedSpecs() | |||||
if len(s.RelatedSpecs) == 0 { | |||||
return make([]string, 0) | |||||
} | |||||
var uId int64 | |||||
if len(userIds) > 0 { | |||||
uId = userIds[0] | |||||
} | |||||
//filter exclusive specs | |||||
specs := FilterExclusiveSpecs(s.RelatedSpecs, uId) | |||||
centerIds := make([]string, len(specs)) | |||||
for i, v := range specs { | |||||
centerIds[i] = v.AiCenterCode | |||||
} | |||||
return centerIds | |||||
} | |||||
func FilterExclusiveSpecs(r []*Specification, userId int64) []*Specification { | |||||
if userId == 0 { | |||||
return r | |||||
} | |||||
specs := make([]*Specification, 0, len(r)) | |||||
specMap := make(map[int64]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if _, has := specMap[spec.ID]; has { | |||||
continue | |||||
} | |||||
if !spec.IsExclusive { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
continue | |||||
} | |||||
orgs := strings.Split(spec.ExclusiveOrg, ";") | |||||
for _, org := range orgs { | |||||
isMember, _ := IsOrganizationMemberByOrgName(org, userId) | |||||
if isMember { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
break | |||||
} | |||||
} | |||||
} | |||||
return specs | |||||
} | |||||
func DistinctSpecs(r []*Specification) []*Specification { | |||||
specs := make([]*Specification, 0, len(r)) | |||||
sourceSpecIdMap := make(map[string]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if spec.SourceSpecId == "" { | |||||
specs = append(specs, spec) | |||||
continue | |||||
} | |||||
if _, has := sourceSpecIdMap[spec.SourceSpecId]; has { | |||||
continue | |||||
} | |||||
specs = append(specs, spec) | |||||
sourceSpecIdMap[spec.SourceSpecId] = "" | |||||
} | |||||
return specs | |||||
} | |||||
func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | ||||
return x.Insert(&r) | return x.Insert(&r) | ||||
} | } | ||||
@@ -449,3 +449,20 @@ func QueryUserLoginInfo(userIds []int64) []*UserLoginLog { | |||||
return loginList | return loginList | ||||
} | } | ||||
func QueryUserAnnualReport(userId int64) *UserSummaryCurrentYear { | |||||
statictisSess := xStatistic.NewSession() | |||||
defer statictisSess.Close() | |||||
log.Info("userId=" + fmt.Sprint(userId)) | |||||
reList := make([]*UserSummaryCurrentYear, 0) | |||||
err := statictisSess.Select("*").Table(new(UserSummaryCurrentYear)).Where("id=" + fmt.Sprint(userId)).Find(&reList) | |||||
if err == nil { | |||||
if len(reList) > 0 { | |||||
return reList[0] | |||||
} | |||||
} else { | |||||
log.Info("error:=" + err.Error()) | |||||
} | |||||
return nil | |||||
} |
@@ -132,11 +132,17 @@ func makeResultForMonth(allUserInfo []*UserMetrics, count int) []*UserMetrics { | |||||
if count > 0 { | if count > 0 { | ||||
for _, userMetrics := range allUserInfo { | for _, userMetrics := range allUserInfo { | ||||
dateTime := time.Unix(userMetrics.CountDate, 0) | dateTime := time.Unix(userMetrics.CountDate, 0) | ||||
month := fmt.Sprint(dateTime.Year()) + "-" + fmt.Sprint(int(dateTime.Month())) | |||||
mInt := int(dateTime.Month()) | |||||
mString := fmt.Sprint(mInt) | |||||
if mInt < 10 { | |||||
mString = "0" + mString | |||||
} | |||||
month := fmt.Sprint(dateTime.Year()) + "-" + mString | |||||
if _, ok := monthMap[month]; !ok { | if _, ok := monthMap[month]; !ok { | ||||
monthUserMetrics := &UserMetrics{ | monthUserMetrics := &UserMetrics{ | ||||
DisplayDate: month, | DisplayDate: month, | ||||
ActivateRegistUser: userMetrics.ActivateRegistUser, | ActivateRegistUser: userMetrics.ActivateRegistUser, | ||||
RegistActivityUser: userMetrics.RegistActivityUser, | |||||
NotActivateRegistUser: userMetrics.NotActivateRegistUser, | NotActivateRegistUser: userMetrics.NotActivateRegistUser, | ||||
TotalUser: userMetrics.TotalUser, | TotalUser: userMetrics.TotalUser, | ||||
TotalNotActivateRegistUser: userMetrics.TotalUser - userMetrics.TotalActivateRegistUser, | TotalNotActivateRegistUser: userMetrics.TotalUser - userMetrics.TotalActivateRegistUser, | ||||
@@ -152,6 +158,7 @@ func makeResultForMonth(allUserInfo []*UserMetrics, count int) []*UserMetrics { | |||||
value.ActivateRegistUser += userMetrics.ActivateRegistUser | value.ActivateRegistUser += userMetrics.ActivateRegistUser | ||||
value.NotActivateRegistUser += userMetrics.NotActivateRegistUser | value.NotActivateRegistUser += userMetrics.NotActivateRegistUser | ||||
value.HasActivityUser += userMetrics.HasActivityUser | value.HasActivityUser += userMetrics.HasActivityUser | ||||
value.RegistActivityUser += userMetrics.RegistActivityUser | |||||
value.TotalRegistUser += userMetrics.ActivateRegistUser + userMetrics.NotActivateRegistUser | value.TotalRegistUser += userMetrics.ActivateRegistUser + userMetrics.NotActivateRegistUser | ||||
value.ActivateIndex = float64(value.ActivateRegistUser) / float64(value.TotalRegistUser) | value.ActivateIndex = float64(value.ActivateRegistUser) / float64(value.TotalRegistUser) | ||||
value.DaysForMonth += 1 | value.DaysForMonth += 1 | ||||
@@ -610,7 +617,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||||
DataDate := currentTimeNow.Format("2006-01-02") + " 00:01" | DataDate := currentTimeNow.Format("2006-01-02") + " 00:01" | ||||
bonusMap := make(map[string]map[string]int) | bonusMap := make(map[string]map[string]int) | ||||
if tableName == "user_business_analysis_current_year" { | |||||
if isUserYearData(tableName) { | |||||
bonusMap = getBonusMap() | bonusMap = getBonusMap() | ||||
log.Info("truncate all data from table:user_summary_current_year ") | log.Info("truncate all data from table:user_summary_current_year ") | ||||
statictisSess.Exec("TRUNCATE TABLE user_summary_current_year") | statictisSess.Exec("TRUNCATE TABLE user_summary_current_year") | ||||
@@ -712,7 +719,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||||
userMetrics["TotalHasActivityUser"] = getMapKeyStringValue("TotalHasActivityUser", userMetrics) + 1 | userMetrics["TotalHasActivityUser"] = getMapKeyStringValue("TotalHasActivityUser", userMetrics) + 1 | ||||
} | } | ||||
} | } | ||||
if tableName == "user_business_analysis_current_year" { | |||||
if isUserYearData(tableName) { | |||||
//年度数据 | //年度数据 | ||||
subTime := time.Now().UTC().Sub(dateRecordAll.RegistDate.AsTime().UTC()) | subTime := time.Now().UTC().Sub(dateRecordAll.RegistDate.AsTime().UTC()) | ||||
mostActiveDay := "" | mostActiveDay := "" | ||||
@@ -772,6 +779,17 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||||
log.Info("refresh data finished.tableName=" + tableName + " total record:" + fmt.Sprint(insertCount)) | log.Info("refresh data finished.tableName=" + tableName + " total record:" + fmt.Sprint(insertCount)) | ||||
} | } | ||||
func isUserYearData(tableName string) bool { | |||||
if tableName == "user_business_analysis_current_year" { | |||||
currentTimeNow := time.Now() | |||||
if currentTimeNow.Year() >= 2023 { | |||||
return false | |||||
} | |||||
return true | |||||
} | |||||
return false | |||||
} | |||||
func getBonusMap() map[string]map[string]int { | func getBonusMap() map[string]map[string]int { | ||||
bonusMap := make(map[string]map[string]int) | bonusMap := make(map[string]map[string]int) | ||||
url := setting.RecommentRepoAddr + "bonus/record.txt" | url := setting.RecommentRepoAddr + "bonus/record.txt" | ||||
@@ -794,6 +812,7 @@ func getBonusMap() map[string]map[string]int { | |||||
record, ok := bonusMap[userName] | record, ok := bonusMap[userName] | ||||
if !ok { | if !ok { | ||||
record = make(map[string]int) | record = make(map[string]int) | ||||
bonusMap[userName] = record | |||||
} | } | ||||
record["times"] = getMapKeyStringValue("times", record) + getIntValue(aLine[3]) | record["times"] = getMapKeyStringValue("times", record) + getIntValue(aLine[3]) | ||||
record["total_bonus"] = getMapKeyStringValue("total_bonus", record) + getIntValue(aLine[4]) | record["total_bonus"] = getMapKeyStringValue("total_bonus", record) + getIntValue(aLine[4]) | ||||
@@ -13,6 +13,7 @@ type Invitation struct { | |||||
SrcUserID int64 `xorm:"NOT NULL DEFAULT 0"` | SrcUserID int64 `xorm:"NOT NULL DEFAULT 0"` | ||||
UserID int64 `xorm:"NOT NULL DEFAULT 0"` | UserID int64 `xorm:"NOT NULL DEFAULT 0"` | ||||
Phone string `xorm:"INDEX"` | Phone string `xorm:"INDEX"` | ||||
Email string `xorm:"-"` | |||||
Avatar string `xorm:"-"` | Avatar string `xorm:"-"` | ||||
Name string `xorm:"-"` | Name string `xorm:"-"` | ||||
InvitationUserNum int `xorm:"-"` | InvitationUserNum int `xorm:"-"` | ||||
@@ -5,10 +5,13 @@ | |||||
package cron | package cron | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/urfs_client/urchin" | |||||
"code.gitea.io/gitea/modules/setting" | |||||
"context" | "context" | ||||
"time" | "time" | ||||
"code.gitea.io/gitea/modules/urfs_client/urchin" | |||||
cloudbrainService "code.gitea.io/gitea/services/cloudbrain" | |||||
"code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
"code.gitea.io/gitea/services/cloudbrain/resource" | "code.gitea.io/gitea/services/cloudbrain/resource" | ||||
"code.gitea.io/gitea/services/reward" | "code.gitea.io/gitea/services/reward" | ||||
@@ -190,6 +193,17 @@ func registerHandleRepoAndUserStatistic() { | |||||
}) | }) | ||||
} | } | ||||
func registerHandleClearCloudbrainResult() { | |||||
RegisterTaskFatal("handle_cloudbrain_one_result_clear", &BaseConfig{ | |||||
Enabled: true, | |||||
RunAtStart: setting.ClearStrategy.RunAtStart, | |||||
Schedule: setting.ClearStrategy.Cron, | |||||
}, func(ctx context.Context, _ *models.User, _ Config) error { | |||||
cloudbrainService.ClearCloudbrainResultSpace() | |||||
return nil | |||||
}) | |||||
} | |||||
func registerHandleSummaryStatistic() { | func registerHandleSummaryStatistic() { | ||||
RegisterTaskFatal("handle_summary_statistic", &BaseConfig{ | RegisterTaskFatal("handle_summary_statistic", &BaseConfig{ | ||||
Enabled: true, | Enabled: true, | ||||
@@ -306,6 +320,7 @@ func initBasicTasks() { | |||||
registerHandleRepoAndUserStatistic() | registerHandleRepoAndUserStatistic() | ||||
registerHandleSummaryStatistic() | registerHandleSummaryStatistic() | ||||
registerHandleClearCloudbrainResult() | |||||
registerSyncCloudbrainStatus() | registerSyncCloudbrainStatus() | ||||
registerHandleOrgStatistic() | registerHandleOrgStatistic() | ||||
@@ -317,6 +332,6 @@ func initBasicTasks() { | |||||
registerHandleModelSafetyTask() | registerHandleModelSafetyTask() | ||||
registerHandleScheduleRecord() | |||||
registerHandleScheduleRecord() | |||||
registerHandleCloudbrainDurationStatistic() | registerHandleCloudbrainDurationStatistic() | ||||
} | } |
@@ -105,8 +105,6 @@ func getDatasetGrampus(datasetInfos map[string]models.DatasetInfo) []models.Gram | |||||
func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId string, err error) { | func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId string, err error) { | ||||
createTime := timeutil.TimeStampNow() | createTime := timeutil.TimeStampNow() | ||||
centerID, centerName := getCentersParamter(ctx, req) | |||||
var datasetGrampus, modelGrampus []models.GrampusDataset | var datasetGrampus, modelGrampus []models.GrampusDataset | ||||
var codeGrampus models.GrampusDataset | var codeGrampus models.GrampusDataset | ||||
if ProcessorTypeNPU == req.ProcessType { | if ProcessorTypeNPU == req.ProcessType { | ||||
@@ -138,8 +136,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId str | |||||
ResourceSpecId: req.Spec.SourceSpecId, | ResourceSpecId: req.Spec.SourceSpecId, | ||||
ImageId: req.ImageId, | ImageId: req.ImageId, | ||||
ImageUrl: req.ImageUrl, | ImageUrl: req.ImageUrl, | ||||
CenterID: centerID, | |||||
CenterName: centerName, | |||||
CenterID: req.Spec.GetAvailableCenterIds(ctx.User.ID), | |||||
ReplicaNum: 1, | ReplicaNum: 1, | ||||
Datasets: datasetGrampus, | Datasets: datasetGrampus, | ||||
Models: modelGrampus, | Models: modelGrampus, | ||||
@@ -519,6 +519,7 @@ var ( | |||||
CullIdleTimeout string | CullIdleTimeout string | ||||
CullInterval string | CullInterval string | ||||
//benchmark config | //benchmark config | ||||
IsBenchmarkEnabled bool | IsBenchmarkEnabled bool | ||||
BenchmarkOwner string | BenchmarkOwner string | ||||
@@ -613,6 +614,16 @@ var ( | |||||
UsageRateBeginTime string | UsageRateBeginTime string | ||||
}{} | }{} | ||||
ClearStrategy= struct { | |||||
Enabled bool | |||||
ResultSaveDays int | |||||
BatchSize int | |||||
DebugJobSize int | |||||
TrashSaveDays int | |||||
Cron string | |||||
RunAtStart bool | |||||
}{} | |||||
C2NetInfos *C2NetSqInfos | C2NetInfos *C2NetSqInfos | ||||
CenterInfos *AiCenterInfos | CenterInfos *AiCenterInfos | ||||
C2NetMapInfo map[string]*C2NetSequenceInfo | C2NetMapInfo map[string]*C2NetSequenceInfo | ||||
@@ -1619,6 +1630,7 @@ func NewContext() { | |||||
getModelConvertConfig() | getModelConvertConfig() | ||||
getModelSafetyConfig() | getModelSafetyConfig() | ||||
getModelAppConfig() | getModelAppConfig() | ||||
getClearStrategy() | |||||
} | } | ||||
func getModelSafetyConfig() { | func getModelSafetyConfig() { | ||||
@@ -1679,6 +1691,18 @@ func getModelartsCDConfig() { | |||||
getNotebookFlavorInfos() | getNotebookFlavorInfos() | ||||
} | } | ||||
func getClearStrategy(){ | |||||
sec := Cfg.Section("clear_strategy") | |||||
ClearStrategy.Enabled=sec.Key("ENABLED").MustBool(false) | |||||
ClearStrategy.ResultSaveDays=sec.Key("RESULT_SAVE_DAYS").MustInt(30) | |||||
ClearStrategy.BatchSize=sec.Key("BATCH_SIZE").MustInt(500) | |||||
ClearStrategy.DebugJobSize=sec.Key("DEBUG_BATCH_SIZE").MustInt(100) | |||||
ClearStrategy.TrashSaveDays=sec.Key("TRASH_SAVE_DAYS").MustInt(90) | |||||
ClearStrategy.Cron=sec.Key("CRON").MustString("* 0,30 2-8 * * ?") | |||||
ClearStrategy.RunAtStart=sec.Key("RUN_AT_START").MustBool(false) | |||||
} | |||||
func getGrampusConfig() { | func getGrampusConfig() { | ||||
sec := Cfg.Section("grampus") | sec := Cfg.Section("grampus") | ||||
@@ -0,0 +1,23 @@ | |||||
package structs | |||||
type Pipeline struct { | |||||
ID int64 `json:"id"` | |||||
Name string `json:"name"` | |||||
Status string `json:"status"` | |||||
} | |||||
type NodeInfo struct { | |||||
Name string `json:"name"` | |||||
Status string `json:"status"` | |||||
Code string `json:"code"` | |||||
Message string `json:"message"` | |||||
} | |||||
type PipelineNotification struct { | |||||
Type int `json:"type"` | |||||
Username string `json:"username"` | |||||
Reponame string `json:"reponame"` | |||||
Pipeline Pipeline `json:"pipeline"` | |||||
PipelineRunId string `json:"pipeline_run_id"` | |||||
Node NodeInfo `json:"node"` | |||||
OccurTime int64 `json:"occur_time"` | |||||
} |
@@ -1305,6 +1305,11 @@ model.manage.select.engine=Select model engine | |||||
model.manage.modelfile=Model file | model.manage.modelfile=Model file | ||||
model.manage.modellabel=Model label | model.manage.modellabel=Model label | ||||
model.manage.modeldesc=Model description | model.manage.modeldesc=Model description | ||||
model.manage.modelaccess=Model Access | |||||
model.manage.modelaccess.public=Public | |||||
model.manage.modelaccess.private=Private | |||||
model.manage.modelaccess.setpublic=Set Public | |||||
model.manage.modelaccess.setprivate=Set Private | |||||
model.manage.baseinfo=Base Information | model.manage.baseinfo=Base Information | ||||
modelconvert.notcreate=No model conversion task has been created. | modelconvert.notcreate=No model conversion task has been created. | ||||
modelconvert.importfirst1=Please import the | modelconvert.importfirst1=Please import the | ||||
@@ -3246,6 +3251,7 @@ specification = specification | |||||
select_specification = select specification | select_specification = select specification | ||||
description = description | description = description | ||||
wrong_specification=You cannot use this specification, please choose another item. | wrong_specification=You cannot use this specification, please choose another item. | ||||
result_cleared=The files of the task have been cleared, can not restart any more, please create a new debug task instead. | |||||
resource_use=Resource Occupancy | resource_use=Resource Occupancy | ||||
job_name_rule = Please enter letters, numbers, _ and - up to 64 characters and cannot end with a dash (-). | job_name_rule = Please enter letters, numbers, _ and - up to 64 characters and cannot end with a dash (-). | ||||
@@ -1318,6 +1318,11 @@ model.manage.select.engine=选择模型框架 | |||||
model.manage.modelfile=模型文件 | model.manage.modelfile=模型文件 | ||||
model.manage.modellabel=模型标签 | model.manage.modellabel=模型标签 | ||||
model.manage.modeldesc=模型描述 | model.manage.modeldesc=模型描述 | ||||
model.manage.modelaccess=模型权限 | |||||
model.manage.modelaccess.public=公开 | |||||
model.manage.modelaccess.private=私有 | |||||
model.manage.modelaccess.setpublic=设为公开 | |||||
model.manage.modelaccess.setprivate=设为私有 | |||||
model.manage.baseinfo=基本信息 | model.manage.baseinfo=基本信息 | ||||
modelconvert.notcreate=未创建过模型转换任务 | modelconvert.notcreate=未创建过模型转换任务 | ||||
modelconvert.importfirst1=请您先导入 | modelconvert.importfirst1=请您先导入 | ||||
@@ -3266,6 +3271,8 @@ card_duration = 运行卡时 | |||||
card_type = 卡类型 | card_type = 卡类型 | ||||
wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 | wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 | ||||
result_cleared=本任务的文件已被清理,无法再次调试,请新建调试任务。 | |||||
job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | ||||
train_dataset_path_rule = 数据集位置存储在运行参数 <strong style="color:#010101">data_url</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">ckpt_url</strong> 中,训练输出路径存储在运行参数 <strong style="color:#010101">train_url</strong> 中。 | train_dataset_path_rule = 数据集位置存储在运行参数 <strong style="color:#010101">data_url</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">ckpt_url</strong> 中,训练输出路径存储在运行参数 <strong style="color:#010101">train_url</strong> 中。 | ||||
infer_dataset_path_rule = 数据集位置存储在运行参数 <strong style="color:#010101">data_url</strong> 中,推理输出路径存储在运行参数 <strong style="color:#010101">result_url</strong> 中。 | infer_dataset_path_rule = 数据集位置存储在运行参数 <strong style="color:#010101">data_url</strong> 中,推理输出路径存储在运行参数 <strong style="color:#010101">result_url</strong> 中。 | ||||
@@ -544,6 +544,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Post("/complete_multipart", repo.CompleteMultipart) | m.Post("/complete_multipart", repo.CompleteMultipart) | ||||
}, reqToken()) | }, reqToken()) | ||||
m.Group("/pipeline", func() { | |||||
m.Post("/notification", bind(api.PipelineNotification{}), notify.PipelineNotify) | |||||
}, reqToken()) | |||||
// Notifications | // Notifications | ||||
m.Group("/notifications", func() { | m.Group("/notifications", func() { | ||||
@@ -610,6 +614,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Get("/query_invitation_yesterday", operationReq, repo_ext.QueryInvitationYesterday) | m.Get("/query_invitation_yesterday", operationReq, repo_ext.QueryInvitationYesterday) | ||||
m.Get("/query_invitation_all", operationReq, repo_ext.QueryInvitationAll) | m.Get("/query_invitation_all", operationReq, repo_ext.QueryInvitationAll) | ||||
m.Get("/query_invitation_userdefine", operationReq, repo_ext.QueryUserDefineInvitationPage) | m.Get("/query_invitation_userdefine", operationReq, repo_ext.QueryUserDefineInvitationPage) | ||||
m.Get("/query_user_annual_report", repo_ext.QueryUserAnnualReport) | |||||
m.Get("/download_invitation_detail", operationReq, repo_ext.DownloadInvitationDetail) | m.Get("/download_invitation_detail", operationReq, repo_ext.DownloadInvitationDetail) | ||||
@@ -758,6 +763,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Group("/:username/:reponame", func() { | m.Group("/:username/:reponame", func() { | ||||
m.Get("/right", reqToken(), repo.GetRight) | m.Get("/right", reqToken(), repo.GetRight) | ||||
m.Get("/tagger", reqToken(), repo.ListTagger) | m.Get("/tagger", reqToken(), repo.ListTagger) | ||||
m.Get("/cloudBrainJobId", repo.GetCloudBrainJobId) | |||||
m.Combo("").Get(reqAnyRepoReader(), repo.Get). | m.Combo("").Get(reqAnyRepoReader(), repo.Get). | ||||
Delete(reqToken(), reqOwner(), repo.Delete). | Delete(reqToken(), reqOwner(), repo.Delete). | ||||
Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRef(), repo.Edit) | Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRef(), repo.Edit) | ||||
@@ -998,6 +1004,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Get("/detail", reqToken(), reqRepoReader(models.UnitTypeCloudBrain), repo.CloudBrainShow) | m.Get("/detail", reqToken(), reqRepoReader(models.UnitTypeCloudBrain), repo.CloudBrainShow) | ||||
m.Get("/model_list", repo.CloudBrainModelList) | m.Get("/model_list", repo.CloudBrainModelList) | ||||
m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | ||||
m.Put("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GeneralCloudBrainJobStop) | |||||
}) | }) | ||||
}) | }) | ||||
m.Group("/inference-job", func() { | m.Group("/inference-job", func() { | ||||
@@ -1018,12 +1025,15 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Delete("/delete_model", repo.DeleteModel) | m.Delete("/delete_model", repo.DeleteModel) | ||||
m.Get("/downloadall", repo.DownloadModel) | m.Get("/downloadall", repo.DownloadModel) | ||||
m.Get("/query_model_byId", repo.QueryModelById) | m.Get("/query_model_byId", repo.QueryModelById) | ||||
m.Get("/query_model_byName", repo.QueryModelByName) | |||||
m.Get("/query_model_for_predict", repo.QueryModelListForPredict) | m.Get("/query_model_for_predict", repo.QueryModelListForPredict) | ||||
m.Get("/query_modelfile_for_predict", repo.QueryModelFileForPredict) | m.Get("/query_modelfile_for_predict", repo.QueryModelFileForPredict) | ||||
m.Get("/query_train_model", repo.QueryTrainModelList) | m.Get("/query_train_model", repo.QueryTrainModelList) | ||||
m.Post("/create_model_convert", repo.CreateModelConvert) | m.Post("/create_model_convert", repo.CreateModelConvert) | ||||
m.Post("/convert_stop", repo.StopModelConvert) | |||||
m.Get("/show_model_convert_page", repo.ShowModelConvertPage) | m.Get("/show_model_convert_page", repo.ShowModelConvertPage) | ||||
m.Get("/query_model_convert_byId", repo.QueryModelConvertById) | m.Get("/query_model_convert_byId", repo.QueryModelConvertById) | ||||
m.Get("/query_model_convert_byName", repo.QueryModelConvertByName) | |||||
m.Get("/:id", repo.GetCloudbrainModelConvertTask) | m.Get("/:id", repo.GetCloudbrainModelConvertTask) | ||||
m.Get("/:id/log", repo.CloudbrainForModelConvertGetLog) | m.Get("/:id/log", repo.CloudbrainForModelConvertGetLog) | ||||
@@ -0,0 +1,15 @@ | |||||
package notify | |||||
import ( | |||||
"net/http" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/context" | |||||
api "code.gitea.io/gitea/modules/structs" | |||||
) | |||||
func PipelineNotify(ctx *context.APIContext, form api.PipelineNotification) { | |||||
ctx.JSON(http.StatusOK, models.BaseOKMessageApi) | |||||
} |
@@ -17,6 +17,8 @@ import ( | |||||
"strings" | "strings" | ||||
"time" | "time" | ||||
"code.gitea.io/gitea/modules/grampus" | |||||
cloudbrainService "code.gitea.io/gitea/services/cloudbrain" | cloudbrainService "code.gitea.io/gitea/services/cloudbrain" | ||||
"code.gitea.io/gitea/modules/convert" | "code.gitea.io/gitea/modules/convert" | ||||
@@ -80,6 +82,30 @@ func CloudBrainShow(ctx *context.APIContext) { | |||||
ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)}) | ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)}) | ||||
} | } | ||||
func GeneralCloudBrainJobStop(ctx *context.APIContext) { | |||||
task := ctx.Cloudbrain | |||||
if task.IsTerminal() { | |||||
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("cloudbrain.Already_stopped")) | |||||
return | |||||
} | |||||
var err error | |||||
if ctx.Cloudbrain.Type == models.TypeCloudBrainOne { | |||||
err = cloudbrain.StopJob(task.JobID) | |||||
} else if ctx.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||||
_, err = modelarts.StopTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | |||||
} else { | |||||
_, err = grampus.StopJob(task.JobID) | |||||
} | |||||
if err != nil { | |||||
log.Warn("cloud brain stopped failed.", err) | |||||
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("cloudbrain.Stopped_failed")) | |||||
return | |||||
} | |||||
ctx.JSON(http.StatusOK, models.BaseOKMessageApi) | |||||
} | |||||
func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) { | func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) { | ||||
cloudbrainTask.FileNotebookCreate(ctx.Context, option) | cloudbrainTask.FileNotebookCreate(ctx.Context, option) | ||||
} | } | ||||
@@ -968,6 +968,8 @@ func GetWaittingTop(ctx *context.Context) { | |||||
taskDetail.RepoID = ciTasks[i].RepoID | taskDetail.RepoID = ciTasks[i].RepoID | ||||
if ciTasks[i].Repo != nil { | if ciTasks[i].Repo != nil { | ||||
taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name | taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name | ||||
} else { | |||||
taskDetail.RepoName = "" | |||||
} | } | ||||
WaitTimeInt := time.Now().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() | WaitTimeInt := time.Now().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() | ||||
taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) | taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) | ||||
@@ -975,6 +977,13 @@ func GetWaittingTop(ctx *context.Context) { | |||||
if WaitTimeInt < 0 { | if WaitTimeInt < 0 { | ||||
taskDetail.WaitTime = "00:00:00" | taskDetail.WaitTime = "00:00:00" | ||||
} | } | ||||
taskDetail.ID = ciTasks[i].Cloudbrain.ID | |||||
taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource | |||||
taskDetail.JobType = ciTasks[i].Cloudbrain.JobType | |||||
taskDetail.JobID = ciTasks[i].Cloudbrain.JobID | |||||
taskDetail.Type = ciTasks[i].Cloudbrain.Type | |||||
tasks = append(tasks, taskDetail) | tasks = append(tasks, taskDetail) | ||||
} | } | ||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
@@ -1001,6 +1010,12 @@ func GetRunningTop(ctx *context.Context) { | |||||
taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name | taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name | ||||
} | } | ||||
taskDetail.ID = ciTasks[i].Cloudbrain.ID | |||||
taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource | |||||
taskDetail.JobType = ciTasks[i].Cloudbrain.JobType | |||||
taskDetail.JobID = ciTasks[i].Cloudbrain.JobID | |||||
taskDetail.Type = ciTasks[i].Cloudbrain.Type | |||||
tasks = append(tasks, taskDetail) | tasks = append(tasks, taskDetail) | ||||
} | } | ||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
@@ -69,3 +69,17 @@ func GetRight(ctx *context.APIContext) { | |||||
}) | }) | ||||
} | } | ||||
func GetCloudBrainJobId(ctx *context.APIContext) { | |||||
cloudbrains, err := models.GetCloudbrainsByDisplayJobName(ctx.Repo.Repository.ID, ctx.Query("jobType"), ctx.Query("name")) | |||||
if err != nil { | |||||
log.Warn("get cloudbrain by display name failed", err) | |||||
ctx.JSON(http.StatusOK, map[string]string{"jobId": ""}) | |||||
return | |||||
} | |||||
if len(cloudbrains) > 0 { | |||||
ctx.JSON(http.StatusOK, map[string]string{"jobId": cloudbrains[0].JobID}) | |||||
return | |||||
} | |||||
ctx.JSON(http.StatusOK, map[string]string{"jobId": ""}) | |||||
} |
@@ -43,8 +43,14 @@ func QueryModelById(ctx *context.APIContext) { | |||||
routerRepo.QueryModelById(ctx.Context) | routerRepo.QueryModelById(ctx.Context) | ||||
} | } | ||||
func QueryModelByName(ctx *context.APIContext) { | |||||
log.Info("QueryModelByName by api.") | |||||
routerRepo.ShowSingleModel(ctx.Context) | |||||
} | |||||
func QueryModelListForPredict(ctx *context.APIContext) { | func QueryModelListForPredict(ctx *context.APIContext) { | ||||
log.Info("QueryModelListForPredict by api.") | log.Info("QueryModelListForPredict by api.") | ||||
ctx.Context.SetParams("isOnlyThisRepo", "true") | |||||
routerRepo.QueryModelListForPredict(ctx.Context) | routerRepo.QueryModelListForPredict(ctx.Context) | ||||
} | } | ||||
@@ -88,6 +94,11 @@ func CreateModelConvert(ctx *context.APIContext) { | |||||
routerRepo.SaveModelConvert(ctx.Context) | routerRepo.SaveModelConvert(ctx.Context) | ||||
} | } | ||||
func StopModelConvert(ctx *context.APIContext) { | |||||
log.Info("StopModelConvert by api.") | |||||
routerRepo.StopModelConvertApi(ctx.Context) | |||||
} | |||||
func ShowModelConvertPage(ctx *context.APIContext) { | func ShowModelConvertPage(ctx *context.APIContext) { | ||||
log.Info("ShowModelConvertPage by api.") | log.Info("ShowModelConvertPage by api.") | ||||
modelResult, count, err := routerRepo.GetModelConvertPageData(ctx.Context) | modelResult, count, err := routerRepo.GetModelConvertPageData(ctx.Context) | ||||
@@ -113,3 +124,12 @@ func QueryModelConvertById(ctx *context.APIContext) { | |||||
ctx.JSON(http.StatusOK, nil) | ctx.JSON(http.StatusOK, nil) | ||||
} | } | ||||
} | } | ||||
func QueryModelConvertByName(ctx *context.APIContext) { | |||||
modelResult, err := routerRepo.GetModelConvertByName(ctx.Context) | |||||
if err == nil { | |||||
ctx.JSON(http.StatusOK, modelResult) | |||||
} else { | |||||
ctx.JSON(http.StatusOK, nil) | |||||
} | |||||
} |
@@ -573,13 +573,10 @@ func deleteCloudBrainTask(task *models.AiModelConvert) { | |||||
} | } | ||||
} | } | ||||
func StopModelConvert(ctx *context.Context) { | |||||
id := ctx.Params(":id") | |||||
log.Info("stop model convert start.id=" + id) | |||||
func stopModelConvert(id string) error { | |||||
job, err := models.QueryModelConvertById(id) | job, err := models.QueryModelConvertById(id) | ||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("Not found task.", err) | |||||
return | |||||
return err | |||||
} | } | ||||
if job.IsGpuTrainTask() { | if job.IsGpuTrainTask() { | ||||
err = cloudbrain.StopJob(job.CloudBrainTaskId) | err = cloudbrain.StopJob(job.CloudBrainTaskId) | ||||
@@ -600,6 +597,35 @@ func StopModelConvert(ctx *context.Context) { | |||||
err = models.UpdateModelConvert(job) | err = models.UpdateModelConvert(job) | ||||
if err != nil { | if err != nil { | ||||
log.Error("UpdateModelConvert failed:", err) | log.Error("UpdateModelConvert failed:", err) | ||||
return err | |||||
} | |||||
return nil | |||||
} | |||||
func StopModelConvertApi(ctx *context.Context) { | |||||
id := ctx.Params(":id") | |||||
log.Info("stop model convert start.id=" + id) | |||||
err := stopModelConvert(id) | |||||
if err == nil { | |||||
ctx.JSON(200, map[string]string{ | |||||
"code": "0", | |||||
"msg": "succeed", | |||||
}) | |||||
} else { | |||||
ctx.JSON(200, map[string]string{ | |||||
"code": "1", | |||||
"msg": err.Error(), | |||||
}) | |||||
} | |||||
} | |||||
func StopModelConvert(ctx *context.Context) { | |||||
id := ctx.Params(":id") | |||||
log.Info("stop model convert start.id=" + id) | |||||
err := stopModelConvert(id) | |||||
if err != nil { | |||||
ctx.ServerError("Not found task.", err) | |||||
return | |||||
} | } | ||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelmanage/convert_model") | ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelmanage/convert_model") | ||||
} | } | ||||
@@ -620,7 +646,7 @@ func ShowModelConvertInfo(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
ctx.Data["Name"] = job.Name | ctx.Data["Name"] = job.Name | ||||
ctx.Data["canDownload"] = isOper(ctx, job.UserId) | |||||
ctx.Data["canDownload"] = isOperModifyOrDelete(ctx, job.UserId) | |||||
user, err := models.GetUserByID(job.UserId) | user, err := models.GetUserByID(job.UserId) | ||||
if err == nil { | if err == nil { | ||||
job.UserName = user.Name | job.UserName = user.Name | ||||
@@ -732,6 +758,11 @@ func GetModelConvertById(ctx *context.Context) (*models.AiModelConvert, error) { | |||||
return models.QueryModelConvertById(id) | return models.QueryModelConvertById(id) | ||||
} | } | ||||
func GetModelConvertByName(ctx *context.Context) ([]*models.AiModelConvert, error) { | |||||
name := ctx.Query("name") | |||||
return models.QueryModelConvertByName(name, ctx.Repo.Repository.ID) | |||||
} | |||||
func GetModelConvertPageData(ctx *context.Context) ([]*models.AiModelConvert, int64, error) { | func GetModelConvertPageData(ctx *context.Context) ([]*models.AiModelConvert, int64, error) { | ||||
page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
if page <= 0 { | if page <= 0 { | ||||
@@ -755,7 +786,7 @@ func GetModelConvertPageData(ctx *context.Context) ([]*models.AiModelConvert, in | |||||
} | } | ||||
userIds := make([]int64, len(modelResult)) | userIds := make([]int64, len(modelResult)) | ||||
for i, model := range modelResult { | for i, model := range modelResult { | ||||
model.IsCanOper = isOper(ctx, model.UserId) | |||||
model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId) | |||||
model.IsCanDelete = isCanDelete(ctx, model.UserId) | model.IsCanDelete = isCanDelete(ctx, model.UserId) | ||||
userIds[i] = model.UserId | userIds[i] = model.UserId | ||||
} | } | ||||
@@ -93,7 +93,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
log.Info("accuracyJson=" + string(accuracyJson)) | log.Info("accuracyJson=" + string(accuracyJson)) | ||||
aiTask.ContainerIp = "" | aiTask.ContainerIp = "" | ||||
aiTaskJson, _ := json.Marshal(aiTask) | aiTaskJson, _ := json.Marshal(aiTask) | ||||
isPrivate := ctx.QueryBool("isPrivate") | |||||
model := &models.AiModelManage{ | model := &models.AiModelManage{ | ||||
ID: id, | ID: id, | ||||
Version: version, | Version: version, | ||||
@@ -114,6 +114,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
TrainTaskInfo: string(aiTaskJson), | TrainTaskInfo: string(aiTaskJson), | ||||
Accuracy: string(accuracyJson), | Accuracy: string(accuracyJson), | ||||
Status: STATUS_COPY_MODEL, | Status: STATUS_COPY_MODEL, | ||||
IsPrivate: isPrivate, | |||||
} | } | ||||
err = models.SaveModelToDb(model) | err = models.SaveModelToDb(model) | ||||
@@ -216,6 +217,7 @@ func SaveLocalModel(ctx *context.Context) { | |||||
description := ctx.Query("description") | description := ctx.Query("description") | ||||
engine := ctx.QueryInt("engine") | engine := ctx.QueryInt("engine") | ||||
taskType := ctx.QueryInt("type") | taskType := ctx.QueryInt("type") | ||||
isPrivate := ctx.QueryBool("isPrivate") | |||||
modelActualPath := "" | modelActualPath := "" | ||||
if taskType == models.TypeCloudBrainOne { | if taskType == models.TypeCloudBrainOne { | ||||
destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(id) + "/" | destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(id) + "/" | ||||
@@ -262,6 +264,7 @@ func SaveLocalModel(ctx *context.Context) { | |||||
TrainTaskInfo: "", | TrainTaskInfo: "", | ||||
Accuracy: "", | Accuracy: "", | ||||
Status: STATUS_FINISHED, | Status: STATUS_FINISHED, | ||||
IsPrivate: isPrivate, | |||||
} | } | ||||
err := models.SaveModelToDb(model) | err := models.SaveModelToDb(model) | ||||
@@ -554,20 +557,6 @@ func deleteModelByID(ctx *context.Context, id string) error { | |||||
return err | return err | ||||
} | } | ||||
func QueryModelByParameters(repoId int64, page int) ([]*models.AiModelManage, int64, error) { | |||||
return models.QueryModel(&models.AiModelQueryOptions{ | |||||
ListOptions: models.ListOptions{ | |||||
Page: page, | |||||
PageSize: setting.UI.IssuePagingNum, | |||||
}, | |||||
RepoID: repoId, | |||||
Type: -1, | |||||
New: MODEL_LATEST, | |||||
Status: -1, | |||||
}) | |||||
} | |||||
func DownloadMultiModelFile(ctx *context.Context) { | func DownloadMultiModelFile(ctx *context.Context) { | ||||
log.Info("DownloadMultiModelFile start.") | log.Info("DownloadMultiModelFile start.") | ||||
id := ctx.Query("id") | id := ctx.Query("id") | ||||
@@ -578,7 +567,7 @@ func DownloadMultiModelFile(ctx *context.Context) { | |||||
ctx.ServerError("no such model:", err) | ctx.ServerError("no such model:", err) | ||||
return | return | ||||
} | } | ||||
if !isOper(ctx, task.UserId) { | |||||
if !isCanDownload(ctx, task) { | |||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ||||
return | return | ||||
} | } | ||||
@@ -806,7 +795,7 @@ func DownloadSingleModelFile(ctx *context.Context) { | |||||
ctx.ServerError("no such model:", err) | ctx.ServerError("no such model:", err) | ||||
return | return | ||||
} | } | ||||
if !isOper(ctx, task.UserId) { | |||||
if !isCanDownload(ctx, task) { | |||||
ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ||||
return | return | ||||
} | } | ||||
@@ -874,8 +863,9 @@ func QueryModelById(ctx *context.Context) { | |||||
id := ctx.Query("id") | id := ctx.Query("id") | ||||
model, err := models.QueryModelById(id) | model, err := models.QueryModelById(id) | ||||
if err == nil { | if err == nil { | ||||
model.IsCanOper = isOper(ctx, model.UserId) | |||||
model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId) | |||||
model.IsCanDelete = isCanDelete(ctx, model.UserId) | model.IsCanDelete = isCanDelete(ctx, model.UserId) | ||||
model.IsCanDownload = isCanDownload(ctx, model) | |||||
removeIpInfo(model) | removeIpInfo(model) | ||||
ctx.JSON(http.StatusOK, model) | ctx.JSON(http.StatusOK, model) | ||||
} else { | } else { | ||||
@@ -891,7 +881,8 @@ func ShowSingleModel(ctx *context.Context) { | |||||
userIds := make([]int64, len(models)) | userIds := make([]int64, len(models)) | ||||
for i, model := range models { | for i, model := range models { | ||||
model.IsCanOper = isOper(ctx, model.UserId) | |||||
model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId) | |||||
model.IsCanDownload = isCanDownload(ctx, model) | |||||
model.IsCanDelete = isCanDelete(ctx, model.UserId) | model.IsCanDelete = isCanDelete(ctx, model.UserId) | ||||
userIds[i] = model.UserId | userIds[i] = model.UserId | ||||
} | } | ||||
@@ -941,7 +932,8 @@ func ShowOneVersionOtherModel(ctx *context.Context) { | |||||
userIds := make([]int64, len(aimodels)) | userIds := make([]int64, len(aimodels)) | ||||
for i, model := range aimodels { | for i, model := range aimodels { | ||||
model.IsCanOper = isOper(ctx, model.UserId) | |||||
model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId) | |||||
model.IsCanDownload = isCanDownload(ctx, model) | |||||
model.IsCanDelete = isCanDelete(ctx, model.UserId) | model.IsCanDelete = isCanDelete(ctx, model.UserId) | ||||
userIds[i] = model.UserId | userIds[i] = model.UserId | ||||
} | } | ||||
@@ -964,6 +956,7 @@ func ShowOneVersionOtherModel(ctx *context.Context) { | |||||
} | } | ||||
func SetModelCount(ctx *context.Context) { | func SetModelCount(ctx *context.Context) { | ||||
isQueryPrivate := isQueryPrivateModel(ctx) | |||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
Type := -1 | Type := -1 | ||||
_, count, _ := models.QueryModel(&models.AiModelQueryOptions{ | _, count, _ := models.QueryModel(&models.AiModelQueryOptions{ | ||||
@@ -971,10 +964,12 @@ func SetModelCount(ctx *context.Context) { | |||||
Page: 1, | Page: 1, | ||||
PageSize: 2, | PageSize: 2, | ||||
}, | }, | ||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
Status: -1, | |||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
IsOnlyThisRepo: true, | |||||
Status: -1, | |||||
IsQueryPrivate: isQueryPrivate, | |||||
}) | }) | ||||
ctx.Data["MODEL_COUNT"] = count | ctx.Data["MODEL_COUNT"] = count | ||||
} | } | ||||
@@ -1001,27 +996,87 @@ func isQueryRight(ctx *context.Context) bool { | |||||
} | } | ||||
} | } | ||||
func isCanDownload(ctx *context.Context, task *models.AiModelManage) bool { | |||||
if ctx.User == nil { | |||||
return false | |||||
} | |||||
isCollaborator, err := ctx.Repo.Repository.IsCollaborator(ctx.User.ID) | |||||
if err != nil { | |||||
log.Info("query error.") | |||||
} | |||||
isTeamMember, err := ctx.Repo.Repository.IsInRepoTeam(ctx.User.ID) | |||||
if err != nil { | |||||
log.Info("query IsInRepoTeam error." + err.Error()) | |||||
} | |||||
if ctx.User.IsAdmin || ctx.User.ID == task.UserId || isCollaborator || isTeamMember { | |||||
return true | |||||
} | |||||
if ctx.Repo.IsOwner() { | |||||
return true | |||||
} | |||||
if !task.IsPrivate { | |||||
return true | |||||
} | |||||
return false | |||||
} | |||||
func isQueryPrivateModel(ctx *context.Context) bool { | |||||
if ctx.User == nil { | |||||
return false | |||||
} | |||||
isCollaborator, err := ctx.Repo.Repository.IsCollaborator(ctx.User.ID) | |||||
if err != nil { | |||||
log.Info("query IsCollaborator error." + err.Error()) | |||||
} | |||||
isTeamMember, err := ctx.Repo.Repository.IsInRepoTeam(ctx.User.ID) | |||||
if err != nil { | |||||
log.Info("query IsInRepoTeam error." + err.Error()) | |||||
} | |||||
if ctx.User.IsAdmin || isCollaborator || isTeamMember { | |||||
return true | |||||
} | |||||
if ctx.Repo.IsOwner() { | |||||
return true | |||||
} | |||||
return false | |||||
} | |||||
func isCanDelete(ctx *context.Context, modelUserId int64) bool { | func isCanDelete(ctx *context.Context, modelUserId int64) bool { | ||||
if ctx.User == nil { | if ctx.User == nil { | ||||
return false | return false | ||||
} | } | ||||
if ctx.User.IsAdmin || ctx.User.ID == modelUserId { | |||||
if ctx.User.ID == modelUserId { | |||||
return true | |||||
} | |||||
return isAdminRight(ctx) | |||||
} | |||||
func isAdminRight(ctx *context.Context) bool { | |||||
if ctx.User.IsAdmin { | |||||
return true | return true | ||||
} | } | ||||
if ctx.Repo.IsOwner() { | if ctx.Repo.IsOwner() { | ||||
return true | return true | ||||
} | } | ||||
permission, err := models.GetUserRepoPermission(ctx.Repo.Repository, ctx.User) | |||||
if err != nil { | |||||
log.Error("GetUserRepoPermission failed:%v", err.Error()) | |||||
return false | |||||
} | |||||
if permission.AccessMode >= models.AccessModeAdmin { | |||||
return true | |||||
} | |||||
return false | return false | ||||
} | } | ||||
func isOper(ctx *context.Context, modelUserId int64) bool { | |||||
func isOperModifyOrDelete(ctx *context.Context, modelUserId int64) bool { | |||||
if ctx.User == nil { | if ctx.User == nil { | ||||
return false | return false | ||||
} | } | ||||
if ctx.User.IsAdmin || ctx.User.ID == modelUserId { | if ctx.User.IsAdmin || ctx.User.ID == modelUserId { | ||||
return true | return true | ||||
} | } | ||||
return false | |||||
return isAdminRight(ctx) | |||||
} | } | ||||
func ShowModelPageInfo(ctx *context.Context) { | func ShowModelPageInfo(ctx *context.Context) { | ||||
@@ -1038,6 +1093,7 @@ func ShowModelPageInfo(ctx *context.Context) { | |||||
if pageSize <= 0 { | if pageSize <= 0 { | ||||
pageSize = setting.UI.IssuePagingNum | pageSize = setting.UI.IssuePagingNum | ||||
} | } | ||||
isQueryPrivate := isQueryPrivateModel(ctx) | |||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
Type := -1 | Type := -1 | ||||
modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{ | modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{ | ||||
@@ -1045,10 +1101,12 @@ func ShowModelPageInfo(ctx *context.Context) { | |||||
Page: page, | Page: page, | ||||
PageSize: pageSize, | PageSize: pageSize, | ||||
}, | }, | ||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
Status: -1, | |||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
IsOnlyThisRepo: true, | |||||
Status: -1, | |||||
IsQueryPrivate: isQueryPrivate, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("Cloudbrain", err) | ctx.ServerError("Cloudbrain", err) | ||||
@@ -1057,8 +1115,9 @@ func ShowModelPageInfo(ctx *context.Context) { | |||||
userIds := make([]int64, len(modelResult)) | userIds := make([]int64, len(modelResult)) | ||||
for i, model := range modelResult { | for i, model := range modelResult { | ||||
model.IsCanOper = isOper(ctx, model.UserId) | |||||
model.IsCanOper = isOperModifyOrDelete(ctx, model.UserId) | |||||
model.IsCanDelete = isCanDelete(ctx, model.UserId) | model.IsCanDelete = isCanDelete(ctx, model.UserId) | ||||
model.IsCanDownload = isCanDownload(ctx, model) | |||||
userIds[i] = model.UserId | userIds[i] = model.UserId | ||||
} | } | ||||
@@ -1089,6 +1148,37 @@ func ModifyModel(id string, description string) error { | |||||
return err | return err | ||||
} | } | ||||
func ModifyModelPrivate(ctx *context.Context) { | |||||
id := ctx.Query("id") | |||||
isPrivate := ctx.QueryBool("isPrivate") | |||||
re := map[string]string{ | |||||
"code": "-1", | |||||
} | |||||
task, err := models.QueryModelById(id) | |||||
if err != nil || task == nil { | |||||
re["msg"] = err.Error() | |||||
log.Error("no such model!", err.Error()) | |||||
ctx.JSON(200, re) | |||||
return | |||||
} | |||||
if !isOperModifyOrDelete(ctx, task.UserId) { | |||||
re["msg"] = "No right to operation." | |||||
ctx.JSON(200, re) | |||||
return | |||||
} | |||||
err = models.ModifyModelPrivate(id, isPrivate) | |||||
if err == nil { | |||||
re["code"] = "0" | |||||
ctx.JSON(200, re) | |||||
log.Info("modify success.") | |||||
} else { | |||||
re["msg"] = err.Error() | |||||
ctx.JSON(200, re) | |||||
log.Info("Failed to modify.id=" + id + " isprivate=" + fmt.Sprint(isPrivate) + " error:" + err.Error()) | |||||
} | |||||
} | |||||
func ModifyModelInfo(ctx *context.Context) { | func ModifyModelInfo(ctx *context.Context) { | ||||
log.Info("modify model start.") | log.Info("modify model start.") | ||||
id := ctx.Query("id") | id := ctx.Query("id") | ||||
@@ -1102,7 +1192,7 @@ func ModifyModelInfo(ctx *context.Context) { | |||||
ctx.JSON(200, re) | ctx.JSON(200, re) | ||||
return | return | ||||
} | } | ||||
if !isOper(ctx, task.UserId) { | |||||
if !isOperModifyOrDelete(ctx, task.UserId) { | |||||
re["msg"] = "No right to operation." | re["msg"] = "No right to operation." | ||||
ctx.JSON(200, re) | ctx.JSON(200, re) | ||||
return | return | ||||
@@ -1112,6 +1202,7 @@ func ModifyModelInfo(ctx *context.Context) { | |||||
label := ctx.Query("label") | label := ctx.Query("label") | ||||
description := ctx.Query("description") | description := ctx.Query("description") | ||||
engine := ctx.QueryInt("engine") | engine := ctx.QueryInt("engine") | ||||
isPrivate := ctx.QueryBool("isPrivate") | |||||
aimodels := models.QueryModelByName(name, task.RepoId) | aimodels := models.QueryModelByName(name, task.RepoId) | ||||
if aimodels != nil && len(aimodels) > 0 { | if aimodels != nil && len(aimodels) > 0 { | ||||
if len(aimodels) == 1 { | if len(aimodels) == 1 { | ||||
@@ -1126,14 +1217,14 @@ func ModifyModelInfo(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
} | } | ||||
err = models.ModifyLocalModel(id, name, label, description, engine) | |||||
err = models.ModifyLocalModel(id, name, label, description, engine, isPrivate) | |||||
} else { | } else { | ||||
label := ctx.Query("label") | label := ctx.Query("label") | ||||
description := ctx.Query("description") | description := ctx.Query("description") | ||||
engine := task.Engine | engine := task.Engine | ||||
name := task.Name | name := task.Name | ||||
err = models.ModifyLocalModel(id, name, label, description, int(engine)) | |||||
err = models.ModifyLocalModel(id, name, label, description, int(engine), task.IsPrivate) | |||||
} | } | ||||
if err != nil { | if err != nil { | ||||
@@ -1148,15 +1239,27 @@ func ModifyModelInfo(ctx *context.Context) { | |||||
func QueryModelListForPredict(ctx *context.Context) { | func QueryModelListForPredict(ctx *context.Context) { | ||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
page := ctx.QueryInt("page") | |||||
if page <= 0 { | |||||
page = -1 | |||||
} | |||||
pageSize := ctx.QueryInt("pageSize") | |||||
if pageSize <= 0 { | |||||
pageSize = -1 | |||||
} | |||||
isQueryPrivate := isQueryPrivateModel(ctx) | |||||
//IsOnlyThisRepo := ctx.QueryBool("isOnlyThisRepo") | |||||
modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{ | modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{ | ||||
ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
Page: -1, | |||||
PageSize: -1, | |||||
Page: page, | |||||
PageSize: pageSize, | |||||
}, | }, | ||||
RepoID: repoId, | |||||
Type: ctx.QueryInt("type"), | |||||
New: -1, | |||||
Status: 0, | |||||
RepoID: repoId, | |||||
Type: ctx.QueryInt("type"), | |||||
New: -1, | |||||
Status: 0, | |||||
IsOnlyThisRepo: true, | |||||
IsQueryPrivate: isQueryPrivate, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("Cloudbrain", err) | ctx.ServerError("Cloudbrain", err) | ||||
@@ -1168,7 +1271,9 @@ func QueryModelListForPredict(ctx *context.Context) { | |||||
nameMap := make(map[string][]*models.AiModelManage) | nameMap := make(map[string][]*models.AiModelManage) | ||||
for _, model := range modelResult { | for _, model := range modelResult { | ||||
removeIpInfo(model) | |||||
model.TrainTaskInfo = "" | |||||
model.Accuracy = "" | |||||
//removeIpInfo(model) | |||||
if _, value := nameMap[model.Name]; !value { | if _, value := nameMap[model.Name]; !value { | ||||
models := make([]*models.AiModelManage, 0) | models := make([]*models.AiModelManage, 0) | ||||
models = append(models, model) | models = append(models, model) | ||||
@@ -670,6 +670,13 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
break | break | ||||
} | } | ||||
if _, err := os.Stat(getOldJobPath(task)); err != nil { | |||||
log.Error("Can not find job minio path", err) | |||||
resultCode = "-1" | |||||
errorMsg = ctx.Tr("cloudbrain.result_cleared") | |||||
break | |||||
} | |||||
count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug)) | count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug)) | ||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
@@ -704,6 +711,11 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
}) | }) | ||||
} | } | ||||
func getOldJobPath(task *models.Cloudbrain) string { | |||||
return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + task.JobName | |||||
} | |||||
func CloudBrainBenchMarkShow(ctx *context.Context) { | func CloudBrainBenchMarkShow(ctx *context.Context) { | ||||
cloudBrainShow(ctx, tplCloudBrainBenchmarkShow, models.JobTypeBenchmark) | cloudBrainShow(ctx, tplCloudBrainBenchmarkShow, models.JobTypeBenchmark) | ||||
} | } | ||||
@@ -2337,7 +2337,7 @@ func InferenceJobIndex(ctx *context.Context) { | |||||
tasks[i].ComputeResource = models.NPUResource | tasks[i].ComputeResource = models.NPUResource | ||||
} | } | ||||
} | } | ||||
isQueryPrivate := isQueryPrivateModel(ctx) | |||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
Type := -1 | Type := -1 | ||||
_, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{ | _, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{ | ||||
@@ -2345,10 +2345,12 @@ func InferenceJobIndex(ctx *context.Context) { | |||||
Page: 1, | Page: 1, | ||||
PageSize: 2, | PageSize: 2, | ||||
}, | }, | ||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
Status: 0, | |||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
IsOnlyThisRepo: true, | |||||
Status: 0, | |||||
IsQueryPrivate: isQueryPrivate, | |||||
}) | }) | ||||
ctx.Data["MODEL_COUNT"] = model_count | ctx.Data["MODEL_COUNT"] = model_count | ||||
@@ -2417,7 +2419,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
return err | return err | ||||
} | } | ||||
ctx.Data["config_list"] = configList.ParaConfigs | ctx.Data["config_list"] = configList.ParaConfigs | ||||
isQueryPrivate := isQueryPrivateModel(ctx) | |||||
repoId := ctx.Repo.Repository.ID | repoId := ctx.Repo.Repository.ID | ||||
Type := -1 | Type := -1 | ||||
_, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{ | _, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{ | ||||
@@ -2425,10 +2427,12 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
Page: 1, | Page: 1, | ||||
PageSize: 2, | PageSize: 2, | ||||
}, | }, | ||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
Status: 0, | |||||
RepoID: repoId, | |||||
Type: Type, | |||||
New: MODEL_LATEST, | |||||
IsOnlyThisRepo: true, | |||||
Status: 0, | |||||
IsQueryPrivate: isQueryPrivate, | |||||
}) | }) | ||||
ctx.Data["MODEL_COUNT"] = model_count | ctx.Data["MODEL_COUNT"] = model_count | ||||
ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ||||
@@ -907,3 +907,9 @@ func QueryUserLoginInfo(ctx *context.Context) { | |||||
log.Info("writer exel error." + err.Error()) | log.Info("writer exel error." + err.Error()) | ||||
} | } | ||||
} | } | ||||
func QueryUserAnnualReport(ctx *context.Context) { | |||||
log.Info("start to QueryUserAnnualReport ") | |||||
result := models.QueryUserAnnualReport(ctx.User.ID) | |||||
ctx.JSON(http.StatusOK, result) | |||||
} |
@@ -49,9 +49,10 @@ func getInvitationDetailExcelHeader(ctx *context.Context) map[string]string { | |||||
excelHeader := make([]string, 0) | excelHeader := make([]string, 0) | ||||
excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | ||||
excelHeader = append(excelHeader, ctx.Tr("user.static.name")) | excelHeader = append(excelHeader, ctx.Tr("user.static.name")) | ||||
excelHeader = append(excelHeader, ctx.Tr("user.static.srcUserId")) | |||||
excelHeader = append(excelHeader, ctx.Tr("user.static.email")) | |||||
excelHeader = append(excelHeader, ctx.Tr("user.static.phone")) | excelHeader = append(excelHeader, ctx.Tr("user.static.phone")) | ||||
excelHeader = append(excelHeader, ctx.Tr("user.static.registdate")) | excelHeader = append(excelHeader, ctx.Tr("user.static.registdate")) | ||||
excelHeader = append(excelHeader, ctx.Tr("user.static.srcUserId")) | |||||
excelHeaderMap := make(map[string]string, 0) | excelHeaderMap := make(map[string]string, 0) | ||||
var i byte | var i byte | ||||
@@ -92,8 +93,7 @@ func writeInvitationDetailExcel(row int, xlsx *excelize.File, sheetName string, | |||||
tmp = tmp + 1 | tmp = tmp + 1 | ||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name) | xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name) | ||||
tmp = tmp + 1 | tmp = tmp + 1 | ||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID) | |||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Email) | |||||
tmp = tmp + 1 | tmp = tmp + 1 | ||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone) | xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone) | ||||
@@ -101,7 +101,9 @@ func writeInvitationDetailExcel(row int, xlsx *excelize.File, sheetName string, | |||||
formatTime := userRecord.CreatedUnix.Format("2006-01-02 15:04:05") | formatTime := userRecord.CreatedUnix.Format("2006-01-02 15:04:05") | ||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3]) | xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3]) | ||||
tmp = tmp + 1 | |||||
xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID) | |||||
} | } | ||||
func DownloadInvitationDetail(ctx *context.Context) { | func DownloadInvitationDetail(ctx *context.Context) { | ||||
@@ -413,6 +415,7 @@ func queryData(ctx *context.Context, startTime time.Time, endTime time.Time) { | |||||
invi.Name = tmpUser.Name | invi.Name = tmpUser.Name | ||||
invi.Phone = tmpUser.PhoneNumber | invi.Phone = tmpUser.PhoneNumber | ||||
invi.CreatedUnix = tmpUser.CreatedUnix | invi.CreatedUnix = tmpUser.CreatedUnix | ||||
invi.Email = tmpUser.Email | |||||
} else { | } else { | ||||
invi.Name = "已注销" | invi.Name = "已注销" | ||||
} | } | ||||
@@ -1262,6 +1262,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Post("/delete_model_convert/:id", repo.DeleteModelConvert) | m.Post("/delete_model_convert/:id", repo.DeleteModelConvert) | ||||
m.Post("/convert_stop/:id", repo.StopModelConvert) | m.Post("/convert_stop/:id", repo.StopModelConvert) | ||||
m.Put("/modify_model", repo.ModifyModelInfo) | m.Put("/modify_model", repo.ModifyModelInfo) | ||||
m.Put("/modify_model_status", repo.ModifyModelPrivate) | |||||
m.Get("/show_model", reqRepoModelManageReader, repo.ShowModelTemplate) | m.Get("/show_model", reqRepoModelManageReader, repo.ShowModelTemplate) | ||||
m.Get("/convert_model", reqRepoModelManageReader, repo.ConvertModelTemplate) | m.Get("/convert_model", reqRepoModelManageReader, repo.ConvertModelTemplate) | ||||
m.Get("/show_model_info", repo.ShowModelInfo) | m.Get("/show_model_info", repo.ShowModelInfo) | ||||
@@ -63,7 +63,7 @@ func InviationTpl(ctx *context.Context) { | |||||
ctx.HTML(200, tplInvitation) | ctx.HTML(200, tplInvitation) | ||||
} | } | ||||
func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhoneNumber string) error { | |||||
func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhoneNumber string, email string) error { | |||||
user := parseInvitaionCode(invitationcode) | user := parseInvitaionCode(invitationcode) | ||||
if user == nil { | if user == nil { | ||||
return errors.New("The invitated user not existed.") | return errors.New("The invitated user not existed.") | ||||
@@ -85,6 +85,7 @@ func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhone | |||||
SrcUserID: user.ID, | SrcUserID: user.ID, | ||||
UserID: newUserId, | UserID: newUserId, | ||||
Phone: newPhoneNumber, | Phone: newPhoneNumber, | ||||
Email: email, | |||||
} | } | ||||
err := models.InsertInvitaion(invitation) | err := models.InsertInvitaion(invitation) | ||||
@@ -1368,7 +1368,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||||
log.Info("enter here, and form.InvitaionCode =" + invitationCode) | log.Info("enter here, and form.InvitaionCode =" + invitationCode) | ||||
if invitationCode != "" { | if invitationCode != "" { | ||||
RegisteUserByInvitaionCode(invitationCode, u.ID, u.PhoneNumber) | |||||
RegisteUserByInvitaionCode(invitationCode, u.ID, u.PhoneNumber, u.Email) | |||||
} | } | ||||
err := models.AddEmailAddress(&models.EmailAddress{ | err := models.AddEmailAddress(&models.EmailAddress{ | ||||
@@ -0,0 +1,151 @@ | |||||
package cloudbrain | |||||
import ( | |||||
"io/ioutil" | |||||
"os" | |||||
"sort" | |||||
"time" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/setting" | |||||
"code.gitea.io/gitea/modules/storage" | |||||
) | |||||
func ClearCloudbrainResultSpace() { | |||||
log.Info("clear cloudbrain one result space begin.") | |||||
if !setting.ClearStrategy.Enabled{ | |||||
return | |||||
} | |||||
tasks, err := models.GetCloudBrainOneStoppedNotDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.BatchSize) | |||||
if err != nil { | |||||
log.Warn("Failed to get cloudbrain, clear result failed.", err) | |||||
return | |||||
} | |||||
debugTasks, err := models.GetCloudBrainOneStoppedDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.DebugJobSize) | |||||
if err != nil { | |||||
log.Warn("Failed to get debug cloudbrain.", err) | |||||
} | |||||
tasks=append(tasks,debugTasks...) | |||||
if err != nil { | |||||
log.Warn("Failed to get cloudbrain, clear result failed.", err) | |||||
return | |||||
} | |||||
var ids []int64 | |||||
for _, task := range tasks { | |||||
err := DeleteCloudbrainOneJobStorage(task.JobName) | |||||
if err == nil { | |||||
log.Info("clear job in cloudbrain table:"+task.JobName) | |||||
ids = append(ids, task.ID) | |||||
} | |||||
} | |||||
err = models.UpdateCloudBrainRecordsCleared(ids) | |||||
if err != nil { | |||||
log.Warn("Failed to set cloudbrain cleared status", err) | |||||
} | |||||
//如果云脑表处理完了,通过遍历minio对象处理历史垃圾数据,如果存在的话 | |||||
if len(tasks) < setting.ClearStrategy.BatchSize+setting.ClearStrategy.DebugJobSize { | |||||
clearLocalHistoryTrashFile() | |||||
clearMinioHistoryTrashFile() | |||||
} | |||||
log.Info("clear cloudbrain one result space end.") | |||||
} | |||||
func clearMinioHistoryTrashFile() { | |||||
JobRealPrefix := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix | |||||
miniofiles, err := ioutil.ReadDir(JobRealPrefix) | |||||
processCount := 0 | |||||
if err != nil { | |||||
log.Warn("Can not browser minio job path.") | |||||
} else { | |||||
SortModTimeAscend(miniofiles) | |||||
for _, file := range miniofiles { | |||||
if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) { | |||||
has,err:=models.IsCloudbrainExistByJobName(file.Name()) | |||||
if err==nil && !has { | |||||
dirPath := setting.CBCodePathPrefix + file.Name() + "/" | |||||
log.Info("clear job in minio trash:" + file.Name()) | |||||
storage.Attachments.DeleteDir(dirPath) | |||||
processCount++ | |||||
} | |||||
if processCount == setting.ClearStrategy.BatchSize { | |||||
break | |||||
} | |||||
} else { | |||||
break | |||||
} | |||||
} | |||||
} | |||||
} | |||||
func clearLocalHistoryTrashFile() { | |||||
files, err := ioutil.ReadDir(setting.JobPath) | |||||
processCount := 0 | |||||
if err != nil { | |||||
log.Warn("Can not browser local job path.") | |||||
} else { | |||||
SortModTimeAscend(files) | |||||
for _, file := range files { | |||||
//清理n天前的历史垃圾数据,清理job目录 | |||||
if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) { | |||||
has,err:=models.IsCloudbrainExistByJobName(file.Name()) | |||||
if err==nil && !has{ | |||||
os.RemoveAll(setting.JobPath + file.Name()) | |||||
log.Info("clear job in local trash:"+file.Name()) | |||||
processCount++ | |||||
} | |||||
if processCount == setting.ClearStrategy.BatchSize { | |||||
break | |||||
} | |||||
} else { | |||||
break | |||||
} | |||||
} | |||||
} | |||||
} | |||||
func SortModTimeAscend(files []os.FileInfo) { | |||||
sort.Slice(files, func(i, j int) bool { | |||||
return files[i].ModTime().Before(files[j].ModTime()) | |||||
}) | |||||
} | |||||
func DeleteCloudbrainOneJobStorage(jobName string) error { | |||||
if jobName==""{ | |||||
return nil | |||||
} | |||||
//delete local | |||||
localJobPath := setting.JobPath + jobName | |||||
err := os.RemoveAll(localJobPath) | |||||
if err != nil { | |||||
log.Error("RemoveAll(%s) failed:%v", localJobPath, err) | |||||
} | |||||
dirPath := setting.CBCodePathPrefix + jobName + "/" | |||||
err1 := storage.Attachments.DeleteDir(dirPath) | |||||
if err1 != nil { | |||||
log.Error("DeleteDir(%s) failed:%v", localJobPath, err) | |||||
} | |||||
if err == nil { | |||||
err = err1 | |||||
} | |||||
return err | |||||
} |
@@ -246,10 +246,10 @@ func FindAvailableSpecs(userId int64, opts models.FindSpecsOptions) ([]*models.S | |||||
return nil, err | return nil, err | ||||
} | } | ||||
//filter exclusive specs | //filter exclusive specs | ||||
specs := filterExclusiveSpecs(r, userId) | |||||
specs := models.FilterExclusiveSpecs(r, userId) | |||||
//distinct by sourceSpecId | //distinct by sourceSpecId | ||||
specs = distinctSpecs(specs) | |||||
specs = models.DistinctSpecs(specs) | |||||
return specs, err | return specs, err | ||||
} | } | ||||
@@ -265,50 +265,6 @@ func FindAvailableSpecs4Show(userId int64, opts models.FindSpecsOptions) ([]*api | |||||
return result, nil | return result, nil | ||||
} | } | ||||
func filterExclusiveSpecs(r []*models.Specification, userId int64) []*models.Specification { | |||||
specs := make([]*models.Specification, 0, len(r)) | |||||
specMap := make(map[int64]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if _, has := specMap[spec.ID]; has { | |||||
continue | |||||
} | |||||
if !spec.IsExclusive { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
continue | |||||
} | |||||
orgs := strings.Split(spec.ExclusiveOrg, ";") | |||||
for _, org := range orgs { | |||||
isMember, _ := models.IsOrganizationMemberByOrgName(org, userId) | |||||
if isMember { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
break | |||||
} | |||||
} | |||||
} | |||||
return specs | |||||
} | |||||
func distinctSpecs(r []*models.Specification) []*models.Specification { | |||||
specs := make([]*models.Specification, 0, len(r)) | |||||
sourceSpecIdMap := make(map[string]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if spec.SourceSpecId == "" { | |||||
specs = append(specs, spec) | |||||
continue | |||||
} | |||||
if _, has := sourceSpecIdMap[spec.SourceSpecId]; has { | |||||
continue | |||||
} | |||||
specs = append(specs, spec) | |||||
sourceSpecIdMap[spec.SourceSpecId] = "" | |||||
} | |||||
return specs | |||||
} | |||||
func GetAndCheckSpec(userId int64, specId int64, opts models.FindSpecsOptions) (*models.Specification, error) { | func GetAndCheckSpec(userId int64, specId int64, opts models.FindSpecsOptions) (*models.Specification, error) { | ||||
if specId == 0 { | if specId == 0 { | ||||
return nil, nil | return nil, nil | ||||
@@ -647,6 +647,23 @@ | |||||
<input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | <input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | ||||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | ||||
</div> | </div> | ||||
<div class="inline fields"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess"}} </label> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" checked="checked" value="false"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.public"}}</label> | |||||
</div> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" value="true"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.private"}}</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="inline field"> | <div class="inline field"> | ||||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | <label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | ||||
<textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | <textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | ||||
@@ -849,6 +866,10 @@ | |||||
} | } | ||||
let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | ||||
let data = $("#formId").serialize() | let data = $("#formId").serialize() | ||||
var radio = document.getElementsByName("isPrivate"); | |||||
if(radio == null || radio.length == 0){ | |||||
data +="&isPrivate=true"; | |||||
} | |||||
$("#mask").css({ "display": "block", "z-index": "9999" }) | $("#mask").css({ "display": "block", "z-index": "9999" }) | ||||
$.ajax({ | $.ajax({ | ||||
url: url_href, | url: url_href, | ||||
@@ -679,6 +679,23 @@ | |||||
<input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | <input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | ||||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | ||||
</div> | </div> | ||||
<div class="inline fields"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess"}} </label> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" checked="checked" value="false"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.public"}}</label> | |||||
</div> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" value="true"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.private"}}</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="inline field"> | <div class="inline field"> | ||||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | <label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | ||||
<textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | <textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | ||||
@@ -910,6 +927,10 @@ | |||||
} | } | ||||
let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | ||||
let data = $("#formId").serialize() | let data = $("#formId").serialize() | ||||
var radio = document.getElementsByName("isPrivate"); | |||||
if(radio == null || radio.length == 0){ | |||||
data +="&isPrivate=true"; | |||||
} | |||||
$("#mask").css({ "display": "block", "z-index": "9999" }) | $("#mask").css({ "display": "block", "z-index": "9999" }) | ||||
$.ajax({ | $.ajax({ | ||||
url: url_href, | url: url_href, | ||||
@@ -703,6 +703,25 @@ | |||||
<input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | <input style="width: 83%;margin-left: 7px;" id="label" name="label" maxlength="255" | ||||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | ||||
</div> | </div> | ||||
{{if eq $.Repository.IsPrivate false}} | |||||
<div class="inline fields"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess"}} </label> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" checked="checked" value="false"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.public"}}</label> | |||||
</div> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" value="true"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.private"}}</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{end}} | |||||
<div class="inline field"> | <div class="inline field"> | ||||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | <label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | ||||
<textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | <textarea style="width: 83%;margin-left: 7px;" id="description" name="description" rows="3" | ||||
@@ -930,6 +949,10 @@ | |||||
} | } | ||||
let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | let url_href = `/${userName}/${repoPath}/modelmanage/create_new_model` | ||||
let data = $("#formId").serialize() | let data = $("#formId").serialize() | ||||
var radio = document.getElementsByName("isPrivate"); | |||||
if(radio == null || radio.length == 0){ | |||||
data +="&isPrivate=true"; | |||||
} | |||||
$("#mask").css({ "display": "block", "z-index": "9999" }) | $("#mask").css({ "display": "block", "z-index": "9999" }) | ||||
$.ajax({ | $.ajax({ | ||||
url: url_href, | url: url_href, | ||||
@@ -487,7 +487,7 @@ | |||||
} | } | ||||
function loadModelList(){ | function loadModelList(){ | ||||
$.get(`${repolink}/modelmanage/query_model_for_predict?repoId=${repoId}&type=-1`, (data) => { | |||||
$.get(`${repolink}/modelmanage/query_model_for_predict?repoId=${repoId}&type=-1&isOnlyThisRepo=true`, (data) => { | |||||
modelData = data | modelData = data | ||||
let nameList = data.nameList | let nameList = data.nameList | ||||
const n_length = nameList.length | const n_length = nameList.length | ||||
@@ -2,6 +2,7 @@ | |||||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-modelmanage-local-create-1.css?v={{MD5 AppVer}}" /> | <link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-modelmanage-local-create-1.css?v={{MD5 AppVer}}" /> | ||||
<div class="repository release dataset-list view"> | <div class="repository release dataset-list view"> | ||||
{{template "repo/header" .}} | {{template "repo/header" .}} | ||||
<script>var REPO_IS_PRIVATE = {{$.Repository.IsPrivate}};</script> | |||||
<div class="ui container"> | <div class="ui container"> | ||||
<div id="__vue-root"></div> | <div id="__vue-root"></div> | ||||
</div> | </div> | ||||
@@ -135,6 +135,25 @@ | |||||
<input class="ays-ignore" id="label" name="label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | <input class="ays-ignore" id="label" name="label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
{{if eq $.Repository.IsPrivate false}} | |||||
<div class="inline fields"> | |||||
<div class="two wide field right aligned"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess"}}  </label> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" checked="checked" value="false"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.public"}}</label> | |||||
</div> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="isPrivate" value="true"> | |||||
<label>{{.i18n.Tr "repo.model.manage.modelaccess.private"}}</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{end}} | |||||
<div class="inline fields"> | <div class="inline fields"> | ||||
<div class="two wide field right aligned"> | <div class="two wide field right aligned"> | ||||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}  </label> | <label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}  </label> | ||||
@@ -549,6 +568,10 @@ | |||||
let cName = $("input[name='name']").val(); | let cName = $("input[name='name']").val(); | ||||
let version = $("input[name='version']").val(); | let version = $("input[name='version']").val(); | ||||
let data = $("#formId").serialize(); | let data = $("#formId").serialize(); | ||||
var radio = document.getElementsByName("isPrivate"); | |||||
if(radio == null || radio.length == 0){ | |||||
data +="&isPrivate=true"; | |||||
} | |||||
const initModel = $("input[name='initModel']").val(); | const initModel = $("input[name='initModel']").val(); | ||||
let url_href = location.href.split("create_online_model")[0] + 'create_new_model'; | let url_href = location.href.split("create_online_model")[0] + 'create_new_model'; | ||||
$("#mask").css({ display: "block", "z-index": "9999" }); | $("#mask").css({ display: "block", "z-index": "9999" }); | ||||
@@ -44,7 +44,7 @@ | |||||
} | } | ||||
</style> | </style> | ||||
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> | <link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> | ||||
<script>var REPO_IS_PRIVATE = {{.Repository.IsPrivate}};</script> | |||||
<!-- 弹窗 --> | <!-- 弹窗 --> | ||||
<div id="mask"> | <div id="mask"> | ||||
@@ -57,6 +57,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{$repository := .Repository.ID}} | {{$repository := .Repository.ID}} | ||||
<!-- 提示框 --> | <!-- 提示框 --> | ||||
<div class="alert"></div> | <div class="alert"></div> | ||||
@@ -234,6 +235,7 @@ | |||||
<input id="label" name="label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | <input id="label" name="label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="inline fields"> | <div class="inline fields"> | ||||
<div class="two wide field right aligned"> | <div class="two wide field right aligned"> | ||||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}  </label> | <label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}  </label> | ||||
@@ -32,18 +32,7 @@ | |||||
> | > | ||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column | |||||
prop="status" | |||||
:label="i18n.model_status" | |||||
align="center" | |||||
min-width="6.5%" | |||||
> | |||||
<template slot-scope="scope"> | |||||
<span class="text-over" :title="scope.row.status_title"> | |||||
<i style="vertical-align: middle" :class="scope.row.status"></i | |||||
></span> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column | <el-table-column | ||||
prop="version" | prop="version" | ||||
:label="i18n.model_version" | :label="i18n.model_version" | ||||
@@ -102,6 +91,22 @@ | |||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column | <el-table-column | ||||
prop="isPrivate" | |||||
:label="i18n.model_status" | |||||
align="center" | |||||
min-width="6.75%" | |||||
> | |||||
<template slot-scope="scope"> | |||||
<span class="text-over" :title="scope.row.status_title"> | |||||
<i style="vertical-align: middle" :class="scope.row.status"></i | |||||
></span> | |||||
<span style="color: #fa8c16;" v-if="scope.row.isPrivate">{{ i18n.modelaccess_private }}</span> | |||||
<span style="color: #13c28d;" v-else="!scope.row.isPrivate">{{ i18n.modelaccess_public }}</span> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column | |||||
prop="createdUnix" | prop="createdUnix" | ||||
:label="i18n.model_create_time" | :label="i18n.model_create_time" | ||||
align="center" | align="center" | ||||
@@ -137,29 +142,23 @@ | |||||
> | > | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<div class="space-around" > | <div class="space-around" > | ||||
<!--<a | |||||
:style="{ | |||||
visibility: !scope.row.Children ? 'visible' : 'hidden', | |||||
}" | |||||
:class="{ disabled: !scope.row.isCanOper }" | |||||
@click=" | |||||
showcreateVue( | |||||
scope.row.name, | |||||
scope.row.version, | |||||
scope.row.label | |||||
) | |||||
" | |||||
>{{ i18n.model_create_new_ver }}</a | |||||
>--> | |||||
<a class="op-btn" | <a class="op-btn" | ||||
v-show="scope.row.modelType == 1" | v-show="scope.row.modelType == 1" | ||||
:href="url + 'create_local_model_1?type=1&name=' + encodeURIComponent(scope.row.name) + '&id=' + scope.row.id" | :href="url + 'create_local_model_1?type=1&name=' + encodeURIComponent(scope.row.name) + '&id=' + scope.row.id" | ||||
:class="{ disabled: !scope.row.isCanOper }" | :class="{ disabled: !scope.row.isCanOper }" | ||||
>{{ i18n.modify }}</a> | >{{ i18n.modify }}</a> | ||||
<a class="op-btn" v-show="scope.row.modelType != 1" style="color:transparent;cursor:default;" >{{ i18n.modify }}</a> | |||||
<a class="op-btn" v-show="scope.row.modelType != 1" style="color:transparent;cursor:default;" >{{ i18n.modify }}</a> | |||||
<a class="op-btn" style="color: #13c28d;" v-show="repoIsPrivate == false && scope.row.isPrivate==true && scope.row.isCanOper" @click=" | |||||
modifyModelStatus(scope.row.id, scope.row.cName, scope.row.rowKey,false) | |||||
">{{ i18n.modelaccess_setpublic }}</a> | |||||
<a class="op-btn" style="color: #fa8c16;" v-show="repoIsPrivate == false && scope.row.isPrivate==false && scope.row.isCanOper" @click=" | |||||
modifyModelStatus(scope.row.id, scope.row.cName, scope.row.rowKey,true) | |||||
">{{ i18n.modelaccess_setprivate }}</a> | |||||
<a class="op-btn" | <a class="op-btn" | ||||
:href="loadhref + scope.row.id" | :href="loadhref + scope.row.id" | ||||
:class="{ disabled: !scope.row.isCanOper }" | |||||
:class="{ disabled: !scope.row.isCanDownload }" | |||||
>{{ i18n.model_download }}</a> | >{{ i18n.model_download }}</a> | ||||
<a class="op-btn" | <a class="op-btn" | ||||
:class="{ disabled: !scope.row.isCanDelete }" | :class="{ disabled: !scope.row.isCanDelete }" | ||||
@@ -190,8 +189,9 @@ | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import { modifyModelStatus } from '~/apis/modules/modelmanage'; | |||||
const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | ||||
const REPOISPRIVATE = window.REPO_IS_PRIVATE; | |||||
export default { | export default { | ||||
components: {}, | components: {}, | ||||
data() { | data() { | ||||
@@ -206,11 +206,13 @@ export default { | |||||
isLoading: true, | isLoading: true, | ||||
loadNodeMap: new Map(), | loadNodeMap: new Map(), | ||||
submitId: {}, | submitId: {}, | ||||
repo: location.pathname.split('/').slice(0, 3).join('/'), | |||||
defaultAvatar: "/user/avatar/Ghost/-1", | defaultAvatar: "/user/avatar/Ghost/-1", | ||||
defaultAvatarName: "Ghost", | defaultAvatarName: "Ghost", | ||||
data: "", | data: "", | ||||
timer: null, | timer: null, | ||||
timerFlag: false, | timerFlag: false, | ||||
repoIsPrivate: REPOISPRIVATE, | |||||
}; | }; | ||||
}, | }, | ||||
methods: { | methods: { | ||||
@@ -403,6 +405,26 @@ export default { | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
modifyModelStatus(id, name, rowKey,isPrivate) { | |||||
let data = {'id':id,'isPrivate':isPrivate,'repo':this.repo}; | |||||
modifyModelStatus(data).then(res => { | |||||
res = res.data; | |||||
if (res && res.code == '0') { | |||||
this.getModelList(); | |||||
} else { | |||||
this.$message({ | |||||
type: 'error', | |||||
message: this.$t('modelManage.infoModificationFailed'), | |||||
}); | |||||
} | |||||
}).catch(err => { | |||||
console.log(err); | |||||
this.$message({ | |||||
type: 'error', | |||||
message: this.$t('modelManage.infoModificationFailed'), | |||||
}); | |||||
}); | |||||
}, | |||||
deleteModel(id, name, rowKey) { | deleteModel(id, name, rowKey) { | ||||
let row = { cName: name, id: id, rowKey: rowKey }; | let row = { cName: name, id: id, rowKey: rowKey }; | ||||
let _this = this; | let _this = this; | ||||
@@ -542,6 +564,14 @@ export default { | |||||
showinfoHref() { | showinfoHref() { | ||||
return this.url + "show_model_info?name="; | return this.url + "show_model_info?name="; | ||||
}, | }, | ||||
transStatus(){ | |||||
return function (state) { | |||||
if(state){ | |||||
return this.i18n.modelaccess_private; | |||||
} | |||||
return this.i18n.modelaccess_public; | |||||
} | |||||
}, | |||||
transTime() { | transTime() { | ||||
return function (time) { | return function (time) { | ||||
let date = new Date(time * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000 | let date = new Date(time * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000 | ||||
@@ -92,6 +92,11 @@ export const i18nVue = { | |||||
model_create_time: "创建时间", | model_create_time: "创建时间", | ||||
model_creator: "创建者", | model_creator: "创建者", | ||||
model_operation: "操作", | model_operation: "操作", | ||||
model_access: "权限", | |||||
modelaccess_public:"公开", | |||||
modelaccess_private:"私有", | |||||
modelaccess_setpublic:"设为公开", | |||||
modelaccess_setprivate:"设为私有", | |||||
model_create_new_ver: "创建新版本", | model_create_new_ver: "创建新版本", | ||||
model_download: "下载", | model_download: "下载", | ||||
model_delete: "删除", | model_delete: "删除", | ||||
@@ -208,6 +213,11 @@ export const i18nVue = { | |||||
model_create_time: "Created Time", | model_create_time: "Created Time", | ||||
model_creator: "Creator", | model_creator: "Creator", | ||||
model_operation: "Operation", | model_operation: "Operation", | ||||
model_access: "Access", | |||||
modelaccess_public:"Public", | |||||
modelaccess_private:"Private", | |||||
modelaccess_setpublic:"Set Public", | |||||
modelaccess_setprivate:"Set Private", | |||||
model_create_new_ver: "New Version", | model_create_new_ver: "New Version", | ||||
model_download: "Download", | model_download: "Download", | ||||
model_delete: "Delete", | model_delete: "Delete", | ||||
@@ -24,6 +24,16 @@ export const modifyModel = (data) => { | |||||
}); | }); | ||||
}; | }; | ||||
export const modifyModelStatus = (data) => { | |||||
return service({ | |||||
url: `${data.repo}/modelmanage/modify_model_status`, | |||||
method: 'put', | |||||
headers: { 'Content-type': 'application/x-www-form-urlencoded' }, | |||||
params: {}, | |||||
data: Qs.stringify(data), | |||||
}); | |||||
}; | |||||
// 求模型信息 | // 求模型信息 | ||||
export const getModelInfoByName = (params) => { | export const getModelInfoByName = (params) => { | ||||
return service({ | return service({ | ||||
@@ -281,6 +281,9 @@ const en = { | |||||
infoModificationFailed: 'Information modify failed', | infoModificationFailed: 'Information modify failed', | ||||
deleteModelFileConfirmTips: 'Are you sure you want to delete the current model file?', | deleteModelFileConfirmTips: 'Are you sure you want to delete the current model file?', | ||||
modelFileDeleteFailed: 'Model file delete failed', | modelFileDeleteFailed: 'Model file delete failed', | ||||
modelAccess:'Model Access', | |||||
modelAccessPublic:'Public', | |||||
modelAccessPrivate:'Private', | |||||
}, | }, | ||||
} | } | ||||
@@ -282,6 +282,9 @@ const zh = { | |||||
infoModificationFailed: '信息修改失败', | infoModificationFailed: '信息修改失败', | ||||
deleteModelFileConfirmTips: '请确认是否删除当前模型文件?', | deleteModelFileConfirmTips: '请确认是否删除当前模型文件?', | ||||
modelFileDeleteFailed: '模型文件删除失败', | modelFileDeleteFailed: '模型文件删除失败', | ||||
modelAccess:'模型权限', | |||||
modelAccessPublic:'公开', | |||||
modelAccessPrivate:'私有', | |||||
}, | }, | ||||
}; | }; | ||||
@@ -51,6 +51,12 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="row"> | |||||
<div class="tit">{{ $t('modelManage.modelAccess') }}:</div> | |||||
<div class="val"> | |||||
<div class="txt-wrap">{{ state.isPrivate }}</div> | |||||
</div> | |||||
</div> | |||||
</div> | </div> | ||||
<div class="area"> | <div class="area"> | ||||
<div class="row"> | <div class="row"> | ||||
@@ -176,8 +182,8 @@ | |||||
<span>{{ scope.row.FileName }}</span> | <span>{{ scope.row.FileName }}</span> | ||||
</div> | </div> | ||||
</a> | </a> | ||||
<a v-else :class="!canOperate ? 'disabled-download' : ''" | |||||
:href="canOperate ? `${repo}/modelmanage/${state.id}/downloadsingle?parentDir=${filePath.length > 1 ? encodeURIComponent(filePath.map(item => item.path).join('/').slice(1) + '/') : ''}&fileName=${scope.row.FileName}` : 'javascript:;'"> | |||||
<a v-else :class="!canDownload ? 'disabled-download' : ''" | |||||
:href="canDownload ? `${repo}/modelmanage/${state.id}/downloadsingle?parentDir=${filePath.length > 1 ? encodeURIComponent(filePath.map(item => item.path).join('/').slice(1) + '/') : ''}&fileName=${scope.row.FileName}` : 'javascript:;'"> | |||||
<div class="fitted" :title="scope.row.FileName"> | <div class="fitted" :title="scope.row.FileName"> | ||||
<i class="icon file" width="16" height="16" aria-hidden="true"></i> | <i class="icon file" width="16" height="16" aria-hidden="true"></i> | ||||
<span>{{ scope.row.FileName }}</span> | <span>{{ scope.row.FileName }}</span> | ||||
@@ -222,6 +228,7 @@ export default { | |||||
return { | return { | ||||
modelType: '0', // 1-本地, 0-线上 | modelType: '0', // 1-本地, 0-线上 | ||||
canOperate: false, | canOperate: false, | ||||
canDownload:false, | |||||
canDelete: false, | canDelete: false, | ||||
isExpanded: false, | isExpanded: false, | ||||
loading: false, | loading: false, | ||||
@@ -285,6 +292,7 @@ export default { | |||||
const data = this.modelList.filter((model) => model.version == version)[0]; | const data = this.modelList.filter((model) => model.version == version)[0]; | ||||
this.modelType = data.modelType; | this.modelType = data.modelType; | ||||
this.canOperate = data.isCanOper; | this.canOperate = data.isCanOper; | ||||
this.canDownload = data.isCanDownload; | |||||
this.canDelete = data.isCanDelete; | this.canDelete = data.isCanDelete; | ||||
this.state.type = data.type; | this.state.type = data.type; | ||||
this.state.typeStr = data.type == 0 ? 'CPU/GPU' : data.type == 1 ? 'NPU' : ''; | this.state.typeStr = data.type == 0 ? 'CPU/GPU' : data.type == 1 ? 'NPU' : ''; | ||||
@@ -298,6 +306,7 @@ export default { | |||||
this.state._label = data.label; | this.state._label = data.label; | ||||
this.state.description = data.description || '--'; | this.state.description = data.description || '--'; | ||||
this.state._description = data.description; | this.state._description = data.description; | ||||
this.state.isPrivate= (data.isPrivate == true ? this.$t('modelManage.modelAccessPrivate'):this.$t('modelManage.modelAccessPublic')); | |||||
this.state.createTime = formatDate(new Date(data.createdUnix * 1000), 'yyyy-MM-dd HH:mm:ss'); | this.state.createTime = formatDate(new Date(data.createdUnix * 1000), 'yyyy-MM-dd HH:mm:ss'); | ||||
const trainTaskInfo = data.trainTaskInfo ? JSON.parse(data.trainTaskInfo) : ''; | const trainTaskInfo = data.trainTaskInfo ? JSON.parse(data.trainTaskInfo) : ''; | ||||
@@ -85,6 +85,28 @@ | |||||
:placeholder="$t('modelManage.modelLabelInputTips')" @input="labelInput"></el-input> | :placeholder="$t('modelManage.modelLabelInputTips')" @input="labelInput"></el-input> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="row" v-if="repoIsPrivate==false"> | |||||
<div class="r-title"><label>{{ $t('modelManage.modelAccess') }}</label></div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input id="isPrivate_false" type="radio" name="isPrivate" checked="checked" value="false"> | |||||
<label>{{ $t('modelManage.modelAccessPublic') }}</label> | |||||
</div> | |||||
</div> | |||||
<div class="field"> | |||||
<label> </label> | |||||
</div> | |||||
<div class="field"> | |||||
<div class="ui radio checkbox"> | |||||
<input id="isPrivate_true" type="radio" name="isPrivate" value="true"> | |||||
<label>{{ $t('modelManage.modelAccessPrivate') }}</label> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="row" style="align-items:flex-start;"> | <div class="row" style="align-items:flex-start;"> | ||||
<div class="r-title"><label>{{ $t('modelManage.modelDescr') }}</label></div> | <div class="r-title"><label>{{ $t('modelManage.modelDescr') }}</label></div> | ||||
<div class="r-content"> | <div class="r-content"> | ||||
@@ -93,6 +115,7 @@ | |||||
</el-input> | </el-input> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="row" style="margin-top:20px"> | <div class="row" style="margin-top:20px"> | ||||
<div class="r-title"><label></label></div> | <div class="r-title"><label></label></div> | ||||
<div class="r-content"> | <div class="r-content"> | ||||
@@ -116,7 +139,7 @@ import { MODEL_ENGINES } from '~/const' | |||||
const REPO_NAME = location.pathname.split('/')[2]; | const REPO_NAME = location.pathname.split('/')[2]; | ||||
const MAX_LABEL_COUNT = 5; | const MAX_LABEL_COUNT = 5; | ||||
const REPOISPRIVATE = window.REPO_IS_PRIVATE; | |||||
export default { | export default { | ||||
data() { | data() { | ||||
return { | return { | ||||
@@ -129,10 +152,12 @@ export default { | |||||
engine: '0', | engine: '0', | ||||
label: '', | label: '', | ||||
description: '', | description: '', | ||||
isPrivate : false, | |||||
}, | }, | ||||
nameErr: false, | nameErr: false, | ||||
isShowVersion: false, | isShowVersion: false, | ||||
engineList: MODEL_ENGINES, | engineList: MODEL_ENGINES, | ||||
repoIsPrivate: REPOISPRIVATE, | |||||
}; | }; | ||||
}, | }, | ||||
components: {}, | components: {}, | ||||
@@ -145,6 +170,7 @@ export default { | |||||
const hasEndSpace = this.state.label[this.state.label.length - 1] == ' '; | const hasEndSpace = this.state.label[this.state.label.length - 1] == ' '; | ||||
const list = this.state.label.trim().split(' ').filter(label => label != ''); | const list = this.state.label.trim().split(' ').filter(label => label != ''); | ||||
this.state.label = list.slice(0, MAX_LABEL_COUNT).join(' ') + (hasEndSpace && list.length < MAX_LABEL_COUNT ? ' ' : ''); | this.state.label = list.slice(0, MAX_LABEL_COUNT).join(' ') + (hasEndSpace && list.length < MAX_LABEL_COUNT ? ' ' : ''); | ||||
}, | }, | ||||
submit() { | submit() { | ||||
if (!this.checkName()) { | if (!this.checkName()) { | ||||
@@ -154,6 +180,16 @@ export default { | |||||
// }); | // }); | ||||
return; | return; | ||||
} | } | ||||
var radio = document.getElementsByName("isPrivate"); | |||||
if(radio != null && radio.length > 0){ | |||||
for (var i=0; i<radio.length; i++) { | |||||
if (radio[i].checked) { | |||||
this.state.isPrivate=radio[i].value; | |||||
} | |||||
} | |||||
}else{ | |||||
this.state.isPrivate = true; | |||||
} | |||||
const submintApi = this.type == '1' ? modifyModel : saveLocalModel; | const submintApi = this.type == '1' ? modifyModel : saveLocalModel; | ||||
submintApi({ | submintApi({ | ||||
repo: location.pathname.split('/').slice(0, 3).join('/'), | repo: location.pathname.split('/').slice(0, 3).join('/'), | ||||
@@ -220,6 +256,14 @@ export default { | |||||
this.state.engine = data.engine.toString(); | this.state.engine = data.engine.toString(); | ||||
this.state.label = data.label; | this.state.label = data.label; | ||||
this.state.description = data.description; | this.state.description = data.description; | ||||
this.state.isPrivate = data.isPrivate; | |||||
if(data.isPrivate){ | |||||
$('#isPrivate_true').attr("checked",true); | |||||
$('#isPrivate_false').attr("checked",false); | |||||
}else{ | |||||
$('#isPrivate_true').attr("checked",false); | |||||
$('#isPrivate_false').attr("checked",true); | |||||
} | |||||
} | } | ||||
}).catch(err => { | }).catch(err => { | ||||
this.loading = false; | this.loading = false; | ||||