package repo import ( "errors" "fmt" "net/http" "path" "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" uuid "github.com/satori/go.uuid" ) const ( Model_prefix = "aimodels/" tplModelManageIndex = "repo/modelmanage/index" tplModelManageDownload = "repo/modelmanage/download" ) func SaveModelByParameters(jobId string, name string, version string, label string, description string, userId int64) error { aiTask, err := models.GetCloudbrainByJobID(jobId) if err != nil { log.Info("query task error." + err.Error()) return err } uuid := uuid.NewV4() id := uuid.String() modelPath := id parent := id var modelSize int64 cloudType := models.TypeCloudBrainTwo log.Info("find task name:" + aiTask.JobName) aimodels := models.QueryModelByName(name, userId) if len(aimodels) > 0 { for _, model := range aimodels { if model.ID == model.Parent { parent = model.ID } } } cloudType = aiTask.Type //download model zip //train type if cloudType == models.TypeCloudBrainTwo { modelPath, modelSize, err = downloadModelFromCloudBrainTwo(id, aiTask.JobName, "") if err != nil { log.Info("download model from CloudBrainTwo faild." + err.Error()) return err } } model := &models.AiModelManage{ ID: id, Version: version, Label: label, Name: name, Description: description, Parent: parent, Type: cloudType, Path: modelPath, Size: modelSize, AttachmentId: aiTask.Uuid, RepoId: aiTask.RepoID, UserId: userId, } models.SaveModelToDb(model) log.Info("save model end.") return nil } func SaveModel(ctx *context.Context) { log.Info("save model start.") JobId := ctx.Query("JobId") name := ctx.Query("Name") version := ctx.Query("Version") label := ctx.Query("Label") description := ctx.Query("Description") err := SaveModelByParameters(JobId, name, version, label, description, ctx.User.ID) if err != nil { log.Info("save model error." + err.Error()) ctx.Error(500, fmt.Sprintf("save model error. %v", err)) return } log.Info("save model end.") } func downloadModelFromCloudBrainTwo(modelUUID string, jobName string, parentDir string) (string, int64, error) { dataActualPath := setting.Bucket + "/" + Model_prefix + models.AttachmentRelativePath(modelUUID) + "/" modelDbResult, err := storage.GetObsListObject(jobName, parentDir) if err != nil { log.Info("get TrainJobListModel failed:", err) return "", 0, err } if len(modelDbResult) == 0 { return "", 0, errors.New("cannot create model, as model is empty.") } var size int64 prefix := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, parentDir), "/") + "/" for _, modelFile := range modelDbResult { destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(modelUUID) + "/" log.Info("copy file, bucket=" + setting.Bucket + ", src keyname=" + prefix + modelFile.FileName) log.Info("Dest key name=" + destKeyNamePrefix + modelFile.FileName) err := storage.ObsCopyFile(setting.Bucket, prefix+modelFile.FileName, setting.Bucket, destKeyNamePrefix+modelFile.FileName) if err != nil { log.Info("copy failed.") } size += modelFile.Size } return dataActualPath, size, nil } func DeleteModel(ctx *context.Context) { log.Info("delete model start.") id := ctx.Query("ID") err := DeleteModelByID(id) if err != nil { ctx.JSON(500, err.Error()) } else { ctx.JSON(200, map[string]string{ "result_code": "0", }) } } func DeleteModelByID(id string) error { log.Info("delete model start. id=" + id) model, err := models.QueryModelById(id) if err == nil { log.Info("bucket=" + setting.Bucket + " path=" + model.Path) if strings.HasPrefix(model.Path, setting.Bucket+"/"+Model_prefix) { err := storage.ObsRemoveObject(setting.Bucket, model.Path[len(setting.Bucket)+1:]) if err != nil { log.Info("Failed to delete model. id=" + id) return err } } return models.DeleteModelById(id) } return err } func DownloadModel(ctx *context.Context) { log.Info("download model start.") } 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, }) } func DownloadMultiModelFile(ctx *context.Context) { log.Info("DownloadMultiModelFile start.") id := ctx.Query("ID") log.Info("id=" + id) } func DownloadSingleModelFile(ctx *context.Context) { log.Info("DownloadSingleModelFile start.") path := ctx.Query("path") url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path[len(setting.Bucket)+1:]) if err != nil { log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"]) ctx.ServerError("GetObsCreateSignedUrl", err) return } http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) } func ShowSingleModel(ctx *context.Context) { log.Info("Show single ModelInfo start.") id := ctx.Query("ID") task, err := models.QueryModelById(id) if err != nil { log.Error("no such model!", ctx.Data["msgID"]) ctx.ServerError("no such model:", err) return } models, err := storage.GetObsListObjectByBucketAndPrefix(setting.Bucket, task.Path[len(setting.Bucket)+1:]) if err != nil { log.Info("get TrainJobListModel failed:", err) ctx.ServerError("GetObsListObject:", err) return } ctx.Data["Dirs"] = models ctx.Data["task"] = task ctx.Data["ID"] = id ctx.HTML(200, tplModelManageDownload) } func ShowModelPageInfo(ctx *context.Context) { log.Info("ShowModelInfo start.") page := ctx.QueryInt("page") if page <= 0 { page = 1 } repoId := ctx.Repo.Repository.ID Type := -1 modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{ ListOptions: models.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: repoId, Type: Type, }) if err != nil { ctx.ServerError("Cloudbrain", err) return } pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) pager.SetDefaultParams(ctx) ctx.Data["Page"] = pager ctx.Data["PageIsCloudBrain"] = true ctx.Data["Tasks"] = modelResult } func ModifyModel(id string, description string) error { err := models.ModifyModelDescription(id, description) if err == nil { log.Info("modify success.") } else { log.Info("Failed to modify.id=" + id + " desc=" + description + " error:" + err.Error()) } return err } func ModifyModelInfo(ctx *context.Context) { log.Info("delete model start.") id := ctx.Query("ID") description := ctx.Query("Description") err := ModifyModel(id, description) if err == nil { ctx.HTML(200, "success") } else { ctx.HTML(500, "Failed.") } }