Browse Source

Merge branch 'V20210731' of https://git.openi.org.cn/OpenI/aiforge into web

tags/v1.21.12.1
avadesian 4 years ago
parent
commit
f3f350dd20
21 changed files with 305 additions and 74 deletions
  1. +7
    -3
      models/cloudbrain.go
  2. +12
    -0
      models/error.go
  3. +16
    -3
      modules/cloudbrain/resty.go
  4. +31
    -7
      modules/log/logger.go
  5. +1
    -1
      modules/storage/minio.go
  6. +1
    -0
      options/locale/locale_zh-CN.ini
  7. +1
    -0
      routers/org/home.go
  8. +1
    -1
      routers/repo/attachment.go
  9. +9
    -9
      routers/repo/blockchain.go
  10. +89
    -10
      routers/repo/cloudbrain.go
  11. +18
    -8
      routers/repo/dir.go
  12. +2
    -0
      routers/repo/download.go
  13. +25
    -3
      routers/routes/routes.go
  14. +4
    -1
      routers/user/auth.go
  15. +1
    -1
      templates/explore/dataset_list.tmpl
  16. +18
    -14
      templates/org/navber.tmpl
  17. +10
    -10
      templates/repo/cloudbrain/index.tmpl
  18. +27
    -0
      templates/repo/cloudbrain/models/dir_list.tmpl
  19. +29
    -0
      templates/repo/cloudbrain/models/index.tmpl
  20. +1
    -1
      templates/repo/datasets/dirs/dir_list.tmpl
  21. +2
    -2
      templates/repo/datasets/index.tmpl

+ 7
- 3
models/cloudbrain.go View File

@@ -2,7 +2,6 @@ package models


import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"time" "time"
"xorm.io/xorm" "xorm.io/xorm"
@@ -300,7 +299,7 @@ type CommitImageResult struct {
Payload map[string]interface{} `json:"payload"` Payload map[string]interface{} `json:"payload"`
} }


type StopJobResult struct {
type CloudBrainResult struct {
Code string `json:"code"` Code string `json:"code"`
Msg string `json:"msg"` Msg string `json:"msg"`
} }
@@ -569,7 +568,7 @@ func getRepoCloudBrain(cb *Cloudbrain) (*Cloudbrain, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, errors.New("cloudbrain task is not found")
return nil, ErrJobNotExist{}
} }
return cb, nil return cb, nil
} }
@@ -609,3 +608,8 @@ func deleteJob(e Engine, job *Cloudbrain) error {
_, err := e.ID(job.ID).Delete(job) _, err := e.ID(job.ID).Delete(job)
return err return err
} }

func GetCloudbrainByName(jobName string) (*Cloudbrain, error) {
cb := &Cloudbrain{JobName: jobName}
return getRepoCloudBrain(cb)
}

+ 12
- 0
models/error.go View File

@@ -1987,3 +1987,15 @@ func IsErrFileChunkNotExist(err error) bool {
_, ok := err.(ErrFileChunkNotExist) _, ok := err.(ErrFileChunkNotExist)
return ok return ok
} }

type ErrJobNotExist struct {
}

func IsErrJobNotExist(err error) bool {
_, ok := err.(ErrJobNotExist)
return ok
}

func (err ErrJobNotExist) Error() string {
return fmt.Sprintf("the job does not exist")
}

+ 16
- 3
modules/cloudbrain/resty.go View File

@@ -2,6 +2,7 @@ package cloudbrain


import ( import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"encoding/json"
"fmt" "fmt"


"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@@ -143,14 +144,26 @@ sendjob:
return nil, fmt.Errorf("resty GetImages: %v", err) return nil, fmt.Errorf("resty GetImages: %v", err)
} }


if getImagesResult.Code == "S401" && retry < 1 {
var response models.CloudBrainResult
err = json.Unmarshal(res.Body(), &response)
if err != nil {
log.Error("json.Unmarshal failed: %s", err.Error())
return &getImagesResult, fmt.Errorf("json.Unmarshal failed: %s", err.Error())
}

if response.Code == "S401" && retry < 1 {
retry++ retry++
_ = loginCloudbrain() _ = loginCloudbrain()
goto sendjob goto sendjob
} }


if len(response.Code) != 0 {
log.Error("getImagesResult failed(%s): %s", response.Code, response.Msg)
return &getImagesResult, fmt.Errorf("getImagesResult failed(%s): %s", response.Code, response.Msg)
}

if getImagesResult.Code != Success { if getImagesResult.Code != Success {
return &getImagesResult, fmt.Errorf("getImgesResult err: %s", res.String())
return &getImagesResult, fmt.Errorf("getImagesResult err: %s", res.String())
} }


return &getImagesResult, nil return &getImagesResult, nil
@@ -223,7 +236,7 @@ sendjob:
func StopJob(jobID string) error { func StopJob(jobID string) error {
checkSetting() checkSetting()
client := getRestyClient() client := getRestyClient()
var result models.StopJobResult
var result models.CloudBrainResult


retry := 0 retry := 0




+ 31
- 7
modules/log/logger.go View File

@@ -67,19 +67,43 @@ func (l *Logger) Log(skip int, level Level, format string, v ...interface{}) err
caller = fn.Name() + "()" caller = fn.Name() + "()"
} }
} }
msg := format
if len(v) > 0 {
msg = ColorSprintf(format, v...)
}

stack := "" stack := ""
if l.GetStacktraceLevel() <= level { if l.GetStacktraceLevel() <= level {
stack = Stack(skip + 1) stack = Stack(skip + 1)
} }
return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, stack)

msg := format
if len(v) > 0 {
switch v[len(v)-1].(type) {
case string:
if !strings.Contains(v[len(v)-1].(string), "-") {
//has no msgID
msg = ColorSprintf(format, v...)
return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack)
} else {
if len(v) > 1 {
args := make([]interface{}, len(v)-1)
for i := 0; i < len(v)-1; i++ {
args[i] = v[i]
}
msg = ColorSprintf(format, args...)
}
return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, v[len(v)-1].(string), stack)
}
default:
//has no msgID
msg = ColorSprintf(format, v...)
return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack)
}
} else {
//has no msgID
return l.SendLog(level, caller, strings.TrimPrefix(filename, prefix), line, msg, "", stack)
}
} }


// SendLog sends a log event at the provided level with the information given // SendLog sends a log event at the provided level with the information given
func (l *Logger) SendLog(level Level, caller, filename string, line int, msg string, stack string) error {
func (l *Logger) SendLog(level Level, caller, filename string, line int, msg, msgID, stack string) error {
if l.GetLevel() > level { if l.GetLevel() > level {
return nil return nil
} }
@@ -88,7 +112,7 @@ func (l *Logger) SendLog(level Level, caller, filename string, line int, msg str
caller: caller, caller: caller,
filename: filename, filename: filename,
line: line, line: line,
msg: msg,
msg: msg + "[" + msgID + "]",
time: time.Now(), time: time.Now(),
stacktrace: stack, stacktrace: stack,
} }


+ 1
- 1
modules/storage/minio.go View File

@@ -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
} }


+ 1
- 0
options/locale/locale_zh-CN.ini View File

@@ -1819,6 +1819,7 @@ org_full_name_holder=组织全名
org_name_helper=组织名字应该简单明了。 org_name_helper=组织名字应该简单明了。
create_org=创建组织 create_org=创建组织
repo_updated=最后更新于 repo_updated=最后更新于
home=组织主页
people=组织成员 people=组织成员
teams=组织团队 teams=组织团队
lower_members=名成员 lower_members=名成员


+ 1
- 0
routers/org/home.go View File

@@ -20,6 +20,7 @@ const (
// Home show organization home page // Home show organization home page
func Home(ctx *context.Context) { func Home(ctx *context.Context) {
ctx.SetParams(":org", ctx.Params(":username")) ctx.SetParams(":org", ctx.Params(":username"))
ctx.Data["PageIsOrgHome"] = true
context.HandleOrgAssignment(ctx) context.HandleOrgAssignment(ctx)
if ctx.Written() { if ctx.Written() {
return return


+ 1
- 1
routers/repo/attachment.go View File

@@ -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


+ 9
- 9
routers/repo/blockchain.go View File

@@ -28,14 +28,14 @@ const (
func BlockChainIndex(ctx *context.Context) { func BlockChainIndex(ctx *context.Context) {
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
if repo.ContractAddress == "" || ctx.User.PublicKey == "" { if repo.ContractAddress == "" || ctx.User.PublicKey == "" {
log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID)
log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID, ctx.Data["msgID"])
ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex)
return return
} }


res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey) res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey)
if err != nil { if err != nil {
log.Error("GetBalance(%s) failed:%v", ctx.User.PublicKey, err)
log.Error("GetBalance(%s) failed:%s", ctx.User.PublicKey, err, ctx.Data["msgID"])
ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex)
return return
} }
@@ -52,7 +52,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {


repo, err := models.GetRepositoryByID(req.RepoId) repo, err := models.GetRepositoryByID(req.RepoId)
if err != nil { if err != nil {
log.Error("GetRepositoryByID failed:", err.Error())
log.Error("GetRepositoryByID failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "internal error", "message": "internal error",
@@ -61,7 +61,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {
} }


if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 { if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 {
log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId)
log.Error("the repo has been RepoBlockChainSuccess:%d", req.RepoId, ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "the repo has been RepoBlockChainSuccess", "message": "the repo has been RepoBlockChainSuccess",
@@ -73,7 +73,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {
repo.ContractAddress = req.ContractAddress repo.ContractAddress = req.ContractAddress


if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil {
log.Error("UpdateRepositoryCols failed:", err.Error())
log.Error("UpdateRepositoryCols failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "internal error", "message": "internal error",
@@ -91,7 +91,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
var req BlockChainCommitNotify var req BlockChainCommitNotify
data, _ := ctx.Req.Body().Bytes() data, _ := ctx.Req.Body().Bytes()
if err := json.Unmarshal(data, &req); err != nil { if err := json.Unmarshal(data, &req); err != nil {
log.Error("json.Unmarshal failed:", err.Error())
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "response data error", "message": "response data error",
@@ -101,7 +101,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {


blockChain, err := models.GetBlockChainByCommitID(req.CommitID) blockChain, err := models.GetBlockChainByCommitID(req.CommitID)
if err != nil { if err != nil {
log.Error("GetRepositoryByID failed:", err.Error())
log.Error("GetRepositoryByID failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "internal error", "message": "internal error",
@@ -110,7 +110,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
} }


if blockChain.Status == models.BlockChainCommitSuccess { if blockChain.Status == models.BlockChainCommitSuccess {
log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID)
log.Error("the commit has been BlockChainCommitReady:%s", blockChain.RepoID, ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "the commit has been BlockChainCommitReady", "message": "the commit has been BlockChainCommitReady",
@@ -122,7 +122,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
blockChain.TransactionHash = req.TransactionHash blockChain.TransactionHash = req.TransactionHash


if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil { if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil {
log.Error("UpdateBlockChainCols failed:", err.Error())
log.Error("UpdateBlockChainCols failed:%v", err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"code": "-1", "code": "-1",
"message": "internal error", "message": "internal error",


+ 89
- 10
routers/repo/cloudbrain.go View File

@@ -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 (
@@ -93,7 +96,7 @@ func CloudBrainNew(ctx *context.Context) {
result, err := cloudbrain.GetImages() result, err := cloudbrain.GetImages()
if err != nil { if err != nil {
ctx.Data["error"] = err.Error() ctx.Data["error"] = err.Error()
log.Error("cloudbrain.GetImages failed:", err.Error())
log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["msgID"])
} }


for i, payload := range result.Payload.ImageInfo { for i, payload := range result.Payload.ImageInfo {
@@ -109,7 +112,7 @@ func CloudBrainNew(ctx *context.Context) {
resultPublic, err := cloudbrain.GetPublicImages() resultPublic, err := cloudbrain.GetPublicImages()
if err != nil { if err != nil {
ctx.Data["error"] = err.Error() ctx.Data["error"] = err.Error()
log.Error("cloudbrain.GetPublicImages failed:", err.Error())
log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["msgID"])
} }


for i, payload := range resultPublic.Payload.ImageInfo { for i, payload := range resultPublic.Payload.ImageInfo {
@@ -161,15 +164,28 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath


if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) { if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) {
log.Error("jobtype error:", jobType)
log.Error("jobtype error:", jobType, ctx.Data["msgID"])
ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form) ctx.RenderWithErr("jobtype error", tplCloudBrainNew, &form)
return return
} }

_, err := models.GetCloudbrainByName(jobName)
if err == nil {
log.Error("the job name did already exist", ctx.Data["MsgID"])
ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form)
return
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
ctx.RenderWithErr("system error", tplCloudBrainNew, &form)
return
}
}
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
downloadCode(repo, codePath) downloadCode(repo, codePath)


modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath
err := os.MkdirAll(modelPath, os.ModePerm)
err = os.MkdirAll(modelPath, os.ModePerm)
if err != nil { if err != nil {
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
return return
@@ -264,7 +280,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain
ImageTag: form.Tag, ImageTag: form.Tag,
}) })
if err != nil { if err != nil {
log.Error("CommitImage(%s) failed:", task.JobName, err.Error())
log.Error("CommitImage(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"])
ctx.JSON(200, map[string]string{ ctx.JSON(200, map[string]string{
"result_code": "-1", "result_code": "-1",
"error_msg": "CommitImage failed", "error_msg": "CommitImage failed",
@@ -287,14 +303,14 @@ func CloudBrainStop(ctx *context.Context) {
} }


if task.Status == string(models.JobStopped) { if task.Status == string(models.JobStopped) {
log.Error("the job(%s) has been stopped", task.JobName)
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
ctx.ServerError("the job has been stopped", errors.New("the job has been stopped")) ctx.ServerError("the job has been stopped", errors.New("the job has been stopped"))
return return
} }


err = cloudbrain.StopJob(jobID) err = cloudbrain.StopJob(jobID)
if err != nil { if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err.Error())
log.Error("StopJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"])
ctx.ServerError("StopJob failed", err) ctx.ServerError("StopJob failed", err)
return return
} }
@@ -318,7 +334,7 @@ func CloudBrainDel(ctx *context.Context) {
} }


if task.Status != string(models.JobStopped) { if task.Status != string(models.JobStopped) {
log.Error("the job(%s) has not been stopped", task.JobName)
log.Error("the job(%s) has not been stopped", task.JobName, ctx.Data["msgID"])
ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped")) ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
return return
} }
@@ -332,6 +348,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.Data["msgID"])
ctx.ServerError("no such job:", err)
return
}

//get dirs
dirs, err := getModelDirs(task.JobName, parentDir)
if err != nil {
log.Error("getModelDirs failed:%v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("getModelDirs failed:", err)
return
}

var fileInfos []FileInfo
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
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.Data["msgID"])
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)
@@ -341,11 +420,11 @@ func GetRate(ctx *context.Context) {
} }


if job.JobType == string(models.JobTypeBenchmark) { if job.JobType == string(models.JobTypeBenchmark) {
ctx.Redirect(setting.BenchmarkServerHost)
ctx.Redirect(setting.BenchmarkServerHost + "?username=" + ctx.User.Name)
} else if job.JobType == string(models.JobTypeSnn4imagenet) { } else if job.JobType == string(models.JobTypeSnn4imagenet) {
ctx.Redirect(setting.Snn4imagenetServerHost) ctx.Redirect(setting.Snn4imagenetServerHost)
} else { } else {
log.Error("JobType error:", job.JobType)
log.Error("JobType error:%s", job.JobType, ctx.Data["msgID"])
} }
} }




+ 18
- 8
routers/repo/dir.go View File

@@ -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
} }

+ 2
- 0
routers/repo/download.go View File

@@ -8,6 +8,7 @@ package repo
import ( import (
"fmt" "fmt"
"io" "io"
"net/url"
"path" "path"
"strings" "strings"


@@ -32,6 +33,7 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error {


// Google Chrome dislike commas in filenames, so let's change it to a space // Google Chrome dislike commas in filenames, so let's change it to a space
name = strings.Replace(name, ",", " ", -1) name = strings.Replace(name, ",", " ", -1)
name = url.QueryEscape(name)


if base.IsTextFile(buf) || ctx.QueryBool("render") { if base.IsTextFile(buf) || ctx.QueryBool("render") {
cs, err := charset.DetectEncoding(buf) cs, err := charset.DetectEncoding(buf)


+ 25
- 3
routers/routes/routes.go View File

@@ -49,6 +49,7 @@ import (
"gitea.com/macaron/session" "gitea.com/macaron/session"
"gitea.com/macaron/toolbox" "gitea.com/macaron/toolbox"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
gouuid "github.com/satori/go.uuid"
"github.com/tstranex/u2f" "github.com/tstranex/u2f"
) )


@@ -85,7 +86,7 @@ func setupAccessLogger(m *macaron.Macaron) {
log.Error("Could not set up macaron access logger: %v", err.Error()) log.Error("Could not set up macaron access logger: %v", err.Error())
} }


err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "")
err = logger.SendLog(log.INFO, "", "", 0, buf.String(), ctx.Data["msgID"].(string), "")
if err != nil { if err != nil {
log.Error("Could not set up macaron access logger: %v", err.Error()) log.Error("Could not set up macaron access logger: %v", err.Error())
} }
@@ -107,6 +108,24 @@ func RouterHandler(level log.Level) func(ctx *macaron.Context) {
} }
} }


// SetLogMsgID set msgID in Context
func SetLogMsgID() func(ctx *macaron.Context) {
return func(ctx *macaron.Context) {
start := time.Now()

uuid := gouuid.NewV4().String()
ctx.Data["MsgID"] = uuid

log.Info("Started %s %s for %s", log.ColoredMethod(ctx.Req.Method), ctx.Req.URL.RequestURI(), ctx.RemoteAddr(), ctx.Data["MsgID"])

rw := ctx.Resp.(macaron.ResponseWriter)
ctx.Next()

status := rw.Status()
log.Info("Completed %s %s %v %s in %v", log.ColoredMethod(ctx.Req.Method), ctx.Req.URL.RequestURI(), log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(rw.Status())), log.ColoredTime(time.Since(start)), ctx.Data["MsgID"])
}
}

// NewMacaron initializes Macaron instance. // NewMacaron initializes Macaron instance.
func NewMacaron() *macaron.Macaron { func NewMacaron() *macaron.Macaron {
gob.Register(&u2f.Challenge{}) gob.Register(&u2f.Challenge{})
@@ -125,6 +144,7 @@ func NewMacaron() *macaron.Macaron {
m.Use(macaron.Logger()) m.Use(macaron.Logger())
} }
} }
m.Use(SetLogMsgID())
// Access Logger is similar to Router Log but more configurable and by default is more like the NCSA Common Log format // Access Logger is similar to Router Log but more configurable and by default is more like the NCSA Common Log format
if setting.EnableAccessLog { if setting.EnableAccessLog {
setupAccessLogger(m) setupAccessLogger(m)
@@ -910,9 +930,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())




+ 4
- 1
routers/user/auth.go View File

@@ -535,7 +535,10 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
log.Error("Unable to store session: %v", err) log.Error("Unable to store session: %v", err)
} }


// Language setting of the user overwrites the one previously set
// Language setting of the user use the one previously set
if len(ctx.GetCookie("lang")) != 0 {
u.Language = ctx.GetCookie("lang")
}
// If the user does not have a locale set, we save the current one. // If the user does not have a locale set, we save the current one.
if len(u.Language) == 0 { if len(u.Language) == 0 {
u.Language = ctx.Locale.Language() u.Language = ctx.Locale.Language()


+ 1
- 1
templates/explore/dataset_list.tmpl View File

@@ -25,7 +25,7 @@
{{range .Datasets}} {{range .Datasets}}
<div class="item"> <div class="item">
<div class="ui header"> <div class="ui header">
<a class="name" href="{{.Repo.Link}}/datasets">
<a class="name" href="{{.Repo.Link}}/datasets?type=0">
{{.Repo.OwnerName}} / {{.Title}} {{.Repo.OwnerName}} / {{.Title}}
</a> </a>
<div class="ui right metas"> <div class="ui right metas">


+ 18
- 14
templates/org/navber.tmpl View File

@@ -1,14 +1,16 @@
<div class="tablet only mobile only sixteen wide mobile sixteen wide tablet column row"> <div class="tablet only mobile only sixteen wide mobile sixteen wide tablet column row">
<div class="ui secondary pointing tabular top attached borderless menu navbar"> <div class="ui secondary pointing tabular top attached borderless menu navbar">
<a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> <a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}">
{{svg "octicon-home" 16}}&nbsp;{{$.i18n.Tr "org.组织主页"}}
</a>
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
{{svg "octicon-organization" 16}}&nbsp;{{$.i18n.Tr "org.people"}}
</a>
<a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams">
{{svg "octicon-jersey" 16}}&nbsp;{{$.i18n.Tr "org.teams"}}
{{svg "octicon-home" 16}}&nbsp;{{$.i18n.Tr "org.home"}}
</a> </a>
{{if or ($.IsOrganizationMember) ($.IsOrganizationOwner)}}
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
{{svg "octicon-organization" 16}}&nbsp;{{$.i18n.Tr "org.people"}}
</a>
<a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams">
{{svg "octicon-jersey" 16}}&nbsp;{{$.i18n.Tr "org.teams"}}
</a>
{{end}}
</div> </div>
</div> </div>
<!--平板、移动端--> <!--平板、移动端-->
@@ -18,15 +20,17 @@
<div class="sixteen wide column ui secondary sticky pointing tabular vertical menu"> <div class="sixteen wide column ui secondary sticky pointing tabular vertical menu">
{{with .Org}} {{with .Org}}
<a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> <a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}">
{{svg "octicon-home" 16}}&nbsp;{{$.i18n.Tr "org.主页"}}
{{svg "octicon-home" 16}}&nbsp;{{$.i18n.Tr "org.home"}}
</a> </a>
{{end}} {{end}}
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
{{svg "octicon-organization" 16}}&nbsp;{{$.i18n.Tr "org.people"}}
</a>
<a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams">
{{svg "octicon-jersey" 16}}&nbsp;{{$.i18n.Tr "org.teams"}}
</a>
{{if or ($.IsOrganizationMember) ($.IsOrganizationOwner)}}
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
{{svg "octicon-organization" 16}}&nbsp;{{$.i18n.Tr "org.people"}}
</a>
<a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams">
{{svg "octicon-jersey" 16}}&nbsp;{{$.i18n.Tr "org.teams"}}
</a>
{{end}}
</div> </div>
</div> </div>
</div> </div>

+ 10
- 10
templates/repo/cloudbrain/index.tmpl View File

@@ -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>


+ 27
- 0
templates/repo/cloudbrain/models/dir_list.tmpl View File

@@ -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}}

+ 29
- 0
templates/repo/cloudbrain/models/index.tmpl View File

@@ -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" .}}

+ 1
- 1
templates/repo/datasets/dirs/dir_list.tmpl View File

@@ -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>


+ 2
- 2
templates/repo/datasets/index.tmpl View File

@@ -76,8 +76,8 @@
{{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> {{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i>
</span> </span>
<div class="menu"> <div class="menu">
<a class="item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a>
<a class="item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a>
<a class="item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a>
<a class="item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&type={{.Type}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a>
</div> </div>
</div> </div>
</div> </div>


Loading…
Cancel
Save