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+"\"") | reqParams.Set("response-content-disposition", "attachment; filename=\""+fileName+"\"") | ||||
| var preURL *url.URL | 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 { | if err != nil { | ||||
| return "", err | return "", err | ||||
| } | } | ||||
| @@ -205,7 +205,7 @@ func GetAttachment(ctx *context.Context) { | |||||
| if setting.Attachment.StoreType == storage.MinioStorageType { | if setting.Attachment.StoreType == storage.MinioStorageType { | ||||
| url := "" | url := "" | ||||
| if typeCloudBrain == models.TypeCloudBrainOne { | 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 { | if err != nil { | ||||
| ctx.ServerError("PresignedGetURL", err) | ctx.ServerError("PresignedGetURL", err) | ||||
| return | return | ||||
| @@ -2,8 +2,10 @@ package repo | |||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "encoding/json" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "net/http" | |||||
| "os" | "os" | ||||
| "os/exec" | "os/exec" | ||||
| "strconv" | "strconv" | ||||
| @@ -23,6 +25,7 @@ const ( | |||||
| tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | tplCloudBrainIndex base.TplName = "repo/cloudbrain/index" | ||||
| tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | tplCloudBrainNew base.TplName = "repo/cloudbrain/new" | ||||
| tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | tplCloudBrainShow base.TplName = "repo/cloudbrain/show" | ||||
| tplCloudBrainShowModels base.TplName = "repo/cloudbrain/models/index" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| @@ -332,6 +335,69 @@ func CloudBrainDel(ctx *context.Context) { | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain") | 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) { | func GetRate(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
| job, err := models.GetCloudbrainByJobID(jobID) | job, err := models.GetCloudbrainByJobID(jobID) | ||||
| @@ -58,10 +58,10 @@ func DirIndex(ctx *context.Context) { | |||||
| dirArray = []string{attachment.Name} | dirArray = []string{attachment.Name} | ||||
| } | } | ||||
| dirs, err := getDirs(uuid, parentDir) | |||||
| dirs, err := getDatasetDirs(uuid, parentDir) | |||||
| if err != nil { | 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 | return | ||||
| } | } | ||||
| @@ -75,20 +75,31 @@ func DirIndex(ctx *context.Context) { | |||||
| ctx.Data["Path"] = dirArray | ctx.Data["Path"] = dirArray | ||||
| ctx.Data["Dirs"] = fileInfos | ctx.Data["Dirs"] = fileInfos | ||||
| ctx.Data["Uuid"] = uuid | |||||
| ctx.Data["PageIsDataset"] = true | ctx.Data["PageIsDataset"] = true | ||||
| ctx.HTML(200, tplDirIndex) | 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 | var req string | ||||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||||
| setting.Attachment.Minio.Bucket + "/" + | |||||
| setting.Attachment.Minio.BasePath + | |||||
| models.AttachmentRelativePath(uuid) + | |||||
| uuid + "/" | |||||
| if parentDir == "" { | if parentDir == "" { | ||||
| req = "uuid=" + uuid | |||||
| req = "baseDir=" + dataActualPath | |||||
| } else { | } 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 | url := setting.DecompressAddress + "/dirs?" + req | ||||
| reqHttp, err := http.NewRequest(http.MethodGet, url, nil) | reqHttp, err := http.NewRequest(http.MethodGet, url, nil) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -127,6 +138,5 @@ func getDirs(uuid string, parentDir string) (string, error) { | |||||
| } | } | ||||
| dirs = resp.FileInfos | dirs = resp.FileInfos | ||||
| return dirs, nil | return dirs, nil | ||||
| } | } | ||||
| @@ -910,9 +910,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | ||||
| m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | ||||
| m.Post("/del", reqRepoCloudBrainWriter, repo.CloudBrainDel) | 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) | m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | ||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| @@ -248,7 +248,7 @@ | |||||
| </div> | </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}} | {{.Status}} | ||||
| </div> | </div> | ||||
| @@ -257,15 +257,6 @@ | |||||
| <span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> | <span class="ui text center">{{svg "octicon-flame" 16}} {{TimeSinceUnix .CreatedUnix $.Lang}}</span> | ||||
| </div> | </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="one wide column"> | ||||
| <div class="ui text center clipboard"> | <div class="ui text center clipboard"> | ||||
| @@ -304,6 +295,15 @@ | |||||
| </div> | </div> | ||||
| </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> | <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> | <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"> | <td class="name four wide"> | ||||
| <span class="truncate"> | <span class="truncate"> | ||||
| <span class="octicon octicon-file-directory"></span> | <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}} | <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | ||||
| </a> | </a> | ||||
| </span> | </span> | ||||