Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/118tags/v1.21.7
| @@ -83,7 +83,7 @@ func (m *MinioStorage) PresignedGetURL(path string, fileName string) (string, er | |||
| reqParams.Set("response-content-disposition", "attachment; filename=\""+fileName+"\"") | |||
| var preURL *url.URL | |||
| preURL, err := m.client.PresignedGetObject(m.bucket, m.buildMinioPath(path), PresignedGetUrlExpireTime, reqParams) | |||
| preURL, err := m.client.PresignedGetObject(m.bucket, path, PresignedGetUrlExpireTime, reqParams) | |||
| if err != nil { | |||
| return "", err | |||
| } | |||
| @@ -205,7 +205,7 @@ func GetAttachment(ctx *context.Context) { | |||
| if setting.Attachment.StoreType == storage.MinioStorageType { | |||
| url := "" | |||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||
| url, err = storage.Attachments.PresignedGetURL(attach.RelativePath(), attach.Name) | |||
| url, err = storage.Attachments.PresignedGetURL(setting.Attachment.Minio.BasePath + attach.RelativePath(), attach.Name) | |||
| if err != nil { | |||
| ctx.ServerError("PresignedGetURL", err) | |||
| return | |||
| @@ -2,8 +2,10 @@ package repo | |||
| import ( | |||
| "code.gitea.io/gitea/modules/git" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "encoding/json" | |||
| "errors" | |||
| "net/http" | |||
| "os" | |||
| "os/exec" | |||
| "strconv" | |||
| @@ -23,6 +25,7 @@ const ( | |||
| tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | |||
| tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | |||
| tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | |||
| tplCloudBrainShowModels base.TplName = "repo/cloudbrain/models/index" | |||
| ) | |||
| var ( | |||
| @@ -332,6 +335,69 @@ func CloudBrainDel(ctx *context.Context) { | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain") | |||
| } | |||
| func CloudBrainShowModels(ctx *context.Context) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| jobID := ctx.Params(":jobid") | |||
| parentDir := ctx.Query("parentDir") | |||
| dirArray := strings.Split(parentDir, "/") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| log.Error("no such job!") | |||
| ctx.ServerError("no such job:", err) | |||
| return | |||
| } | |||
| //get dirs | |||
| dirs, err := getModelDirs(task.JobName, parentDir) | |||
| if err != nil { | |||
| log.Error("getModelDirs failed:", err.Error()) | |||
| ctx.ServerError("getModelDirs failed:", err) | |||
| return | |||
| } | |||
| var fileInfos []FileInfo | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:", err.Error()) | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return | |||
| } | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["task"] = task | |||
| ctx.Data["JobID"] = jobID | |||
| ctx.HTML(200, tplCloudBrainShowModels) | |||
| } | |||
| func getModelDirs(jobName string, parentDir string) (string, error) { | |||
| var req string | |||
| modelActualPath := setting.JobPath + jobName + "/model/" | |||
| if parentDir == "" { | |||
| req = "baseDir=" + modelActualPath | |||
| } else { | |||
| req = "baseDir=" + modelActualPath + "&parentDir=" + parentDir | |||
| } | |||
| return getDirs(req) | |||
| } | |||
| func CloudBrainDownloadModel(ctx *context.Context) { | |||
| parentDir := ctx.Query("parentDir") | |||
| fileName := ctx.Query("fileName") | |||
| jobName := ctx.Query("jobName") | |||
| filePath := "jobs/" +jobName + "/model/" + parentDir | |||
| url, err := storage.Attachments.PresignedGetURL(filePath, fileName) | |||
| if err != nil { | |||
| log.Error("PresignedGetURL failed: %v", err.Error()) | |||
| ctx.ServerError("PresignedGetURL", err) | |||
| return | |||
| } | |||
| http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) | |||
| } | |||
| func GetRate(ctx *context.Context) { | |||
| var jobID = ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| @@ -58,10 +58,10 @@ func DirIndex(ctx *context.Context) { | |||
| dirArray = []string{attachment.Name} | |||
| } | |||
| dirs, err := getDirs(uuid, parentDir) | |||
| dirs, err := getDatasetDirs(uuid, parentDir) | |||
| if err != nil { | |||
| log.Error("getDirs failed:", err.Error()) | |||
| ctx.ServerError("getDirs failed:", err) | |||
| log.Error("getDatasetDirs failed:", err.Error()) | |||
| ctx.ServerError("getDatasetDirs failed:", err) | |||
| return | |||
| } | |||
| @@ -75,20 +75,31 @@ func DirIndex(ctx *context.Context) { | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["Uuid"] = uuid | |||
| ctx.Data["PageIsDataset"] = true | |||
| ctx.HTML(200, tplDirIndex) | |||
| } | |||
| func getDirs(uuid string, parentDir string) (string, error) { | |||
| var dirs string | |||
| func getDatasetDirs(uuid string, parentDir string) (string, error) { | |||
| var req string | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| models.AttachmentRelativePath(uuid) + | |||
| uuid + "/" | |||
| if parentDir == "" { | |||
| req = "uuid=" + uuid | |||
| req = "baseDir=" + dataActualPath | |||
| } else { | |||
| req = "uuid=" + uuid + "&parentDir=" + parentDir | |||
| req = "baseDir=" + dataActualPath + "&parentDir=" + parentDir | |||
| } | |||
| return getDirs(req) | |||
| } | |||
| func getDirs(req string) (string, error) { | |||
| var dirs string | |||
| url := setting.DecompressAddress + "/dirs?" + req | |||
| reqHttp, err := http.NewRequest(http.MethodGet, url, nil) | |||
| if err != nil { | |||
| @@ -127,6 +138,5 @@ func getDirs(uuid string, parentDir string) (string, error) { | |||
| } | |||
| dirs = resp.FileInfos | |||
| return dirs, nil | |||
| } | |||
| @@ -910,9 +910,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | |||
| m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | |||
| m.Post("/del", reqRepoCloudBrainWriter, repo.CloudBrainDel) | |||
| m.Get("/rate", reqRepoCloudBrainWriter, repo.GetRate) | |||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | |||
| m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) | |||
| m.Get("/download_model", reqRepoCloudBrainReader, repo.CloudBrainDownloadModel) | |||
| }) | |||
| m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew) | |||
| m.Get("/create", reqRepoCloudBrainReader, repo.CloudBrainNew) | |||
| m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | |||
| }, context.RepoRef()) | |||
| @@ -248,7 +248,7 @@ | |||
| </div> | |||
| <!--任务状态 --> | |||
| <div class="three wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| <div class="two wide column job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| {{.Status}} | |||
| </div> | |||
| @@ -257,15 +257,6 @@ | |||
| <span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <!-- 查看 --> | |||
| <div class="one wide column"> | |||
| <span class="ui text clipboard"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}"> | |||
| <span class="fitted">查看</span> | |||
| </a> | |||
| </span> | |||
| </div> | |||
| <!-- 评分 --> | |||
| <div class="one wide column"> | |||
| <div class="ui text center clipboard"> | |||
| @@ -304,6 +295,15 @@ | |||
| </div> | |||
| </div> | |||
| <!-- 模型下载 --> | |||
| <div class="two wide column"> | |||
| <span class="ui text clipboard"> | |||
| <a class="title" href="{{$.Link}}/{{.JobID}}/models"> | |||
| <span class="fitted">模型下载</span> | |||
| </a> | |||
| </span> | |||
| </div> | |||
| <!-- 接收结果 --> | |||
| <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> | |||
| <a class="imageBtn" style="{{if not .CanDebug}}color:#CCCCCC;cursor:pointer;pointer-events:none;{{end}}; font-size:16px; font-weight:bold" value="{{.CanDebug}}">提交镜像</a> | |||
| @@ -0,0 +1,27 @@ | |||
| {{if .Dirs}} | |||
| <table id="repo-files-table" class="ui single line table"> | |||
| <tbody> | |||
| {{range .Dirs}} | |||
| <tr> | |||
| <td class="name four wide"> | |||
| <span class="truncate"> | |||
| <span class="octicon octicon-file-directory"></span> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/models?parentDir={{.ParenDir}}{{else}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/download_model?parentDir={{.ParenDir}}&fileName={{.FileName}}&jobName={{$.task.JobName}}{{end}}"> | |||
| <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | |||
| </a> | |||
| </span> | |||
| </td> | |||
| <td class="message nine wide"> | |||
| <span class="truncate has-emoji"> | |||
| {{.Size | FileSize}} | |||
| </span> | |||
| </td> | |||
| <td class="text right age three wide"> | |||
| <span class="time-since poping up">{{.ModTime}}</span> | |||
| </td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{end}} | |||
| @@ -0,0 +1,29 @@ | |||
| {{template "base/head" .}} | |||
| <div class="repository dataset dir-list view"> | |||
| {{template "repo/header" .}} | |||
| <form class="ui container"> | |||
| <div class="ui stackable grid {{if .Error}}hide{{end}}" id="dir-content"> | |||
| <div class="row"> | |||
| <div class="column sixteen wide"> | |||
| <p> | |||
| {{ range $index, $item := .Path }}<a href='{{$.Link}}/?parentDir={{if gt $index 0}}{{DatasetPathJoin $.Path $index "/"}}{{else}}{{end}}'>{{ $item }}</a><span class="directory-seperator">/</span>{{ end }} | |||
| </p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui grid"> | |||
| <div class="row"> | |||
| <div class="ui sixteen wide column"> | |||
| <div class="dir list"> | |||
| {{template "repo/cloudbrain/models/dir_list" .}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -6,7 +6,7 @@ | |||
| <td class="name four wide"> | |||
| <span class="truncate"> | |||
| <span class="octicon octicon-file-directory"></span> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/datasets/dirs/{{.UUID}}?parentDir={{.ParenDir}}{{end}}"> | |||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/datasets/dirs/{{$.Uuid}}?parentDir={{.ParenDir}}{{end}}"> | |||
| <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | |||
| </a> | |||
| </span> | |||