Browse Source

Merge branch 'develop' into train-job

tags/v1.21.11.1
Gitea 4 years ago
parent
commit
a0c77e2cda
52 changed files with 355 additions and 265 deletions
  1. +12
    -12
      Makefile
  2. +12
    -159
      assets/logo.svg
  3. +2
    -0
      models/attachment.go
  4. +11
    -0
      models/cloudbrain.go
  5. +8
    -0
      models/dataset.go
  6. +19
    -12
      models/repo.go
  7. +1
    -0
      modules/auth/cloudbrain.go
  8. +1
    -0
      modules/auth/dataset.go
  9. +5
    -4
      modules/base/tool.go
  10. +2
    -2
      modules/cloudbrain/cloudbrain.go
  11. +10
    -1
      modules/cloudbrain/resty.go
  12. +31
    -7
      modules/log/logger.go
  13. +3
    -1
      modules/setting/setting.go
  14. +1
    -1
      modules/storage/minio.go
  15. +0
    -0
      modules/structs/repo.go
  16. +3
    -1
      options/locale/locale_en-US.ini
  17. +5
    -1
      options/locale/locale_zh-CN.ini
  18. BIN
      public/img/404.png
  19. BIN
      public/img/500.png
  20. BIN
      public/img/apple-touch-icon.png
  21. BIN
      public/img/avatar_default.png
  22. BIN
      public/img/emoji/gitea.png
  23. BIN
      public/img/favicon.ico
  24. BIN
      public/img/favicon.png
  25. BIN
      public/img/feishu.png
  26. BIN
      public/img/gitea-192.png
  27. BIN
      public/img/gitea-512.png
  28. BIN
      public/img/gitea-lg.png
  29. BIN
      public/img/gitea-sm.png
  30. BIN
      public/img/org_bg.png
  31. +0
    -0
      routers/api/v1/repo/repo.go
  32. +1
    -1
      routers/repo/attachment.go
  33. +9
    -9
      routers/repo/blockchain.go
  34. +101
    -15
      routers/repo/cloudbrain.go
  35. +7
    -1
      routers/repo/dataset.go
  36. +18
    -8
      routers/repo/dir.go
  37. +2
    -0
      routers/repo/download.go
  38. +26
    -4
      routers/routes/routes.go
  39. +0
    -0
      routers/user/home.go
  40. +0
    -0
      routers/user/profile.go
  41. +9
    -0
      templates/base/head.tmpl
  42. +1
    -5
      templates/base/head_navbar.tmpl
  43. +1
    -1
      templates/explore/dataset_list.tmpl
  44. +0
    -0
      templates/explore/repo_list.tmpl
  45. +10
    -10
      templates/repo/cloudbrain/index.tmpl
  46. +30
    -3
      templates/repo/cloudbrain/new.tmpl
  47. +6
    -2
      templates/repo/datasets/dataset_list.tmpl
  48. +1
    -1
      templates/repo/datasets/dirs/dir_list.tmpl
  49. +4
    -3
      templates/repo/datasets/index.tmpl
  50. +0
    -0
      templates/user/profile.tmpl
  51. +0
    -1
      web_src/js/index.js
  52. +3
    -0
      web_src/less/_base.less

+ 12
- 12
Makefile View File

@@ -616,20 +616,20 @@ update-translations:
generate-images:
$(eval TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp'))
mkdir -p $(TMPDIR)/images
inkscape -f $(PWD)/assets/logo.svg -w 880 -h 880 -e $(PWD)/public/img/gitea-lg.png
inkscape -f $(PWD)/assets/logo.svg -w 512 -h 512 -e $(PWD)/public/img/gitea-512.png
inkscape -f $(PWD)/assets/logo.svg -w 192 -h 192 -e $(PWD)/public/img/gitea-192.png
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer1 -e $(TMPDIR)/images/sm-1.png
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer2 -e $(TMPDIR)/images/sm-2.png
inkscape $(PWD)/assets/logo.svg -w 880 -h 880 --export-filename=$(PWD)/public/img/gitea-lg.png
inkscape $(PWD)/assets/logo.svg -w 512 -h 512 --export-filename=$(PWD)/public/img/gitea-512.png
inkscape $(PWD)/assets/logo.svg -w 192 -h 192 --export-filename=$(PWD)/public/img/gitea-192.png
inkscape $(PWD)/assets/logo.svg -w 120 -h 120 --export-filename=$(TMPDIR)/images/sm-1.png
inkscape $(PWD)/assets/logo.svg -w 120 -h 120 --export-filename=$(TMPDIR)/images/sm-2.png
composite -compose atop $(TMPDIR)/images/sm-2.png $(TMPDIR)/images/sm-1.png $(PWD)/public/img/gitea-sm.png
inkscape -f $(PWD)/assets/logo.svg -w 200 -h 200 -e $(PWD)/public/img/avatar_default.png
inkscape -f $(PWD)/assets/logo.svg -w 180 -h 180 -e $(PWD)/public/img/favicon.png
inkscape -f $(PWD)/assets/logo.svg -w 128 -h 128 -e $(TMPDIR)/images/128-raw.png
inkscape -f $(PWD)/assets/logo.svg -w 64 -h 64 -e $(TMPDIR)/images/64-raw.png
inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer1 -e $(TMPDIR)/images/32-1.png
inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer2 -e $(TMPDIR)/images/32-2.png
inkscape $(PWD)/assets/logo.svg -w 200 -h 200 --export-filename=$(PWD)/public/img/avatar_default.png
inkscape $(PWD)/assets/logo.svg -w 180 -h 180 --export-filename=$(PWD)/public/img/favicon.png
inkscape $(PWD)/assets/logo.svg -w 128 -h 128 --export-filename=$(TMPDIR)/images/128-raw.png
inkscape $(PWD)/assets/logo.svg -w 64 -h 64 --export-filename=$(TMPDIR)/images/64-raw.png
inkscape $(PWD)/assets/logo.svg -w 32 -h 32 --export-filename=$(TMPDIR)/images/32-1.png
inkscape $(PWD)/assets/logo.svg -w 32 -h 32 --export-filename=$(TMPDIR)/images/32-2.png
composite -compose atop $(TMPDIR)/images/32-2.png $(TMPDIR)/images/32-1.png $(TMPDIR)/images/32-raw.png
inkscape -f $(PWD)/assets/logo.svg -w 16 -h 16 -jC -i layer1 -e $(TMPDIR)/images/16-raw.png
inkscape $(PWD)/assets/logo.svg -w 16 -h 16 --export-filename=$(TMPDIR)/images/16-raw.png
zopflipng -m -y $(TMPDIR)/images/128-raw.png $(TMPDIR)/images/128.png
zopflipng -m -y $(TMPDIR)/images/64-raw.png $(TMPDIR)/images/64.png
zopflipng -m -y $(TMPDIR)/images/32-raw.png $(TMPDIR)/images/32.png


+ 12
- 159
assets/logo.svg View File

@@ -1,160 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="0 0 135.46667 135.46667"
version="1.1"
id="svg8"
sodipodi:docname="logo.svg"
inkscape:version="0.92.1 r15371"
inkscape:export-filename=""
inkscape:export-xdpi="48.000004"
inkscape:export-ydpi="48.000004">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="0.70710678"
inkscape:cx="418.13805"
inkscape:cy="177.57445"
inkscape:document-units="mm"
inkscape:current-layer="layer2"
showgrid="false"
units="px"
width="256px"
showguides="false"
inkscape:window-width="1920"
inkscape:window-height="1137"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:pagecheckerboard="false"
inkscape:measure-start="283.373,243.952"
inkscape:measure-end="290.267,236.527">
<sodipodi:guide
position="0,0"
orientation="0,512"
id="guide3699"
inkscape:locked="false" />
<sodipodi:guide
position="135.46667,0"
orientation="-512,0"
id="guide3701"
inkscape:locked="false" />
<sodipodi:guide
position="135.46667,135.46667"
orientation="0,-512"
id="guide3703"
inkscape:locked="false" />
<sodipodi:guide
position="0,135.46667"
orientation="512,0"
id="guide3705"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-161.53334)"
style="display:inline">
<path
style="fill:#609926;fill-opacity:1;stroke:#428f29;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 27.709937,195.15095 c -9.546573,-0.0272 -22.3392732,6.79805 -21.6317552,23.90397 1.105534,26.72889 25.4565952,29.20839 35.1916502,29.42301 1.068023,5.01357 12.521798,22.30563 21.001818,23.21667 h 37.15277 c 22.27763,-1.66785 38.9607,-75.75671 26.59321,-76.03825 -46.781583,2.47691 -49.995146,2.13838 -88.599758,0 -2.495053,-0.0266 -5.972321,-0.49474 -9.707935,-0.5054 z m 2.491319,9.45886 c 1.351378,13.69267 3.555849,21.70359 8.018216,33.94345 -11.382872,-1.50473 -21.069822,-5.22443 -22.851515,-19.10984 -0.950962,-7.4112 2.390428,-15.16769 14.833299,-14.83361 z"
id="path3722"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sscccccsccsc" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2"
style="display:inline">
<rect
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.24757317;stroke-opacity:1"
id="rect4599"
width="34.762054"
height="34.762054"
x="87.508659"
y="18.291576"
transform="rotate(25.914715)"
ry="5.4825778" />
<path
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26644793px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 79.804947,57.359056 3.241146,1.609954 V 35.255731 h -3.262698 z"
id="path4525"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Layer 3"
style="display:inline">
<g
style="display:inline"
id="g4539">
<circle
transform="rotate(-19.796137)"
r="3.4745038"
cy="90.077766"
cx="49.064713"
id="path4606"
style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" />
<circle
transform="rotate(-19.796137)"
r="3.4745038"
cy="102.1049"
cx="36.810425"
id="path4606-3"
style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" />
<circle
transform="rotate(-19.796137)"
r="3.4745038"
cy="111.43928"
cx="46.484283"
id="path4606-1"
style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-opacity:1" />
<rect
transform="rotate(26.024158)"
y="18.061695"
x="97.333458"
height="27.261492"
width="2.6726954"
id="rect4629-8"
style="fill:#609926;fill-opacity:1;stroke:none;stroke-width:0.27444693;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4514"
d="m 76.558096,68.116343 c 12.97589,6.395378 13.012989,4.101862 4.890858,20.907244"
style="fill:none;stroke:#609926;stroke-width:2.68000007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
.st0{fill:#036EFF;}
</style>
<path class="st0" d="M892.63,193.98L598.19,23.99c-53.06-30.64-118.43-30.64-171.49,0L132.26,193.98
C79.2,224.62,46.51,281.23,46.51,342.5v339.99c0,61.27,32.69,117.88,85.75,148.52L426.7,1001c53.06,30.63,118.43,30.63,171.49,0
l294.44-169.99c53.06-30.64,85.75-87.25,85.75-148.52V342.5C978.38,281.23,945.69,224.62,892.63,193.98z M587.45,824.49
c0,41.43-33.58,75-75,75c-41.43,0-75-33.57-75-75v-624c0-41.42,33.57-75,75-75c20.71,0,39.46,8.39,53.03,21.97
c13.58,13.57,21.97,32.32,21.97,53.03V824.49z"/>
</svg>

+ 2
- 0
models/attachment.go View File

@@ -43,6 +43,8 @@ type Attachment struct {
DecompressState int32 `xorm:"DEFAULT 0"`
Type int `xorm:"DEFAULT 0"`
CreatedUnix timeutil.TimeStamp `xorm:"created"`

FileChunk *FileChunk `xorm:"-"`
}

type AttachmentUsername struct {


+ 11
- 0
models/cloudbrain.go View File

@@ -171,6 +171,7 @@ type TaskInfo struct {
CodeName string `json:"code_name"`
BenchmarkCategory []string `json:"selected_category"`
CodeLink string `json:"code_link"`
GpuType string `json:"gpu_type"`
}

func ConvertToTaskPod(input map[string]interface{}) (TaskPod, error) {
@@ -280,6 +281,16 @@ type Category struct {
Value string `json:"value"`
}

type GpuInfos struct {
GpuInfo []*GpuInfo `json:"gpu_type"`
}

type GpuInfo struct {
Id int `json:"id"`
Value string `json:"value"`
Queue string `json:"queue"`
}

type CommitImageParams struct {
Ip string `json:"ip"`
TaskContainerId string `json:"taskContainerId"`


+ 8
- 0
models/dataset.go View File

@@ -235,6 +235,14 @@ func getDatasetAttachments(e Engine, typeCloudBrain int, rels ...*Dataset) (err
for sortedRels.ID[currentIndex] < attachment.DatasetID {
currentIndex++
}
fileChunks := make([]*FileChunk, 0, 10)
err = e.
Where("uuid = ?", attachment.UUID).
Find(&fileChunks)
if err != nil {
return err
}
attachment.FileChunk = fileChunks[0]
sortedRels.Rel[currentIndex].Attachments = append(sortedRels.Rel[currentIndex].Attachments, attachment)
}



+ 19
- 12
models/repo.go View File

@@ -6,14 +6,12 @@
package models

import (
"code.gitea.io/gitea/modules/blockchain"
"context"
"crypto/md5"
"errors"
"fmt"
"html/template"
"sync"

"code.gitea.io/gitea/modules/blockchain"

// Needed for jpeg support
_ "image/jpeg"
@@ -2409,15 +2407,6 @@ func (repo *Repository) GetTreePathLock(treePath string) (*LFSLock, error) {
return nil, nil
}

var lck sync.Mutex

func (repo *Repository) IncreaseCloneCnt() {
lck.Lock()
defer lck.Unlock()
repo.CloneCnt++
_ = UpdateRepositoryCols(repo, "clone_cnt")
}

func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error {
_, err := e.ID(repo.ID).Cols(cols...).Update(repo)
return err
@@ -2434,3 +2423,21 @@ func GetBlockChainUnSuccessRepos() ([]*Repository, error) {
Where("block_chain_status != ?", RepoBlockChainSuccess).
Find(&repos)
}

func (repo *Repository) IncreaseCloneCnt() {
sess := x.NewSession()
defer sess.Close()

if err := sess.Begin(); err != nil {
return
}
if _, err := sess.Exec("UPDATE `repository` SET clone_cnt = clone_cnt + 1 WHERE id = ?", repo.ID); err != nil {
return
}

if err := sess.Commit(); err != nil {
return
}

return
}

+ 1
- 0
modules/auth/cloudbrain.go View File

@@ -12,6 +12,7 @@ type CreateCloudBrainForm struct {
Attachment string `form:"attachment" binding:"Required"`
JobType string `form:"job_type" binding:"Required"`
BenchmarkCategory string `form:"get_benchmark_category"`
GpuType string `form:"gpu_type"`
}

type CommitImageCloudBrainForm struct {


+ 1
- 0
modules/auth/dataset.go View File

@@ -31,4 +31,5 @@ type EditDatasetForm struct {
Private bool
ReleaseID int64 `xorm:"INDEX"`
Files []string
Type string `binding:"Required"`
}

+ 5
- 4
modules/base/tool.go View File

@@ -21,6 +21,7 @@ import (
"strings"
"time"
"unicode"
"unicode/utf8"

"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@@ -287,19 +288,19 @@ func EllipsisString(str string, length int) string {
if length <= 3 {
return "..."
}
if len(str) <= length {
if utf8.RuneCountInString(str) <= length {
return str
}
return str[:length-3] + "..."
return string([]rune(str)[:length-3]) + "..."
}

// TruncateString returns a truncated string with given limit,
// it returns input string if length is not reached limit.
func TruncateString(str string, limit int) string {
if len(str) < limit {
if utf8.RuneCountInString(str) < limit {
return str
}
return str[:limit]
return string([]rune(str)[:limit])
}

// StringsToInt64s converts a slice of string to a slice of int64.


+ 2
- 2
modules/cloudbrain/cloudbrain.go View File

@@ -23,7 +23,7 @@ const (
Success = "S000"
)

func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType string) error {
func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string) error {
dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
@@ -32,7 +32,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
RetryCount: 1,
GpuType: setting.JobType,
GpuType: gpuQueue,
Image: image,
TaskRoles: []models.TaskRole{
{


+ 10
- 1
modules/cloudbrain/resty.go View File

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

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

"code.gitea.io/gitea/models"
@@ -14,6 +15,10 @@ var (
TOKEN string
)

const (
JobHasBeenStopped = "S410"
)

func getRestyClient() *resty.Client {
if restyClient == nil {
restyClient = resty.New()
@@ -240,7 +245,11 @@ sendjob:
}

if result.Code != Success {
return fmt.Errorf("StopJob err: %s", res.String())
if result.Code == JobHasBeenStopped {
log.Info("StopJob(%s) failed:%s", jobID, result.Msg)
} else {
return fmt.Errorf("StopJob err: %s", res.String())
}
}

return nil


+ 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() + "()"
}
}
msg := format
if len(v) > 0 {
msg = ColorSprintf(format, v...)
}

stack := ""
if l.GetStacktraceLevel() <= level {
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
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 {
return nil
}
@@ -88,7 +112,7 @@ func (l *Logger) SendLog(level Level, caller, filename string, line int, msg str
caller: caller,
filename: filename,
line: line,
msg: msg,
msg: msg + "[" + msgID + "]",
time: time.Now(),
stacktrace: stack,
}


+ 3
- 1
modules/setting/setting.go View File

@@ -437,6 +437,7 @@ var (
RestServerHost string
JobPath string
JobType string
GpuTypes string
DebugServerHost string

//benchmark config
@@ -1146,7 +1147,8 @@ func NewContext() {
RestServerHost = sec.Key("REST_SERVER_HOST").MustString("http://192.168.202.73")
JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/")
DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73")
JobType = sec.Key("JOB_TYPE").MustString("debug_openi")
JobType = sec.Key("GPU_TYPE_DEFAULT").MustString("openidebug")
GpuTypes = sec.Key("GPU_TYPES").MustString("openidebug,openidgx")

sec = Cfg.Section("benchmark")
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false)


+ 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+"\"")

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
}


+ 0
- 0
modules/structs/repo.go View File


+ 3
- 1
options/locale/locale_en-US.ini View File

@@ -391,7 +391,8 @@ follow = Follow
unfollow = Unfollow
heatmap.loading = Loading Heatmap…
user_bio = Biography

own = Own
all = All
form.name_reserved = The username '%s' is reserved.
form.name_pattern_not_allowed = The pattern '%s' is not allowed in a username.
form.name_chars_not_allowed = User name '%s' contains invalid characters.
@@ -753,6 +754,7 @@ cloudbrain.new=New cloudbrain
cloudbrain.desc=cloudbrain
cloudbrain.cancel=Cancel
cloudbrain.commit_image = submit
clone_cnt=download
balance = balance
balance.total_view = total balance
balance.available = available balance:


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

@@ -1,4 +1,5 @@
home=个人中心
index=首页
dashboard=个人中心
explore=探索
datasets=数据集
@@ -391,7 +392,8 @@ follow=关注
unfollow=取消关注
heatmap.loading=正在加载热图...
user_bio=简历

own = 个人
all = 所有
form.name_reserved='%s' 用户名被保留。
form.name_pattern_not_allowed=用户名中不允许使用 "%s"。
form.name_chars_not_allowed=用户名 '%s' 包含无效字符。
@@ -642,6 +644,7 @@ public=公有
dir=目录
back=返回
copy_url=复制下载链接
copy_md5=复制文件MD5
directory=查看数据集目录结构
visibility=可见性
visibility_description=只有组织所有人或拥有权利的组织成员才能看到。
@@ -753,6 +756,7 @@ cloudbrain.new=新建任务
cloudbrain.desc=云脑功能
cloudbrain.cancel=取消
cloudbrain.commit_image=提交
clone_cnt=次下载
balance=余额
balance.total_view=余额总览
balance.available=可用余额:


BIN
public/img/404.png View File

Before After
Width: 1920  |  Height: 1080  |  Size: 170 kB Width: 1920  |  Height: 1080  |  Size: 167 kB

BIN
public/img/500.png View File

Before After
Width: 1920  |  Height: 1080  |  Size: 82 kB Width: 1920  |  Height: 1080  |  Size: 72 kB

BIN
public/img/apple-touch-icon.png View File

Before After
Width: 180  |  Height: 180  |  Size: 5.4 kB Width: 180  |  Height: 180  |  Size: 2.0 kB

BIN
public/img/avatar_default.png View File

Before After
Width: 200  |  Height: 200  |  Size: 6.2 kB Width: 200  |  Height: 200  |  Size: 2.5 kB

BIN
public/img/emoji/gitea.png View File

Before After
Width: 128  |  Height: 128  |  Size: 13 kB Width: 128  |  Height: 128  |  Size: 11 kB

BIN
public/img/favicon.ico View File

Before After

BIN
public/img/favicon.png View File

Before After
Width: 104  |  Height: 104  |  Size: 3.2 kB Width: 180  |  Height: 180  |  Size: 2.2 kB

BIN
public/img/feishu.png View File

Before After
Width: 64  |  Height: 64  |  Size: 2.0 kB Width: 64  |  Height: 64  |  Size: 1.9 kB

BIN
public/img/gitea-192.png View File

Before After
Width: 192  |  Height: 192  |  Size: 5.9 kB Width: 192  |  Height: 192  |  Size: 2.4 kB

BIN
public/img/gitea-512.png View File

Before After
Width: 512  |  Height: 512  |  Size: 18 kB Width: 512  |  Height: 512  |  Size: 5.3 kB

BIN
public/img/gitea-lg.png View File

Before After
Width: 880  |  Height: 880  |  Size: 34 kB Width: 880  |  Height: 880  |  Size: 9.1 kB

BIN
public/img/gitea-sm.png View File

Before After
Width: 120  |  Height: 120  |  Size: 3.4 kB Width: 120  |  Height: 120  |  Size: 1.6 kB

BIN
public/img/org_bg.png View File

Before After
Width: 1200  |  Height: 800  |  Size: 89 kB Width: 1200  |  Height: 800  |  Size: 77 kB

+ 0
- 0
routers/api/v1/repo/repo.go View File


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

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


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

@@ -28,14 +28,14 @@ const (
func BlockChainIndex(ctx *context.Context) {
repo := ctx.Repo.Repository
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)
return
}

res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey)
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)
return
}
@@ -52,7 +52,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {

repo, err := models.GetRepositoryByID(req.RepoId)
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{
"code": "-1",
"message": "internal error",
@@ -61,7 +61,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {
}

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{
"code": "-1",
"message": "the repo has been RepoBlockChainSuccess",
@@ -73,7 +73,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) {
repo.ContractAddress = req.ContractAddress

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{
"code": "-1",
"message": "internal error",
@@ -91,7 +91,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
var req BlockChainCommitNotify
data, _ := ctx.Req.Body().Bytes()
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{
"code": "-1",
"message": "response data error",
@@ -101,7 +101,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {

blockChain, err := models.GetBlockChainByCommitID(req.CommitID)
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{
"code": "-1",
"message": "internal error",
@@ -110,7 +110,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
}

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{
"code": "-1",
"message": "the commit has been BlockChainCommitReady",
@@ -122,7 +122,7 @@ func HandleBlockChainCommitNotify(ctx *context.Context) {
blockChain.TransactionHash = req.TransactionHash

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{
"code": "-1",
"message": "internal error",


+ 101
- 15
routers/repo/cloudbrain.go View File

@@ -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,12 @@ 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 (
gpuInfos *models.GpuInfos
categories *models.Categories
)

// MustEnableDataset check if repository enable internal cb
@@ -88,7 +96,7 @@ func CloudBrainNew(ctx *context.Context) {
result, err := cloudbrain.GetImages()
if err != nil {
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 {
@@ -104,7 +112,7 @@ func CloudBrainNew(ctx *context.Context) {
resultPublic, err := cloudbrain.GetPublicImages()
if err != nil {
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 {
@@ -131,9 +139,15 @@ func CloudBrainNew(ctx *context.Context) {
ctx.Data["benchmark_path"] = cloudbrain.BenchMarkMountPath
ctx.Data["is_benchmark_enabled"] = setting.IsBenchmarkEnabled

var categories *models.Categories
json.Unmarshal([]byte(setting.BenchmarkCategory), &categories)
if categories == nil {
json.Unmarshal([]byte(setting.BenchmarkCategory), &categories)
}
ctx.Data["benchmark_categories"] = categories.Category

if gpuInfos == nil {
json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos)
}
ctx.Data["gpu_types"] = gpuInfos.GpuInfo
ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath
ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled
ctx.HTML(200, tplCloudBrainNew)
@@ -146,10 +160,11 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
command := form.Command
uuid := form.Attachment
jobType := form.JobType
gpuQueue := setting.JobType
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath

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)
return
}
@@ -165,15 +180,22 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {

benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath
if setting.IsBenchmarkEnabled && jobType == string(models.JobTypeBenchmark) {
downloadRateCode(repo, jobName, setting.BenchmarkCode, benchmarkPath, form.BenchmarkCategory)
gpuQueue = form.GpuType
var gpuType string
for _, gpuInfo := range gpuInfos.GpuInfo {
if gpuInfo.Queue == gpuQueue {
gpuType = gpuInfo.Value
}
}
downloadRateCode(repo, jobName, setting.BenchmarkCode, benchmarkPath, form.BenchmarkCategory, gpuType)
}

snn4imagenetPath := setting.JobPath + jobName + cloudbrain.Snn4imagenetMountPath
if setting.IsSnn4imagenetEnabled && jobType == string(models.JobTypeSnn4imagenet) {
downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "")
downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "", "")
}

err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType)
err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue)
if err != nil {
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
return
@@ -245,7 +267,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain
ImageTag: form.Tag,
})
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{
"result_code": "-1",
"error_msg": "CommitImage failed",
@@ -268,14 +290,14 @@ func CloudBrainStop(ctx *context.Context) {
}

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"))
return
}

err = cloudbrain.StopJob(jobID)
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)
return
}
@@ -299,7 +321,7 @@ func CloudBrainDel(ctx *context.Context) {
}

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"))
return
}
@@ -313,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.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) {
var jobID = ctx.Params(":jobid")
job, err := models.GetCloudbrainByJobID(jobID)
@@ -322,11 +407,11 @@ func GetRate(ctx *context.Context) {
}

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) {
ctx.Redirect(setting.Snn4imagenetServerHost)
} else {
log.Error("JobType error:", job.JobType)
log.Error("JobType error:%s", job.JobType, ctx.Data["msgID"])
}
}

@@ -339,7 +424,7 @@ func downloadCode(repo *models.Repository, codePath string) error {
return nil
}

func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benchmarkCategory string) error {
func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benchmarkCategory, gpuType string) error {
err := os.MkdirAll(codePath, os.ModePerm)
if err != nil {
log.Error("mkdir codePath failed", err.Error())
@@ -370,6 +455,7 @@ func downloadRateCode(repo *models.Repository, taskName, gitPath, codePath, benc
CodeName: repo.Name,
BenchmarkCategory: strings.Split(benchmarkCategory, ","),
CodeLink: strings.TrimSuffix(repo.CloneLink().HTTPS, ".git"),
GpuType: gpuType,
})
if err != nil {
log.Error("json.Marshal failed", err.Error())


+ 7
- 1
routers/repo/dataset.go View File

@@ -49,6 +49,12 @@ func DatasetIndex(ctx *context.Context) {
ctx.NotFound("GetDatasetByRepo", err)
return
}

if ctx.Query("type") == "" {
log.Error("not found param type")
ctx.NotFound("type error", nil)
return
}
err = models.GetDatasetAttachments(ctx.QueryInt("type"), dataset)
if err != nil {
ctx.ServerError("GetDatasetAttachments", err)
@@ -116,5 +122,5 @@ func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) {
ctx.HTML(200, tplIndex)
log.Error("%v", err)
}
ctx.Redirect(ctx.Repo.RepoLink + "/datasets")
ctx.Redirect(ctx.Repo.RepoLink + "/datasets?type=" + form.Type)
}

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

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

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

@@ -8,6 +8,7 @@ package repo
import (
"fmt"
"io"
"net/url"
"path"
"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
name = strings.Replace(name, ",", " ", -1)
name = url.QueryEscape(name)

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


+ 26
- 4
routers/routes/routes.go View File

@@ -49,6 +49,7 @@ import (
"gitea.com/macaron/session"
"gitea.com/macaron/toolbox"
"github.com/prometheus/client_golang/prometheus"
gouuid "github.com/satori/go.uuid"
"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())
}

err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "")
err = logger.SendLog(log.INFO, "", "", 0, buf.String(), ctx.Data["msgID"].(string), "")
if err != nil {
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.
func NewMacaron() *macaron.Macaron {
gob.Register(&u2f.Challenge{})
@@ -125,6 +144,7 @@ func NewMacaron() *macaron.Macaron {
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
if setting.EnableAccessLog {
setupAccessLogger(m)
@@ -285,7 +305,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Head("/", func() string {
return ""
})
m.Get("/", routers.Home)
m.Get("/", routers.ExploreRepos)
m.Get("/dashboard", routers.Dashboard)
m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) {
@@ -910,9 +930,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())



+ 0
- 0
routers/user/home.go View File


+ 0
- 0
routers/user/profile.go View File


+ 9
- 0
templates/base/head.tmpl View File

@@ -176,6 +176,15 @@
{{end}}
{{template "custom/header" .}}

<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?7c4ef0a24be6109ab22e63c832ab21cf";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
{{template "custom/body_outer_pre" .}}


+ 1
- 5
templates/base/head_navbar.tmpl View File

@@ -9,7 +9,7 @@
</div>

{{if .IsSigned}}
<a class="item {{if .PageIsDashboard}}active{{end}}" href="/dashboard">{{.i18n.Tr "dashboard"}}</a>
<a class="item {{if .PageIsDashboard}}active{{end}}" href="/dashboard">{{.i18n.Tr "index"}}</a>
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi"}}</a>
{{if not .UnitIssuesGlobalDisabled}}
<a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
@@ -109,10 +109,6 @@
</div>

<div class="divider"></div>
<a class="item" href="{{AppSubUrl}}/dashboard">
{{svg "octicon-info" 16}}
{{.i18n.Tr "your_dashboard"}}<!-- Your dashboard -->
</a>
<a class="item" href="{{AppSubUrl}}/{{.SignedUser.Name}}">
{{svg "octicon-person" 16}}
{{.i18n.Tr "your_profile"}}<!-- Your profile -->


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

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


+ 0
- 0
templates/explore/repo_list.tmpl View File


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

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


+ 30
- 3
templates/repo/cloudbrain/new.tmpl View File

@@ -88,6 +88,17 @@
.inline.required.field.cloudbrain_snn4imagenet {
display: none;
}

.select2-container .select2-selection--single{
height:38px !important;
}

.select2-container--default .select2-selection--single {
border : 1px solid rgba(34,36,38,.15) !important;
}
.select2-container--default .select2-selection--single .select2-selection__rendered{
line-height: 38px !important;
}
</style>

<div id="mask">
@@ -139,9 +150,18 @@
</div>
<input id="store_category" type="hidden" name="get_benchmark_category">

<div class="inline required field cloudbrain_benchmark">
<label>GPU类型</label>
<select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type">
{{range .gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
</select>
</div>

<div class="inline required field">
<label>镜像</label>
<select class="ui search dropdown" id="cloudbrain_image" placeholder="选择镜像" style='width:385px' name="image">
<select class="ui search" id="cloudbrain_image" placeholder="选择镜像" style='width:385px;' name="image">
{{range .images}}
<option name="image" value="{{.Place}}">{{.PlaceView}}</option>
{{end}}
@@ -198,7 +218,8 @@
</div>
</div>
{{template "base/footer" .}}

<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
// 点击按钮后遮罩层显示
function showmask() {
@@ -215,11 +236,17 @@
$('#cloudbrain_benchmark_category')
.dropdown({
placeholder: "选择数据集类别",
})
})
$('select.dropdown')
.dropdown();

$('#cloudbrain_image').select2({
placeholder: "选择镜像"
});

$(".ui.button.reset").click(function(e){
e.preventDefault()
$('#cloudbrain_benchmark_category')


+ 6
- 2
templates/repo/datasets/dataset_list.tmpl View File

@@ -18,17 +18,21 @@
<span class="ui text center clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy">{{svg "octicon-file" 16}}</span>
</div>

<div class="one wide column">
<span class="ui text center clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span>
</div>

<div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}">
<a class="ui text center" href="datasets/dirs/{{.UUID}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a>
</div>

{{if $.Permission.CanWrite $.UnitTypeDatasets}}
{{if $.Repository.IsPrivate}}
<div class="three wide column">
<div class="two wide column">
<a class="ui button mini" disabled='true' data-tooltip='{{$.i18n.Tr "dataset.how_to_public"}}'>{{$.i18n.Tr "dataset.private"}}</a>
</div>
{{ else }}
<div class="three wide column">
<div class="two wide column">
<div class="ui buttons mini">
<a class="ui button mini {{if .IsPrivate}}positive active{{end}}" href="javascript:void(0)" data-dataset-status="true-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="true" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.private"}}</a>
<div class="or"></div>


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

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


+ 4
- 3
templates/repo/datasets/index.tmpl View File

@@ -55,6 +55,7 @@
<div class="sixteen wide column">
<textarea name="description" rows="3">{{.dataset.Description}}</textarea>
</div>
<input name="type" value="{{.Type}}" type="hidden" />
<div class="sixteen wide column">
<a class="ui button" id="cancel">{{.i18n.Tr "cancel"}}</a>
<button class="ui primary button" id="submit">{{.i18n.Tr "dataset.update_dataset"}}</button>
@@ -67,7 +68,7 @@
<div class="ui sixteen wide column">
<div class="ui two column stackable grid">
<div class="column">
<h2>{{.i18n.Tr "datasets"}}</h2>
<h2>{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}</h2>
</div>
<div class="column right aligned" style="z-index:1">
<div class="ui right dropdown type jump item">
@@ -75,8 +76,8 @@
{{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i>
</span>
<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>


+ 0
- 0
templates/user/profile.tmpl View File


+ 0
- 1
web_src/js/index.js View File

@@ -3324,7 +3324,6 @@ function initVueComponents() {
self.$refs.search.focus();
});
},

methods: {
changeTab(t) {
this.tab = t;


+ 3
- 0
web_src/less/_base.less View File

@@ -1299,4 +1299,7 @@ i.icon.centerlock {

.ui.search.action.input > input {
width: auto;
}
.button.mobile-only {
background-color: transparent !important;
}

Loading…
Cancel
Save