Browse Source

merge

tags/v1.22.12.1^2
ychao_1983 2 years ago
parent
commit
3b1291b2c7
100 changed files with 4676 additions and 841 deletions
  1. +16
    -9
      custom/public/css/git.openi.css
  2. BIN
      custom/public/img/home-banner-01-en.jpg
  3. BIN
      custom/public/img/home-banner-01.jpg
  4. BIN
      custom/public/img/home-bg-ps.png
  5. +1
    -0
      custom/public/img/logo-footer.svg
  6. +45
    -1
      custom/public/img/logo-w.svg
  7. BIN
      custom/public/rotation3D/img/baseimg.png
  8. +4
    -4
      index.html
  9. +55
    -0
      models/cloudbrain.go
  10. +34
    -16
      models/cloudbrain_static.go
  11. +14
    -6
      models/dataset.go
  12. +5
    -1
      models/repo_activity_custom.go
  13. +9
    -0
      models/resource_specification.go
  14. +1
    -1
      models/user.go
  15. +21
    -0
      models/user_mail.go
  16. +4
    -0
      modules/auth/user_form.go
  17. +20
    -4
      modules/cloudbrain/cloudbrain.go
  18. +1
    -1
      modules/grampus/grampus.go
  19. +99
    -23
      modules/modelarts/modelarts.go
  20. +1
    -1
      modules/modelarts/resty.go
  21. +8
    -45
      modules/modelarts_cd/modelarts.go
  22. +1
    -1
      modules/repository/hooks.go
  23. +36
    -2
      modules/setting/setting.go
  24. +8
    -0
      modules/structs/cloudbrain.go
  25. +3
    -0
      modules/templates/helper.go
  26. +32
    -8
      options/locale/locale_en-US.ini
  27. +29
    -7
      options/locale/locale_zh-CN.ini
  28. +374
    -56
      public/home/home.js
  29. +1
    -1
      public/img/search.svg
  30. +7
    -1
      routers/api/v1/api.go
  31. +83
    -8
      routers/api/v1/repo/cloudbrain.go
  32. +61
    -69
      routers/api/v1/repo/cloudbrain_dashboard.go
  33. +5
    -1
      routers/api/v1/repo/modelarts.go
  34. +58
    -15
      routers/home.go
  35. +1
    -2
      routers/repo/ai_model_convert.go
  36. +4
    -5
      routers/repo/aisafety.go
  37. +12
    -53
      routers/repo/cloudbrain.go
  38. +49
    -50
      routers/repo/cloudbrain_statistic.go
  39. +1
    -3
      routers/repo/grampus.go
  40. +33
    -10
      routers/repo/modelarts.go
  41. +4
    -2
      routers/routes/routes.go
  42. +28
    -0
      routers/user/auth.go
  43. +362
    -0
      services/cloudbrain/cloudbrainTask/notebook.go
  44. +20
    -13
      services/cloudbrain/cloudbrainTask/sync_status.go
  45. +12
    -0
      services/cloudbrain/cloudbrainTask/train.go
  46. +26
    -0
      services/cloudbrain/util.go
  47. +6
    -10
      services/repository/repository.go
  48. +2
    -0
      templates/admin/cloudbrain/list.tmpl
  49. +47
    -7
      templates/base/footer_content.tmpl
  50. +2
    -2
      templates/base/footer_content_fluid.tmpl
  51. +1
    -0
      templates/base/head.tmpl
  52. +1
    -0
      templates/base/head_home.tmpl
  53. +42
    -21
      templates/base/head_navbar.tmpl
  54. +1
    -1
      templates/base/head_navbar_fluid.tmpl
  55. +1
    -1
      templates/base/head_navbar_home.tmpl
  56. +1
    -1
      templates/base/head_navbar_pro.tmpl
  57. +1
    -1
      templates/base/head_notice.tmpl
  58. +36
    -0
      templates/custom/home/home_activity.tmpl
  59. +85
    -0
      templates/custom/home/home_dataset.tmpl
  60. +20
    -0
      templates/custom/home/home_org.tmpl
  61. +21
    -0
      templates/custom/home/home_repo.tmpl
  62. +2079
    -0
      templates/custom/home/home_top.tmpl
  63. +134
    -0
      templates/custom/home/home_user_experience.tmpl
  64. +7
    -7
      templates/explore/repo_orgtop.tmpl
  65. +5
    -5
      templates/explore/repo_right.tmpl
  66. +1
    -3
      templates/explore/repos.tmpl
  67. +27
    -89
      templates/home.tmpl
  68. +81
    -0
      templates/notice.tmpl
  69. +2
    -2
      templates/org/home_courses.tmpl
  70. +10
    -10
      templates/repo/cloudbrain/benchmark/new.tmpl
  71. +1
    -1
      templates/repo/cloudbrain/inference/new.tmpl
  72. +1
    -1
      templates/repo/cloudbrain/trainjob/new.tmpl
  73. +1
    -1
      templates/repo/datasets/index.tmpl
  74. +13
    -2
      templates/repo/debugjob/index.tmpl
  75. +1
    -1
      templates/repo/grampus/trainjob/gpu/new.tmpl
  76. +1
    -1
      templates/repo/grampus/trainjob/npu/new.tmpl
  77. +3
    -3
      templates/repo/header.tmpl
  78. +29
    -29
      templates/repo/home.tmpl
  79. +1
    -1
      templates/repo/modelarts/inferencejob/new.tmpl
  80. +1
    -1
      templates/repo/modelarts/trainjob/new.tmpl
  81. +1
    -1
      templates/repo/modelarts/trainjob/version_new.tmpl
  82. +1
    -1
      templates/repo/modelmanage/convertIndex.tmpl
  83. +1
    -1
      templates/repo/modelmanage/index.tmpl
  84. +4
    -2
      templates/repo/modelsafety/new.tmpl
  85. +47
    -1
      templates/user/auth/activate.tmpl
  86. +6
    -4
      templates/user/dashboard/cloudbrains.tmpl
  87. +1
    -1
      templates/user/dashboard/dashboard.tmpl
  88. +1
    -1
      web_src/js/components/EditAboutInfo.vue
  89. +1
    -1
      web_src/js/components/dataset/referenceDataset.vue
  90. +2
    -2
      web_src/js/features/ad.js
  91. +23
    -12
      web_src/js/features/cloudrbanin.js
  92. +4
    -0
      web_src/js/features/i18nVue.js
  93. +19
    -1
      web_src/js/index.js
  94. +16
    -2
      web_src/less/openi.less
  95. +47
    -0
      web_src/vuepages/apis/modules/notobook.js
  96. +0
    -1
      web_src/vuepages/apis/service.js
  97. +30
    -2
      web_src/vuepages/langs/config/en-US.js
  98. +217
    -186
      web_src/vuepages/langs/config/zh-CN.js
  99. +1
    -1
      web_src/vuepages/pages/model/tuomin/index.vue
  100. +1
    -1
      web_src/vuepages/pages/modelmanage/common/modelmanage-common-detail.vue

+ 16
- 9
custom/public/css/git.openi.css View File

@@ -72,9 +72,7 @@
z-index: 10;
}
.ui.secondary.c2net.segment{
/* background: #f8faff;
border: none;*/
margin-bottom: 5em;
padding-bottom: 3em;
padding-top: 2em;
color: rgba(0,0,0,.87);
background-image: linear-gradient(to bottom left,var(--tw-gradient-stops));
@@ -176,7 +174,7 @@
}
.homeorg, .homepro, .homemodel, .i-env{
position: relative;
padding-bottom: 5em;
padding-bottom: 3em;
}
.homenews::before{
content: '';
@@ -203,7 +201,7 @@
padding: 0;
}
.newslist{
height: 300px;
height: 260px;
overflow: hidden;
}

@@ -278,7 +276,7 @@
z-index: 9;
}
.homeorg-list .card{
background-image: linear-gradient(#FFF, #FFF 60%, #DFF0EF) !important;
/* background-image: linear-gradient(#FFF, #FFF 60%, #DFF0EF) !important; */
box-shadow: none !important;
}
.homeorg-list .card .ui.small.header .content{
@@ -299,7 +297,7 @@
background-color: #FFF;
box-shadow: 0px 5px 10px 0px rgba(105, 192, 255, .3);
border: 1px solid rgba(105, 192, 255, .4);
min-height: 10.8em;
/* min-height: 10.8em; */
}
.homepro-list .ui.card>.content>.header{
line-height: 40px !important;
@@ -307,7 +305,7 @@

.homepro-list .swiper-pagination-bullet-active, .homeorg-list .swiper-pagination-bullet-active{
width: 40px;
border-radius: 4px;
border-radius: 4px;
}
.i-env > div{
position: relative;
@@ -317,6 +315,15 @@
}

@media only screen and (max-width: 767px) {
.mobile-margin-left-20 {
margin-left: 20px !important;
}
.mobile-text-align-center {
text-align: center !important;
}
.mobile-justify-content-center {
justify-content: center !important;
}
.am-mt-30{ margin-top: 1.5rem !important;}
.ui.secondary.hometop.segment{
margin-bottom: 5.0rem;
@@ -341,7 +348,7 @@
background: #FFF;
}
.homeorg{
padding-left: 3.5em;
/* padding-left: 3.5em; */
}
.homeorg-tit::after {
left: -2.3em;


BIN
custom/public/img/home-banner-01-en.jpg View File

Before After
Width: 1920  |  Height: 580  |  Size: 180 kB

BIN
custom/public/img/home-banner-01.jpg View File

Before After
Width: 1920  |  Height: 580  |  Size: 174 kB

BIN
custom/public/img/home-bg-ps.png View File

Before After
Width: 681  |  Height: 800  |  Size: 62 kB

+ 1
- 0
custom/public/img/logo-footer.svg
File diff suppressed because it is too large
View File


+ 45
- 1
custom/public/img/logo-w.svg View File

@@ -1 +1,45 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 50"><defs><style>.cls-1{fill:#5bb973;}.cls-2{fill:#fff;}</style></defs><title>logo-w</title><path class="cls-1" d="M42.08,12.13l-15.65-9a4.44,4.44,0,0,0-4.43,0l-15.65,9A4.44,4.44,0,0,0,4.13,16V34a4.44,4.44,0,0,0,2.22,3.84l3.83,2.21a2.88,2.88,0,0,0-.06.59,2.95,2.95,0,1,0,1-2.17L7.26,36.3A2.63,2.63,0,0,1,6,34V16A2.62,2.62,0,0,1,7.26,13.7l15.65-9a2.59,2.59,0,0,1,2.61,0l15.65,9A2.63,2.63,0,0,1,42.47,16V34a2.64,2.64,0,0,1-1.3,2.27l-15.65,9a3.16,3.16,0,0,1-.5.22V39.88a1.31,1.31,0,0,0,0-.28V36.35l.1,0,9-6a.92.92,0,0,0,.41-.75V20a3,3,0,1,0-1.82,0v9L25,34.18V15.94a3,3,0,1,0-1.82,0v12l-5.08-2.95V20.19a3,3,0,1,0-1.82,0v5.26a.9.9,0,0,0,.45.79L23.2,30v8.16L12.11,31.73V23.84a2.93,2.93,0,1,0-1.82,0v8.41a.94.94,0,0,0,.46.79l12.45,7.2v6.34a.22.22,0,0,0,0,.08v.09l0,.1s0,0,0,.07l.06.1s0,0,0,0l.08.1,0,0a.39.39,0,0,0,.1.08l0,0,.12.07,0,0,.14,0h0a.39.39,0,0,0,.15,0h.16a4.44,4.44,0,0,0,2.22-.59l15.65-9A4.46,4.46,0,0,0,44.29,34V16a4.45,4.45,0,0,0-2.21-3.83m-29,27.42a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m20.6-23.46a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-16.45.19a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12m-6,3.65a1.12,1.12,0,1,1-1.12,1.12,1.12,1.12,0,0,1,1.12-1.12M24.13,12A1.12,1.12,0,1,1,23,13.14,1.12,1.12,0,0,1,24.13,12"/><path class="cls-2" d="M81.68,26.69H67.86c-2,.1-3.06,1-3.06,2.85v6.33c.1,1.68,1.16,2.53,3.06,2.63H81.57c1.9-.1,2.85-1,3-2.74V29.54A2.71,2.71,0,0,0,81.68,26.69Zm-.53,8c-.11.73-.53,1.16-1.48,1.26H69.54c-1-.21-1.37-.53-1.47-1.26V30.59a1.44,1.44,0,0,1,1.47-1.48h10a1.54,1.54,0,0,1,1.58,1.48Z"/><path class="cls-2" d="M63.21,20.57V17A1.63,1.63,0,0,1,64.8,15.4H79.25c1.06-.11,1.58.42,1.58,1.37V19.3c0,.85-.52,1.27-1.47,1.27H64.59V23H81.47c1.79,0,2.74-.85,2.74-2.43V15.72A2.45,2.45,0,0,0,81.47,13H74.08V11H70.6v2H62.69c-2,0-3,.95-3,3v9.39a42.65,42.65,0,0,1-2,13l3.27.64a43.43,43.43,0,0,0,2.11-13V20.57Z"/><path class="cls-2" d="M90,24.47l3.38,1.8a10.1,10.1,0,0,0,3.9-5.81h5.91V18H97.82a25.57,25.57,0,0,0,.21-3h5V12.55H93.7V11H90.22v4h4.43a17.38,17.38,0,0,1-.21,2.95H89.38v2.53h4.43A7.05,7.05,0,0,1,90,24.47Z"/><path class="cls-2" d="M97.82,21.62A21.82,21.82,0,0,1,100,26.05h3.7a25.8,25.8,0,0,0-2.22-4.43Z"/><path class="cls-2" d="M112.17,26.79H93.39c-1.8.21-2.85,1.06-3,2.64v4.75H112v1c0,.85-.52,1.27-1.58,1.27h-15c-1,0-1.48-.42-1.48-1.16H90.54v1A2.75,2.75,0,0,0,93.18,39h19.09c2-.1,3.06-1,3.06-2.64V29.54A3.21,3.21,0,0,0,112.17,26.79Zm-.32,4.86h-18V30.8a1.43,1.43,0,0,1,1.48-1.47h15c1,0,1.58.52,1.58,1.47Z"/><path class="cls-2" d="M113.64,12h-6.22q-2.53.17-2.85,2.22V23.1a2.33,2.33,0,0,0,2.32,2.22h6.65c1.47-.11,2.32-.85,2.32-2.22V14.24C116,13,115.23,12.23,113.64,12Zm-1,9.29c0,1.05-.53,1.58-1.48,1.58h-1.79A1.39,1.39,0,0,1,108,21.31V16a1.42,1.42,0,0,1,1.47-1.47H111A1.53,1.53,0,0,1,112.59,16Z"/></svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.3.1, 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 160 64" style="enable-background:new 0 0 160 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M105.3,33.3H87.1c-2.6,0.1-4,1.3-4,3.8v8.3c0.1,2.2,1.5,3.3,4,3.5h18c2.5-0.1,3.8-1.3,3.9-3.6v-8.2
c0.1-2-1.4-3.6-3.4-3.8C105.6,33.3,105.4,33.3,105.3,33.3z M104.6,43.9c-0.1,1-0.7,1.5-1.9,1.7H89.3c-1.3-0.3-1.8-0.7-1.9-1.7v-5.4
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h13.1c1.1,0,2,0.8,2.1,2L104.6,43.9z"/>
<path class="st0" d="M81,25.3v-4.7c0-1.1,0.9-2.1,2.1-2.1h19c1.4-0.1,2.1,0.5,2.1,1.8v3.3c0,1.1-0.7,1.7-1.9,1.7H82.8v3.2H105
c2.3,0,3.6-1.1,3.6-3.2v-6.4c0.2-1.8-1.1-3.4-2.8-3.6c-0.3,0-0.5,0-0.8,0h-9.7v-2.6h-4.6v2.6H80.3c-2.6,0-3.9,1.2-3.9,3.9v12.3
c0,5.8-0.9,11.6-2.6,17.1l4.3,0.8c1.8-5.5,2.7-11.3,2.8-17.1v-7.2H81z"/>
<path class="st0" d="M116.2,30.4l4.4,2.4c2.6-1.9,4.4-4.6,5.1-7.6h7.8v-3.2h-7.1c0.2-1.3,0.3-2.6,0.3-3.9h6.6v-3.2h-12.3v-2h-4.6
V18h5.8c0,1.3-0.1,2.6-0.3,3.9h-6.7v3.3h5.8C120.4,27.5,118.6,29.4,116.2,30.4z"/>
<path class="st0" d="M126.5,26.7c1.2,1.8,2.1,3.8,2.9,5.8h4.9c-0.8-2-1.8-4-2.9-5.8H126.5z"/>
<path class="st0" d="M145.4,33.5h-24.7c-2.4,0.3-3.8,1.4-3.9,3.5v6.2h28.4v1.3c0,1.1-0.7,1.7-2.1,1.7h-19.7c-1.3,0-1.9-0.5-1.9-1.5
h-4.5V46c0,1.9,1.6,3.5,3.5,3.6h25.1c2.6-0.1,4-1.3,4-3.5v-9C149.2,35,147.5,33.5,145.4,33.5z M145,39.9h-23.7v-1.1
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0H143c1.3,0,2.1,0.7,2.1,1.9L145,39.9z"/>
<path class="st0" d="M147.3,14h-8.2c-2.2,0.1-3.5,1.1-3.8,2.9v11.7c0.1,1.6,1.4,2.9,3.1,2.9h8.7c1.9-0.1,3.1-1.1,3.1-2.9V17
C150.4,15.4,149.4,14.3,147.3,14z M146,26.2c0,1.4-0.7,2.1-1.9,2.1h-2.4c-1,0-1.8-0.8-1.8-1.8c0-0.1,0-0.1,0-0.2v-7
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h2c1.1,0,2.1,0.8,2.1,1.9l0,0L146,26.2z"/>
</g>
<path class="st1" d="M67.2,44.1V20c0-2.6-1.4-5.1-3.7-6.4l-20.9-12c-2.3-1.3-5.1-1.3-7.4,0l-20.9,12c-2.3,1.3-3.7,3.8-3.7,6.4v24.1
c0,2.6,1.4,5.1,3.7,6.4l20.9,12c2.3,1.3,5.1,1.3,7.4,0l20.9-12C65.8,49.2,67.2,46.7,67.2,44.1z"/>
<path class="st0" d="M61.9,15.4L42,3.9c-1.9-1.1-4.3-1.1-6.2,0L15.9,15.4c-1.9,1.1-3.1,3.2-3.1,5.4v22.9c0,2.2,1.2,4.3,3.1,5.4
l3.8,2c0.8,0.4,0.8,1,0.8,1.9c0,0,0,0.1,0,0.1c0.1,1.6,1.8,3.5,4.2,3.5c2.3,0,4.3-1.9,4.4-4.2c0-1.6-0.8-3.1-2.3-3.9
c-0.6-0.3-1.7-0.5-2.9-0.4c-0.9,0.1-1,0.6-2.8-0.5l-2.8-1.6c-0.8-0.5-1.7-1.3-1.6-2.3V22c0-1.8,0.8-2.8,2.1-3.5L37,7.8
C38.1,7,40.2,7.2,41.5,8l16.4,9.5c2.9,1.6,3,3,3,4v19.7c0,2.3-1.5,4-2.3,4.5l-15.1,8.5C42.8,54.5,42,54,42,53.3l0-2.5
c0-0.1,0-0.3,0-0.4v-2.5c0-0.8,0.4-1.6,1.1-2l8.8-5.7c1.4-0.9,2-1.7,2-3.8L53.7,28c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6
c-0.8-1.4-2.4-2.2-4-2c-1.6,0.1-2.8,1-3.5,2.4c-0.5,1-0.6,2.2-0.3,3.3c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v7.2
c0,1.1-0.5,2.1-1.5,2.7l-5.5,2.8c-0.7,0.5-1.6,0-1.6-0.8l-0.2-17.1c0-1,0.5-1.9,1.2-2.5c0.4-0.3,0.7-0.8,1-1.3
c0.7-1.3,0.7-2.9-0.1-4.3c-0.8-1.4-2.5-2.2-4.1-2.1c-2.9,0.3-4.6,3.1-3.8,5.7c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v9.9
c0,0.8-0.8,1.3-1.5,0.9L34,32.5c-0.7-0.4-1.2-1.2-1.2-2.1v-2.2c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6c-0.8-1.3-2.4-2.1-4-2
c-2.9,0.2-4.7,3.1-3.8,5.7c0.2,0.8,0.7,1.5,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5l0,3.5c0,1,0,2,1.6,3.1l5.5,3c0.7,0.4,1.2,1.2,1.2,2.1v4.5
c0,0.8-0.8,1.3-1.5,0.9L26.6,41c-0.7-0.4-1.2-1.2-1.2-2.1l-0.2-6.1c0-1,0.4-1.8,1.1-2.5c1.4-1.3,1.9-3.4,0.9-5.3
c-0.8-1.4-2.4-2.3-4-2.2c-2.9,0.2-4.6,3-3.8,5.6c0.2,0.7,0.7,1.4,1.2,1.9c0.7,0.6,1.1,1.5,1.1,2.5l-0.5,6.8c0,1.9,0.3,2.8,1.8,3.5
l11.8,6.3c1,0.6,1.6,1.7,1.6,2.8l0,3.1c0,3.1,4.3,5.7,8.7,3.3l16.4-9.8c1.9-1,3.2-3,3.4-5.2V20.7C65,18.5,63.8,16.5,61.9,15.4z
M24.2,50.7c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C22.2,51.7,23.1,50.7,24.2,50.7z M48.7,21.5c0-1.1,0.9-2,2-2
s2,0.9,2,2c0,1.1-0.9,2-2,2S48.7,22.6,48.7,21.5z M30.6,23.8c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S31.8,23.8,30.6,23.8z
M22.2,26.4c0-1.1,0.9-2,2-2c1.1,0,2,0.9,2,2s-0.9,2-2,2C23.1,28.4,22.2,27.5,22.2,26.4z M40,17.9c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2
c1.1,0,2,0.9,2,2C42,17,41.1,17.9,40,17.9z"/>
</svg>

BIN
custom/public/rotation3D/img/baseimg.png View File

Before After
Width: 976  |  Height: 850  |  Size: 353 kB

+ 4
- 4
index.html View File

@@ -107,7 +107,7 @@
<meta property="og:title" content="OpenI">
<meta property="og:type" content="website" />
<meta property="og:image" content="/img/gitea-lg.png" />
<meta property="og:url" content="https://git.openi.org.cn/" />
<meta property="og:url" content="https://openi.pcl.ac.cn/" />
<meta property="og:description" content="Efficient code management center, you can host and review code">

<meta property="og:site_name" content="OpenI" />
@@ -250,7 +250,7 @@ var _hmt = _hmt || [];
<a href=https://git.openi.org.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md class="a_width" target="_blank">
<a href=https://openi.pcl.ac.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md class="a_width" target="_blank">
<i class="ri-arrow-right-s-line"></i>
7月中下旬登录启智AI协作平台,需登记手机号码啦&gt;&gt;&gt;
</a>
@@ -308,7 +308,7 @@ var _hmt = _hmt || [];
isNewNotice=false;
}
let isShowNoticeTag = false;
let notices= [{"Title":"“我为开源打榜狂”上榜领奖者名单公示1周,10万奖金被瓜分,请大家自行确认\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/notices_0701/636.html","Visible":1},{"Title":"7月中下旬登录启智AI协作平台,需登记手机号码啦\u003e\u003e\u003e","Link":"https://git.openi.org.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md","Visible":1},{"Title":"智算网络Beta版本上线,大大缩短算力排队时间,速来体验吧~\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/dongtai_0628/634.html","Visible":1},{"Title":"启智AI协作平台问卷调查,邀请您参加\u003e\u003e\u003e","Link":"https://wj.qq.com/s2/10362208/5c0c","Visible":1}]
let notices= [{"Title":"“我为开源打榜狂”上榜领奖者名单公示1周,10万奖金被瓜分,请大家自行确认\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/notices_0701/636.html","Visible":1},{"Title":"7月中下旬登录启智AI协作平台,需登记手机号码啦\u003e\u003e\u003e","Link":"https://openi.pcl.ac.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md","Visible":1},{"Title":"智算网络Beta版本上线,大大缩短算力排队时间,速来体验吧~\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/dongtai_0628/634.html","Visible":1},{"Title":"启智AI协作平台问卷调查,邀请您参加\u003e\u003e\u003e","Link":"https://wj.qq.com/s2/10362208/5c0c","Visible":1}]
if(notices != null && notices!=''){
for (i =0;i<notices.length;i++){
if (notices[i].Visible==1){
@@ -604,7 +604,7 @@ var _hmt = _hmt || [];
</div>
</div>

<a href="https://git.openi.org.cn/zeizei/OpenI_Learning" class=" item a_margin" target="_blank"><i class="ri-creative-commons-by-line footer_icon" ></i><p class="footer_icon">Tutorial</p> </a>
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" class=" item a_margin" target="_blank"><i class="ri-creative-commons-by-line footer_icon" ></i><p class="footer_icon">Tutorial</p> </a>
<a href="/api/swagger" class=" item a_margin"><i class="ri-exchange-line footer_icon" > </i><p class="footer_icon">API</p> </a>
<a href="/user/login" class=" item a_margin" ><i class="ri-mail-send-line footer_icon" ></i><p class="footer_icon">Feedback</p></a>


+ 55
- 0
models/cloudbrain.go View File

@@ -2397,6 +2397,61 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er
return cloudbrains, count, nil
}

func CloudbrainAllKanBan(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
sess := x.NewSession()
defer sess.Close()

var cond = builder.NewCond()

if (opts.Type) >= 0 {
cond = cond.And(
builder.Eq{"cloudbrain.type": opts.Type},
)
}
if opts.BeginTimeUnix > 0 && opts.EndTimeUnix > 0 {
cond = cond.And(
builder.And(builder.Gte{"cloudbrain.created_unix": opts.BeginTimeUnix}, builder.Lte{"cloudbrain.created_unix": opts.EndTimeUnix}),
)
}
var count int64
var err error
count, err = sess.Unscoped().Where(cond).Count(new(Cloudbrain))

if err != nil {
return nil, 0, fmt.Errorf("Count: %v", err)
}

if opts.Page >= 0 && opts.PageSize > 0 {
var start int
if opts.Page == 0 {
start = 0
} else {
start = (opts.Page - 1) * opts.PageSize
}
sess.Limit(opts.PageSize, start)
}
// sess.OrderBy("cloudbrain.created_unix DESC")
cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum)
if err := sess.Cols("id", "type", "work_server_number", "duration", "train_job_duration", "ai_center", "cluster").Table(&Cloudbrain{}).Unscoped().Where(cond).
Find(&cloudbrains); err != nil {
return nil, 0, fmt.Errorf("Find: %v", err)
}
if opts.NeedRepoInfo {
var ids []int64
for _, task := range cloudbrains {
ids = append(ids, task.RepoID)
}
repositoryMap, err := GetRepositoriesMapByIDs(ids)
if err == nil {
for _, task := range cloudbrains {
task.Repo = repositoryMap[task.RepoID]
}
}

}
return cloudbrains, count, nil
}

func GetStartedCloudbrainTaskByUpdatedUnix(startTime, endTime time.Time) ([]Cloudbrain, error) {
r := make([]Cloudbrain, 0)
err := x.Where("updated_unix >= ? and updated_unix <= ? and start_time > 0", startTime.Unix(), endTime.Unix()).Unscoped().Find(&r)


+ 34
- 16
models/cloudbrain_static.go View File

@@ -46,7 +46,8 @@ type CloudbrainDurationStatistic struct {
ComputeResource string
AccCardType string `xorm:"INDEX"`

DateTime timeutil.TimeStamp `xorm:"INDEX"`
DateTime timeutil.TimeStamp `xorm:"INDEX DEFAULT 0"`
DateTimeUnix timeutil.TimeStamp `xorm:"INDEX DEFAULT 0"`
DayTime string `xorm:"INDEX"`
HourTime int `xorm:"INDEX"`
CardsUseDuration int
@@ -274,7 +275,6 @@ func GetCloudbrainByTime(beginTime int64, endTime int64) ([]*CloudbrainInfo, err
sess := x.NewSession()
defer sess.Close()
var cond = builder.NewCond()
sess.Exec("if ")
cond = cond.Or(
builder.And(builder.Gte{"cloudbrain.end_time": beginTime}, builder.Lte{"cloudbrain.start_time": beginTime}, builder.Gt{"cloudbrain.start_time": 0}),
)
@@ -284,11 +284,12 @@ func GetCloudbrainByTime(beginTime int64, endTime int64) ([]*CloudbrainInfo, err
cond = cond.Or(
builder.And(builder.Eq{"cloudbrain.status": string(JobRunning)}),
)
sess.OrderBy("cloudbrain.created_unix ASC")
sess.OrderBy("cloudbrain.id ASC")
cloudbrains := make([]*CloudbrainInfo, 0, 10)
if err := sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Find(&cloudbrains); err != nil {
log.Info("find error.")
log.Error("find error.")
return nil, err
}
return cloudbrains, nil
}
@@ -303,7 +304,8 @@ func GetSpecByAiCenterCodeAndType(aiCenterCode string, accCardType string) ([]*C
cloudbrainSpecs := make([]*CloudbrainSpec, 0, 10)
if err := sess.Table(&CloudbrainSpec{}).Where(cond).
Find(&cloudbrainSpecs); err != nil {
log.Info("find error.")
log.Error("find error.")
return nil, err
}
return cloudbrainSpecs, nil
}
@@ -328,7 +330,8 @@ func GetCanUseCardInfo() ([]*ResourceQueue, error) {
sess.OrderBy("resource_queue.cluster DESC, resource_queue.ai_center_code ASC")
ResourceQueues := make([]*ResourceQueue, 0, 10)
if err := sess.Table(&ResourceQueue{}).Find(&ResourceQueues); err != nil {
log.Info("find error.")
log.Error("find error.")
return nil, err
}
return ResourceQueues, nil
}
@@ -339,7 +342,7 @@ func GetCardDurationStatistics(opts *DurationStatisticOptions) ([]*CloudbrainDur
var cond = builder.NewCond()
if opts.BeginTime.Unix() > 0 && opts.EndTime.Unix() > 0 {
cond = cond.And(
builder.And(builder.Gte{"cloudbrain_duration_statistic.date_time": opts.BeginTime.Unix()}, builder.Lt{"cloudbrain_duration_statistic.date_time": opts.EndTime.Unix()}),
builder.And(builder.Gte{"cloudbrain_duration_statistic.date_time_unix": opts.BeginTime.Unix()}, builder.Lt{"cloudbrain_duration_statistic.date_time_unix": opts.EndTime.Unix()}),
)
}
if opts.AiCenterCode != "" {
@@ -350,7 +353,8 @@ func GetCardDurationStatistics(opts *DurationStatisticOptions) ([]*CloudbrainDur
CloudbrainDurationStatistics := make([]*CloudbrainDurationStatistic, 0, 10)
if err := sess.Table(&CloudbrainDurationStatistic{}).Where(cond).
Find(&CloudbrainDurationStatistics); err != nil {
log.Info("find error.")
log.Error("find error.")
return nil, err
}
return CloudbrainDurationStatistics, nil
}
@@ -358,10 +362,18 @@ func GetCardDurationStatistics(opts *DurationStatisticOptions) ([]*CloudbrainDur
func GetDurationRecordBeginTime() ([]*CloudbrainDurationStatistic, error) {
sess := xStatistic.NewSession()
defer sess.Close()
sess.OrderBy("cloudbrain_duration_statistic.date_time ASC limit 1")

var cond = builder.NewCond()

cond = cond.And(
builder.Gt{"cloudbrain_duration_statistic.date_time_unix": 0},
)

sess.OrderBy("cloudbrain_duration_statistic.date_time_unix ASC limit 1")
CloudbrainDurationStatistics := make([]*CloudbrainDurationStatistic, 0)
if err := sess.Table(&CloudbrainDurationStatistic{}).Find(&CloudbrainDurationStatistics); err != nil {
log.Info("find error.")
if err := sess.Table(&CloudbrainDurationStatistic{}).Where(cond).Find(&CloudbrainDurationStatistics); err != nil {
log.Error("find error.")
return nil, err
}
return CloudbrainDurationStatistics, nil
}
@@ -369,10 +381,16 @@ func GetDurationRecordBeginTime() ([]*CloudbrainDurationStatistic, error) {
func GetDurationRecordUpdateTime() ([]*CloudbrainDurationStatistic, error) {
sess := xStatistic.NewSession()
defer sess.Close()
sess.OrderBy("cloudbrain_duration_statistic.date_time DESC limit 1")
var cond = builder.NewCond()

cond = cond.And(
builder.Gt{"cloudbrain_duration_statistic.date_time_unix": 1577808000},
)
sess.OrderBy("cloudbrain_duration_statistic.date_time_unix DESC limit 1")
CloudbrainDurationStatistics := make([]*CloudbrainDurationStatistic, 0)
if err := sess.Table(&CloudbrainDurationStatistic{}).Find(&CloudbrainDurationStatistics); err != nil {
log.Info("find error.")
if err := sess.Table(&CloudbrainDurationStatistic{}).Where(cond).Find(&CloudbrainDurationStatistics); err != nil {
log.Error("find error.")
return nil, err
}
return CloudbrainDurationStatistics, nil
}
@@ -380,8 +398,8 @@ func GetDurationRecordUpdateTime() ([]*CloudbrainDurationStatistic, error) {
func DeleteCloudbrainDurationStatistic(beginTime timeutil.TimeStamp, endTime timeutil.TimeStamp) error {
sess := xStatistic.NewSession()
defer sess.Close()
if _, err := sess.Exec("DELETE FROM cloudbrain_duration_statistic WHERE cloudbrain_duration_statistic.date_time BETWEEN ? AND ?", beginTime, endTime); err != nil {
log.Info("DELETE cloudbrain_duration_statistic data error.")
if _, err := sess.Exec("DELETE FROM cloudbrain_duration_statistic WHERE cloudbrain_duration_statistic.date_time_unix BETWEEN ? AND ?", beginTime, endTime); err != nil {
log.Error("DELETE cloudbrain_duration_statistic data error.")
return err
}
return nil


+ 14
- 6
models/dataset.go View File

@@ -122,22 +122,22 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions)
for i := range datasets {
if attachment.DatasetID == datasets[i].ID {

if !attachment.IsPrivate{
if !attachment.IsPrivate {
datasets[i].Attachments = append(datasets[i].Attachments, attachment)
}else{
} else {
permission, ok := permissionMap[datasets[i].ID]
if !ok {

permission = false
datasets[i].Repo.GetOwner()
if !permission {
if datasets[i].Repo.OwnerID==opts.User.ID{
if datasets[i].Repo.OwnerID == opts.User.ID {
permission = true
}else{
} else {
isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID)
isInRepoTeam,_:=datasets[i].Repo.IsInRepoTeam(opts.User.ID)
isInRepoTeam, _ := datasets[i].Repo.IsInRepoTeam(opts.User.ID)

if isCollaborator ||isInRepoTeam {
if isCollaborator || isInRepoTeam {
permission = true
}
}
@@ -603,3 +603,11 @@ func UpdateDatasetCreateUser(ID int64, user *User) error {
}
return nil
}

func QueryDatasetGroupByTask() ([]map[string]interface{}, error) {
rows, err := x.QueryInterface("SELECT count(*) as total,task FROM public.dataset where task <>'' group by task order by total desc limit 7")
if err != nil {
return nil, err
}
return rows, nil
}

+ 5
- 1
models/repo_activity_custom.go View File

@@ -263,7 +263,11 @@ func GetAllUserKPIStats(startTime time.Time, endTime time.Time) (map[string]*git
log.Warn("get user kpi status err:"+repository.RepoPath(), err1.Error())
continue
}

// if repository.Name == "yolov5" {
// log.Info("repoName=" + repository.Name + " owner=" + repository.RepoPath())
// authorsOneRepoJson, _ := json.Marshal(authorsOneRepo)
// log.Info("authorsOneRepoJson=" + string(authorsOneRepoJson))
// }
for key, value := range authorsOneRepo {
if _, ok := authors[key]; !ok {
authors[key] = &git.UserKPIStats{


+ 9
- 0
models/resource_specification.go View File

@@ -298,6 +298,15 @@ func ResourceSpecOffShelf(id int64) (int64, error) {
return n, err
}

func GetResourceSpecificationByIds(ids []int64) ([]*Specification, error) {
r := make([]*Specification, 0)
err := x.In("resource_specification.id", ids).
Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id").
Find(&r)
return r, err

}

func GetResourceSpecification(r *ResourceSpecification) (*ResourceSpecification, error) {
has, err := x.Get(r)
if err != nil {


+ 1
- 1
models/user.go View File

@@ -346,7 +346,7 @@ func (u *User) DashboardLink() string {
if u.IsOrganization() {
return setting.AppSubURL + "/org/" + u.Name + "/dashboard/"
}
return setting.AppSubURL + "/"
return setting.AppSubURL + "/dashboard"
}

// HomeLink returns the user or organization home page link.


+ 21
- 0
models/user_mail.go View File

@@ -216,6 +216,27 @@ func (email *EmailAddress) updateActivation(e Engine, activate bool) error {
return updateUserCols(e, user, "rands")
}

// UpdateEmailAddress update an email address of given user.
func (email *EmailAddress) UpdateEmailAddress(newEmailAddress string) error {
return email.updateEmailAddress(x, newEmailAddress)
}
func (email *EmailAddress) updateEmailAddress(e Engine, newEmailAddress string) error {
user, err := getUserByID(e, email.UID)
if err != nil {
return err
}
if user.Rands, err = GetUserSalt(); err != nil {
return err
}
user.Email = newEmailAddress
user.AvatarEmail = newEmailAddress
email.Email = newEmailAddress
if _, err := e.ID(email.ID).Cols("email").Update(email); err != nil {
return err
}
return updateUserCols(e, user, "email", "avatar_email")
}

// DeleteEmailAddress deletes an email address of given user.
func DeleteEmailAddress(email *EmailAddress) (err error) {
var deleted int64


+ 4
- 0
modules/auth/user_form.go View File

@@ -88,6 +88,10 @@ type RegisterForm struct {
Agree bool
}

type UpdateEmailForm struct {
NewEmail string `binding:"Required;MaxSize(254)"`
}

// Validate valideates the fields
func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)


+ 20
- 4
modules/cloudbrain/cloudbrain.go View File

@@ -145,7 +145,7 @@ func isAdminOrImageCreater(ctx *context.Context, image *models.Image, err error)
func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {

var id = ctx.Params(":id")
job, err := models.GetCloudbrainByID(id)
job, err := GetCloudBrainByIdOrJobId(id)
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -161,7 +161,7 @@ func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {
func AdminOrJobCreaterRight(ctx *context.Context) {

var id = ctx.Params(":id")
job, err := models.GetCloudbrainByID(id)
job, err := GetCloudBrainByIdOrJobId(id)
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -177,7 +177,7 @@ func AdminOrJobCreaterRight(ctx *context.Context) {
func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {

var jobID = ctx.Params(":jobid")
job, err := models.GetCloudbrainByJobID(jobID)
job, err := GetCloudBrainByIdOrJobId(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -193,7 +193,7 @@ func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {
func AdminOrJobCreaterRightForTrain(ctx *context.Context) {

var jobID = ctx.Params(":jobid")
job, err := models.GetCloudbrainByJobID(jobID)
job, err := GetCloudBrainByIdOrJobId(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -652,3 +652,19 @@ func IsElementExist(s []string, str string) bool {
}
return false
}

func GetCloudBrainByIdOrJobId(id string) (*models.Cloudbrain,error) {
_, err := strconv.ParseInt(id, 10, 64)
var job *models.Cloudbrain
if err != nil {

job, err = models.GetCloudbrainByJobID(id)
} else {
job, err = models.GetCloudbrainByID(id)
if err!=nil{
job, err = models.GetCloudbrainByJobID(id)
}

}
return job,err
}

+ 1
- 1
modules/grampus/grampus.go View File

@@ -40,7 +40,7 @@ var (

SpecialPools *models.SpecialPools

CommandPrepareScriptGpu = ";mkdir -p output;mkdir -p code;mkdir -p dataset;mkdir -p pretrainmodel;echo \"start loading script\";wget -q https://git.openi.org.cn/OpenIOSSG/%s/archive/master.zip;" +
CommandPrepareScriptGpu = ";mkdir -p output;mkdir -p code;mkdir -p dataset;mkdir -p pretrainmodel;echo \"start loading script\";wget -q https://openi.pcl.ac.cn/OpenIOSSG/%s/archive/master.zip;" +
"echo \"finish loading script\";unzip -q master.zip;cd %s;chmod 777 downloader_for_obs uploader_for_npu downloader_for_minio uploader_for_gpu;"
)



+ 99
- 23
modules/modelarts/modelarts.go View File

@@ -1,12 +1,18 @@
package modelarts

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"path"
"strconv"
"strings"

"code.gitea.io/gitea/modules/cloudbrain"

"code.gitea.io/gitea/modules/modelarts_cd"

"code.gitea.io/gitea/models"
@@ -19,22 +25,11 @@ import (

const (
//notebook
autoStopDurationMs = 4 * 60 * 60 * 1000


//train-job
// ResourcePools = "{\"resource_pool\":[{\"id\":\"pool1328035d\", \"value\":\"专属资源池\"}]}"
// Engines = "{\"engine\":[{\"id\":1, \"value\":\"Ascend-Powered-Engine\"}]}"
// EngineVersions = "{\"version\":[{\"id\":118,\"value\":\"MindSpore-1.0.0-c75-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":119,\"value\":\"MindSpore-1.1.1-c76-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":120,\"value\":\"MindSpore-1.1.1-c76-tr5-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":117,\"value\":\"TF-1.15-c75-python3.7-euleros2.8-aarch64\"}" +
// "]}"
// TrainJobFlavorInfo = "{\"flavor\":[{\"code\":\"modelarts.bm.910.arm.public.2\",\"value\":\"Ascend : 2 * Ascend 910 CPU:48 核 512GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.8\",\"value\":\"Ascend : 8 * Ascend 910 CPU:192 核 2048GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.4\",\"value\":\"Ascend : 4 * Ascend 910 CPU:96 核 1024GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.1\",\"value\":\"Ascend : 1 * Ascend 910 CPU:24 核 256GiB\"}" +
// "]}"

storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000

CodePath = "/code/"
OutputPath = "/output/"
ResultPath = "/result/"
@@ -186,7 +181,7 @@ type Parameters struct {
}


func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error {
func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string,autoStopDurationInMs int64) (string, error) {
if poolInfos == nil {
json.Unmarshal([]byte(setting.PoolInfos), &poolInfos)
}
@@ -194,14 +189,14 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
imageName, err := GetNotebookImageName(imageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
return err
return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook2(models.CreateNotebook2Params{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
Duration: autoStopDurationMs,
Duration: autoStopDurationInMs,
ImageID: imageId,
PoolID: poolInfos.PoolInfo[0].PoolId,
Feature: models.NotebookFeature,
@@ -226,10 +221,10 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
})
if errTemp != nil {
log.Error("InsertCloudbrainTemp failed: %v", errTemp.Error())
return errTemp
return "", errTemp
}
}
return err
return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
@@ -244,6 +239,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
Uuid: uuid,
ComputeResource: models.NPUResource,
Image: imageName,
BootFile: bootFile,
Description: description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
@@ -252,12 +248,12 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc

err = models.CreateCloudbrain(task)
if err != nil {
return err
return "", err
}

stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
return nil
return jobResult.ID, nil
}

func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId string, err error) {
@@ -817,6 +813,11 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
if task.FlavorCode == "" {
task.FlavorCode = result.Flavor
}

if oldStatus != task.Status && task.Status == string(models.ModelArtsRunning) && task.BootFile != "" {
uploadNoteBookFile(task, result)

}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
@@ -827,6 +828,81 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
return nil
}

func uploadNoteBookFile(task *models.Cloudbrain, result *models.GetNotebook2Result) {
jupyterUrl := result.Url + "?token=" + result.Token

cookies, xsrf := getCookiesAndCsrf(jupyterUrl)
if xsrf == "" {
log.Error("browser jupyterUrl failed:%v", task.DisplayJobName)
} else {

codePath := setting.JobPath + task.JobName + cloudbrain.CodeMountPath
fileContents, err := ioutil.ReadFile(codePath + "/" + task.BootFile)
if err != nil {
log.Error("read jupyter file failed:%v", task.DisplayJobName, err)
}

base64Content := base64.StdEncoding.EncodeToString(fileContents)
client := getRestyClient()
uploadUrl := getJupyterBaseUrl(result.Url) + "api/contents/" + path.Base(task.BootFile)
res, err := client.R().
SetCookies(cookies).
SetHeader("X-XSRFToken", xsrf).
SetBody(map[string]interface{}{
"type": "file",
"format": "base64",
"name": path.Base(task.BootFile),
"path": path.Base(task.BootFile),
"content": base64Content}).
Put(uploadUrl)
if err != nil {
log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
} else if res.StatusCode() != http.StatusCreated {
log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
}

}

}

func getJupyterBaseUrl(url string) string {
jupyterUrlLength := len(url)
baseUrl := url[0 : jupyterUrlLength-len(path.Base(url))]
return baseUrl
}

func getCookiesAndCsrf(jupyterUrl string) ([]*http.Cookie, string) {
log.Info("jupyter url:"+jupyterUrl)
var cookies []*http.Cookie
const retryTimes = 10
for i := 0; i < retryTimes; i++ {
res, err := http.Get(jupyterUrl)
if err != nil {
log.Error("browser jupyterUrl failed.",err)
if i==retryTimes-1{
return cookies, ""
}

} else {
cookies = res.Cookies()
xsrf := ""
for _, cookie := range cookies {
if cookie.Name == "_xsrf" {
xsrf = cookie.Value
break
}

}
if xsrf != "" {
return cookies, xsrf
}

}
}
return cookies, ""

}

func SyncTempStatusJob() {
jobs, err := models.GetCloudBrainTempJobs()
if err != nil {


+ 1
- 1
modules/modelarts/resty.go View File

@@ -280,7 +280,7 @@ sendjob:
SetHeader("Content-Type", "application/json").
SetAuthToken(TOKEN).
SetResult(&result).
Post(HOST + "/v1/" + setting.ProjectID + urlNotebook2 + "/" + jobID + "/" + param.Action + "?duration=" + strconv.Itoa(autoStopDurationMs))
Post(HOST + "/v1/" + setting.ProjectID + urlNotebook2 + "/" + jobID + "/" + param.Action + "?duration=" + strconv.Itoa(AutoStopDurationMs))

if err != nil {
return &result, fmt.Errorf("resty ManageNotebook2: %v", err)


+ 8
- 45
modules/modelarts_cd/modelarts.go View File

@@ -88,18 +88,18 @@ type Parameters struct {
} `json:"parameter"`
}

func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error {
func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string,autoStopDurationInMs int64) (string, error) {
imageName, err := GetNotebookImageName(imageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
return err
return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook(models.CreateNotebookWithoutPoolParams{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
Duration: autoStopDurationMs,
Duration: autoStopDurationInMs,
ImageID: imageId,
Feature: models.NotebookFeature,
Volume: models.VolumeReq{
@@ -123,10 +123,10 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
})
if errTemp != nil {
log.Error("InsertCloudbrainTemp failed: %v", errTemp.Error())
return errTemp
return "", errTemp
}
}
return err
return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
@@ -145,16 +145,17 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
BootFile: bootFile,
}

err = models.CreateCloudbrain(task)
if err != nil {
return err
return "", err
}

stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
return nil
return jobResult.ID, nil
}

func GetNotebookImageName(imageId string) (string, error) {
@@ -175,41 +176,3 @@ func GetNotebookImageName(imageId string) (string, error) {

return imageName, nil
}

/*
func HandleNotebookInfo(task *models.Cloudbrain) error {

result, err := GetNotebook(task.JobID)
if err != nil {
log.Error("GetNotebook2(%s) failed:%v", task.DisplayJobName, err)
return err
}

if result != nil {
oldStatus := task.Status
task.Status = result.Status
if task.StartTime == 0 && result.Lease.UpdateTime > 0 {
task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000)
}
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) {
task.EndTime = timeutil.TimeStampNow()
}
task.CorrectCreateUnix()
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
if task.FlavorCode == "" {
task.FlavorCode = result.Flavor
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
return err
}
}

return nil
}

*/

+ 1
- 1
modules/repository/hooks.go View File

@@ -36,7 +36,7 @@ func getHookTemplates() (hookNames, hookTpls, giteaHookTpls, sizeLimitTpls []str
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
}
sizeLimitTpls = []string{
fmt.Sprintf("#!/usr/bin/env %s\n\n\nset -o pipefail\n\nreadonly DEFAULT_FILE_MAXSIZE_MB=\"30\" \nreadonly CONFIG_NAME=\"hooks.maxfilesize\"\nreadonly NULLSHA=\"0000000000000000000000000000000000000000\"\nreadonly EXIT_SUCCESS=0\nreadonly EXIT_FAILURE=1\nreadonly DEFAULT_REPO_MAXSIZE_MB=\"1024\" \nreadonly CHECK_FLAG_ON=1\n\n\nstatus=\"$EXIT_SUCCESS\"\n\n# skip this hook entirely if shell check is not open\ncheck_flag=${PUSH_SIZE_CHECK_FLAG}\nif [[ $check_flag != $CHECK_FLAG_ON ]]; then\nexit $EXIT_SUCCESS\nfi\n\n\n#######################################\n# check the file max size limit\n#######################################\n\n# get maximum filesize (from repository-specific config)\nmaxsize_mb=\"${REPO_MAX_FILE_SIZE}\"\n\nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\necho \"failed to get ${CONFIG_NAME} from config\"\nexit \"$EXIT_FAILURE\"\nfi\n\npush_size=\"0\"\n# read lines from stdin (format: \"<oldref> <newref> <refname>\\n\")\nwhile read oldref newref refname; do\n# skip branch deletions\nif [[ \"$newref\" == \"$NULLSHA\" ]]; then\n continue\nfi\n\n# find large objects\n# check all objects from $oldref (possible $NULLSHA) to $newref, but\n# skip all objects that have already been accepted (i.e. are referenced by\n# another branch or tag).\n\nnew_branch_flag=0\nif [[ \"$oldref\" == \"$NULLSHA\" ]]; then\n target=\"$newref\"\n new_branch_flag=1\n echo \"You are creating a new remote branch,openI will check all files in commit history to find oversize files\"\nelse\n target=\"${oldref}..${newref}\"\nfi\nmaxsize=`expr $maxsize_mb \\* 1048576` \n\n# find objects in this push_size\n# print like:\n# 08da8e2ab9ae4095bf94dd71ac913132b880b463 commit 214\n# 43e993b768ede5740e8c65de2ed6edec25053ea1 tree 185\n# 4476971d76569039df7569af1b8d03c288f6b193 blob 20167318 b0417e6593a1.zip\nfiles=\"$(git rev-list --objects \"$target\" | \\\n git cat-file $'--batch-check=%%(objectname) %%(objecttype) %%(objectsize) %%(rest)' | \\\n awk -F ' ' -v maxbytes=\"$maxsize\" 'BEGIN {totalIn=0} {if( $3 > maxbytes && $2 == \"blob\") { totalIn+=$3; print $4} else { totalIn+=$3}} END { printf (\"totalIn=\\t%%s\",totalIn)}' )\"\n \nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\n echo \"failed to check for large files in ref ${refname}\"\n continue\nfi\n\nIFS=$'\\n'\n# rewrite IFS to seperate line in $files\nfor file in $files; do\n # if don't unset IFS,temp_array=(${file}) will get error answer\n \n if [[ ${file} == totalIn=* ]]; then\n\tIFS=$'\\t'\n\ttemp_array=(${file})\n\tpush_size=${temp_array[1]}\n\tcontinue\n fi\n\tunset IFS\n if [[ \"$status\" == $EXIT_SUCCESS ]]; then\n\t\techo -e \"Error: Your push was rejected because it contains files larger than $(numfmt --to=iec \"$maxsize_mb\") Mb\"\n\t\techo \"help document -- https://git.openi.org.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n\t\techo \"oversize files:\"\n\t\tstatus=\"$EXIT_FAILURE\"\t\n fi\n echo -e \"\\033[31m- ${file}\\033[0m \"\ndone\n\nif [[ \"$status\" != $EXIT_SUCCESS ]]; then\n\texit \"$status\"\nfi\n\ndone\n\n#######################################\n# check the repo max size limit\n#######################################\nif [[ $push_size -eq \"0\" ]]; then\n\texit $EXIT_SUCCESS\nfi\n\n# if create new branch or tag,use count-objects -v to get pack size\nif [[ $new_branch_flag -eq 1 ]]; then\n size_kb=`git count-objects -v | grep 'size-pack' | sed 's/.*\\(size-pack:\\).//'`\n size_pack_kb=`git count-objects -v | grep 'size:' | sed 's/.*\\(size:\\).//'`\n\ttotal_kb=`expr $size_kb + $size_pack_kb`\n\tlet push_size=$total_kb*1024\nfi\n\nsizelimit_mb=\"${REPO_MAX_SIZE}\"\nlet sizelimit_b=$sizelimit_mb*1024*1024\n\n# repo size at here means the size of repo directory in server \nreposize_b=${REPO_CURRENT_SIZE}\n\ntotal=`expr $push_size + $reposize_b`\n\nif [ $total -gt $sizelimit_b ]; then\n echo \"Error: Your push was rejected because the repository size is large than $sizelimit_mb Mb\"\n echo \"see the help document--https://git.openi.org.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n exit $EXIT_FAILURE\nfi\n\n\nexit $EXIT_SUCCESS", setting.ScriptType),
fmt.Sprintf("#!/usr/bin/env %s\n\n\nset -o pipefail\n\nreadonly DEFAULT_FILE_MAXSIZE_MB=\"30\" \nreadonly CONFIG_NAME=\"hooks.maxfilesize\"\nreadonly NULLSHA=\"0000000000000000000000000000000000000000\"\nreadonly EXIT_SUCCESS=0\nreadonly EXIT_FAILURE=1\nreadonly DEFAULT_REPO_MAXSIZE_MB=\"1024\" \nreadonly CHECK_FLAG_ON=1\n\n\nstatus=\"$EXIT_SUCCESS\"\n\n# skip this hook entirely if shell check is not open\ncheck_flag=${PUSH_SIZE_CHECK_FLAG}\nif [[ $check_flag != $CHECK_FLAG_ON ]]; then\nexit $EXIT_SUCCESS\nfi\n\n\n#######################################\n# check the file max size limit\n#######################################\n\n# get maximum filesize (from repository-specific config)\nmaxsize_mb=\"${REPO_MAX_FILE_SIZE}\"\n\nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\necho \"failed to get ${CONFIG_NAME} from config\"\nexit \"$EXIT_FAILURE\"\nfi\n\npush_size=\"0\"\n# read lines from stdin (format: \"<oldref> <newref> <refname>\\n\")\nwhile read oldref newref refname; do\n# skip branch deletions\nif [[ \"$newref\" == \"$NULLSHA\" ]]; then\n continue\nfi\n\n# find large objects\n# check all objects from $oldref (possible $NULLSHA) to $newref, but\n# skip all objects that have already been accepted (i.e. are referenced by\n# another branch or tag).\n\nnew_branch_flag=0\nif [[ \"$oldref\" == \"$NULLSHA\" ]]; then\n target=\"$newref\"\n new_branch_flag=1\n echo \"You are creating a new remote branch,openI will check all files in commit history to find oversize files\"\nelse\n target=\"${oldref}..${newref}\"\nfi\nmaxsize=`expr $maxsize_mb \\* 1048576` \n\n# find objects in this push_size\n# print like:\n# 08da8e2ab9ae4095bf94dd71ac913132b880b463 commit 214\n# 43e993b768ede5740e8c65de2ed6edec25053ea1 tree 185\n# 4476971d76569039df7569af1b8d03c288f6b193 blob 20167318 b0417e6593a1.zip\nfiles=\"$(git rev-list --objects \"$target\" | \\\n git cat-file $'--batch-check=%%(objectname) %%(objecttype) %%(objectsize) %%(rest)' | \\\n awk -F ' ' -v maxbytes=\"$maxsize\" 'BEGIN {totalIn=0} {if( $3 > maxbytes && $2 == \"blob\") { totalIn+=$3; print $4} else { totalIn+=$3}} END { printf (\"totalIn=\\t%%s\",totalIn)}' )\"\n \nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\n echo \"failed to check for large files in ref ${refname}\"\n continue\nfi\n\nIFS=$'\\n'\n# rewrite IFS to seperate line in $files\nfor file in $files; do\n # if don't unset IFS,temp_array=(${file}) will get error answer\n \n if [[ ${file} == totalIn=* ]]; then\n\tIFS=$'\\t'\n\ttemp_array=(${file})\n\tpush_size=${temp_array[1]}\n\tcontinue\n fi\n\tunset IFS\n if [[ \"$status\" == $EXIT_SUCCESS ]]; then\n\t\techo -e \"Error: Your push was rejected because it contains files larger than $(numfmt --to=iec \"$maxsize_mb\") Mb\"\n\t\techo \"help document -- https://openi.pcl.ac.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n\t\techo \"oversize files:\"\n\t\tstatus=\"$EXIT_FAILURE\"\t\n fi\n echo -e \"\\033[31m- ${file}\\033[0m \"\ndone\n\nif [[ \"$status\" != $EXIT_SUCCESS ]]; then\n\texit \"$status\"\nfi\n\ndone\n\n#######################################\n# check the repo max size limit\n#######################################\nif [[ $push_size -eq \"0\" ]]; then\n\texit $EXIT_SUCCESS\nfi\n\n# if create new branch or tag,use count-objects -v to get pack size\nif [[ $new_branch_flag -eq 1 ]]; then\n size_kb=`git count-objects -v | grep 'size-pack' | sed 's/.*\\(size-pack:\\).//'`\n size_pack_kb=`git count-objects -v | grep 'size:' | sed 's/.*\\(size:\\).//'`\n\ttotal_kb=`expr $size_kb + $size_pack_kb`\n\tlet push_size=$total_kb*1024\nfi\n\nsizelimit_mb=\"${REPO_MAX_SIZE}\"\nlet sizelimit_b=$sizelimit_mb*1024*1024\n\n# repo size at here means the size of repo directory in server \nreposize_b=${REPO_CURRENT_SIZE}\n\ntotal=`expr $push_size + $reposize_b`\n\nif [ $total -gt $sizelimit_b ]; then\n echo \"Error: Your push was rejected because the repository size is large than $sizelimit_mb Mb\"\n echo \"see the help document--https://openi.pcl.ac.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n exit $EXIT_FAILURE\nfi\n\n\nexit $EXIT_SUCCESS", setting.ScriptType),
fmt.Sprintf(""),
fmt.Sprintf(""),
}


+ 36
- 2
modules/setting/setting.go View File

@@ -584,6 +584,8 @@ var (
TrainJobFLAVORINFOS string
ModelArtsSpecialPools string
ModelArtsMultiNode string
//kanban
IsCloudbrainTimingEnabled bool

// modelarts-cd config
ModelartsCD = struct {
@@ -715,6 +717,21 @@ var (
TeamName string
}{}

FileNoteBook = struct {
ProjectName string
ImageGPU string
SpecIdGPU int64
SpecIdCPU int64
ImageIdNPU string
SpecIdNPU int64
ImageIdNPUCD string
SpecIdNPUCD int64
ImageCPUDescription string
ImageGPUDescription string
ImageNPUDescription string
ImageNPUCDDescription string
}{}

ModelConvert = struct {
GPU_PYTORCH_IMAGE string
GpuQueue string
@@ -1429,7 +1446,7 @@ func NewContext() {
DecompressOBSTaskName = sec.Key("DecompressOBSTaskName").MustString("LabelDecompressOBSQueue")

sec = Cfg.Section("homepage")
RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/")
RecommentRepoAddr = sec.Key("Address").MustString("https://openi.pcl.ac.cn/OpenIOSSG/promote/raw/branch/master/")
ESSearchURL = sec.Key("ESSearchURL").MustString("http://192.168.207.94:9200")
INDEXPOSTFIX = sec.Key("INDEXPOSTFIX").MustString("")

@@ -1580,6 +1597,23 @@ func NewContext() {
Course.OrgName = sec.Key("org_name").MustString("")
Course.TeamName = sec.Key("team_name").MustString("")

sec = Cfg.Section("file_notebook")
FileNoteBook.ProjectName = sec.Key("project_name").MustString("openi-notebook")
FileNoteBook.ImageIdNPU = sec.Key("imageid_npu").MustString("")
FileNoteBook.ImageGPU = sec.Key("image_gpu").MustString("")
FileNoteBook.SpecIdCPU = sec.Key("specid_cpu").MustInt64(-1)
FileNoteBook.SpecIdGPU = sec.Key("specid_gpu").MustInt64(-1)
FileNoteBook.SpecIdNPU = sec.Key("specid_npu").MustInt64(-1)
FileNoteBook.ImageIdNPUCD = sec.Key("imageid_npu_cd").MustString("")
FileNoteBook.SpecIdNPUCD = sec.Key("specid_npu_cd").MustInt64(-1)
FileNoteBook.ImageCPUDescription = sec.Key("image_cpu_desc").MustString("")
FileNoteBook.ImageGPUDescription = sec.Key("image_gpu_desc").MustString("")
FileNoteBook.ImageNPUDescription = sec.Key("image_npu_desc").MustString("")
FileNoteBook.ImageNPUCDDescription = sec.Key("image_npu_cd_desc").MustString("")

sec = Cfg.Section("kanban")
IsCloudbrainTimingEnabled = sec.Key("ENABLED").MustBool(false)

getGrampusConfig()
getModelartsCDConfig()
getModelConvertConfig()
@@ -1612,7 +1646,7 @@ func getModelConvertConfig() {
ModelConvert.MindsporeBootFile = sec.Key("MindsporeBootFile").MustString("convert_mindspore.py")
ModelConvert.TensorFlowNpuBootFile = sec.Key("TensorFlowNpuBootFile").MustString("convert_tensorflow.py")
ModelConvert.TensorFlowGpuBootFile = sec.Key("TensorFlowGpuBootFile").MustString("convert_tensorflow_gpu.py")
ModelConvert.ConvertRepoPath = sec.Key("ConvertRepoPath").MustString("https://git.openi.org.cn/zouap/npu_test")
ModelConvert.ConvertRepoPath = sec.Key("ConvertRepoPath").MustString("https://openi.pcl.ac.cn/zouap/npu_test")
ModelConvert.GPU_Resource_Specs_ID = sec.Key("GPU_Resource_Specs_ID").MustInt(1)
ModelConvert.NPU_FlavorCode = sec.Key("NPU_FlavorCode").MustString("modelarts.bm.910.arm.public.1")
ModelConvert.NPU_PoolID = sec.Key("NPU_PoolID").MustString("pool7908321a")


+ 8
- 0
modules/structs/cloudbrain.go View File

@@ -41,6 +41,14 @@ type CreateTrainJobOption struct {
SpecId int64 `json:"spec_id" binding:"Required"`
}

type CreateFileNotebookJobOption struct {
Type int `json:"type"` //0 CPU 1 GPU 2 NPU
File string `json:"file" binding:"Required"`
BranchName string `json:"branch_name" binding:"Required"`
OwnerName string `json:"owner_name" binding:"Required"`
ProjectName string `json:"project_name" binding:"Required"`
}

type Cloudbrain struct {
ID int64 `json:"id"`
JobID string `json:"job_id"`


+ 3
- 0
modules/templates/helper.go View File

@@ -153,6 +153,9 @@ func NewFuncMap() []template.FuncMap {
"EscapePound": func(str string) string {
return strings.NewReplacer("%", "%25", "#", "%23", " ", "%20", "?", "%3F").Replace(str)
},
"IpynbBool":func(str string) bool{
return strings.Contains(str, ".ipynb")
},
"nl2br": func(text string) template.HTML {
return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))
},


+ 32
- 8
options/locale/locale_en-US.ini View File

@@ -24,6 +24,7 @@ enable_javascript = This website works better with JavaScript.
toc = Table of Contents
return=Back OpenI
calculation_points = Calculation Points
notice_announcement = Notice Announcement

username = Username
email = Email Address
@@ -236,7 +237,7 @@ page_title=Explore Better AI
page_small_title=OpenI AI Development Cooperation Platform
page_description=The one-stop collaborative development environment for AI field provides AI development pipeline integrating code development, data management, model debugging, reasoning and evaluation
page_use=Use Now
page_only_dynamic=Only show the dynamics of open source projects
page_only_dynamic=The dynamics of open source projects
page_recommend_org=Recommended Organizations
page_recommend_org_desc=These excellent organizations are using the OpenI AI Collaboration Platform for collaborative development of projects. To show your organization here,
page_recommend_org_commit=Click here to submit.
@@ -260,7 +261,7 @@ page_dev_env_desc3_title=Once Configuration, Multiple Reuse
page_dev_env_desc3_desc=Provide execution environment sharing, Once Configuration, Multiple Reuse. Lower the threshold of model development, and avoid spending repetitive time configuring complex environments.
page_dev_yunlao=OpenI AI Collaboration Platform
page_dev_yunlao_desc1=OpenI AI collaboration platform has cooperated with Pengcheng cloud brain and China computing power network (C²NET) can be used to complete AI development tasks by using the rich computing resources of Pengcheng cloud brain and China computing network.
page_dev_yunlao_desc2=Pengcheng CloudBrain's existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure consists of GPU servers equipped with NVIDIA Tesla V100 and A100, and Atlas 900 AI clusters equipped with Kunpeng and shengteng processors.
page_dev_yunlao_desc2=Pengcheng CloudBrain is existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure consists of GPU servers equipped with NVIDIA Tesla V100 and A100, and Atlas 900 AI clusters equipped with Kunpeng and shengteng processors.
page_dev_yunlao_desc3=China computing power network (C²NET) phase I can realize high-speed network interconnection between different artificial intelligence computing centers, and realize reasonable scheduling of computing power and flexible allocation of resources. At present, 11 intelligent computing centers have been connected, and the total scale of computing power is 1924p OPS@FP16. OpenI AI collaboration platform has been connected to Pengcheng Cloud Computing Institute, Chengdu Intelligent Computing Center, Zhongyuan Intelligent Computing Center, Hefei brain and other nodes.
page_dev_yunlao_desc4=Developers can freely select the corresponding computing resources according to the use needs, and can test the adaptability, performance, stability, etc. of the model in different hardware environments.
page_dev_yunlao_desc5=If your model requires more computing resources, you can also apply for it separately.
@@ -283,6 +284,7 @@ search_ge=
wecome_AI_plt = Welcome to OpenI AI Collaboration Platform!
explore_AI = Explore better AI, come here to find more interesting
datasets = Datasets
datasets_descr = Open source dataset base, seamlessly integrated with your project. View all
repositories = Repositories
use_plt__fuction = To use the AI collaboration functions provided by this platform, such as: hosting code, sharing data, debugging algorithms or training models, start with
provide_resoure = Computing resources of CPU/GPU/NPU are provided freely for various types of AI tasks.
@@ -290,6 +292,12 @@ activity = Activity
no_events = There are no events related
or_t = or
powerdby=Powered_by Pengcheng CloudBrain、China Computing NET(C²NET)、
experience_officer=Experience Officer
openi_experience_officer_plan=OpenI AI experience officer growth plan
more_benefits=, More benefits
org_see=See
more_notice=More notices
vedio_detail=Video details

[explore]
repos = Repositories
@@ -345,8 +353,10 @@ account_activated = Account has been activated
prohibit_login = Sign In Prohibited
prohibit_login_desc = Your account is prohibited to sign in, please contact your site administrator.
resent_limit_prompt = You have already requested an activation email recently. Please wait 3 minutes and try again.
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
resend_mail = Click here to resend your activation email
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>).
has_unconfirmed_mail_resend = If you did not receive the activation email, or need to resend it, please click the "Resend your activation email" button below.
has_unconfirmed_mail_change =If you need to change your email address before sending an activation email, please click the "Change email" button below.
resend_mail = Resend your activation email
email_not_associate = The email address is not associated with any account.
email_not_main=The email address is wrong, please input your primary email address.
email_not_right=The email address is not associated with any account, please input the right email address.
@@ -383,15 +393,19 @@ openid_register_desc = The chosen OpenID URI is unknown. Associate it with a new
openid_signin_desc = Enter your OpenID URI. For example: https://anne.me, bob.openid.org.cn or gnusocial.net/carry.
disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator.
email_domain_blacklisted = You cannot register with this kind of email address.
email_domain_blacklisted_change = This type of email address is not currently supported.
authorize_application = Authorize Application
authorize_redirect_notice = You will be redirected to %s if you authorize this application.
authorize_application_created_by = This application was created by %s.
authorize_application_description = If you grant the access, it will be able to access and write to all your account information, including private repos and organisations.
authorize_title = Authorize "%s" to access your account?
authorization_failed = Authorization failed
authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you've tried to authorize.
authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you have tried to authorize.
disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator.
sspi_auth_failed = SSPI authentication failed
change_email = Change email
change_email_address = Change email address
new_email_address = New email address
[phone]
format_err=The format of phone number is wrong.
query_err=Fail to query phone number, please try again later.
@@ -1007,6 +1021,8 @@ readme = README
readme_helper = Select a README file template.
auto_init = Initialize Repository (Adds .gitignore, License and README)
create_repo = Create Repository
failed_to_create_repo=Failed to create repository, please try again later.
failed_to_create_notebook_repo=Failed to create %s repository, please check whether you have the same name project, if yes please update or delete it first.
create_course = Publish Course
failed_to_create_course=Failed to publish course, please try again later.
default_branch = Default Branch
@@ -1041,6 +1057,10 @@ model_experience = Model Experience
model_noright=You have no right to do the operation.
model_rename=Duplicate model name, please modify model name.

notebook_file_not_exist=Notebook file does not exist.
notebook_select_wrong=Please select a Notebook(.ipynb) file first.
notebook_file_no_right=You have no right to access the Notebook(.ipynb) file.

date=Date
repo_add=Project Increment
repo_total=Project Total
@@ -1217,10 +1237,10 @@ cloudbrain.benchmark.evaluate_child_type=Child Type
cloudbrain.benchmark.evaluate_mirror=Mirror
cloudbrain.benchmark.evaluate_train=Train Script
cloudbrain.benchmark.evaluate_test=Test Script
cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"Target detection","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"Target re-identification","second":[{"id":1,"value":"Vehicle re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"Image-based person re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"Multi-target tracking","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=detection","first":"Target detection","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=reid","first":"Target re-identification","second":[{"id":1,"value":"Vehicle re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"Image-based person re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=tracking","first":"Multi-target tracking","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.morethanonejob=You already have a running or waiting task, create it after that task is over.
cloudbrain.morethanonejob1=You have created an <span style="color:rgba(242, 113, 28, 1);"> equivalent task </span> that is waiting or running, please wait for the task to finish before creating it.
cloudbrain.morethanonejob2=You can view all your Cloud Brain tasks in <a href="/cloudbrains" target="_blank"> Home > Cloudbrain Task </a>.
cloudbrain.morethanonejob2=You can view all your Cloud Brain tasks in <a href="/cloudbrains" target="_blank"> Home > Cloudbrain Task </a>.

modelarts.infer_job_model = Model
modelarts.infer_job_model_file = Model File
@@ -1243,7 +1263,7 @@ model_Evaluation_not_created = Model evaluation has not been created
repo_not_initialized = Code version: You have not initialized the code repository, please <a href="%s"> initialized </a> first ;
debug_task_running_limit =Running time: no more than 4 hours, it will automatically stop if it exceeds 4 hours;
dataset_desc = Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU.And dataset also needs to be uploaded to the corresponding environment;
platform_instructions = Instructions for use: You can refer to the <a href="https://git.openi.org.cn/zeizei/OpenI_Learning"> OpenI_Learning </a> course of Qizhi AI collaboration platform.
platform_instructions = Instructions for use: You can refer to the <a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning"> OpenI_Learning </a> course of Qizhi AI collaboration platform.
platform_instructions1 = Instructions for use: You can refer to the
platform_instructions2 = OpenI_Learning
platform_instructions3 = course of Openi AI collaboration platform.
@@ -1440,6 +1460,7 @@ blame = Blame
normal_view = Normal View
line = line
lines = lines
notebook_open = Open in Notebook

editor.new_file = New File
editor.upload_file = Upload File
@@ -3193,6 +3214,9 @@ foot.copyright= Copyright: New Generation Artificial Intelligence Open Source Op
Platform_Tutorial = Tutorial
foot.advice_feedback = Feedback
resource_description = Resource Note
foot.openi_subscription_number = OpenI subscription number
foot.user_communication_group = User communication group

[cloudbrain]
all_resource_cluster=All Cluster
all_ai_center=All Computing NET


+ 29
- 7
options/locale/locale_zh-CN.ini View File

@@ -24,6 +24,7 @@ enable_javascript=使用 JavaScript能使本网站更好的工作。
toc=目录
return=返回OpenI
calculation_points=算力积分
notice_announcement=通知公告

username=用户名
email=电子邮件地址
@@ -238,7 +239,7 @@ page_title=探索更好的AI
page_small_title=启智AI协作平台
page_description=面向AI领域的一站式协同开发环境,提供集代码开发、数据管理、模型调试、推理和评测为一体的AI开发流水线
page_use=立即使用
page_only_dynamic=仅展示开源项目动态
page_only_dynamic=社区开源项目动态
page_recommend_org=推荐组织
page_recommend_org_desc=这些优秀的组织正在使用启智AI开发协作平台;你的组织也想展示到这里,
page_recommend_org_commit=点此提交
@@ -285,6 +286,7 @@ search_ge=个
wecome_AI_plt=欢迎来到启智AI协作平台!
explore_AI = 探索更好的AI,来这里发现更有意思的
datasets = 数据集
datasets_descr=开源数据集大本营,同你的项目无缝集成。查看所有
repositories = 项目
use_plt__fuction = 使用本平台提供的AI协作功能,如:托管代码、共享数据、调试算法或训练模型,请先
provide_resoure = 平台目前提供CPU、GPU、NPU的普惠算力资源,可进行多种类型的AI任务。
@@ -293,7 +295,12 @@ activity = 活动
no_events = 还没有与您相关的活动
or_t = 或
powerdby=Powered_by 鹏城实验室云脑、中国算力网(C²NET)、

experience_officer=体验官
openi_experience_officer_plan=启智社区体验官成长计划
more_benefits=,超多福利大放送
org_see=。查看
more_notice=更多通知
vedio_detail=详细介绍视频

[explore]
repos=项目
@@ -349,8 +356,10 @@ account_activated=帐户已激活
prohibit_login=禁止登录
prohibit_login_desc=您的帐户被禁止登录,请与网站管理员联系。
resent_limit_prompt=您请求发送激活邮件过于频繁,请等待 3 分钟后再试!
has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。
resend_mail=单击此处重新发送确认邮件
has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 <b>%s</b> 但未被确认的邮件。
has_unconfirmed_mail_resend=如果您未收到激活邮件,或需要重新发送,请单击下方的 "重新发送确认邮件 " 按钮。
has_unconfirmed_mail_change=如果您需要更改邮箱后再发送激活邮件,请单击下方的 "修改邮箱" 按钮。
resend_mail=重新发送确认邮件
email_not_associate=您输入的邮箱地址未被关联到任何帐号!
email_not_main=电子邮箱地址不正确,请输入您设置的主要邮箱地址。
email_not_right=您输入了不存在的邮箱地址,请输入正确的邮箱地址。
@@ -387,6 +396,7 @@ openid_register_desc=所选的 OpenID URI 未知。在这里关联一个新帐
openid_signin_desc=输入您的 OpenID URI。例如: https://anne.me、bob.openid.org.cn 或 gnusocial.net/carry。
disable_forgot_password_mail=帐户恢复功能已被禁用。请与网站管理员联系。
email_domain_blacklisted=暂不支持此类电子邮件地址注册。
email_domain_blacklisted_change=暂不支持此类电子邮件地址。
authorize_application=应用授权
authorize_redirect_notice=如果您授权此应用,您将会被重定向到 %s。
authorize_application_created_by=此应用由%s创建。
@@ -396,6 +406,9 @@ authorization_failed=授权失败
authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。
disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator.
sspi_auth_failed=SSPI 认证失败
change_email=修改邮箱
change_email_address=修改邮箱地址
new_email_address=新邮箱地址
[phone]
format_err=手机号格式错误。
query_err=查询手机号失败,请稍后再试。
@@ -1013,6 +1026,8 @@ readme=自述
readme_helper=选择自述文件模板。
auto_init=初始化存储库 (添加. gitignore、许可证和自述文件)
create_repo=创建项目
failed_to_create_repo=创建项目失败,请稍后再试。
failed_to_create_notebook_repo=创建项目%s失败,请检查您是否有同名的项目,如果有请先手工修改或删除后重试。
create_course=发布课程
failed_to_create_course=发布课程失败,请稍后再试。
default_branch=默认分支
@@ -1041,6 +1056,9 @@ model_experience = 模型体验
model_noright=您没有操作权限。
model_rename=模型名称重复,请修改模型名称

notebook_file_not_exist=Notebook文件不存在。
notebook_select_wrong=请先选择Notebook(.ipynb)文件。
notebook_file_no_right=您没有这个Notebook文件的读权限。

date=日期
repo_add=新增项目
@@ -1230,8 +1248,8 @@ cloudbrain.benchmark.evaluate_child_type=子类型
cloudbrain.benchmark.evaluate_mirror=镜像
cloudbrain.benchmark.evaluate_train=训练程序
cloudbrain.benchmark.evaluate_test=测试程序
cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.benchmark.model.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.benchmark.model.types={"type":[{"id":1,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://openi.pcl.ac.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]}
cloudbrain.morethanonejob=您已经创建了一个正在等待或运行中的同类任务,请等待任务结束再创建。
cloudbrain.morethanonejob1=您已经有 <span style="color:rgba(242, 113, 28, 1);">同类任务</span> 正在等待或运行中,请等待任务结束再创建;
cloudbrain.morethanonejob2=可以在 “<a href="/cloudbrains" target="_blank" >个人中心 > 云脑任务</a>” 查看您所有的云脑任务。
@@ -1257,7 +1275,7 @@ model_Evaluation_not_created = 未创建过评测任务
repo_not_initialized = 代码版本:您还没有初始化代码仓库,请先<a href=%s>创建代码版本</a>;
debug_task_running_limit = 运行时长:最长不超过4个小时,超过4个小时将自动停止;
dataset_desc = 数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境;
platform_instructions = 使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程</a>。
platform_instructions = 使用说明:可以参考启智AI协作平台<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">小白训练营课程</a>。
platform_instructions1 = 使用说明:可以参考启智AI协作平台
platform_instructions2 = 小白训练营课程
platform_instructions3 = 。
@@ -1459,6 +1477,8 @@ normal_view=普通视图
line=行
lines=行

notebook_open = 在Notebook中打开

editor.new_file=新建文件
editor.upload_file=上传文件
editor.edit_file=编辑文件
@@ -3211,6 +3231,8 @@ foot.copyright= 版权所有:新一代人工智能开源开放平台(OpenI
Platform_Tutorial=新手指引
foot.advice_feedback = 意见反馈
resource_description = 资源说明
foot.openi_subscription_number = 启智社区订阅号
foot.user_communication_group = 用户交流群

[cloudbrain]
all_resource_cluster=全部集群


+ 374
- 56
public/home/home.js View File

@@ -9,16 +9,20 @@ if(isEmpty(token)){

var swiperNewMessage = new Swiper(".newslist", {
direction: "vertical",
slidesPerView: 9,
slidesPerView: 6,
loop: true,
spaceBetween: 8,
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
});
var swiperEvent = new Swiper(".event-list", {
slidesPerView: 3,
spaceBetween: 30,

var swiperRepo = new Swiper(".homepro-list", {
slidesPerView: 1,
// slidesPerColumn: 2,
// slidesPerColumnFill:'row',
spaceBetween: 20,
pagination: {
el: ".swiper-pagination",
clickable: true,
@@ -27,49 +31,130 @@ var swiperEvent = new Swiper(".event-list", {
delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: 2,
},
1024: {
slidesPerView: 2,
},
1200: {
slidesPerView: 3,
},
1440: {
slidesPerView: 3,
},
1840: {
slidesPerView: 3,
},
1920: {
slidesPerView: 3,
},
},
});
var swiperRepo = new Swiper(".homepro-list", {

var swiperOrg = new Swiper(".homeorg-list", {
slidesPerView: 1,
slidesPerColumn: 2,
slidesPerColumnFill:'row',
spaceBetween: 30,
spaceBetween: 25,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
delay: 2500,
delay: 4500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: 2,
slidesPerView: 3,
slidesPerColumn: 2,
},
1024: {
slidesPerView: 3,
slidesPerColumn: 2,
},
1200: {
slidesPerView: 4,
slidesPerColumn: 2,
},
1440: {
slidesPerView: 4,
slidesPerColumn: 2,
},
1840: {
slidesPerView: 4,
slidesPerColumn: 2,
},
1920: {
slidesPerView: 4,
slidesPerColumn: 2,
},
},
});

var swiperOrg = new Swiper(".homeorg-list", {
var swiperUserExp = new Swiper(".home-user-exp-list", {
slidesPerView: 1,
slidesPerColumn: 4,
spaceBetween: 0,
navigation: {
nextEl: '.homeuserexp .swiper-prev',
prevEl: '.homeuserexp .swiper-next',
},
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: 2,
},
1200: {
slidesPerView: 3,
},
1440: {
slidesPerView: 4,
},
1840: {
slidesPerView: 4,
},
1920: {
slidesPerView: 5,
},
},
});

var swiperDataset = new Swiper(".home-dataset-list", {
slidesPerView: 2,
slidesPerColumn: 1,
slidesPerColumnFill:'row',
spaceBetween: 15,
spaceBetween: 30,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
delay: 4500,
delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
676: {
slidesPerView: 3,
},
768: {
slidesPerView: 2,
slidesPerView: 4,
},
1024: {
slidesPerView: 3,
1320: {
slidesPerView: 5,
},
1520: {
slidesPerView: 6,
},
1720: {
slidesPerView: 7,
},
1920: {
slidesPerView: 7,
},
},
});
@@ -85,7 +170,7 @@ document.onreadystatechange = function () {
if(document.readyState != "complete"){
return;
}
console.log("Start to open WebSocket." + document.readyState);
console.log("Start to open WebSocket." + document.readyState);
queryRecommendData();

var output = document.getElementById("newmessage");
@@ -101,6 +186,7 @@ document.onreadystatechange = function () {
};

socket.onmessage = function (e) {
if (!output) return;
var data =JSON.parse(e.data)
var html = "";
if (data != null){
@@ -177,18 +263,17 @@ document.onreadystatechange = function () {
var time = getTime(record.CreatedUnix,currentTime);
html += " " + time;
}
html += "</div>";
html += "</div></div>";
html += "</div>";
}
}
output.innerHTML = html;
$('#homenews p').show();
swiperNewMessage.updateSlides();
swiperNewMessage.updateProgress();
};
}



function getTaskLink(record){
var re = getRepoLink(record);
if(record.OpType == 24){
@@ -223,7 +308,7 @@ function getMsg(record){
}else{
console.log("act user is null.");
}
html += " <img class=\"ui avatar image\" src=\"/user/avatar/" + name + "/-1\" alt=\"\">"
html += "<div class=\"content-c\"><img class=\"ui avatar image\" src=\"/user/avatar/" + name + "/-1\" alt=\"\">"
html += " <div class=\"middle aligned content nowrap\">"
html += " <a href=\"/" + encodeURI(name) + "\" title=\"\">" + name + "</a>"
return html;
@@ -236,6 +321,7 @@ function getRepotext(record){
return record.Repo.OwnerName + "/" + record.Repo.Name;
}
}

function getRepoLink(record){
return encodeURI(record.Repo.OwnerName + "/" + record.Repo.Name);

@@ -437,10 +523,6 @@ function getAction(opType,isZh){
}
}





function queryRecommendData(){
$.ajax({
type:"GET",
@@ -453,7 +535,10 @@ function queryRecommendData(){
success:function(json){
displayOrg(json.org);
displayRepo(json.repo);
displayActivity(json.image);
displayActivity(json.activity);
displayDataset(json.dataset);
displayUserExp(json.user_experience);
LetterAvatar && LetterAvatar.transform();
},
error:function(response) {
}
@@ -463,49 +548,99 @@ function queryRecommendData(){

function displayActivity(json){
var activityDiv = document.getElementById("recommendactivity");
if (!activityDiv) return;
var html = "";
if (json != null && json.length > 0){
for(var i = 0; i < json.length;i++){
var record = json[i]
html += "<div class=\"swiper-slide\">";
html += "<a href=\"" + record["image_link"] + "\" class=\"ui fluid card\">";
html += " <div class=\"image\"><img src=\"" + record["url"] + "\"></div>"
var record = json[i];
var name = isZh ? (record["name"] || '') : (record["name_en"] || record["name"]);
html += "<div class=\"swiper-slide\" style=\"text-align:center;\">";
html += "<a href=\"" + record["image_link"] + "\">";
html += " <div class=\"image ui card\"><img src=\"" + record["url"] + "\">";
html += ' <div class="image-name" title="' + name + '">' + name + "</div>";
html += "</div>";
html += "</a>";
html += "</div>";
}
var swiperEvent = new Swiper(".event-list", {
slidesPerView: 1,
spaceBetween: 30,
// pagination: {
// el: ".swiper-pagination",
// clickable: true,
// },
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: Math.min(2, json.length),
},
1024: {
slidesPerView: Math.min(3, json.length),
},
1200: {
slidesPerView: Math.min(3, json.length),
},
1440: {
slidesPerView: Math.min(4, json.length),
},
1840: {
slidesPerView: Math.min(4, json.length),
},
1920: {
slidesPerView: Math.min(4, json.length),
},
},
});
activityDiv.innerHTML = html;
swiperEvent.updateSlides();
swiperEvent.updateProgress();
}
activityDiv.innerHTML = html;
swiperEvent.updateSlides();
swiperEvent.updateProgress();
}

function displayRepo(json){
var orgRepo = document.getElementById("recommendrepo");
var html = "";
if (json != null && json.length > 0){
for(var i = 0; i < json.length;i++){
var record = json[i]
html += "<div class=\"swiper-slide\">";
html += " <div class=\"ui fluid card\">";
html += " <div class=\"content\">";
html += " <span class=\"right floated meta\">";
html += " <i class=\"ri-star-line\"></i>" + record["NumStars"] + "<i class=\"ri-git-branch-line am-ml-10\"></i>" + record["NumForks"];
html += " </span>";
html += " <img class=\"left floated mini ui image\" src=\"" + record["Avatar"] + "\">";
html += " <a class=\"header nowrap\" href=\"/" + record["OwnerName"] + "/" + record["Name"] + "\">" + record["Alias"] +"</a>";
html += " <div class=\"description nowrap-2\">" + record["Description"] + " </div>";
html += " <div class=\"ui tags nowrap am-mt-10\">"
if(record["Topics"] != null){
for(var j = 0; j < record["Topics"].length; j++){
topic = record["Topics"][j];
url = "/explore/repos?q=" + (topic) + "&amp;topic="
html += "<a class=\"ui small label topic\" href=\"" + url + "\">" + topic + "</a>";
}
var repoMap = {};
for (var i = 0, iLen = json.length; i < iLen; i++) {
var repo = json[i];
var label = isZh ? repo.Label : repo.Label_en;
if (repoMap[label]) {
repoMap[label].push(repo);
} else {
repoMap[label] = [repo];
}
html += " </div>";
html += " </div>";
html += " </div>";
html += "</div>";
}

for (var label in repoMap) {
var repos = repoMap[label];
var labelSearch = repos[0].Label;
html += `<div class="swiper-slide"><div><a style="color:rgb(50, 145, 248);font-size:16px;font-weight:550;" href="/explore/repos?q=&topic=${labelSearch}&sort=hot"># ${label}</a></div>`;
for (var i = 0, iLen = repos.length; i < iLen; i++) {
if (i >= 4) break;
var repo = repos[i];
// <i class="ri-star-line"></i>${repo["NumStars"]}<i class="ri-git-branch-line am-ml-10"></i>${repo["NumForks"]}</span> <div class="ui tags nowrap am-mt-10"></div>
html += `<div class="ui fluid card" style="border-radius:6px;">
<div class="content">
${repo["Avatar"] ? `<img class="left floated mini ui image" src="${repo["Avatar"]}">` : `<img class="left floated mini ui image" avatar="${repo["OwnerName"]}">`}
<a class="header nowrap" style="color:rgb(50, 145, 248);font-size:14px;" href="/${repo["OwnerName"]}/${repo["Name"]}" title="${repo["Alias"]}">${repo["Alias"]}</a>
<div class="description nowrap-2" style="rgba(136,136,136,1);;font-size:12px;" title="${repo["Description"]}">${repo["Description"]}</div>
`;
// if (repo["Topics"] != null) {
// for(var j = 0; j < repo["Topics"].length; j++){
// var topic = repo["Topics"][j];
// var url = "/explore/repos?q=" + (topic) + "&amp;topic="
// html += `<a class="ui small label topic" href=" ${url}">${topic}</a>`;
// }
// }
html += `
</div>
</div>`;
}
html += '</div>'
}
}
orgRepo.innerHTML = html;
@@ -513,7 +648,6 @@ function displayRepo(json){
swiperRepo.updateProgress();
}


function getRepoOrOrg(key,isZhLang,numbers=1){
if(numbers > 1){
key+="1";
@@ -537,7 +671,7 @@ function displayOrg(json){
html += " <img class=\"ui image\" src=\"" + record["Avatar"] + "\">";
html += " <div class=\"content nowrap\">";
html += " <span class=\"ui blue\">" + record["Name"] + "</span> " + record["FullName"];
html += " <div class=\"sub header\">" + record["NumRepos"] +" " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ " + record["NumMembers"] +" " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ " + record["NumTeams"] + " " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "</div>";
html += " <div class=\"sub header\" style=\"margin-top:4px;\"><span style=\"color:rgb(54, 56, 64)\">" + record["NumRepos"] +"</span> " + getRepoOrOrg(1,isZh,record["NumRepos"]) + " ・ <span style=\"color:rgb(54, 56, 64)\">" + record["NumMembers"] +"</span> " + getRepoOrOrg(2,isZh,record["NumMembers"]) + " ・ <span style=\"color:rgb(54, 56, 64)\">" + record["NumTeams"] + "</span> " + getRepoOrOrg(3,isZh,record["NumTeams"]) + "</div>";
html += " </div>";
html += " </div>";
html += " </div>";
@@ -548,3 +682,187 @@ function displayOrg(json){
orgDiv.innerHTML = html;
swiperOrg.updateSlides();
}

function displayDataset(data) {
var homeDatasetEl = document.getElementById("home_dataset");
if (!homeDatasetEl) return;
var html = '';
var svgStrMap = {
'0': '<svg xmlns="http://www.w3.org/2000/svg" class="svg svg-icon-path-icon fill" viewBox="0 0 32 32" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93em9ydx6bi61,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><path d="M16 4c7.189 0 13.171 5.173 14.425 12-1.253 6.827-7.236 12-14.425 12s-13.171-5.173-14.425-12c1.253-6.827 7.236-12 14.425-12zM16 25.333c5.682-0.001 10.442-3.949 11.687-9.252l0.016-0.081c-1.265-5.379-6.024-9.322-11.703-9.322s-10.437 3.943-11.686 9.241l-0.016 0.081c1.261 5.384 6.021 9.332 11.703 9.333h0zM16 22c-3.314 0-6-2.686-6-6s2.686-6 6-6v0c3.314 0 6 2.686 6 6s-2.686 6-6 6v0zM16 19.333c1.841 0 3.333-1.492 3.333-3.333s-1.492-3.333-3.333-3.333v0c-1.841 0-3.333 1.492-3.333 3.333s1.492 3.333 3.333 3.333v0z"></path></g></svg>',
'1': '<svg xmlns="http://www.w3.org/2000/svg" class="svg svg-icon-path-icon fill" viewBox="0 0 32 32" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93gapd7aoa4d1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><path d="M2.667 16c0-7.364 5.969-13.333 13.333-13.333s13.333 5.969 13.333 13.333-5.969 13.333-13.333 13.333h-13.333l3.905-3.905c-2.413-2.407-3.905-5.735-3.905-9.411 0-0.006 0-0.012 0-0.018v0.001zM9.104 26.667h6.896c5.891 0 10.667-4.776 10.667-10.667s-4.776-10.667-10.667-10.667c-5.891 0-10.667 4.776-10.667 10.667v0c0 2.869 1.135 5.553 3.124 7.543l1.885 1.885-1.239 1.239zM14.667 8h2.667v16h-2.667v-16zM9.333 12h2.667v8h-2.667v-8zM20 12h2.667v8h-2.667v-8z"></path></g></svg>',
'2': '<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 lhfskE svg-icon-path-icon fill" viewBox="0 0 48 48" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93j5tkotzm421,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><rect width="48" height="48" fill-opacity="0.01" fill="url(#ila93j5tkotzm421,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" storke="none"></rect><path stroke="url(#ila93j5tkotzm421,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" d="M4 24C4 24 10 15 14 15C18 15 22 17 24 17C26 17 30 15 34 15C38 15 44 24 44 24C44 24 34 34 24 34C14 34 4 24 4 24Z" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path><path stroke="url(#ila93j5tkotzm421,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" d="M4 24H44" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>',
'3': '<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 beWLko svg-icon-path-icon fill" viewBox="0 0 48 48" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><path d="M6 25C6 15.0589 14.0589 7 24 7C30.8669 7 36.8357 10.8453 39.8706 16.5" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M41 25H43L42 24L41 25Z" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M31 34L28.375 27L25 18H23L19.625 27L17 34" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M28.375 27H19.625" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M7 25H5L6 26L7 25Z" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M42 25C42 34.9411 33.9411 43 24 43C17.1331 43 11.1643 39.1547 8.12939 33.5" stroke="url(#ila93k86om2ayqg1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path></g></svg>',
'4': '<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 kqqJug svg-icon-path-icon fill" viewBox="0 0 48 48" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93lcoqm7710i1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><path d="M33 4.99976H41C42.1046 4.99976 43 5.89519 43 6.99976V14.9998M43 32.9998V40.9998C43 42.1043 42.1046 42.9998 41 42.9998H33M15 42.9998H7C5.89543 42.9998 5 42.1043 5 40.9998V32.9998M5 14.9998V6.99976C5 5.89519 5.89543 4.99976 7 4.99976H15" stroke="url(#ila93lcoqm7710i1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path><path d="M24 38C30.6274 38 36 31.732 36 24C36 16.268 30.6274 10 24 10C17.3726 10 12 16.268 12 24C12 31.732 17.3726 38 24 38Z" stroke="url(#ila93lcoqm7710i1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M6 24H42" stroke="url(#ila93lcoqm7710i1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path><path d="M20.0693 30.1057C21.3372 31.0429 22.6473 31.5115 23.9996 31.5115C25.3519 31.5115 26.698 31.0429 28.0378 30.1057" stroke="url(#ila93lcoqm7710i1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path></g></svg>',
'5': '<svg xmlns="http://www.w3.org/2000/svg" class="svg svg-icon-path-icon fill" viewBox="0 0 32 32" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93mrrwzocn0r1,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><path d="M16 26.667c5.891 0 10.667-4.776 10.667-10.667s-4.776-10.667-10.667-10.667v0c-5.891 0-10.667 4.776-10.667 10.667s4.776 10.667 10.667 10.667v0zM16 29.333c-7.364 0-13.333-5.969-13.333-13.333s5.969-13.333 13.333-13.333 13.333 5.969 13.333 13.333-5.969 13.333-13.333 13.333zM16 21.333c2.946 0 5.333-2.388 5.333-5.333s-2.388-5.333-5.333-5.333v0c-2.946 0-5.333 2.388-5.333 5.333s2.388 5.333 5.333 5.333v0zM16 24c-4.418 0-8-3.582-8-8s3.582-8 8-8v0c4.418 0 8 3.582 8 8s-3.582 8-8 8v0zM16 18.667c-1.473 0-2.667-1.194-2.667-2.667s1.194-2.667 2.667-2.667v0c1.473 0 2.667 1.194 2.667 2.667s-1.194 2.667-2.667 2.667v0z"></path></g></svg>',
'6': '<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 cAmoNA svg-icon-path-icon fill" viewBox="0 0 48 48" width="32" height="32"><defs data-reactroot=""><linearGradient id="ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs" x1="0" x2="100%" y1="0" y2="0" gradientUnits="userSpaceOnUse"><stop stop-color="#82d1f6" stop-opacity="1" offset="0"></stop><stop stop-color="#29b6f4" stop-opacity="1" offset="0.5"></stop><stop stop-color="#0089cd" stop-opacity="1" offset="0.99"></stop></linearGradient></defs><g><rect width="48" height="48" fill="white" fill-opacity="0.01"></rect><path d="M14.5397 20.0186C12.8522 17.9434 11.2675 17.4979 9.78564 18.6821C7.5629 20.4583 6.92453 26.6496 8.71324 32.1086C10.502 37.5676 13.9801 45.0017 21.0016 45.0017C28.0231 45.0017 29.684 37.5222 32.5485 33.0001C35.413 28.478 36.9285 24.1152 34.1208 18.6821" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11 18.0368C9.29707 15.4428 7.96374 13.4306 6.99996 12.0002C5.5543 9.85464 9.25107 7.08164 11 8.96807C12.1659 10.2257 13.7148 12.078 15.6466 14.5249" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path><path d="M15.0236 25.6396C14.5391 19.5759 14.9333 15.6276 16.2062 13.7947C18.1155 11.0455 21.6631 10.0031 25.0035 10.0031C26.9924 10.0031 28.8087 10.8502 30.4525 12.5444" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M41.0003 12.6128C41.5858 14.6492 40.6294 16.5097 37.6844 16.931C34.7393 17.3523 32.5313 18.8332 30.9388 20.079C29.3463 21.3248 26.4983 25.1046 25.9361 27.0023C25.3738 28.9 22.1602 27.1547 21.2971 26.3971C20.434 25.6394 19.5855 23.9806 21.2971 22.2457C23.0086 20.5108 22.6383 20.1646 22.6383 18.4052C22.6383 16.6459 32.0003 10.8263 37.2729 10.2941C38.4449 10.2257 40.4147 10.5763 41.0003 12.6128Z" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4"></path><path d="M23.0078 4.00014V9.26283" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path><path d="M20.3066 10.7178C17.2888 6.92534 14.8555 4.80868 13.0068 4.36781" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path><path d="M17.0039 7.02894L17.9944 2.96156" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path><path d="M35.6128 10.7174C35.2905 11.8219 35.2905 12.8575 35.6128 13.8241C35.935 14.7908 36.6255 15.8264 37.6842 16.9308" stroke="url(#ila93oiqy4t1x861,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs)" fill="none" stroke-width="4" stroke-linecap="round"></path></g></svg>',
}
for (var i = 0, iLen = data.length; i < iLen; i++) {
var dataI = data[i];
html += `<div class="swiper-slide">
<a href="/explore/datasets?sort=default&q=&tab=&category=&task=${dataI.task}&license=">
<div class="ui fluid dataset-card">
<div><div class="content icon-c">
${svgStrMap[i % 7]}
</div></div>
<div><div class="content label" title="${i18n[dataI.task] || dataI.task}">${i18n[dataI.task] || dataI.task}</div></div>
<div><div class="content count" style="">${i18n['about']} ${dataI.total} ${i18n['count']}</div></div>
</div>
</a>
</div>`
}
homeDatasetEl.innerHTML = html;
swiperDataset.updateSlides();
swiperDataset.updateProgress();
}

function displayUserExp(data) {
var homeUserExpEl = document.getElementById("home_user-exp");
if (!homeUserExpEl) return;
var html = '';
for (var i = 0, iLen = data.length; i < iLen; i++) {
var dataI = data[i];
html += `<div class="swiper-slide">
<div class="ui fluid user-card">
<div><div class="content img-c">
<a href="/${dataI.name}">
<div class="img" style="width:60px;height:60px;background-image:url('${dataI.avatar}')"></div>
</a>
</div></div>
<div><div class="content label" title="${dataI.fullname || dataI.name}">${dataI.fullname || dataI.name}</div></div>
<div><div class="content descr" title="${dataI.desc}">${dataI.desc}</div></div>
</div>
</div>`
}
homeUserExpEl.innerHTML = html;
swiperUserExp.updateSlides();
swiperUserExp.updateProgress();
}

function getNotice() {
$.ajax({
type:"GET",
url:"/dashboard/invitation",
headers: { authorization:token, },
dataType:"json",
data: {
filename: 'notice/notice.json',
},
success:function(json){
if (json) {
try {
var noticeList = JSON.parse(json).Notices || [];
var noticeEls = $('._hm-recommend-info-area-1 a._hm-notice');
for (var i = 0, iLen = noticeEls.length; i < iLen; i++) {
var noticeEl = noticeEls.eq(i);
var noticeObj = noticeList[i];
if (noticeObj) {
var title = isZh ? noticeObj.Title : (noticeObj.Title_en || noticeObj.Title);
noticeEl.attr('href', noticeObj.Link);
noticeEl.find('span').text(title).attr('title', title);
noticeEl.show();
} else {
noticeEl.hide();
}
}
} catch (e) {
console.info(e);
}
}
},
error:function(response) {
}
});
}

function getRecommendModule() {
$.ajax({
type:"GET",
url:"/dashboard/invitation",
headers: { authorization:token, },
dataType:"json",
data: {
filename: 'home/newfunction',
},
success:function(json){
if (json) {
try {
var recommendModuleList = JSON.parse(json) || [];
var recommendModuleEls = $('._hm-recommend-info-area a._hm-link');
for (var i = 0, iLen = recommendModuleEls.length; i < iLen; i++) {
var recommendModuleEl = recommendModuleEls.eq(i);
var recommendModuleObj = recommendModuleList[i];
if (recommendModuleObj) {
recommendModuleEl.attr('href', recommendModuleObj.image_link);
recommendModuleEl.text(isZh ? recommendModuleObj.name : (recommendModuleObj.name_en || recommendModuleObj.name));
} else {
}
}
} catch (e) {
console.info(e);
}
}
},
error:function(response) {
}
});
}

function initHomeTopBanner() {
var homeSlideTimer = null;
var homeSlideDuration = 8000;
function homeSlide(direction, index) {
var slidePages = $('._hm-pg-c ._hm-pg');
var currentPage = slidePages.filter('._hm-pg-show');
var slidePagination = $('._hm-slide-pagination-c ._hm-slide-pagination-item');
var currentIndex = currentPage.index();
var next = 0;
if (direction) {
next = direction == 'left' ? currentIndex - 1 : currentIndex + 1;
} else {
next = index || 0;
}
if (next < 0) next = slidePages.length - 1;
if (next == slidePages.length) next = 0;
slidePages.removeClass('_hm-pg-show');
slidePages.eq(next).addClass('_hm-pg-show');
slidePagination.removeClass('_hm-slide-pagination-item-active');
slidePagination.eq(next).addClass('_hm-slide-pagination-item-active');
}

function startSlide() {
homeSlideTimer && clearTimeout(homeSlideTimer);
homeSlideTimer = setTimeout(function() {
homeSlide('right');
startSlide();
}, homeSlideDuration);
}

function stopSlide() {
homeSlideTimer && clearTimeout(homeSlideTimer);
}

$('._hm-slide-btn').on('click', function () {
if ($(this).hasClass('_hm-slide-btn-left')) {
homeSlide('left');
} else {
homeSlide('right');
}
startSlide();
});
$('._hm-pg #homenews').on('mouseenter', function() {
stopSlide();
}).on('mouseleave', function() {
startSlide();
});
$('._hm-slide-pagination-c ._hm-slide-pagination-item').on('click', function() {
var self = $(this);
if (self.hasClass('_hm-slide-pagination-item-active')) return;
homeSlide('', self.index());
startSlide();
});
setTimeout(function() { startSlide(); }, 500);
}

initHomeTopBanner();
getNotice();
getRecommendModule();

+ 1
- 1
public/img/search.svg View File

@@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1638433773401" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2884" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M469.333333 768c-166.4 0-298.666667-132.266667-298.666666-298.666667s132.266667-298.666667 298.666666-298.666666 298.666667 132.266667 298.666667 298.666666-132.266667 298.666667-298.666667 298.666667z m0-85.333333c119.466667 0 213.333333-93.866667 213.333334-213.333334s-93.866667-213.333333-213.333334-213.333333-213.333333 93.866667-213.333333 213.333333 93.866667 213.333333 213.333333 213.333334z m251.733334 0l119.466666 119.466666-59.733333 59.733334-119.466667-119.466667 59.733334-59.733333z" fill="#5BB973" p-id="2885"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 fPsHiw svg-icon-path-icon fill" viewBox="0 0 32 32" width="24" height="24"><defs data-reactroot=""></defs><g><path fill="rgb(255, 255, 255)" d="M14.667 2.667c6.624 0 12 5.376 12 12s-5.376 12-12 12-12-5.376-12-12 5.376-12 12-12zM14.667 24c5.156 0 9.333-4.177 9.333-9.333 0-5.157-4.177-9.333-9.333-9.333-5.157 0-9.333 4.176-9.333 9.333 0 5.156 4.176 9.333 9.333 9.333zM25.98 24.095l3.772 3.771-1.887 1.887-3.771-3.772 1.885-1.885z"></path></g></svg>

+ 7
- 1
routers/api/v1/api.go View File

@@ -614,6 +614,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/download_invitation_detail", operationReq, repo_ext.DownloadInvitationDetail)

//cloudbrain board
m.Get("/cloudbrainboard/cloudbrain/resource_queues", repo.GetResourceQueues)
m.Group("/cloudbrainboard", func() {
m.Get("/downloadAll", repo.DownloadCloudBrainBoard)
m.Group("/cloudbrain", func() {
@@ -631,7 +632,6 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/overview_resource", repo.GetCloudbrainResourceOverview)
m.Get("/resource_usage_statistic", repo.GetDurationRateStatistic)
m.Get("/resource_usage_rate_detail", repo.GetCloudbrainResourceUsageDetail)
m.Get("/resource_queues", repo.GetResourceQueues)
m.Get("/apitest_for_statistic", repo.CloudbrainDurationStatisticForTest)
})
}, operationReq)
@@ -737,6 +737,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/my_favorite", repo.MyFavoriteDatasetMultiple)
}, reqToken(), repoAssignment())

m.Group("/file_notebook", func() {
m.Get("", reqToken(), repo.GetFileNoteBookInfo)
m.Post("/create", reqToken(), reqWeChat(), bind(api.CreateFileNotebookJobOption{}), repo.CreateFileNoteBook)

})

m.Group("/repos", func() {
m.Get("/search", repo.Search)



+ 83
- 8
routers/api/v1/repo/cloudbrain.go View File

@@ -11,6 +11,7 @@ import (
"io"
"net/http"
"os"
"path"
"sort"
"strconv"
"strings"
@@ -78,6 +79,74 @@ func CloudBrainShow(ctx *context.APIContext) {

ctx.JSON(http.StatusOK, models.BaseMessageWithDataApi{Code: 0, Message: "", Data: convert.ToCloudBrain(task)})

}
func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) {
cloudbrainTask.FileNotebookCreate(ctx.Context, option)
}

func GetFileNoteBookInfo(ctx *context.APIContext) {
//image description spec description waiting count

specs, err := models.GetResourceSpecificationByIds([]int64{setting.FileNoteBook.SpecIdCPU, setting.FileNoteBook.SpecIdGPU, setting.FileNoteBook.SpecIdNPU, setting.FileNoteBook.SpecIdNPUCD})
if err != nil {
log.Error("Fail to query specifications", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
return
}

var specCPU, specGpu, specNPU, specNPUCD *api.SpecificationShow
var specGpuQueueCode string
for _, spec := range specs {
if spec.ID == setting.FileNoteBook.SpecIdCPU {
specCPU = convert.ToSpecification(spec)
} else if spec.ID == setting.FileNoteBook.SpecIdGPU {
specGpu = convert.ToSpecification(spec)
specGpuQueueCode = spec.QueueCode
} else if spec.ID == setting.FileNoteBook.SpecIdNPU {
specNPU = convert.ToSpecification(spec)
} else if spec.ID == setting.FileNoteBook.SpecIdNPUCD {
specNPUCD = convert.ToSpecification(spec)
}
}

waitCountNpu := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")

queuesMap, err := cloudbrain.GetQueuesDetail()
if err != nil {
log.Error("Fail to query gpu queues waiting count", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_query_fail")))
return
}
waitCountGPU := (*queuesMap)[specGpuQueueCode]
if !setting.ModelartsCD.Enabled {
ctx.JSON(http.StatusOK, map[string]interface{}{
"code": 0,
"projectName": setting.FileNoteBook.ProjectName,
"specCpu": specCPU,
"specGpu": specGpu,
"specNpu": specNPU,
"waitCountGpu": waitCountGPU,
"waitCountNpu": waitCountNpu,
"imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
"imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
"imageNpuDescription": setting.FileNoteBook.ImageNPUDescription,
})
} else {
ctx.JSON(http.StatusOK, map[string]interface{}{
"code": 0,
"projectName": setting.FileNoteBook.ProjectName,
"specCpu": specCPU,
"specGpu": specGpu,
"specNpu": specNPUCD,
"waitCountGpu": waitCountGPU,
"waitCountNpu": waitCountNpu,
"imageCpuDescription": setting.FileNoteBook.ImageCPUDescription,
"imageGpuDescription": setting.FileNoteBook.ImageGPUDescription,
"imageNpuDescription": setting.FileNoteBook.ImageNPUCDDescription,
})

}

}

func CreateCloudBrain(ctx *context.APIContext, option api.CreateTrainJobOption) {
@@ -141,10 +210,11 @@ func GetCloudbrainTask(ctx *context.APIContext) {
)

ID := ctx.Params(":id")
job, err := models.GetCloudbrainByID(ID)

job, err := cloudbrain.GetCloudBrainByIdOrJobId(ID)

if err != nil {
ctx.NotFound(err)
log.Error("GetCloudbrainByID failed:", err)
return
}
if job.JobType == string(models.JobTypeModelSafety) {
@@ -487,6 +557,12 @@ func ModelSafetyGetLog(ctx *context.APIContext) {
})
return
}
prefix := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, job.JobName, modelarts.LogPath, job.VersionName), "/") + "/job"
_, err = storage.GetObsLogFileName(prefix)
canLogDownload := isCanDownloadLog(ctx, job)
if err != nil {
canLogDownload = false
}
ctx.Data["log_file_name"] = resultLogFile.LogFileList[0]
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobID": job.JobID,
@@ -495,7 +571,7 @@ func ModelSafetyGetLog(ctx *context.APIContext) {
"EndLine": result.EndLine,
"Content": result.Content,
"Lines": result.Lines,
"CanLogDownload": isCanDownloadLog(ctx, job),
"CanLogDownload": canLogDownload,
"StartTime": job.StartTime,
})
}
@@ -566,7 +642,6 @@ func CloudbrainDownloadLogFile(ctx *context.Context) {
url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName)
if err != nil {
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("Get minio get SignedUrl failed", err)
return
}
log.Info("fileName=" + fileName)
@@ -650,7 +725,7 @@ func CloudbrainGetLog(ctx *context.APIContext) {
result = getLogFromModelDir(job.JobName, startLine, endLine, resultPath)
if result == nil {
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"])
ctx.ServerError(err.Error(), err)
//ctx.ServerError(err.Error(), err)
return
}
}
@@ -865,7 +940,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
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)
//ctx.ServerError("json.Unmarshal failed:", err)
return
}

@@ -896,7 +971,7 @@ func CloudBrainModelConvertList(ctx *context.APIContext) {
models, err := storage.GetObsListObject(job.ID, "output/", parentDir, versionName)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
ctx.ServerError("GetObsListObject:", err)
//ctx.ServerError("GetObsListObject:", err)
return
}

@@ -941,7 +1016,7 @@ func CloudBrainModelList(ctx *context.APIContext) {
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)
//ctx.ServerError("json.Unmarshal failed:", err)
return
}



+ 61
- 69
routers/api/v1/repo/cloudbrain_dashboard.go View File

@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/routers/repo"
cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
"code.gitea.io/gitea/services/cloudbrain/resource"
@@ -58,42 +59,30 @@ func GetAllCloudbrainsOverview(ctx *context.Context) {
return
}
cloudbrainTypeCount, err := models.GetCloudbrainTypeCount()
log.Info("cloudbrainTypeCount:", cloudbrainTypeCount)
if err != nil {
log.Error("Can not query cloudbrainTypeCount.", err)
return
}

cloudbrainTpyeDurationSum, err := models.GetCloudbrainTpyeDurationSum()
log.Info("cloudbrainTpyeDurationSum:", cloudbrainTpyeDurationSum)
if err != nil {
log.Error("Can not query cloudbrainTpyeDurationSum.", err)
return
}

todayCloudbrainCount, err := models.GetTodayCloudbrainCount(beginTime, endTime)
log.Info("todayCloudbrainCount:", todayCloudbrainCount)
if err != nil {
log.Error("Can not query todayCloudbrainCount.", err)
return
}

todayRunningCount, err := models.GetTodayRunningCount(beginTime, endTime)
log.Info("todayRunningCount:", todayRunningCount)
if err != nil {
log.Error("Can not query todayRunningCount.", err)
return
}

todayWaitingCount, err := models.GetTodayWaitingCount(beginTime, endTime)
log.Info("todayWaittingCount:", todayWaitingCount)
if err != nil {
log.Error("Can not query todayWaitingCount.", err)
return
}

todayCompletedCount := todayCloudbrainCount - todayRunningCount - todayWaitingCount
log.Info("todayCompletedCount:", todayCompletedCount)

creatorCount, err := models.GetCreatorCount()
if err != nil {
@@ -139,60 +128,48 @@ func GetOverviewDuration(ctx *context.Context) {
c2NetDuration := int64(0)
cDCenterDuration := int64(0)

page := 1
pagesize := 10000
count := pagesize
// Each time a maximum of 10000 pieces of data are detected to the memory, batch processing
for count == pagesize && count != 0 {
cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
ListOptions: models.ListOptions{
Page: page,
PageSize: pagesize,
},
Type: models.TypeCloudBrainAll,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
})
if err != nil {
ctx.ServerError("Get cloudbrains failed:", err)
return
}
models.LoadSpecs4CloudbrainInfo(cloudbrains)

for _, cloudbrain := range cloudbrains {
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum)
} else {
cardNum = 1
}
if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber)
} else {
workServerNumber = 1
}
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration)
CardDuration := workServerNumber * int64(cardNum) * duration

if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration += duration
cloudBrainOneCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
cloudBrainTwoDuration += duration
cloudBrainTwoCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
c2NetDuration += duration
c2NetCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
cDCenterDuration += duration
cDNetCardDuSum += CardDuration
}
cloudbrains, _, err := models.CloudbrainAllKanBan(&models.CloudbrainsOptions{
Type: models.TypeCloudBrainAll,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
})
if err != nil {
ctx.ServerError("Get cloudbrains failed:", err)
return
}
models.LoadSpecs4CloudbrainInfo(cloudbrains)

durationAllSum += duration
cardDuSum += CardDuration
for _, cloudbrain := range cloudbrains {
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum)
} else {
cardNum = 1
}
count = len(cloudbrains)
page += 1
if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber)
} else {
workServerNumber = 1
}
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration)
CardDuration := workServerNumber * int64(cardNum) * duration

if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration += duration
cloudBrainOneCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
cloudBrainTwoDuration += duration
cloudBrainTwoCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
c2NetDuration += duration
c2NetCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
cDCenterDuration += duration
cDNetCardDuSum += CardDuration
}

durationAllSum += duration
cardDuSum += CardDuration
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"cloudBrainOneCardDuSum": cloudBrainOneCardDuSum,
@@ -1488,12 +1465,17 @@ func getCloudbrainTimePeroid(ctx *context.Context, recordBeginTime time.Time) (t
}

func GetCloudbrainResourceOverview(ctx *context.Context) {
var recordBeginTime timeutil.TimeStamp
recordCloudbrainDuration, err := models.GetDurationRecordBeginTime()
if err != nil {
log.Error("Can not get GetDurationRecordBeginTime", err)
return
}
recordBeginTime := recordCloudbrainDuration[0].DateTime
if len(recordCloudbrainDuration) > 0 && err == nil {
recordBeginTime = recordCloudbrainDuration[0].DateTimeUnix
} else {
recordBeginTime = timeutil.TimeStamp(time.Now().Unix())
}
recordUpdateTime := time.Now().Unix()
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
@@ -1620,6 +1602,7 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
now := time.Now()
beginTimeStr := ctx.QueryTrim("beginTime")
endTimeStr := ctx.QueryTrim("endTime")
var brainRecordBeginTime time.Time

var beginTime time.Time
var endTime time.Time
@@ -1632,7 +1615,12 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
return beginTime, endTime
}
brainRecordBeginTime := recordCloudbrainDuration[0].DateTime.AsTime()
if len(recordCloudbrainDuration) > 0 && err == nil {
brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
} else {
brainRecordBeginTime = now
}

beginTime = brainRecordBeginTime
endTime = now
} else if queryType == "today" {
@@ -1674,7 +1662,11 @@ func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
return beginTime, endTime
}
brainRecordBeginTime := recordCloudbrainDuration[0].DateTime.AsTime()
if len(recordCloudbrainDuration) > 0 && err == nil {
brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
} else {
brainRecordBeginTime = now
}
beginTime = brainRecordBeginTime
endTime = now
} else {
@@ -1705,7 +1697,7 @@ func getAiCenterUsageDuration(beginTime time.Time, endTime time.Time, cloudbrain
usageRate := float64(0)

for _, cloudbrainStatistic := range cloudbrainStatistics {
if int64(cloudbrainStatistic.DateTime) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTime) < endTime.Unix() {
if int64(cloudbrainStatistic.DateTimeUnix) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTimeUnix) < endTime.Unix() {
totalDuration += cloudbrainStatistic.CardsTotalDuration
usageDuration += cloudbrainStatistic.CardsUseDuration
}
@@ -1923,7 +1915,7 @@ func CloudbrainUpdateAiCenter(ctx *context.Context) {
func GetResourceQueues(ctx *context.Context) {
resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
log.Info("GetCanUseCardInfo err: %v", err)
log.Error("GetCanUseCardInfo err: %v", err)
return
}
Resource := make([]*models.ResourceQueue, 0)


+ 5
- 1
routers/api/v1/repo/modelarts.go View File

@@ -6,6 +6,7 @@
package repo

import (
"code.gitea.io/gitea/modules/cloudbrain"
"encoding/json"
"net/http"
"path"
@@ -37,11 +38,14 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {
)

ID := ctx.Params(":id")
job, err := models.GetCloudbrainByID(ID)

job,err := cloudbrain.GetCloudBrainByIdOrJobId(ID)

if err != nil {
ctx.NotFound(err)
return
}

err = modelarts.HandleNotebookInfo(job)
if err != nil {
ctx.NotFound(err)


+ 58
- 15
routers/home.go View File

@@ -7,6 +7,7 @@ package routers

import (
"bytes"
"encoding/json"
"net/http"
"strconv"
"strings"
@@ -672,7 +673,7 @@ func NotFound(ctx *context.Context) {
}

func getRecommendOrg() ([]map[string]interface{}, error) {
url := setting.RecommentRepoAddr + "organizations"
url := setting.RecommentRepoAddr + "home/organizations"
result, err := repository.RecommendFromPromote(url)

if err != nil {
@@ -745,7 +746,7 @@ func GetMapInfo(ctx *context.Context) {
}

func GetRankUser(index string) ([]map[string]interface{}, error) {
url := setting.RecommentRepoAddr + "user_rank_" + index
url := setting.RecommentRepoAddr + "user_rank/user_rank_" + index
result, err := repository.RecommendFromPromote(url)

if err != nil {
@@ -756,13 +757,25 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
tmpIndex := strings.Index(userRank, " ")
userName := userRank
score := 0
label := ""
if tmpIndex != -1 {
userName = userRank[0:tmpIndex]
tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:])
if err != nil {
log.Info("convert to int error.")
left := userRank[tmpIndex+1:]
tmpIndex1 := strings.Index(left, " ")
if tmpIndex1 != -1 {
tmpScore, err := strconv.Atoi(left[0:tmpIndex1])
if err != nil {
log.Info("convert to int error.")
}
score = tmpScore
label = left[tmpIndex1+1:]
} else {
tmpScore, err := strconv.Atoi(left[tmpIndex+1:])
if err != nil {
log.Info("convert to int error.")
}
score = tmpScore
}
score = tmpScore
}
user, err := models.GetUserByName(userName)
if err == nil {
@@ -772,6 +785,7 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
userMap["FullName"] = user.FullName
userMap["HomeLink"] = user.HomeLink()
userMap["ID"] = user.ID
userMap["Label"] = label
userMap["Avatar"] = user.RelAvatarLink()
userMap["Score"] = score
resultOrg = append(resultOrg, userMap)
@@ -792,25 +806,54 @@ func GetUserRankFromPromote(ctx *context.Context) {
ctx.JSON(200, resultUserRank)
}

func getMapContent(fileName string) []map[string]string {
url := setting.RecommentRepoAddr + fileName
result, err := repository.RecommendContentFromPromote(url)
remap := make([]map[string]string, 0)
if err == nil {
json.Unmarshal([]byte(result), &remap)
}
return remap
}

func HomeNoticeTmpl(ctx *context.Context) {
ctx.Data["url_params"] = ""
ctx.HTML(200, "notice")
}

func RecommendHomeInfo(ctx *context.Context) {
resultOrg, err := getRecommendOrg()
if err != nil {
log.Info("error." + err.Error())
}
resultRepo, err := repository.GetRecommendRepoFromPromote("projects")
repoMap := getMapContent("home/projects")
resultRepo, err := repository.GetRecommendRepoFromPromote(repoMap)
if err != nil {
log.Info("error." + err.Error())
}
resultImage, err := getImageInfo("picture_info")
if err != nil {
log.Info("error." + err.Error())
}

resultActivityInfo := getMapContent("home/activity_info")
mapInterface := make(map[string]interface{})
mapInterface["org"] = resultOrg
mapInterface["repo"] = resultRepo
mapInterface["image"] = resultImage
//mapInterface["cloudbrain"] = resultCloudBrain
mapInterface["activity"] = resultActivityInfo

user_experience := getMapContent("home/user_experience")
for _, amap := range user_experience {
userId := amap["userid"]
userIntId, _ := strconv.Atoi(userId)
user, err := models.GetUserByID(int64(userIntId))
if err == nil {
amap["name"] = user.Name
amap["fullname"] = user.FullName
amap["detail"] = user.Description
amap["avatar"] = user.AvatarLink()
}
}
mapInterface["user_experience"] = user_experience
dataset, err := models.QueryDatasetGroupByTask()
if err == nil {
mapInterface["dataset"] = dataset
}
ctx.JSON(http.StatusOK, mapInterface)
}

@@ -824,4 +867,4 @@ func HomePrivacy(ctx *context.Context) {

func HomeResoruceDesc(ctx *context.Context) {
ctx.HTML(200, tplResoruceDesc)
}
}

+ 1
- 2
routers/repo/ai_model_convert.go View File

@@ -49,7 +49,7 @@ const (
//TensorFlowNpuBootFile = "convert_tensorflow.py"
//TensorFlowGpuBootFile = "convert_tensorflow_gpu.py"

//ConvertRepoPath = "https://git.openi.org.cn/zouap/npu_test"
//ConvertRepoPath = "https://openi.pcl.ac.cn/zouap/npu_test"

CONVERT_FORMAT_ONNX = 0
CONVERT_FORMAT_TRT = 1
@@ -828,5 +828,4 @@ func ModelConvertDownloadModel(ctx *context.Context) {
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
}
}

}

+ 4
- 5
routers/repo/aisafety.go View File

@@ -11,7 +11,8 @@ import (
"os"
"strconv"
"strings"
"time"

cloudbrainService "code.gitea.io/gitea/services/cloudbrain"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/aisafety"
@@ -483,7 +484,6 @@ func isTaskNotFinished(status string) bool {
}

func AiSafetyCreateForGetGPU(ctx *context.Context) {
t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainOne
@@ -497,7 +497,7 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
log.Info("GPUBaseDataSetUUID=" + setting.ModelSafetyTest.GPUBaseDataSetUUID)
log.Info("GPUCombatDataSetName=" + setting.ModelSafetyTest.GPUCombatDataSetName)
log.Info("GPUCombatDataSetUUID=" + setting.ModelSafetyTest.GPUCombatDataSetUUID)
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
prepareCloudbrainOneSpecs(ctx)
queuesDetail, _ := cloudbrain.GetQueuesDetail()
@@ -514,12 +514,11 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) {
}

func AiSafetyCreateForGetNPU(ctx *context.Context) {
t := time.Now()
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["IsCreate"] = true
ctx.Data["type"] = models.TypeCloudBrainTwo
ctx.Data["compute_resource"] = models.NPUResource
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
ctx.Data["BaseDataSetName"] = setting.ModelSafetyTest.NPUBaseDataSetName


+ 12
- 53
routers/repo/cloudbrain.go View File

@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"

cloudbrainService "code.gitea.io/gitea/services/cloudbrain"

"code.gitea.io/gitea/modules/urfs_client/urchin"

"code.gitea.io/gitea/modules/dataset"
@@ -92,28 +94,9 @@ func MustEnableCloudbrain(ctx *context.Context) {
}
}

func cutString(str string, lens int) string {
if len(str) < lens {
return str
}
return str[:lens]
}

func jobNamePrefixValid(s string) string {
lowStr := strings.ToLower(s)
re := regexp.MustCompile(`[^a-z0-9_\\-]+`)

removeSpecial := re.ReplaceAllString(lowStr, "")

re = regexp.MustCompile(`^[_\\-]+`)
return re.ReplaceAllString(removeSpecial, "")

}

func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error {
ctx.Data["PageIsCloudBrain"] = true
t := time.Now()
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

ctx.Data["command"] = cloudbrain.GetCloudbrainDebugCommand()
@@ -696,7 +679,7 @@ func CloudBrainRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
resultCode = "-1"
resultCode = "2"
errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
@@ -759,43 +742,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
return
}
if task.Status == string(models.JobWaiting) || task.Status == string(models.JobRunning) {
result, err := cloudbrain.GetJob(task.JobID)
task, err = cloudbrainTask.SyncCloudBrainOneStatus(task)
if err != nil {
log.Info("error:" + err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}

if result != nil {
jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
taskRoles := jobRes.TaskRoles
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
ctx.Data["taskRes"] = taskRes
ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
oldStatus := task.Status
task.Status = taskRes.TaskStatuses[0].State
task.ContainerIp = ""
task.ContainerID = taskRes.TaskStatuses[0].ContainerID
models.ParseAndSetDurationFromCloudBrainOne(jobRes, task)

if task.DeletedAt.IsZero() { //normal record
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
ctx.Data["error"] = err.Error()
return
}
} else { //deleted record

}

ctx.Data["result"] = jobRes
} else {
log.Info("error:" + err.Error())
return
}
}

user, err := models.GetUserByID(task.UserID)
@@ -889,7 +842,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
func CloudBrainDebug(ctx *context.Context) {
task := ctx.Cloudbrain
debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
ctx.Redirect(debugUrl)
if task.BootFile!=""{
ctx.Redirect(getFileUrl(debugUrl,task.BootFile))

}else{
ctx.Redirect(debugUrl)
}

}

func prepareSpec4Show(ctx *context.Context, task *models.Cloudbrain) {


+ 49
- 50
routers/repo/cloudbrain_statistic.go View File

@@ -8,37 +8,39 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
)

func CloudbrainDurationStatisticHour() {
var statisticTime time.Time
var count int64
recordDurationUpdateTime, err := models.GetDurationRecordUpdateTime()
if err != nil {
log.Error("Can not get GetDurationRecordBeginTime", err)
}
now := time.Now()
currentTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
if err == nil && len(recordDurationUpdateTime) > 0 {
statisticTime = time.Unix(int64(recordDurationUpdateTime[0].DateTime), 0).Add(+1 * time.Hour)
} else {
statisticTime = currentTime
}
deleteBeginTime := time.Unix(int64(recordDurationUpdateTime[0].DateTime), 0)
if setting.IsCloudbrainTimingEnabled {
var statisticTime time.Time
var count int64
recordDurationUpdateTime, err := models.GetDurationRecordUpdateTime()
if err != nil {
log.Error("Can not get GetDurationRecordBeginTime", err)
}
now := time.Now()
currentTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
if err == nil && len(recordDurationUpdateTime) > 0 {
statisticTime = time.Unix(int64(recordDurationUpdateTime[0].DateTimeUnix), 0).Add(+1 * time.Hour)
} else {
statisticTime = currentTime
}

err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(deleteBeginTime.Unix()), timeutil.TimeStamp(currentTime.Unix()))
if err != nil {
log.Error("DeleteCloudbrainDurationStatistic failed", err)
}
err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(statisticTime.Add(-1*time.Hour).Unix()), timeutil.TimeStamp(currentTime.Unix()))
if err != nil {
log.Error("DeleteCloudbrainDurationStatistic failed", err)
}

for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
countEach := summaryDurationStat(statisticTime)
count += countEach
statisticTime = statisticTime.Add(+1 * time.Hour)
for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
countEach := summaryDurationStat(statisticTime)
count += countEach
statisticTime = statisticTime.Add(+1 * time.Hour)
}
log.Info("summaryDurationStat count: %v", count)
}
log.Info("summaryDurationStat count: %v", count)
}
func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time) int64 {
var count int64
@@ -55,7 +57,7 @@ func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time)
//statisticTime是当前的时辰,比如当前是2019-01-01 12:01:01,那么statisticTime就是2019-01-01 12:00:00
func summaryDurationStat(statisticTime time.Time) int64 {
var count int64
dateTime := timeutil.TimeStamp(statisticTime.Add(-1 * time.Hour).Unix())
dateTimeUnix := timeutil.TimeStamp(statisticTime.Add(-1 * time.Hour).Unix())
beginTime := statisticTime.Add(-1 * time.Hour).Unix()
dayTime := statisticTime.Add(-1 * time.Hour).Format("2006-01-02")
hourTime := statisticTime.Add(-1 * time.Hour).Hour()
@@ -66,27 +68,8 @@ func summaryDurationStat(statisticTime time.Time) int64 {
log.Info("GetCloudbrainByTime err: %v", err)
return 0
}
cloudbrainMap := make(map[string]*models.Cloudbrain)
models.LoadSpecs4CloudbrainInfo(ciTasks)

for _, cloudbrain := range ciTasks {
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
}
if cloudbrain.Cloudbrain.EndTime == 0 {
cloudbrain.Cloudbrain.EndTime = cloudbrain.Cloudbrain.UpdatedUnix
}
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
if _, ok := cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if cloudbrain.Cloudbrain.Spec != nil {
cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType] = &cloudbrain.Cloudbrain
}
}
}
}

cloudBrainCenterCodeAndCardTypeInfo := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
cloudBrainCenterCodeAndCardTypeInfo, cloudbrainMap := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)

resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
@@ -111,7 +94,7 @@ func summaryDurationStat(statisticTime time.Time) int64 {
cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType] = 0
}
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTime: dateTime,
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: cloudbrainTable.Cluster,
@@ -133,7 +116,7 @@ func summaryDurationStat(statisticTime time.Time) int64 {

for key, cardsTotalDuration := range cardsTotalDurationMap {
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTime: dateTime,
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
@@ -170,11 +153,27 @@ func GetAiCenterNameByCode(centerCode string, language string) string {
return aiCenterName
}

func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, beginTime int64, endTime int64) map[string]map[string]int {
func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, beginTime int64, endTime int64) (map[string]map[string]int, map[string]*models.Cloudbrain) {
var WorkServerNumber int
var AccCardsNum int
cloudbrainMap := make(map[string]*models.Cloudbrain)
cloudBrainCenterCodeAndCardType := make(map[string]map[string]int)
for _, cloudbrain := range ciTasks {
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
}
if cloudbrain.Cloudbrain.EndTime == 0 {
cloudbrain.Cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
}
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
if _, ok := cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if cloudbrain.Cloudbrain.Spec != nil {
cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType] = &cloudbrain.Cloudbrain
}
}
}

cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
@@ -196,7 +195,7 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter] = make(map[string]int)
}
if cloudbrain.Cloudbrain.Spec != nil {
if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) {
if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) && cloudbrain.Cloudbrain.DeletedAt.IsZero() {
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
@@ -240,7 +239,7 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
}
}

return cloudBrainCenterCodeAndCardType
return cloudBrainCenterCodeAndCardType, cloudbrainMap
}

func CloudbrainUpdateHistoryData(ctx *context.Context) {
@@ -258,7 +257,7 @@ func CloudbrainUpdateHistoryData(ctx *context.Context) {
endTimeUnix := timeutil.TimeStamp(endTime.Unix())

err = models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix)
count = UpdateDurationStatisticHistoryData(beginTime.Add(+1*time.Hour), endTime)
count = UpdateDurationStatisticHistoryData(beginTime.Add(+1*time.Hour), endTime.Add(+1*time.Hour))
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"message": 0,


+ 1
- 3
routers/repo/grampus.go View File

@@ -10,7 +10,6 @@ import (
"path"
"strconv"
"strings"
"time"

"code.gitea.io/gitea/modules/urfs_client/urchin"
"code.gitea.io/gitea/routers/response"
@@ -265,8 +264,7 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook
func grampusNotebookNewDataPrepare(ctx *context.Context, processType string) error {
ctx.Data["PageIsCloudBrain"] = true

t := time.Now()
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

//get valid images


+ 33
- 10
routers/repo/modelarts.go View File

@@ -15,6 +15,8 @@ import (
"time"
"unicode/utf8"

cloudbrainService "code.gitea.io/gitea/services/cloudbrain"

"code.gitea.io/gitea/services/cloudbrain/cloudbrainTask"

"code.gitea.io/gitea/modules/dataset"
@@ -128,8 +130,7 @@ func NotebookNew(ctx *context.Context) {

func notebookNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
t := time.Now()
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
@@ -239,9 +240,9 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
}

if setting.ModelartsCD.Enabled {
err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec)
_, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
} else {
err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec)
_, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
}

if err != nil {
@@ -387,8 +388,31 @@ func NotebookDebug2(ctx *context.Context) {
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
return
}
if task.BootFile != "" {
ctx.Redirect(getFileUrl(result.Url, task.BootFile) + "?token=" + result.Token)
} else {
ctx.Redirect(result.Url + "?token=" + result.Token)
}

ctx.Redirect(result.Url + "?token=" + result.Token)
}

func getFileUrl(url string, filename string) string {
middle := ""
if url[len(url)-3:] == "lab" || url[len(url)-4:] == "lab/" {
if url[len(url)-1] == '/' {
middle = "tree/"
} else {
middle = "/tree/"
}
} else {
if url[len(url)-1] == '/' {
middle = "lab/tree/"
} else {
middle = "/lab/tree/"
}
}

return url + middle + path.Base(filename)
}

func NotebookRestart(ctx *context.Context) {
@@ -420,7 +444,8 @@ func NotebookRestart(ctx *context.Context) {
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
errorMsg = "you have already a running or waiting task, can not create more"
resultCode = "2"
errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
}
@@ -719,8 +744,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
// return
//}

t := time.Now()
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)
@@ -2356,8 +2380,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
ctx.Data["newInference"] = true

t := time.Now()
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID)


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

@@ -359,6 +359,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/all/dosearch/", routers.SearchApi)
m.Post("/user/login/kanban", user.SignInPostAPI)
m.Get("/home/term", routers.HomeTerm)
m.Get("/home/notice", routers.HomeNoticeTmpl)
m.Get("/home/privacy", routers.HomePrivacy)
m.Get("/extension/tuomin/upload", modelapp.ProcessImageUI)
m.Post("/extension/tuomin/upload", reqSignIn, modelapp.ProcessImage)
@@ -518,6 +519,7 @@ func RegisterRoutes(m *macaron.Macaron) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
m.Any("/activate", user.Activate, reqSignIn)
m.Any("/activate_email", user.ActivateEmail)
m.Post("/update_email", bindIgnErr(auth.UpdateEmailForm{}), user.UpdateEmailPost)
m.Get("/avatar/:username/:size", user.Avatar)
m.Get("/email2user", user.Email2User)
m.Get("/recover_account", user.ResetPasswd)
@@ -1285,8 +1287,8 @@ func RegisterRoutes(m *macaron.Macaron) {

m.Group("/modelsafety", func() {
m.Group("/:id", func() {
m.Get("/show", reqRepoCloudBrainWriter, repo.GetAiSafetyTaskTmpl)
m.Get("", reqRepoCloudBrainWriter, repo.GetAiSafetyTask)
m.Get("/show", reqRepoCloudBrainReader, repo.GetAiSafetyTaskTmpl)
m.Get("", reqRepoCloudBrainReader, repo.GetAiSafetyTask)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.StopAiSafetyTask)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelAiSafetyTask)
})


+ 28
- 0
routers/user/auth.go View File

@@ -1413,6 +1413,34 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
handleSignInFull(ctx, u, false, true)
}

//update user emailAddress
func UpdateEmailPost(ctx *context.Context, form auth.UpdateEmailForm) {
newEmailAddress := ctx.Query("NewEmail")
if newEmailAddress == "" {
log.Error("please input the newEmail")
return
}
if used, _ := models.IsEmailUsed(newEmailAddress); used {
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), TplActivate, &form)
return
}
user := ctx.User
email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email)
if err != nil {
ctx.ServerError("GetEmailAddressByIDAndEmail failed", err)
return
}
err = email.UpdateEmailAddress(newEmailAddress)
if err != nil {
ctx.ServerError("UpdateEmailAddress failed", err)
return
}
ctx.Data["SignedUser.Email"] = newEmailAddress
ctx.User.Email = newEmailAddress
Activate(ctx)

}

// Activate render activate user page
func Activate(ctx *context.Context) {
code := ctx.Query("code")


+ 362
- 0
services/cloudbrain/cloudbrainTask/notebook.go View File

@@ -0,0 +1,362 @@
package cloudbrainTask

import (
"fmt"
"net/http"
"path"

"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/modelarts_cd"

"code.gitea.io/gitea/modules/git"

"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/redis/redis_key"
"code.gitea.io/gitea/modules/redis/redis_lock"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/services/cloudbrain/resource"
"code.gitea.io/gitea/services/reward/point/account"

"code.gitea.io/gitea/modules/setting"
cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
repo_service "code.gitea.io/gitea/services/repository"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
)

const NoteBookExtension = ".ipynb"

func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption) {

if ctx.Written() {
return
}

if path.Ext(option.File) != NoteBookExtension {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
return
}

isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
if !isNotebookFileExist {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
return
}

sourceRepo, err := models.GetRepositoryByOwnerAndName(option.OwnerName, option.ProjectName)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
return
}

permission, err := models.GetUserRepoPermission(sourceRepo, ctx.User)
if err != nil {
log.Error("Get permission failed", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
return
}

if !permission.CanRead(models.UnitTypeCode) {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_no_right")))
return
}

//create repo if not exist
repo, err := models.GetRepositoryByName(ctx.User.ID, setting.FileNoteBook.ProjectName)
if repo == nil {
repo, err = repo_service.CreateRepository(ctx.User, ctx.User, models.CreateRepoOptions{
Name: setting.FileNoteBook.ProjectName,
Alias: "",
Description: "",
IssueLabels: "",
Gitignores: "",
License: "",
Readme: "Default",
IsPrivate: false,
AutoInit: true,
DefaultBranch: "master",
})
}
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo",setting.FileNoteBook.ProjectName)))
return
}
if option.Type <= 1 {
cloudBrainFileNoteBookCreate(ctx, option, repo, sourceRepo)
} else {
modelartsFileNoteBookCreate(ctx, option, repo, sourceRepo)
}

}

func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {

displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
jobType := string(models.JobTypeDebug)

lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), jobType, displayJobName))
defer lock.UnLock()
isOk, err := lock.Lock(models.CloudbrainKeyDuration)
if !isOk {
log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
return
}

tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName)
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
return
}
}

count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType)
if err != nil {
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK,models.BaseMessageApi{
Code: 2,
Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
})
return
}
}

errStr := uploadCodeFile(sourceRepo, getCodePath(jobName), option.BranchName, option.File, jobName)
if errStr != "" {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
return
}
command := cloudbrain.GetCloudbrainDebugCommand()
specId := setting.FileNoteBook.SpecIdGPU
if option.Type == 0 {
specId = setting.FileNoteBook.SpecIdCPU
}
spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
JobType: models.JobType(jobType),
ComputeResource: models.GPU,
Cluster: models.OpenICluster,
AiCenterCode: models.AICenterOfCloudBrainOne})
if err != nil || spec == nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
return
}

if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
return
}
ctx.Repo = &context.Repository{
Repository: repo,
}

req := cloudbrain.GenerateCloudBrainTaskReq{
Ctx: ctx,
DisplayJobName: displayJobName,
JobName: jobName,
Image: setting.FileNoteBook.ImageGPU,
Command: command,
Uuids: "",
DatasetNames: "",
DatasetInfos: nil,
CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
JobType: jobType,
Description: getDescription(option),
BranchName: option.BranchName,
BootFile: option.File,
Params: "{\"parameter\":[]}",
CommitID: "",
BenchmarkTypeID: 0,
BenchmarkChildTypeID: 0,
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"),
Spec: spec,
}

jobId, err := cloudbrain.GenerateTask(req)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
return
}
ctx.JSON(http.StatusOK, models.BaseMessageApi{
Code: 0,
Message: jobId,
})

}

func getCodePath(jobName string) string {
return setting.JobPath + jobName + cloudbrain.CodeMountPath
}

func getDescription(option api.CreateFileNotebookJobOption) string {
return option.OwnerName + "/" + option.ProjectName + "/" + option.File
}

func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)

lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), string(models.JobTypeDebug), displayJobName))
isOk, err := lock.Lock(models.CloudbrainKeyDuration)
if !isOk {
log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
return
}
defer lock.UnLock()

count, err := GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug))

if err != nil {
log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])

ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK,models.BaseMessageApi{
Code: 2,
Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
})
return
}
}

tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName)
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.cloudbrain_samejob_err")))
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("system error."))
return
}
}

err = downloadCode(sourceRepo, getCodePath(jobName), option.BranchName)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
}

var aiCenterCode = models.AICenterOfCloudBrainTwo
var specId = setting.FileNoteBook.SpecIdNPU
if setting.ModelartsCD.Enabled {
aiCenterCode = models.AICenterOfChengdu
specId = setting.FileNoteBook.SpecIdNPUCD
}
spec, err := resource.GetAndCheckSpec(ctx.User.ID, specId, models.FindSpecsOptions{
JobType: models.JobTypeDebug,
ComputeResource: models.NPU,
Cluster: models.OpenICluster,
AiCenterCode: aiCenterCode})
if err != nil || spec == nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.wrong_specification")))
return
}
if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
log.Error("point balance is not enough,userId=%d specId=%d ", ctx.User.ID, spec.ID)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("points.insufficient_points_balance")))
return
}
ctx.Repo = &context.Repository{
Repository: repo,
}

var jobId string
if setting.ModelartsCD.Enabled {
jobId, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPUCD, spec, option.File,modelarts.AutoStopDurationMs/4)
} else {
jobId, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPU, spec, option.File,modelarts.AutoStopDurationMs/4)
}

if err != nil {
log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"])

ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))

return
}

ctx.JSON(http.StatusOK, models.BaseMessageApi{
Code: 0,
Message: jobId,
})

}

func isNoteBookFileExist(ctx *context.Context, option api.CreateFileNotebookJobOption) (bool, error) {
repoPathOfNoteBook := models.RepoPath(option.OwnerName, option.ProjectName)

gitRepoOfNoteBook, err := git.OpenRepository(repoPathOfNoteBook)
if err != nil {
log.Error("RepoRef Invalid repo "+repoPathOfNoteBook, err.Error())
return false, err
}
// We opened it, we should close it
defer func() {
// If it's been set to nil then assume someone else has closed it.
if gitRepoOfNoteBook != nil {
gitRepoOfNoteBook.Close()
}
}()
fileExist, err := fileExists(gitRepoOfNoteBook, option.File, option.BranchName)
if err != nil || !fileExist {
log.Error("Get file error:", err, ctx.Data["MsgID"])

return false, err
}
return true, nil
}

func uploadCodeFile(repo *models.Repository, codePath string, branchName string, filePath string, jobName string) string {
err := downloadCode(repo, codePath, branchName)
if err != nil {
return "cloudbrain.load_code_failed"
}

err = uploadOneFileToMinio(codePath, filePath, jobName, cloudbrain.CodeMountPath+"/")
if err != nil {
return "cloudbrain.load_code_failed"
}
return ""
}

func fileExists(gitRepo *git.Repository, path string, branch string) (bool, error) {

commit, err := gitRepo.GetBranchCommit(branch)
if err != nil {
return false, err
}
if _, err := commit.GetTreeEntryByPath(path); err != nil {
return false, err
}
return true, nil
}

+ 20
- 13
services/cloudbrain/cloudbrainTask/sync_status.go View File

@@ -1,26 +1,25 @@
package cloudbrainTask

import (
"net/http"

"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/modelarts_cd"

"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/timeutil"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/modelarts_cd"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"net/http"
"strconv"
)

var noteBookOKMap = make(map[int64]int, 20)
var noteBookFailMap = make(map[int64]int, 20)

//if a task notebook url can get two times, the notebook can browser.
//if a task notebook url can get successfulCount times, the notebook can browser.
const successfulCount = 3
const maxSuccessfulCount=10

func SyncCloudBrainOneStatus(task *models.Cloudbrain) (*models.Cloudbrain, error) {
jobResult, err := cloudbrain.GetJob(task.JobID)
@@ -117,21 +116,29 @@ func isNoteBookReady(task *models.Cloudbrain) bool {
return true
}
noteBookUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
r := httplib.Get(noteBookUrl)
res, err := r.Response()
res,err := http.Get(noteBookUrl)
if err != nil {
return false
}
log.Info("notebook success count:"+strconv.Itoa(noteBookOKMap[task.ID])+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
if res.StatusCode == http.StatusOK {
count := noteBookOKMap[task.ID]
if count < successfulCount-1 {
if count==0{ //如果是第一次成功,把失败数重置为0
noteBookFailMap[task.ID]=0
}

if count < successfulCount-1 || (noteBookFailMap[task.ID]==0 && count < maxSuccessfulCount-1) {
noteBookOKMap[task.ID] = count + 1
return false
} else {
log.Info("notebook success count:"+strconv.Itoa(count)+",fail count:"+strconv.Itoa(noteBookFailMap[task.ID]))
delete(noteBookOKMap, task.ID)
delete(noteBookFailMap, task.ID)
return true
}

}else{
noteBookFailMap[task.ID]+=1
}
return false



+ 12
- 0
services/cloudbrain/cloudbrainTask/train.go View File

@@ -810,6 +810,18 @@ func uploadCodeToMinio(codePath, jobName, parentDir string) error {
return nil
}

func uploadOneFileToMinio(codePath, filePath, jobName, parentDir string) error {
destObject := setting.CBCodePathPrefix + jobName + parentDir + path.Base(filePath)
sourceFile := codePath + "/" + filePath
err := storage.Attachments.UploadObject(destObject, sourceFile)
if err != nil {
log.Error("UploadObject(%s) failed: %s", filePath, err.Error())
return err
}
return nil

}

func readDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {


+ 26
- 0
services/cloudbrain/util.go View File

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

import (
"regexp"
"strconv"
"strings"
"time"


"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@@ -33,6 +37,28 @@ func GetAiCenterShow(aiCenter string, ctx *context.Context) string {

}

func GetDisplayJobName(username string) string {
t := time.Now()
return jobNamePrefixValid(cutString(username, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
}

func cutString(str string, lens int) string {
if len(str) < lens {
return str
}
return str[:lens]
}

func jobNamePrefixValid(s string) string {
lowStr := strings.ToLower(s)
re := regexp.MustCompile(`[^a-z0-9_\\-]+`)

removeSpecial := re.ReplaceAllString(lowStr, "")

re = regexp.MustCompile(`^[_\\-]+`)
return re.ReplaceAllString(removeSpecial, "")
}

func GetAiCenterInfoByCenterCode(aiCenterCode string) *setting.C2NetSequenceInfo {
if setting.AiCenterCodeAndNameMapInfo != nil {
if info, ok := setting.AiCenterCodeAndNameMapInfo[aiCenterCode]; ok {


+ 6
- 10
services/repository/repository.go View File

@@ -107,18 +107,13 @@ func GetRecommendCourseKeyWords() ([]string, error) {

}

func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, error) {
func GetRecommendRepoFromPromote(repoMap []map[string]string) ([]map[string]interface{}, error) {
resultRepo := make([]map[string]interface{}, 0)
url := setting.RecommentRepoAddr + filename
result, err := RecommendFromPromote(url)

if err != nil {

return resultRepo, err
}

//resultRepo := make([]*models.Repository, 0)
for _, repoName := range result {
for _, record := range repoMap {
repoName := record["project_url"]
//log.Info("repoName=" + repoName + " tmpIndex1=" + fmt.Sprint(tmpIndex1) + " len(repoName)=" + fmt.Sprint(len(repoName)))
tmpIndex := strings.Index(repoName, "/")
if tmpIndex == -1 {
log.Info("error repo name format.")
@@ -131,7 +126,8 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err
repoMap["ID"] = fmt.Sprint(repo.ID)
repoMap["Name"] = repo.Name
repoMap["Alias"] = repo.Alias

repoMap["Label"] = record["class"]
repoMap["Label_en"] = record["class_en"]
repoMap["OwnerName"] = repo.OwnerName
repoMap["NumStars"] = repo.NumStars
repoMap["NumForks"] = repo.NumForks


+ 2
- 0
templates/admin/cloudbrain/list.tmpl View File

@@ -238,6 +238,7 @@
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
{{if not .BootFile}}
<a id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
@@ -245,6 +246,7 @@
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
{{end}}
</form>
</div>
{{end}}


+ 47
- 7
templates/base/footer_content.tmpl View File

@@ -1,15 +1,17 @@
<footer>
<footer style="border-top:none;">
<div class="ui container">
<div class="ui grid">
<div class="sixteen wide mobile eight wide tablet eight wide computer column">
<div class="sixteen wide mobile wide tablet three wide computer column mobile-text-align-center">
<img style="width:166px;height:66px;margin-top:24px;" src="/img/logo-footer.svg" />
</div>
<div class="sixteen wide mobile wide tablet seven wide computer column" style="padding-left:20px;">
<div class="ui three column grid">
<div class="column ui vertical text menu">
<div class="header item">{{.i18n.Tr "custom.head.community"}}</div>
<a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.council"}}</a>
<a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">{{.i18n.Tr "custom.foot.technical_committee"}}</a>
<a href="https://openi.org.cn/html/Club/2019/0228/17.html" class="item">{{.i18n.Tr "custom.foot.join"}}</a>
<a href="{{AppSubUrl}}/home/term/" class="item">{{.i18n.Tr "custom.foot.agreement"}}</a>
<a href="{{AppSubUrl}}/home/term/" class="item">{{.i18n.Tr "custom.foot.agreement"}}</a>
</div>
<div class="column ui vertical text menu">
<div class="header item">{{.i18n.Tr "custom.foot.news"}}</div>
@@ -48,10 +50,10 @@
});
})();
</script>
<a href="https://git.openi.org.cn/zeizei/OpenI_Learning" class="item" target="_blank"><i class="compass icon" ></i> {{.i18n.Tr "custom.Platform_Tutorial"}}</a>
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" class="item" target="_blank"><i class="compass icon" ></i> {{.i18n.Tr "custom.Platform_Tutorial"}}</a>
{{if .EnableSwagger}}<a href="/api/swagger" class="item"><i class="plug icon"></i> API</a>{{end}}
{{if .IsSigned}}
<a href="https://git.openi.org.cn/zeizei/OpenI_Learning/issues/new" class="item" target="_blank"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning/issues/new" class="item" target="_blank"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
{{else}}
<a href="{{AppSubUrl}}/user/login" class="item"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
{{end}}
@@ -61,7 +63,40 @@
</div>
</div>
</div>
<div class="sixteen wide mobile eight wide tablet eight wide computer column" style=" margin:2.0rem 0">
<style>
.contacts-qr-code-c {
margin:2.0rem 0;
display:flex !important;
justify-content:flex-end;
}
</style>
<div class="sixteen wide mobile wide tablet six wide computer column contacts-qr-code-c mobile-justify-content-center">
<div style="text-align:center;">
<div style="width:80px;height:80px;display:inline-block;
background-image: url('https://openi.pcl.ac.cn/zeizei/OpenI_Learning/raw/branch/master/img/official_account_mini.png');
background-repeat: no-repeat;
background-attachment: scroll;
background-position: -2px -2px;
background-size: 84px 84px;
background-color: transparent;"
></div>
<p style="margin-top:4px;color:rgb(16, 16, 16);">{{.i18n.Tr "custom.foot.openi_subscription_number"}}</p>
</div>
<div style="text-align:center;margin-left:40px;">
<div style="width:80px;height:80px;display:inline-block;
background-image: url('https://openi.pcl.ac.cn/zeizei/OpenI_Learning/raw/branch/master/img/wechatgroup.jpg');
background-repeat: no-repeat;
background-attachment: scroll;
background-position: -7px -25px;
background-size: 94px 117px;
background-color: transparent;"
></div>
<p style="margin-top:4px;color:rgb(16, 16, 16);">{{.i18n.Tr "custom.foot.user_communication_group"}}</p>
</div>
</div>
</div>
<div class="ui grid" style="margin-top:2rem;margin-bottom:2rem;border-top:1px solid #d6d6d6;">
<div class="sixteen wide mobile sixteen wide tablet wide computer column" style=" margin:1.0rem 0;text-align:center;">
{{.i18n.Tr "custom.foot.copyright"}} <a href="http://beian.miit.gov.cn/" target="_blank">京ICP备18004880号</a>
<br>
{{.i18n.Tr "home.powerdby"}}<a href="https://www.trustie.net/" target="_blank">Trustie确实</a>{{.i18n.Tr "、Gitea"}}
@@ -69,4 +104,9 @@
</div>
</div>
</div>
<div class="__go-top" style="display:none;z-index:100;width:44px;height:44px;bottom:50px;right:50px;background:rgba(16, 16, 16, 0.1);position:fixed;cursor:pointer;border-radius:5px;">
<div style="display:flex;align-items:center;justify-content:center;height:100%;">
<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 mHEdk svg-icon-path-icon fill" viewBox="0 0 32 32" width="30" height="30"><defs data-reactroot=""></defs><g><path fill="rgba(16, 16, 16, 0.6)" d="M17.333 10.437v16.229h-2.667v-16.229l-7.152 7.152-1.885-1.885 10.371-10.371 10.371 10.371-1.885 1.885-7.152-7.152z"></path></g></svg>
</div>
</div>
</footer>

+ 2
- 2
templates/base/footer_content_fluid.tmpl View File

@@ -46,10 +46,10 @@
});
})();
</script>
<a href="https://git.openi.org.cn/zeizei/OpenI_Learning" class="item" target="_blank"><i class="compass icon"></i> {{.i18n.Tr "custom.Platform_Tutorial"}} </a>
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" class="item" target="_blank"><i class="compass icon"></i> {{.i18n.Tr "custom.Platform_Tutorial"}} </a>
{{if .EnableSwagger}}<a href="/api/swagger" class="item"><i class="plug icon" ></i> API</a>{{end}}
{{if .IsSigned}}
<a href="https://git.openi.org.cn/zeizei/OpenI_Learning/issues/new" class="item" target="_blank"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning/issues/new" class="item" target="_blank"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
{{else}}
<a href="{{AppSubUrl}}/user/login" class="item"><i class="envelope icon"></i> {{.i18n.Tr "custom.foot.advice_feedback"}}</a>
{{end}}


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

@@ -240,6 +240,7 @@ var _hmt = _hmt || [];
}
}
if (isShowNoticeTag){
if (!document.getElementById("notic_content")) return;
if(isNewNotice){
document.getElementById("notic_content").style.display='block'
}else{


+ 1
- 0
templates/base/head_home.tmpl View File

@@ -247,6 +247,7 @@ var _hmt = _hmt || [];
}
}
if (isShowNoticeTag){
if (!document.getElementById("notic_content")) return;
if(isNewNotice){
document.getElementById("notic_content").style.display='block'
}else{


+ 42
- 21
templates/base/head_navbar.tmpl View File

@@ -1,5 +1,5 @@
<div class="ui container" id="navbar">
<div class="item brand" style="justify-content: space-between;">
<div class="item brand" style="justify-content: space-between;height:62px;">
<a href="https://openi.org.cn/">
<img class="ui mini image" src="{{StaticUrlPrefix}}/img/logo-w.svg">
</a>
@@ -7,15 +7,18 @@
<i class="sidebar icon"></i>
</div>
</div>
<div style="width:1px;background:#606266;height:80%;margin:auto 0.5rem"></div>
<div class="item brand" style="margin-left: 0.9rem;">
<div class="item brand" style="padding-right:1.9rem">
<a href="/">
<img class="ui mini image" style="height: 1.3rem;" src="{{StaticUrlPrefix}}/img/git-logo.svg">
<!-- <img class="ui mini image" style="height: 1.3rem;" src="{{StaticUrlPrefix}}/img/git-logo.svg"> -->
<div>
<div style="display:flex">
<div style="line-height:24px;font-weight:700;font-size:24px;color:rgba(91,185,115,1);margin-right:2px;">AI</div>
<div style="line-height:24px;font-weight:700;font-size:21px;color:rgba(91,185,115,1);">协作平台</div>
</div>
<div style="font-weight:300;font-size:12px;color: rgba(254,221,89,1);font-style:normal;letter-spacing: 0.1px;line-height:17px;">Powered by C²NET</div>
</div>
</a>
</div>


{{if .IsSigned}}
<div class=" item edge">
<div class="dropdown-menu">
@@ -116,14 +119,14 @@
{{if .IsSigned}}
<div class="right stackable menu">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<div class="ui fluid action input" style="background:transparent ;border-radius: 5px;width: 200px;height:30px;border:rgb(233,233,233) solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:white;background:transparent;color:white;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="hot">
<button style="border: none;background-color: #363840;outline: none;border-radius:5px"><img type = "submit" style="width: 25px; height: 25px;margin: auto;" src="/img/search.svg" >
</button>
<!-- <button class="ui green button">{{.i18n.Tr "explore.search"}}</button> -->
<button style="border:none;background-color:transparent;outline:none;border-radius:5px;cursor:pointer;">
<img type="submit" style="width:21px;height:21px;margin:auto;vertical-align:bottom;" src="/img/search.svg" >
</button>
</div>
</form>
<a href="{{AppSubUrl}}/notifications" class="item poping up" data-content='{{.i18n.Tr "notifications"}}' data-variation="tiny inverted">
@@ -160,7 +163,7 @@
</div><!-- end dropdown menu create new -->

<div class="ui simple dropdown jump item poping up" tabindex="-1" data-content="{{.i18n.Tr "user_profile_and_more"}}" data-variation="tiny inverted">
<span class="text">
<span class="text" style="display:flex;align-items:center;">
<img class="ui tiny avatar image" width="24" height="24" src="{{.SignedUser.RelAvatarLink}}">
<span class="sr-only">{{.i18n.Tr "user_profile_and_more"}}</span>
<span class="mobile-only">{{.SignedUser.Name}}</span>
@@ -188,7 +191,7 @@
{{svg "octicon-question" 16}}
{{.i18n.Tr "help"}}<!-- Help -->
</a-->
<a class="item" href="https://git.openi.org.cn/zeizei/OpenI_Learning" target="_blank">
<a class="item" href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" target="_blank">
<i class="tutorial_icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/><path d="M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zM12 5v14h8V5h-8zm1 2h6v2h-6V7zm0 3h6v2h-6v-2z"/>
@@ -216,6 +219,13 @@
</a>
</div><!-- end content avatar menu -->
</div><!-- end dropdown avatar menu -->
<div class="ui simple item poping up" data-content="{{.i18n.Tr "help"}}" data-variation="tiny inverted">
<a target="_blank" href="{{AppSubUrl}}/docs/index.html">
<div style="display:flex;justify-content:center;align-items:center;font-size:10px;cursor:pointer;width:26px;height:26px;border-radius:100%;text-align:center;background: url(&quot;data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3CradialGradient%20id%3D%221%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientTransform%3D%22matrix(0.7%2C%20-0.5250000000000001%2C%200.5250000000000001%2C%200.7%2C%200.283%2C%200.767)%22%3E%3Cstop%20stop-color%3D%22%2361d8dc%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23498af9%22%20stop-opacity%3D%221%22%20offset%3D%220.63%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23e840f7%22%20stop-opacity%3D%221%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E&quot;);">
<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 fPsHiw svg-icon-path-icon fill" viewBox="0 0 384 512" width="16" height="16"><defs data-reactroot=""></defs><g><path fill="rgb(255,255,255)" d="M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"></path></g></svg>
</div>
</a>
</div>
</div><!-- end signed user right menu -->

{{else}}
@@ -224,19 +234,19 @@
<div class="right stackable menu">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<div class="ui fluid action input" style="background:transparent ;border-radius: 5px;width: 200px;height:30px;border:rgb(233,233,233) solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:white;background:transparent;color:white;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="hot">
<button style="border: none;background-color: #363840;outline: none;border-radius:5px"><img type = "submit" style="width: 25px; height: 25px;margin: auto;" src="/img/search.svg" >
</button>
<!-- <button class="ui green button">{{.i18n.Tr "explore.search"}}</button> -->
<button style="border:none;background-color:transparent;outline:none;border-radius:5px;cursor:pointer;">
<img type="submit" style="width:21px;height:21px;margin:auto;vertical-align:bottom;" src="/img/search.svg" >
</button>
</div>
</form>
{{if .ShowRegistrationButton}}
{{if .IsCourse}}
<a class="item{{if .PageIsSignUp}} active{{end}}" href="https://git.openi.org.cn/user/sign_up" target="_blank">
<a class="item{{if .PageIsSignUp}} active{{end}}" href="https://openi.pcl.ac.cn/user/sign_up" target="_blank">
{{svg "octicon-person" 16}} {{.i18n.Tr "register"}}
</a>
{{else}}
@@ -246,7 +256,7 @@
{{end}}
{{end}}
{{if .IsCourse}}
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="https://git.openi.org.cn/user/login?course=true" target="_blank">
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="https://openi.pcl.ac.cn/user/login?course=true" target="_blank">
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}}
</a>
{{else}}
@@ -254,9 +264,20 @@
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}}
</a>
{{end}}

<div class="ui simple item poping up" data-content="{{.i18n.Tr "help"}}" data-variation="tiny inverted">
<a target="_blank" href="{{AppSubUrl}}/docs/index.html">
<div style="display:flex;justify-content:center;align-items:center;font-size:10px;cursor:pointer;width:26px;height:26px;border-radius:100%;text-align:center;background: url(&quot;data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3CradialGradient%20id%3D%221%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientTransform%3D%22matrix(0.7%2C%20-0.5250000000000001%2C%200.5250000000000001%2C%200.7%2C%200.283%2C%200.767)%22%3E%3Cstop%20stop-color%3D%22%2361d8dc%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23498af9%22%20stop-opacity%3D%221%22%20offset%3D%220.63%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23e840f7%22%20stop-opacity%3D%221%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E&quot;);">
<svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 fPsHiw svg-icon-path-icon fill" viewBox="0 0 384 512" width="16" height="16"><defs data-reactroot=""></defs><g><path fill="rgb(255,255,255)" d="M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"></path></g></svg>
</div>
</a>
</div>

</div><!-- end anonymous right menu -->

{{end}}



</div>


+ 1
- 1
templates/base/head_navbar_fluid.tmpl View File

@@ -186,7 +186,7 @@
{{svg "octicon-question" 16}}
{{.i18n.Tr "help"}}<!-- Help -->
</a-->
<a class="item" href="https://git.openi.org.cn/zeizei/OpenI_Learning" target="_blank">
<a class="item" href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" target="_blank">
<i class="tutorial_icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/><path d="M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zM12 5v14h8V5h-8zm1 2h6v2h-6V7zm0 3h6v2h-6v-2z"/>


+ 1
- 1
templates/base/head_navbar_home.tmpl View File

@@ -168,7 +168,7 @@
{{svg "octicon-question" 16}}
{{.i18n.Tr "help"}}<!-- Help -->
</a-->
<a class="item" href="https://git.openi.org.cn/zeizei/OpenI_Learning" target="_blank">
<a class="item" href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" target="_blank">
<i class="tutorial_icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/><path d="M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zM12 5v14h8V5h-8zm1 2h6v2h-6V7zm0 3h6v2h-6v-2z"/>


+ 1
- 1
templates/base/head_navbar_pro.tmpl View File

@@ -189,7 +189,7 @@
{{svg "octicon-question" 16}}
{{.i18n.Tr "help"}}<!-- Help -->
</a-->
<a class="item" href="https://git.openi.org.cn/zeizei/OpenI_Learning" target="_blank">
<a class="item" href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" target="_blank">
<i class="tutorial_icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/><path d="M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zM12 5v14h8V5h-8zm1 2h6v2h-6V7zm0 3h6v2h-6v-2z"/>


+ 1
- 1
templates/base/head_notice.tmpl View File

@@ -1,5 +1,5 @@
{{if not .IsCourse}}
{{ if .notices}}
{{ if (and .notices (not .PageIsHome)) }}
<div class="notic_content" id ="notic_content" style="display: block; position: relative">
<div class="ui container">
<marquee behavior="scroll" direction="left">


+ 36
- 0
templates/custom/home/home_activity.tmpl View File

@@ -0,0 +1,36 @@
<style>
.homeactivity {
padding-top: 5rem;
padding-bottom: 6rem;
overflow: hidden;
}
.homeactivity .card {
width: 360px !important;
height: 160px !important;
}
.homeactivity img {
width: 100% !important;
height: 100% !important;
}
.homeactivity .image-name {
font-size: 14px;
color: rgb(16, 16, 16);
text-align: center;
margin-top: 0.8em;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 20px;
box-sizing: border-box;
white-space: nowrap;
}
</style>
<div class="ui container homeactivity _hm-container">
<div class="ui center homepro-tit am-mb-20">
<h2>{{.page_recommend_activity}}</h2>
<p><span class="ui text grey">{{.page_recommend_activity_desc}}</p>
</div>
<div class="event-list">
<div class="swiper-wrapper" id="recommendactivity"></div>
<div class="swiper-pagination"></div>
</div>
</div>

+ 85
- 0
templates/custom/home/home_dataset.tmpl View File

@@ -0,0 +1,85 @@
<style>
.homedataset {
padding-top: 4em;
padding-bottom: 4em;
}
.home-dataset-list {
position: relative;
z-index: 9;
padding: 0em 1em 3em;
overflow: hidden;
}
.home-dataset-list .swiper-slide {
padding-top: 5px;
}
.home-dataset-list .dataset-card {
height: 130px;
width: 130px;
border: 1px solid rgba(157, 197, 226, 0.4);
box-shadow: rgb(157 197 226 / 20%) 0px 5px 10px 0px;
color: rgb(16, 16, 16);
border-radius: 6px;
display:flex;
justify-content: center;
align-items: center;
flex-direction: column;
transition: all 0.1s;
}
.home-dataset-list .dataset-card:hover {
transform: translateY(-3px);
}
.home-dataset-list .dataset-card>div {
width:100%;
display: flex;
justify-content: center;
}
.home-dataset-list .dataset-card .content {
width:100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
padding: 0 10px;
}
.home-dataset-list .dataset-card .icon-c {
font-size: 14px;
color: #101010;
display:flex;
justify-content: center;
align-items: center;
margin-bottom: 8px;
}
.home-dataset-list .dataset-card .label {
font-size: 14px;
color: #101010;
margin-bottom: 8px;
}
.home-dataset-list .dataset-card .svg.fill:not([stroke]) {
fill: url(#ila93em9ydx6bi61,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs);
}
.home-dataset-list .dataset-card .svg.fill:not([fill]) {
fill: url(#ila93em9ydx6bi61,1,rs,1,f000f000,f0rsf000,f000,00e6msqtrs,dw4hjuqlrs,ri00exmcrs);
}
.home-dataset-list .dataset-card .count {
font-size:12px;
color:rgb(136,136,136);
}
.home-dataset-list .swiper-pagination-bullet-active {
width: 40px;
border-radius: 4px;
}
</style>
<div class="ui container homedataset _hm-container">
<div class="ui stackable grid">
<div class="sixteen wide tablet four wide computer column mobile-text-align-center">
<h2>{{.i18n.Tr "home.search_dataset"}}</h2>
<p><span class="ui text grey">{{.i18n.Tr "home.datasets_descr"}}&nbsp;</span><a href="/explore/datasets">{{.i18n.Tr "home.search_dataset"}}</a></p>
</div>
<div class="sixteen wide tablet twelve wide computer column">
<div class="home-dataset-list">
<div class="swiper-wrapper" id="home_dataset"></div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</div>

+ 20
- 0
templates/custom/home/home_org.tmpl View File

@@ -0,0 +1,20 @@
<style>

</style>
<div class="ui container homeorg _hm-container" style="max-width:1200px;">
<div class="ui stackable grid">
<div class="sixteen wide tablet sixteen wide computer column mobile-text-align-center" style="text-align:center;">
<h2>{{.page_recommend_org}}</h2>
<p><span class="ui text grey">{{.page_recommend_org_desc}}&nbsp;</span><a href="{{.RecommendURL}}">{{.page_recommend_org_commit}}</a>
{{.i18n.Tr "home.org_see"}}
<a href="{{AppSubUrl}}/explore/organizations" class="">{{.page_recommend_org_more}}</a>
</p>
</div>
<div class="sixteen wide tablet sixteen wide computer column">
<div class="homeorg-list">
<div class="swiper-wrapper" id="recommendorg"></div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</div>

+ 21
- 0
templates/custom/home/home_repo.tmpl View File

@@ -0,0 +1,21 @@
<style>
.homepro-bg {
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(0.013999999999999973%2C%201.0040000000000002%2C%20-0.1807553452932099%2C%200.013999999999999973%2C%200.374%2C%20-0.007)%22%3E%3Cstop%20stop-color%3D%22%23eee9da%22%20stop-opacity%3D%220.2%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23f3e7f7%22%20stop-opacity%3D%220.26%22%20offset%3D%220.29%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23d0e7ff%22%20stop-opacity%3D%220.3%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}
</style>
<div class="homepro-bg">
<div class="ui container homepro _hm-container" style="padding-top:4rem;padding-bottom:3rem;">
<div class="ui stackable grid">
<div class="sixteen wide tablet four wide computer column mobile-text-align-center">
<h2>{{.page_recommend_repo}}</h2>
<p><span class="ui text grey">{{.page_recommend_repo_desc}}&nbsp;</span><a href="{{.RecommendURL}}">{{.page_recommend_repo_commit}}</a>&nbsp;<span class="ui text grey">{{.page_recommend_repo_go}}</span>&nbsp;<a href="{{AppSubUrl}}/explore/">{{.page_recommend_repo_more}}</a></p>
</div>
<div class="sixteen wide tablet twelve wide computer column">
<div class="homepro-list">
<div class="swiper-wrapper" id="recommendrepo"></div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</div>
</div>

+ 2079
- 0
templates/custom/home/home_top.tmpl
File diff suppressed because it is too large
View File


+ 134
- 0
templates/custom/home/home_user_experience.tmpl View File

@@ -0,0 +1,134 @@
<style>
.homeuserexp-bg {
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(0.04900000000000009%2C%201.104%2C%20-0.06118479166666667%2C%200.04900000000000009%2C%200.339%2C%20-0.107)%22%3E%3Cstop%20stop-color%3D%22%23ffffff%22%20stop-opacity%3D%220.33%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23e5e7eb%22%20stop-opacity%3D%220.3%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}
.homeuserexp {
padding-top: 5em;
padding-bottom: 2em;
}

.homeuserexp .swiper-prev {
position: absolute;
top: 104px;
left: 14px;
z-index: 10;
}

.homeuserexp .swiper-next {
position: absolute;
top: 104px;
right: 14px;
z-index: 10;
}
.homeuserexp .prev-next-i {
font-size: 22px;
border: 1px solid rgb(0, 122, 255);
border-radius: 100%;
color: rgb(0, 122, 255);
cursor: pointer;
}
.homeuserexp .swiper-prev.swiper-button-disabled .prev-next-i, .homeuserexp .swiper-next.swiper-button-disabled .prev-next-i {
opacity: 0.35;
cursor: default;
}

.home-user-exp-list {
position: relative;
z-index: 9;
padding: 0em 1.2em 3em 1.2em;
overflow: hidden;
}

.home-user-exp-list .user-card {
width: 240px;
height: 180px;
color: rgb(16, 16, 16);
border-radius: 6px;
display:flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.home-user-exp-list .swiper-slide {
display: flex;
justify-content: center;
}

.home-user-exp-list .user-card>div {
width:100%;
display: flex;
justify-content: center;
}

.home-user-exp-list .user-card .content {
width:100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
padding: 0 10px;
}

.home-user-exp-list .user-card .img-c {
font-size: 14px;
color: #101010;
display:flex;
justify-content: center;
align-items: center;
height: 74px;
margin-bottom: 8px;
}

.home-user-exp-list .user-card .img {
border: 3px solid rgb(243, 240, 164);
border-radius: 100%;
box-shadow: rgb(255 220 144) 0px 0px 0px 2px;
height: 60px;
width: 60px;
display: block;
background-size:cover;
}

.home-user-exp-list .user-card .label {
font-size: 14px;
color: #101010;
margin-bottom: 8px;
font-weight: 550;
}

.home-user-exp-list .user-card .descr {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-size:12px;
color:rgb(136,136,136);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
max-height: 50px;
height: 40px;
white-space: break-spaces;
}
</style>
<div class="homeuserexp-bg">
<div class="ui container homeuserexp _hm-container">
<div class="ui stackable grid">
<div class="sixteen wide tablet four wide computer column mobile-text-align-center">
<h2>{{.i18n.Tr "home.experience_officer"}}</h2>
<p><a href="https://openi.org.cn/index.php?m=content&c=index&a=lists&catid=220">{{.i18n.Tr "home.openi_experience_officer_plan"}}</a><span class="ui text grey">{{.i18n.Tr "home.more_benefits"}}</span></p>
</div>
<div class="sixteen wide tablet twelve wide computer column">
<div class="home-user-exp-list">
<div class="swiper-wrapper" id="home_user-exp"></div>
<div style="display:none;" class="swiper-button-prev"></div>
<div style="display:none;" class="swiper-button-next"></div>
</div>
<div class="swiper-prev"><i class="ri-arrow-left-line prev-next-i"></i></div>
<div class="swiper-next"><i class="ri-arrow-right-line prev-next-i"></i></div>
</div>
</div>
</div>
</div>

+ 7
- 7
templates/explore/repo_orgtop.tmpl View File

@@ -46,49 +46,49 @@
{{end}}-->
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/OpenI">
<a class="image" href="https://openi.pcl.ac.cn/OpenI">
<img src="/img/org-openi@2x-80.jpg" alt="OpenI 启智社区" title="OpenI 启智社区">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/JDOpenISCT">
<a class="image" href="https://openi.pcl.ac.cn/JDOpenISCT">
<img src="/img/org-jd@2x-80.jpg" alt="京东智能供应链开源工具" title="京东智能供应链开源工具">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/OpenI/TensorLayerX">
<a class="image" href="https://openi.pcl.ac.cn/OpenI/TensorLayerX">
<img src="/img/org-tensorlayer@2x-80.jpg" alt="TensorLayer" title="TensorLayer">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/PCL-Platform.Intelligence">
<a class="image" href="https://openi.pcl.ac.cn/PCL-Platform.Intelligence">
<img src="/img/org-platform@2x-80.jpg" alt="PCL-Platform.Intelligence" title="PCL-Platform.Intelligence">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/BAAI">
<a class="image" href="https://openi.pcl.ac.cn/BAAI">
<img src="/img/org-baai@2x-80.jpg" alt="BAAI" title="BAAI">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/OpenModelZoo">
<a class="image" href="https://openi.pcl.ac.cn/OpenModelZoo">
<img src="/img/org-modelzoo@2x-80.jpg" alt="OpenModelZoo" title="OpenModelZoo">
</a>
</div>
</div>
<div class="swiper-slide">
<div class="ui card">
<a class="image" href="https://git.openi.org.cn/PCL_EngineClub">
<a class="image" href="https://openi.pcl.ac.cn/PCL_EngineClub">
<img src="/img/org-engineclub@2x-80.jpg" alt="PCL_EngineClub" title="PCL_EngineClub">
</a>
</div>


+ 5
- 5
templates/explore/repo_right.tmpl View File

@@ -9,31 +9,31 @@
<div class="item">
<i class="sticky note outline icon"></i>
<div class="content">
<div ><a href="https://git.openi.org.cn/OpenI/aiforge/wiki">启智AI开发协同平台使用说明</a></div>
<div ><a href="https://openi.pcl.ac.cn/OpenI/aiforge/wiki">启智AI开发协同平台使用说明</a></div>
</div>
</div>
<div class="item">
<i class="sticky note outline icon"></i>
<div class="content">
<div ><a href="https://git.openi.org.cn/OpenI/Paddle/wiki">启智飞桨 Paddle 2.0 项目手册</a></div>
<div ><a href="https://openi.pcl.ac.cn/OpenI/Paddle/wiki">启智飞桨 Paddle 2.0 项目手册</a></div>
</div>
</div>
<div class="item">
<i class="sticky note outline icon"></i>
<div class="content">
<div ><a href="https://git.openi.org.cn/OpenI/aiforge/wiki/cloudbrain">启智社区使用云脑计算资源进行调试说明</a></div>
<div ><a href="https://openi.pcl.ac.cn/OpenI/aiforge/wiki/cloudbrain">启智社区使用云脑计算资源进行调试说明</a></div>
</div>
</div>
<div class="item">
<i class="sticky note outline icon"></i>
<div class="content">
<div ><a href="https://git.openi.org.cn/PCL-Federated.Learning.Middleware/HiStar/wiki">海星HiStar:联邦深度学习中间件帮助文档</a></div>
<div ><a href="https://openi.pcl.ac.cn/PCL-Federated.Learning.Middleware/HiStar/wiki">海星HiStar:联邦深度学习中间件帮助文档</a></div>
</div>
</div>
<div class="item">
<i class="sticky note outline icon"></i>
<div class="content">
<div ><a href="https://git.openi.org.cn/OpenI/octopus/wiki/启智章鱼">启智章鱼开源项目文档</a></div>
<div ><a href="https://openi.pcl.ac.cn/OpenI/octopus/wiki/启智章鱼">启智章鱼开源项目文档</a></div>
</div>
</div>
</div>

+ 1
- 3
templates/explore/repos.tmpl View File

@@ -1,9 +1,7 @@
{{template "base/head_pro" .}}
{{template "base/head_home" .}}
<div class="explore repositories">

{{template "explore/repo_search" .}}
{{template "explore/repo_orgtop" .}}
<div class="ui container">
<div class="ui grid">
{{template "explore/repo_left" .}}


+ 27
- 89
templates/home.tmpl View File

@@ -1,99 +1,32 @@
{{template "base/head_home" .}}
<div class="ui vertical masthead secondary hometop segment">
<div class="ui container" style="position: relative;">
<div class="ui center homebanner">
<h1 class="ui huge header">
{{.page_title}}
<div class="sub header">
{{.page_small_title}}
</div>
</h1>
<p class="ui am-lh-18">{{.page_description}}</p>
{{if .IsSigned}}
<a class="circular huge ui secondary button" href="{{AppSubUrl}}/dashboard">{{.page_use}} <i class="right arrow icon"></i></a>
{{else}}
<a class="circular huge ui secondary button" href="{{AppSubUrl}}/user/login">{{.page_use}} <i class="right arrow icon"></i></a>
{{end}}
</div>
<div class="bannerpic"><img class="ui fluid image" src="/img/gitopeni-index-01.svg"></div>
<div id="homenews">
<p>* {{.page_only_dynamic}}</p>
<div class="ui grid">
<div class="sixteen wide mobile twelve wide tablet ten wide computer column homenews">
<div class="newslist">
<div class="ui mini aligned list swiper-wrapper" id="newmessage">
</div>
</div>
</div>
</div>
</div><!-- end homenews -->
</div>
</div><!-- end segment -->
<div class="ui vertical masthead secondary hometop segment" style="background:transparent;margin-bottom:0">
{{template "custom/home/home_top" .}}
</div>

<!--组织-->
<div class="ui container homeorg">
<div class="ui stackable grid">
<div class="sixteen wide tablet four wide computer column homeorg-tit">
<h2>{{.page_recommend_org}}</h2>
<p><span class="ui text grey">{{.page_recommend_org_desc}}&nbsp;</span><a href="{{.RecommendURL}}">{{.page_recommend_org_commit}}</a></p>
<a href="{{AppSubUrl}}/explore/organizations" class="circular ui primary basic button">{{.page_recommend_org_more}} <i class="arrow circle right icon"></i></a>
</div>
<div class="sixteen wide tablet twelve wide computer column">
<div class="homeorg-list">
<div class="swiper-wrapper" id="recommendorg">
</div>
<div class="swiper-pagination"></div>
</div>
</div>
{{template "custom/home/home_org" .}}

<div class="sixteen wide tablet four wide computer column homeorg-tit">
<h2>{{.page_recommend_activity}}</h2>
<p><span class="ui text grey">{{.page_recommend_activity_desc}}</p>
</div>
<div class="sixteen wide tablet twelve wide computer column">
<div class="event-list">
<div class="swiper-wrapper" id="recommendactivity">
</div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
<div class="leftline01"></div>
</div>
<!--项目-->
<div class="ui container homepro">
<div class="leftline02"></div>
<div class="leftline02-2"></div>
<div class="ui center homepro-tit am-mb-20">
<h2>{{.page_recommend_repo}}</h2>
<p><span class="ui text grey">{{.page_recommend_repo_desc}}&nbsp;</span><a href="{{.RecommendURL}}">{{.page_recommend_repo_commit}}</a>{{.page_recommend_repo_go}}&nbsp;<a href="{{AppSubUrl}}/explore/">{{.page_recommend_repo_more}}</a></p>
</div>
<!-- 项目 -->
{{template "custom/home/home_repo" .}}

<div class="homepro-list">
<div class="swiper-wrapper" id="recommendrepo">
</div>
<div class="swiper-pagination"></div>
</div>
</div>
<!-- 数据集 -->
{{template "custom/home/home_dataset" .}}

<!-- 体验官 -->
{{template "custom/home/home_user_experience" .}}

<!-- 社区活动 -->
{{template "custom/home/home_activity" .}}

<!-- 中国算力网(C²NET) -->
<div class="ui vertical masthead secondary c2net segment">
<div class="ui container">
<div class="ui center am-pt-30 am-pb-30">
<h2>{{.i18n.Tr "home.c2net_title"}}</h2>
<p><span class="ui text grey">{{.i18n.Tr "home.c2net_desc"}}</p>
</div>

<div id="app" v-cloak>
<div id="app" class="_hm-computing-net-container" v-cloak>
<!--底座-->
<div class="rotation3D-baseMap"></div>
<!--旋转3D-->
@@ -135,12 +68,13 @@
</div>
</div>
</div><!--rotation3D end-->
<div class="_hm-computing-net-mobile-container" style="display:none;"></div>
</div>
</div>
</div>

<!-- 协同开发环境 -->
<a name="fourth"></a>
<div class="ui container i-env">
<div class="ui container i-env _hm-container" style="padding-bottom:0rem;padding-top:4rem;">
<div class="ui center am-pb-30">
<h2>{{.page_dev_env}}</h2>
<p><span class="ui text grey">{{.page_dev_env_desc}}</p>
@@ -193,8 +127,10 @@
</div>
</div>

<!-- 启智AI协作平台 介绍 -->
<!--
<a name="fifth"></a>
<div class="ui container">
<div class="ui container _hm-container">
<div class="ui very padded inverted segment radius15">
<div class="ui stackable grid">
<div class="six wide column">
@@ -221,7 +157,9 @@
</div>
</div>
</div>
<div class="am-mt-30"></div>
-->

<!-- <div class="am-mt-30"></div> -->
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/home/home.js?v={{MD5 AppVer}}" type="text/javascript"></script>



+ 81
- 0
templates/notice.tmpl View File

@@ -0,0 +1,81 @@

{{template "base/head_home" .}}
<style>
.notice-container {
}
.notice-row {
display: flex;
justify-content: space-between;
align-items: center;
height: 52px;
border-bottom: 1px solid rgba(157, 197, 226, 0.2);
padding: 0 16px;
}
.notice-title {
flex: 1;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.notice-title a {
font-size: 16px;
color: rgb(16, 16, 16);
}
.notice-title a:hover {
opacity: 0.8;
}
.notice-time {
width: 150px;
text-align: right;
font-size: 14px;
color: rgba(16, 16, 16, 0.6);
}
</style>
<div class="ui container">
<h3 class="ui center am-pt-30 am-pb-20">{{.i18n.Tr "notice_announcement"}}</h3>
<div class="notice-container">
</div>
</div>
{{template "base/footer" .}}
<script>
;(function() {
var isZh = document.documentElement.getAttribute('lang') == 'zh-CN';
function getNotice() {
$.ajax({
type:"GET",
url:"/dashboard/invitation",
dataType:"json",
data: {
filename: 'notice/notice.json',
},
success:function(data){
if (!data) return;
try {
var noticeList = JSON.parse(data).Notices || [];
var noticeEl = $('.notice-container');
for (var i = 0, iLen = noticeList.length; i < iLen; i++) {
var noticeObj = noticeList[i];
noticeEl.append(`<div class="notice-row">
<div class="notice-title">
<a class="_hm-notice" href="${noticeObj.Link}">
<i class="ri-arrow-right-s-line" style="vertical-align:-2px;"></i>
<span>${isZh ? noticeObj.Title : (noticeObj.Title_en || noticeObj.Title)}</span>
</a>
</div>
<div class="notice-time">${noticeObj.Date || ''}</div>
</div>`);
}
} catch (e) {
console.info(e);
}
},
error:function(err) {
console.info(err);
}
});
}
getNotice();
})();
</script>

+ 2
- 2
templates/org/home_courses.tmpl View File

@@ -116,7 +116,7 @@
<div class="ui sixteen wide mobile six wide tablet four wide computer column">
<div class=" ui bottom attached segment text center noborder text center" >
<a style="width: 80%;" class="ui green button bpadding" href="https://git.openi.org.cn/course/create" target="_blank"><i class="ri-folder-add-line" style="vertical-align: middle;"></i> &nbsp;{{.i18n.Tr "org.release_course"}} </a>
<a style="width: 80%;" class="ui green button bpadding" href="https://openi.pcl.ac.cn/course/create" target="_blank"><i class="ri-folder-add-line" style="vertical-align: middle;"></i> &nbsp;{{.i18n.Tr "org.release_course"}} </a>
</div>
</div>
</div>
@@ -185,7 +185,7 @@
{{if .IsSigned}}
<a class="ui blue basic button" onclick="jion_course_team()" style="width: 80%;"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a>
{{else}}
<a class="ui blue basic button" href="https://git.openi.org.cn/user/login?course=true" style="width: 80%;" target="_blank"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a>
<a class="ui blue basic button" href="https://openi.pcl.ac.cn/user/login?course=true" style="width: 80%;" target="_blank"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a>
{{end}}
</div>
</div>


+ 10
- 10
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -113,7 +113,7 @@
data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}}
data-position="right center" data-variation="mini"></i>
</span>
<a id="benchmark_model_example" href="https://git.openi.org.cn/BDIP/snn4imagenet"
<a id="benchmark_model_example" href="https://openi.pcl.ac.cn/BDIP/snn4imagenet"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

@@ -270,7 +270,7 @@
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label>
<input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file"
value="train.py" tabindex="3" autofocus required maxlength="254">
<a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark"
<a id="train_href_id" href="https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark"
target="_blank">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</a>
</div>

@@ -278,7 +278,7 @@
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label>
<input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py"
tabindex="3" autofocus required maxlength="254">
<a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark"
<a id="test_href_id" href="https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

@@ -349,7 +349,7 @@
<label class="label-fix-width" style="font-weight: normal;">推理程序</label>
<input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py"
tabindex="3" autofocus required maxlength="254">
<a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark"
<a id="test_href_id" href="https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

@@ -390,10 +390,10 @@
onChange: function (value, text, $selectedItem) {
if (value === "BRAINSCORE") {
$('#brainscore_child_type').css('display', 'block')
$('#benchmark_model_example').attr('href', 'https://git.openi.org.cn/BDIP/similarity2brain_ann')
$('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/similarity2brain_ann')
} else {
$('#brainscore_child_type').css('display', 'none')
$('#benchmark_model_example').attr('href', 'https://git.openi.org.cn/BDIP/snn4imagenet')
$('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/snn4imagenet')
}
}
})
@@ -401,11 +401,11 @@
function setChildType() {
let type_id = $('#benchmark_types_id').val();
if (type_id == 3) {
$('#train_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark');
$('#test_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark');
$('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
$('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
} else {
$('#train_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark');
$('#test_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark');
$('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
$('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
}
let child_selected_id = $('#benchmark_child_types_id_hidden').val();
$.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => {


+ 1
- 1
templates/repo/cloudbrain/inference/new.tmpl View File

@@ -211,7 +211,7 @@
<span >
<i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

<!-- 运行参数 -->


+ 1
- 1
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -196,7 +196,7 @@
data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}}
data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>
<div id="select-multi-dataset">



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

@@ -415,7 +415,7 @@
<div class="bgtask-content">
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div>
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a
href="https://git.openi.org.cn/zeizei/OpenI_Learning">&nbsp;{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div>
href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">&nbsp;{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div>
</div>
</div>
</div>


+ 13
- 2
templates/repo/debugjob/index.tmpl View File

@@ -220,8 +220,13 @@
<div class="two wide column text center">
<!--任务状态 -->
<span class="job-status" id="{{.Cloudbrain.ID}}"
<<<<<<< HEAD
data-repopath="{{$.RepoRelPath}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}"
data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}">
=======
data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}"
data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}" data-bootfile="{{.BootFile}}">
>>>>>>> V20221214
<span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;"
class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text"
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
@@ -266,6 +271,7 @@
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
{{if not .BootFile}}
<a id="ai-debug-{{.Cloudbrain.ID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{.Cloudbrain.ID}}"
@@ -274,6 +280,7 @@
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
{{end}}
{{else}}
{{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}}
<a class="ui basic disabled button">
@@ -295,6 +302,8 @@
class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED" "CREATE_FAILED" "DELETED"}}disabled {{else}}blue {{end}}button'
data-repopath='{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/stop'
data-jobid="{{.Cloudbrain.ID}}">
{{if .BootFile}}data-bootfile="{{.BootFile}}"{{end}}>

{{$.i18n.Tr "repo.stop"}}
</a>
{{else}}
@@ -322,6 +331,7 @@
{{end}}
</form>
</div>
{{if not .BootFile}}
<div class="ui compact buttons"
style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}">
<div class="ui dropdown" id="model_more"
@@ -363,6 +373,7 @@
</div>
</div>
</div>
{{end}}
</div>
<!-- 镜像列表弹窗 -->

@@ -421,7 +432,7 @@
</div>

<div class="ui modal debug-again-alert">
<div class="ui message" style="background-color: rgba(242, 113, 28, 0.05);border: 1px solid rgba(242, 113, 28, 1);border-radius: 5px;">
<div class="ui message" style="background-color: rgba(242, 113, 28, 0.05);border: 1px solid rgba(242, 113, 28, 1);border-radius: 5px;">
<div style="display: flex;align-items: center;">
<i class="ri-information-line" style="font-size: 35px;color: rgba(242, 113, 28, 1);;"></i>
<div style="text-align: left;margin-left: 1rem;">
@@ -471,4 +482,4 @@
})
})

</script>
</script>

+ 1
- 1
templates/repo/grampus/trainjob/gpu/new.tmpl View File

@@ -172,7 +172,7 @@
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>




+ 1
- 1
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -183,7 +183,7 @@
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_Example/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MNIST_Example/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

<div id="select-multi-dataset">


+ 3
- 3
templates/repo/header.tmpl View File

@@ -52,13 +52,13 @@
{{if not .IsBeingCreated}}
<div class="repo-buttons">
<div class="ui labeled button" tabindex="0">
<div class="ui compact basic button" onclick="$('.__watch_btn__').dropdown('show')">
<div style="position:relative;" class="ui compact basic button" onclick="$('.__watch_btn__').dropdown('show')">
<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.watched"}}{{else}}{{$.i18n.Tr "repo.notWatched"}}{{end}}
<i class="dropdown icon" style="margin:0 -8px 0 4px"></i>
<div class="ui dropdown floating __watch_btn__" onclick="event.stopPropagation();">
<div style="position:absolute;left:0;top:23px;" class="ui dropdown floating __watch_btn__" onclick="event.stopPropagation();">
<div class="text" style="display:none;"></div>
{{$WatchNotifyType := or $.WatchNotifyType 0}}
<div class="menu" style="margin-left:-64px;">
<div class="menu">
<div class="item {{if not $.IsWatchingRepo}}active selected{{end}}">
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/unwatch?redirect_to={{$.Link}}">
{{$.CsrfTokenHtml}}


+ 29
- 29
templates/repo/home.tmpl View File

@@ -99,6 +99,9 @@
animation-fill-mode: both;
}
</style>
{{if and (.IsViewFile) (IpynbBool .TreePath)}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-notebook-debug.css?v={{MD5 AppVer}}" />
{{end}}
<div class="repository file list">
{{template "repo/header" .}}
<div class="ui container">
@@ -154,7 +157,9 @@
{{.i18n.Tr "repo.archive.title"}}
</div>
{{end}}
{{if not .IsViewFile}}
{{template "repo/sub_menu" .}}
{{end}}
<div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins">
{{template "repo/branch_dropdown" .}}
{{ $n := len .TreeNames}}
@@ -200,6 +205,7 @@
class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}"
title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div>
{{end}}
<div class="right fitted item" id="file-buttons">
<div class="ui tiny blue buttons">
{{if .Repository.CanEnableEditor}}
@@ -223,7 +229,6 @@
</a>
{{end}}
</div>

</div>
<div class="fitted item">
{{if eq $n 0}}
@@ -237,7 +242,6 @@
{{end}}
</div>
<div class="fitted item">

<!-- Only show clone panel in repository home page -->
{{if eq $n 0}}
<div class="ui action tiny input" id="clone-panel">
@@ -279,10 +283,22 @@
</div>
{{end}}
</div>
{{if and (.IsViewFile) (IpynbBool .TreePath)}}
<div class="right fitted item">
<button class="ui green button tiny" id="notebook-debug" style="display: flex;align-items: center;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm8 10h6v2h-6v-2zm-3.333-3L5.838 9.172l1.415-1.415L11.495 12l-4.242 4.243-1.415-1.415L8.667 12z" fill="rgba(255,255,255,1)"/></svg>
<span style="margin-left:0.3rem;font-size: 14px;">{{.i18n.Tr "repo.notebook_open"}}</span>
</button>
</div>
{{end}}
</div>
<div class="ui container">
<div class="ui mobile reversed stackable grid">
{{if not .IsViewFile}}
<div class="ui ten wide tablet twelve wide computer column">
{{else}}
<div class="ui sixteen wide tablet sixteen wide computer column">
{{end}}
{{if .IsViewFile}}
{{template "repo/view_file" .}}
{{else if .IsBlame}}
@@ -291,6 +307,7 @@
{{template "repo/view_list" .}}
{{end}}
</div>
{{if not .IsViewFile}}
<div class="ui six wide tablet four wide computer column">
<div id="repo-desc" data-IsAdmin="{{.Permission.IsAdmin}}"
data-IsArchived="{{.Repository.IsArchived}}">
@@ -303,25 +320,17 @@
{{else}}
<span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span>
{{end}}

</p>

</div>



{{if .Repository.Website}}
<p class="ui">
<i class="gray linkify icon"></i>
<a class="link edit-link" target="_blank" title="{{.Repository.Website}}"
href="{{.Repository.Website}}">{{.Repository.Website}}</a>
</p>

{{end}}

<div class="ui" id="repo-topics" style="display: flex;position: relative;margin-bottom: 1.0rem;">
<i class="grey bookmark icon"></i>

<div id="repo-topics1" style="flex: 1;">
{{range .Topics}}
<a class="ui repo-topic small label topic"
@@ -334,32 +343,22 @@
</div>
<div id="topic_edit" class="vue_menu" style="display:none">
<div id="topic_edit1">

</div>
</div>

</div>


<p class="ui">
<i class="grey code icon"></i>
{{range .LanguageStats}}
{{.Language}}
{{end}}
</p>



{{if .LICENSE}}
<p class="ui">
<i class="grey clone icon"></i>
{{.LICENSE}}
</p>

{{end}}

<div class="ui divider"></div>

<div>
<h4 class="ui header">
{{$lenCon := len .ContributorInfo}}
@@ -387,19 +386,20 @@
{{end}}
</div>
</div>

</div>
{{end}}
</div>
</div>

</div>
{{if and (.IsViewFile) (IpynbBool .TreePath)}}
<div id="__vue-root"></div>
<div id="__vue-self-data" data-branch="{{.BranchName}}" data-owner="{{.Repository.OwnerName}}" data-name="{{.SignedUser.Name}}" data-project="{{.Repository.Name}}"
data-file="{{.TreePath}}">
</div>
{{end}}
</div>

<script type="text/javascript">
// $(document).ready(function(){
// $(".membersmore").click(function(){
// $("#contributorInfo > a:nth-child(n+25)").show();
// });
// });
</script>
{{if and (.IsViewFile) (IpynbBool .TreePath)}}
<script src="{{StaticUrlPrefix}}/js/vp-notebook-debug.js?v={{MD5 AppVer}}"></script>
{{end}}
{{template "base/footer" .}}

+ 1
- 1
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -218,7 +218,7 @@
<span >
<i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

<!-- 运行参数 -->


+ 1
- 1
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -207,7 +207,7 @@
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>

<div id="select-multi-dataset">


+ 1
- 1
templates/repo/modelarts/trainjob/version_new.tmpl View File

@@ -195,7 +195,7 @@
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>
<div id="select-multi-dataset">



+ 1
- 1
templates/repo/modelmanage/convertIndex.tmpl View File

@@ -52,7 +52,7 @@
{{if eq .MODEL_COUNT 0}}
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.modelconvert.importfirst1"}}<a href="{{.RepoLink}}/modelmanage/show_model">&nbsp;{{$.i18n.Tr "repo.modelconvert.importfirst2"}}&nbsp;</a>{{$.i18n.Tr "repo.modelconvert.importfirst3"}}</div>
{{end}}
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">&nbsp;{{$.i18n.Tr "repo.platform_instructions2"}}&nbsp;</a>{{$.i18n.Tr "repo.platform_instructions3"}}</div>
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">&nbsp;{{$.i18n.Tr "repo.platform_instructions2"}}&nbsp;</a>{{$.i18n.Tr "repo.platform_instructions3"}}</div>

</div>
</div>


+ 1
- 1
templates/repo/modelmanage/index.tmpl View File

@@ -95,7 +95,7 @@
{{end}}
-->
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.model.manage.createmodel_tip"}}<a href="{{.RepoLink}}/modelarts/train-job">&nbsp;{{$.i18n.Tr "repo.model.manage.createtrainjob"}}</a></div>
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">&nbsp;{{$.i18n.Tr "repo.platform_instructions2"}}&nbsp;</a>{{$.i18n.Tr "repo.platform_instructions3"}}</div>
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">&nbsp;{{$.i18n.Tr "repo.platform_instructions2"}}&nbsp;</a>{{$.i18n.Tr "repo.platform_instructions3"}}</div>

</div>
<div style="display: none;">


+ 4
- 2
templates/repo/modelsafety/new.tmpl View File

@@ -217,7 +217,9 @@
{{end}}
{{else}}
{{range .engine_versions}}
<option value="{{.ID}}">{{.Value}}</option>
{{if not (eq .ID -1)}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
{{end}}
</select>
@@ -258,7 +260,7 @@
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/aisafety" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/aisafety" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>
<div class="inline field min_title required fields" style="width: 95%;">
<label class="label-fix-width label-required" style="font-weight: normal;">{{.i18n.Tr "modelsafety.base_data_set"}}</label>


+ 47
- 1
templates/user/auth/activate.tmpl View File

@@ -23,9 +23,14 @@
{{else if .IsActivateFailed}}
<p>{{.i18n.Tr "auth.invalid_code"}}</p>
{{else}}
<p>{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p>
<p style="margin-bottom: 0;">{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p>
<ul style="margin-top: 0;">
<li style="line-height: 30px;">{{.i18n.Tr "auth.has_unconfirmed_mail_resend"}}</li>
<li>{{.i18n.Tr "auth.has_unconfirmed_mail_change"}}</li>
</ul>
<div class="ui divider"></div>
<div class="text right">
<button type="button" class="ui blue button change">{{.i18n.Tr "auth.change_email"}}</button>
<button class="ui blue button">{{.i18n.Tr "auth.resend_mail"}}</button>
</div>
{{end}}
@@ -34,5 +39,46 @@
</form>
</div>
</div>
<div>
<div class="ui modal chang-email">
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);">
<h4>{{.i18n.Tr "auth.change_email_address"}}</h4>
</div>
<form id="form-email" class="ui form ignore-dirty" action="{{AppSubUrl}}/user/update_email" method="POST" >
<div class="content content-padding">
<div class="ui error message">
</div>
{{$.CsrfTokenHtml}}
<div class="inline required field">
<label>{{.i18n.Tr "auth.new_email_address"}}</label>
<input type="email" style="width: 80%;" id="email" name="NewEmail" maxlength="255" value="{{.SignedUser.Email}}"
pattern="([a-zA-Z0-9_-])+@(163\.com|126\.com|qq\.com|yahoo\.com|sina\.com|sina\.cn|outlook\.com|pcl\.ac\.cn|foxmail\.com|ict\.ac\.cn|21cn\.com|yeah\.net|139\.com)" required>
</div>
</div>
<div class="center actions">
<button id="submitBtn" class="ui green button">{{.i18n.Tr "repo.confirm_choice"}}</button>
<div class="ui deny button">{{.i18n.Tr "cancel"}}</div>
</div>
</form>
</div>
</div>
</div>
{{template "base/footer" .}}
<script>
$('.ui.blue.button.change').on('click',function(){
$('.ui.modal')
.modal({
onShow:function(){
$('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" })
let emailInput=document.getElementById("email");
emailInput.oninvalid = function () {
this.setCustomValidity('{{.i18n.Tr "auth.email_domain_blacklisted_change"}}')
}
emailInput.oninput = function(){
this.setCustomValidity('')
}
}
})
.modal('show')
})
</script>

+ 6
- 4
templates/user/dashboard/cloudbrains.tmpl View File

@@ -124,7 +124,8 @@
style="width: 8% !important;">
<span class="job-status" id="{{$JobID}}"
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-jobid="{{$JobID}}" data-version="{{.VersionName}}">
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"
data-bootfile="{{.BootFile}}">
<span><i id="{{$JobID}}-icon" style="vertical-align: middle;"
class="{{.Status}}"></i><span id="{{$JobID}}-text"
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
@@ -185,7 +186,6 @@
<a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}"
title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a>
</div>

<div class="three wide column text center nowrap" style="width: 15%!important;">
{{if eq .JobType "DEBUG"}}
<div class="ui compact buttons">
@@ -199,6 +199,7 @@
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
{{if not .BootFile}}
<a id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
@@ -206,6 +207,7 @@
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
{{end}}
</form>
</div>
{{end}}
@@ -228,7 +230,7 @@
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button'
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop'
data-jobid="{{$JobID}}">
data-jobid="{{$JobID}}" data-bootfile="{{.BootFile}}">
{{$.i18n.Tr "repo.stop"}}
</a>
</form>
@@ -236,7 +238,7 @@
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button'
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 1}}modelarts/inference-job{{else}}cloudbrain/train-job{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}modelarts/train-job{{else if eq .Cloudbrain.Type 0}}cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}grampus/train-job{{end}}{{end}}'
data-jobid="{{$JobID}}" data-version="{{.VersionName}}">
data-jobid="{{$JobID}}" data-version="{{.VersionName}}" data-bootfile="{{.BootFile}}">
{{$.i18n.Tr "repo.stop"}}
</a>
{{end}}


+ 1
- 1
templates/user/dashboard/dashboard.tmpl View File

@@ -15,7 +15,7 @@
<p class="ui text grey">{{.i18n.Tr "home.provide_resoure"}}</p>
</div>
<div class="guide ">
<a class="mini ui blue basic button" style="font-weight:700" href="https://git.openi.org.cn/zeizei/OpenI_Learning" target="_blank">{{.i18n.Tr "custom.Platform_Tutorial"}} <i class="ri-arrow-right-line" ></i></a>
<a class="mini ui blue basic button" style="font-weight:700" href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning" target="_blank">{{.i18n.Tr "custom.Platform_Tutorial"}} <i class="ri-arrow-right-line" ></i></a>
</div>
</div>
{{if .EnableHeatmap}}


+ 1
- 1
web_src/js/components/EditAboutInfo.vue View File

@@ -23,7 +23,7 @@
<el-input v-model="info.desc" type="textarea" placeholder="请输入内容" :autosize="{minRows:4,maxRows:6}" maxlength="255" show-word-limit></el-input>
</el-form-item>
<el-form-item label="主页" prop="index_web" >
<el-input v-model="info.index_web" placeholder="主页(eg: https://git.openi.org.cn)"></el-input>
<el-input v-model="info.index_web" placeholder="主页(eg: https://openi.pcl.ac.cn)"></el-input>
</el-form-item>
</el-form>
</div>


+ 1
- 1
web_src/js/components/dataset/referenceDataset.vue View File

@@ -209,7 +209,7 @@
</div>
<div class="bgtask-content-txt">
{{ i18n.dataset_instructions_for_use
}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{
}}<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">{{
i18n.dataset_camp_course
}}</a>
</div>


+ 2
- 2
web_src/js/features/ad.js View File

@@ -7,7 +7,7 @@
"left": 50,
"bottom": 50
},
"src": "https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png",
"src": "https://openi.pcl.ac.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png",
"url": "/user/invitation_tpl",
"show": true
},
@@ -18,7 +18,7 @@
"right": 50,
"bottom": 50
},
"src": "https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png",
"src": "https://openi.pcl.ac.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png",
"url": "/user/invitation_tpl",
"show": false
}


+ 23
- 12
web_src/js/features/cloudrbanin.js View File

@@ -24,6 +24,7 @@ export default async function initCloudrain() {
const repoPath = job.dataset.repopath;
// const computeResource = job.dataset.resource
const versionname = job.dataset.version;
const bootfile = job.dataset.bootfile;
const status_text = $(`#${ID}-text`).text();
const finalState = [
"STOPPED",
@@ -99,11 +100,16 @@ export default async function initCloudrain() {
"SUCCEEDED",
].includes(status)
) {
$("#ai-debug-" + ID)
.removeClass("disabled")
.addClass("blue")
.text(debug_again_button)
.css("margin", "0");
if (!bootfile) {
$("#ai-debug-" + ID)
.removeClass("disabled")
.addClass("blue")
.text(debug_again_button)
.css("margin", "0");
} else {
$("#ai-debug-" + ID).remove()
}
}
if (["RUNNING", "WAITING"].includes(status)) {
$("#ai-stop-" + ID)
@@ -289,7 +295,7 @@ export default async function initCloudrain() {
assertDelete(this);
}
});
function stopDebug(ID, stopUrl) {
function stopDebug(ID, stopUrl,bootFile) {
$.ajax({
type: "POST",
url: stopUrl,
@@ -301,11 +307,15 @@ export default async function initCloudrain() {
.addClass(res.status);
$("#" + ID + "-text").text(res.status);
if (res.status === "STOPPED") {
$("#ai-debug-" + ID)
.removeClass("disabled")
.addClass("blue")
.text(debug_again_button)
.css("margin", "0");
if (!bootFile) {
$("#ai-debug-" + ID)
.removeClass("disabled")
.addClass("blue")
.text(debug_again_button)
.css("margin", "0");
} else {
$("#ai-debug-" + ID).remove()
}
$("#ai-image-" + ID)
.removeClass("blue")
.addClass("disabled");
@@ -344,7 +354,8 @@ export default async function initCloudrain() {
$(".ui.basic.ai_stop").click(function () {
const ID = this.dataset.jobid;
const repoPath = this.dataset.repopath;
stopDebug(ID, repoPath);
const bootFile = this.dataset.bootfile
stopDebug(ID, repoPath,bootFile);
});

function stopVersion(version_name, ID, repoPath) {


+ 4
- 0
web_src/js/features/i18nVue.js View File

@@ -108,6 +108,8 @@ export const i18nVue = {
local:"本地",
online:"线上",
modify:"修改",
about:"约",
count:"个",
},
US: {
computer_vision: "computer vision",
@@ -222,5 +224,7 @@ export const i18nVue = {
local:"Local",
online:"Online",
modify:"Modify",
about:"About",
count:"",
},
};

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

@@ -5207,4 +5207,22 @@ Fancybox.bind('.gallery img', {
// Custom animations
showClass: "fancybox-zoomIn",
hideClass: "fancybox-zoomOut",
});
});

function initTopToHome() {
const topToHomeEl = $('.__go-top');
$(window).scroll(function (e) {
const scrollTop = $(document).scrollTop();
const winHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
if (scrollTop > winHeight * 1.2) {
topToHomeEl.fadeIn();
} else {
topToHomeEl.fadeOut();
}
});
topToHomeEl.on('click', function() {
$('html').animate({ scrollTop: 0 }, 'slow', 'swing');
});
}

initTopToHome();

+ 16
- 2
web_src/less/openi.less View File

@@ -34,7 +34,7 @@ a {
}

.following.bar.dark {
background-color: #363840;
background-color: rgb(16, 16, 16);
}
.ui.secondary.menu.dark .item {
color: #fff;
@@ -94,7 +94,7 @@ footer {
}
@media only screen and (min-width: 1600px) {
.ui.ui.ui.container:not(.fluid) {
width: 1200px;
width: 1440px;
}
}

@@ -1426,3 +1426,17 @@ i.SUCCEEDED {
}
}

.chang-email .content {
display: block;
width: 100%;
font-size: 1em;
line-height: 1.4;
padding: 1.5rem;
background: #fff;
}
.chang-email .actions {
background: #f9fafb;
padding: 1rem 1rem;
border-top: 1px solid rgba(34,36,38,.15);
text-align: right;
}

+ 47
- 0
web_src/vuepages/apis/modules/notobook.js View File

@@ -0,0 +1,47 @@
import service from "../service";

// Notebook新建页面需要的信息
export const getFileNotebook = () => {
return service({
url: "/api/v1/file_notebook",
method: "get",
params: {},
});
};

// Notebook新建调试任务
// type, file, branch_name, owner_name, project_name
export const createNotebook = (data) => {
return service({
url: "/api/v1/file_notebook/create",
method: "post",
data,
params: {},
});
};

// Notebook获取云脑I调试任务状态
export const getCb1Notebook = (path,jobid) => {
return service({
url: `/api/v1/${path}/cloudbrain/${jobid}`,
method: "get",
params: {},
});
};

// Notebook获取云脑I调试任务状态
export const getCb2Notebook = (path,jobid) => {
return service({
url: `/api/v1/${path}/modelarts/notebook/${jobid}`,
method: "get",
params: {},
});
};

export const stopNotebook = (url) => {
return service({
url: url,
method: "post",
params: {},
});
};

+ 0
- 1
web_src/vuepages/apis/service.js View File

@@ -2,7 +2,6 @@ import axios from 'axios';

const service = axios.create({
baseURL: '/',
timeout: 20000,
});

service.interceptors.request.use((config) => {


+ 30
- 2
web_src/vuepages/langs/config/en-US.js View File

@@ -157,7 +157,7 @@ const en = {
computeCluster: 'Compute Cluster',
resourceSpecification: 'Resource Specification',
lastUpdateTime: 'Last Update Time',
resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?',
resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?',
resourceSpecificationIsAvailable: 'Specification Is Available',
resourceSpecificationIsAvailableAll: 'Specification Is Available(All)',
available: 'Available',
@@ -192,7 +192,35 @@ const en = {
dataDesensitizationModelExperience:'Data desensitization model experience',
dataDesensitizationModelDesc:'Use AI technology to desensitize the face and license plate number in the picture. For more information about this model, please visit the project',
limitFilesUpload:'Only jpg/jpeg/png files can be uploaded',
limitSizeUpload:'The size of the uploaded file cannot exceed 20M!',
limitSizeUpload: 'The size of the uploaded file cannot exceed 20M!',
notebook: {
createNewNotebook: "Create new notebook debug task",
sameTaskTips1: "You have created an",
sameTaskTips2: "equivalent task",
sameTaskTips3: "that is waiting or running, please wait for the task to finish before creating it.",
sameTaskTips4: "You can view all your Cloudbrain tasks in",
sameTaskTips5: "Home",
sameTaskTips6: "Cloudbrain Task",
sameTaskTips7: "",
cpuEnv: "CPU Environment",
gpuEnv: "GPU Environment",
npuEnv: "NPU environment",
newTask: "Create new task",
noQuene: "The current resources are sufficient and no tasks are queued",
queneTips1: "There are currently",
queneTips2: "tasks queued",
watiResource: "Waiting for resources to be allocated, please be patient",
debug: "Debug",
stop: "Stop",
stopping: "Stopping",
notebookRunning: "The debugging environment has been started, and it will automatically close after 4 hours ",
stopSuccess: "Stop task succeeded",
specification: "Specification",
graphicMemory: "Graphic Memory",
memory: "Memory",
sharedMemory: "Shared Memory",
tips: 'The newly created debugging task will be placed in the project openi-notebook under your name. If there is no such project, the system will automatically create a new one.'
},
modelManage: {
modelManage: 'Model management',
modelName: 'Model name',


+ 217
- 186
web_src/vuepages/langs/config/zh-CN.js View File

@@ -1,198 +1,227 @@
const zh = {
loading: '加载中...',
noData: '暂无数据',
date: '日期',
loading: "加载中...",
noData: "暂无数据",
date: "日期",

confirm: '确定',
cancel: '取消',
confirm1: '确认',
pleaseCompleteTheInformationFirst: '请先完善信息!',
submittedSuccessfully: '提交成功!',
submittedFailed: '提交失败!',
operation: '操作',
edit: '修改',
delete: '删除',
tips: '提示',
confirm: "确定",
cancel: "取消",
confirm1: "确认",
pleaseCompleteTheInformationFirst: "请先完善信息!",
submittedSuccessfully: "提交成功!",
submittedFailed: "提交失败!",
operation: "操作",
edit: "修改",
delete: "删除",
tips: "提示",

accomplishTask: '积分任务',
adminOperate: '管理员操作',
runCloudBrainTask: '运行云脑任务',
operating: '消耗中',
succeeded: '已完成',
debugTask: '调试任务',
trainTask: '训练任务',
inferenceTask: '推理任务',
benchmarkTask: '评测任务',
createPublicProject: '创建公开项目',
dailyPutforwardTasks: '每日提出任务',
dailyPR: '每日提出PR',
comment: '发表评论',
uploadDatasetFile: '上传数据集文件',
importNewModel: '导入新模型',
completeWechatCodeScanningVerification: '完成微信扫码验证',
dailyRunCloudbrainTasks: '每日运行云脑任务',
datasetRecommendedByThePlatform: '数据集被平台推荐',
submitNewPublicImage: '提交新公开镜像',
imageRecommendedByThePlatform: '镜像被平台推荐',
firstChangeofAvatar: '首次更换头像',
dailyCommit: '每日commit',
calcPointDetails: '算力积分明细',
calcPointAcquisitionInstructions: '积分获取说明',
CurrAvailableCalcPoints: '当前可用算力积分(分)',
totalGainCalcPoints: '总获取算力积分(分)',
totalConsumeCalcPoints: '总消耗算力积分(分)',
gainDetail: '获取明细',
consumeDetail: '消耗明细',
serialNumber: '流水号',
time: '时间',
scene: '场景',
behaviorOfPoint: '积分行为',
explanation: '说明',
points: '积分',
status: '状态',
runTime: '运行时长',
taskName: '任务名称',
accomplishTask: "积分任务",
adminOperate: "管理员操作",
runCloudBrainTask: "运行云脑任务",
operating: "消耗中",
succeeded: "已完成",
debugTask: "调试任务",
trainTask: "训练任务",
inferenceTask: "推理任务",
benchmarkTask: "评测任务",
createPublicProject: "创建公开项目",
dailyPutforwardTasks: "每日提出任务",
dailyPR: "每日提出PR",
comment: "发表评论",
uploadDatasetFile: "上传数据集文件",
importNewModel: "导入新模型",
completeWechatCodeScanningVerification: "完成微信扫码验证",
dailyRunCloudbrainTasks: "每日运行云脑任务",
datasetRecommendedByThePlatform: "数据集被平台推荐",
submitNewPublicImage: "提交新公开镜像",
imageRecommendedByThePlatform: "镜像被平台推荐",
firstChangeofAvatar: "首次更换头像",
dailyCommit: "每日commit",
calcPointDetails: "算力积分明细",
calcPointAcquisitionInstructions: "积分获取说明",
CurrAvailableCalcPoints: "当前可用算力积分(分)",
totalGainCalcPoints: "总获取算力积分(分)",
totalConsumeCalcPoints: "总消耗算力积分(分)",
gainDetail: "获取明细",
consumeDetail: "消耗明细",
serialNumber: "流水号",
time: "时间",
scene: "场景",
behaviorOfPoint: "积分行为",
explanation: "说明",
points: "积分",
status: "状态",
runTime: "运行时长",
taskName: "任务名称",

createdRepository: '创建了项目',
repositoryWasDel: '项目已删除',
openedIssue: '创建了任务',
createdPullRequest: '创建了合并请求',
commentedOnIssue: '评论了任务',
uploadDataset: '上传了数据集文件',
createdNewModel: '导入了新模型',
firstBindingWechatRewards: '首次绑定微信奖励',
created: '创建了',
type: '类型',
dataset: '数据集',
setAsRecommendedDataset: '被设置为推荐数据集',
committedImage: '提交了镜像',
image: '镜像',
setAsRecommendedImage: '被设置为推荐镜像',
updatedAvatar: '更新了头像',
pushedBranch: '推送了{branch}分支代码到',
deleteBranch: '从{repo}删除分支{branch}',
pushedTag: '推送了标签{tag}到',
deleteTag: '从{repo}删除了标签{tag}',
dailyMaxTips: '达到每日上限积分,不能拿满分',
memory: '内存',
sharedMemory: '共享内存',
';': ';',
createdRepository: "创建了项目",
repositoryWasDel: "项目已删除",
openedIssue: "创建了任务",
createdPullRequest: "创建了合并请求",
commentedOnIssue: "评论了任务",
uploadDataset: "上传了数据集文件",
createdNewModel: "导入了新模型",
firstBindingWechatRewards: "首次绑定微信奖励",
created: "创建了",
type: "类型",
dataset: "数据集",
setAsRecommendedDataset: "被设置为推荐数据集",
committedImage: "提交了镜像",
image: "镜像",
setAsRecommendedImage: "被设置为推荐镜像",
updatedAvatar: "更新了头像",
pushedBranch: "推送了{branch}分支代码到",
deleteBranch: "从{repo}删除分支{branch}",
pushedTag: "推送了标签{tag}到",
deleteTag: "从{repo}删除了标签{tag}",
dailyMaxTips: "达到每日上限积分,不能拿满分",
memory: "内存",
sharedMemory: "共享内存",
";": ";",

noPointGainRecord: '还没有积分获取记录',
noPointConsumeRecord: '还没有积分消耗记录',
noPointGainRecord: "还没有积分获取记录",
noPointConsumeRecord: "还没有积分消耗记录",

resourcesManagement: {
OpenI: '启智集群',
C2Net: '智算集群',
OpenIOne: '云脑一',
OpenITwo: '云脑二',
OpenIChengdu: '启智成都智算',
chengduCenter: '成都智算',
pclcci: '鹏城云计算所',
hefeiCenter: '合肥类脑类脑智能开放平台',
xuchangCenter: '中原人工智能计算中心',
willOnShelf: '待上架',
onShelf: '已上架',
offShelf: '已下架',
toOnShelf: '上架',
toOffShelf: '下架',
toSetPriceAndOnShelf: '定价上架',
status: '状态',
allStatus: '全部状态',
syncAiNetwork: '同步智算网络',
resQueue: '资源池(队列)',
allResQueue: '全部资源池(队列)',
addResQueue: '新建资源池(队列)',
addResQueueBtn: '新增资源池',
editResQueue: '修改资源池(队列)',
resQueueName: '资源池(队列)名称',
whichCluster: '所属集群',
allCluster: '全部集群',
aiCenter: '智算中心',
aiCenterID: '智算中心ID',
allAiCenter: '全部智算中心',
computeResource: '计算资源',
allComputeResource: '全部计算资源',
accCardType: '卡类型',
allAccCardType: '全部卡类型',
cardsTotalNum: '卡数',
accCardsNum: '卡数',
remark: '备注',
pleaseEnterRemark: '请输入备注(最大长度不超过255)',
pleaseEnterPositiveIntegerCardsTotalNum: '请输入正整数的卡数!',
addResSpecificationAndPriceInfo: '新增资源规格和单价信息',
addResSpecificationBtn: '新增资源规格',
editResSpecificationAndPriceInfo: '修改资源规格和单价信息',
resSpecificationAndPriceManagement: '资源规格单价管理',
sourceSpecCode: '对应资源编码',
sourceSpecCodeTips: '云脑II需要填写对应的资源编码',
sourceSpecId: '智算网络资源规格ID',
cpuNum: 'CPU数',
gpuMem: '显存',
mem: '内存',
shareMem: '共享内存',
unitPrice: '单价',
point_hr: '积分/时',
node: '节点',
free: '免费',
onShelfConfirm: '请确认上架该规格?',
offShelfConfirm: '请确认下架该规格?',
onShelfCode1001: '上架失败,资源池(队列)不可用。',
onShelfCode1003: '上架失败,资源规格不可用。',
offShelfDlgTip1: '当前资源规格已在以下场景中使用:',
offShelfDlgTip2: '请确认进行下架操作?',
resSceneManagement: '算力资源应用场景管理',
addResScene: '新建算力资源应用场景',
addResSceneBtn: '新增应用场景',
editResScene: '修改算力资源应用场景',
resSceneName: '应用场景名称',
jobType: '任务类型',
allJobType: '全部任务类型',
isExclusive: '是否专属',
allExclusiveAndCommonUse: '全部专属和通用',
exclusive: '专属',
commonUse: '通用',
exclusiveOrg: '专属组织',
exclusiveOrgTips: '多个组织名之间用英文分号隔开',
computeCluster: '算力集群',
resourceSpecification: '资源规格',
lastUpdateTime: '最后更新时间',
resSceneDeleteConfirm: '是否确认删除当前应用场景?',
resourceSpecificationIsAvailable: '资源规格是否可用',
resourceSpecificationIsAvailableAll: '资源规格是否可用(全部)',
available: '可用',
notAvailable: '不可用',
OpenI: "启智集群",
C2Net: "智算集群",
OpenIOne: "云脑一",
OpenITwo: "云脑二",
OpenIChengdu: "启智成都智算",
chengduCenter: "成都智算",
pclcci: "鹏城云计算所",
hefeiCenter: "合肥类脑类脑智能开放平台",
xuchangCenter: "中原人工智能计算中心",
willOnShelf: "待上架",
onShelf: "已上架",
offShelf: "已下架",
toOnShelf: "上架",
toOffShelf: "下架",
toSetPriceAndOnShelf: "定价上架",
status: "状态",
allStatus: "全部状态",
syncAiNetwork: "同步智算网络",
resQueue: "资源池(队列)",
allResQueue: "全部资源池(队列)",
addResQueue: "新建资源池(队列)",
addResQueueBtn: "新增资源池",
editResQueue: "修改资源池(队列)",
resQueueName: "资源池(队列)名称",
whichCluster: "所属集群",
allCluster: "全部集群",
aiCenter: "智算中心",
aiCenterID: "智算中心ID",
allAiCenter: "全部智算中心",
computeResource: "计算资源",
allComputeResource: "全部计算资源",
accCardType: "卡类型",
allAccCardType: "全部卡类型",
cardsTotalNum: "卡数",
accCardsNum: "卡数",
remark: "备注",
pleaseEnterRemark: "请输入备注(最大长度不超过255)",
pleaseEnterPositiveIntegerCardsTotalNum: "请输入正整数的卡数!",
addResSpecificationAndPriceInfo: "新增资源规格和单价信息",
addResSpecificationBtn: "新增资源规格",
editResSpecificationAndPriceInfo: "修改资源规格和单价信息",
resSpecificationAndPriceManagement: "资源规格单价管理",
sourceSpecCode: "对应资源编码",
sourceSpecCodeTips: "云脑II需要填写对应的资源编码",
sourceSpecId: "智算网络资源规格ID",
cpuNum: "CPU数",
gpuMem: "显存",
mem: "内存",
shareMem: "共享内存",
unitPrice: "单价",
point_hr: "积分/时",
node: "节点",
free: "免费",
onShelfConfirm: "请确认上架该规格?",
offShelfConfirm: "请确认下架该规格?",
onShelfCode1001: "上架失败,资源池(队列)不可用。",
onShelfCode1003: "上架失败,资源规格不可用。",
offShelfDlgTip1: "当前资源规格已在以下场景中使用:",
offShelfDlgTip2: "请确认进行下架操作?",
resSceneManagement: "算力资源应用场景管理",
addResScene: "新建算力资源应用场景",
addResSceneBtn: "新增应用场景",
editResScene: "修改算力资源应用场景",
resSceneName: "应用场景名称",
jobType: "任务类型",
allJobType: "全部任务类型",
isExclusive: "是否专属",
allExclusiveAndCommonUse: "全部专属和通用",
exclusive: "专属",
commonUse: "通用",
exclusiveOrg: "专属组织",
exclusiveOrgTips: "多个组织名之间用英文分号隔开",
computeCluster: "算力集群",
resourceSpecification: "资源规格",
lastUpdateTime: "最后更新时间",
resSceneDeleteConfirm: "是否确认删除当前应用场景?",
resourceSpecificationIsAvailable: "资源规格是否可用",
resourceSpecificationIsAvailableAll: "资源规格是否可用(全部)",
available: "可用",
notAvailable: "不可用",
},
user: {
inviteFriends: '邀请好友',
inviteFriendsTips: '复制二维码或者注册邀请链接分享给好友',
clickToViewTheEventDetails: '点击查看活动详情',
copyRegistrationInvitationLink: '复制注册邀请链接',
registrationAdress: '注册地址:',
recommender: '推荐人:',
invitedFriends: '已邀请好友',
registrationTime: '注册时间',
theSharedContentHasBeenCopiedToTheClipboard: '分享内容已复制到剪切板',
copyError: '复制错误',
Activated: '已激活',
notActive: '未激活',
inviteFriends: "邀请好友",
inviteFriendsTips: "复制二维码或者注册邀请链接分享给好友",
clickToViewTheEventDetails: "点击查看活动详情",
copyRegistrationInvitationLink: "复制注册邀请链接",
registrationAdress: "注册地址:",
recommender: "推荐人:",
invitedFriends: "已邀请好友",
registrationTime: "注册时间",
theSharedContentHasBeenCopiedToTheClipboard: "分享内容已复制到剪切板",
copyError: "复制错误",
Activated: "已激活",
notActive: "未激活",
},
tranformImageFailed: "图片脱敏失败",
originPicture: "原始图片",
desensitizationPicture: "脱敏图片",
desensitizationObject: "脱敏对象",
example: "示例",
startDesensitization: "开始处理",
all: "全部",
onlyFace: "仅人脸",
onlyLicensePlate: "仅车牌",
dragThePictureHere: "拖动图片到这里",
or: "或",
clickUpload: "点击上传",
dataDesensitizationModelExperience: "数据脱敏模型体验",
dataDesensitizationModelDesc:
"利用人工智能AI技术,把图片中的人脸、车牌号码进行脱敏处理。该模型更多信息请访问项目",
limitFilesUpload: "只能上传 jpg/jpeg/png 格式的文件",
limitSizeUpload: "上传文件大小不能超过 20M !",
notebook: {
createNewNotebook: "新建Notebook调试任务",
sameTaskTips1: "您已经有",
sameTaskTips2: "同类任务",
sameTaskTips3: "正在等待或运行中,请等待任务结束再创建",
sameTaskTips4: "可以在",
sameTaskTips5: "个人中心",
sameTaskTips6: "云脑任务",
sameTaskTips7: "查看您所有的云脑任务。",
cpuEnv: "CPU 环境",
gpuEnv: "GPU 环境",
npuEnv: "NPU 环境",
newTask: "新建任务",
noQuene: "当前资源充足,没有任务排队",
queneTips1: "当前有",
queneTips2: "个任务正在排队",
watiResource: "正在等待分配资源,请耐心等待",
debug: "调试",
stop: "停止",
stopping: "停止中",
notebookRunning: "调试环境已启动,单次连接 4 小时后自动关闭",
stopSuccess: "停止任务成功",
specification: "规格",
graphicMemory: "显存",
memory: "内存",
sharedMemory: "共享内存",
tips:'本次新建的调试任务会放在您名下项目openi-notebook中,如果没有该项目系统会自动新建一个。'
},
tranformImageFailed:'图片脱敏失败',
originPicture:'原始图片',
desensitizationPicture:'脱敏图片',
desensitizationObject:'脱敏对象',
example:'示例',
startDesensitization:'开始处理',
all:'全部',
onlyFace:'仅人脸',
onlyLicensePlate:'仅车牌',
dragThePictureHere:'拖动图片到这里',
or:'或',
clickUpload:'点击上传',
dataDesensitizationModelExperience:'数据脱敏模型体验',
dataDesensitizationModelDesc:'利用人工智能AI技术,把图片中的人脸、车牌号码进行脱敏处理。该模型更多信息请访问项目',
limitFilesUpload:'只能上传 jpg/jpeg/png 格式的文件',
limitSizeUpload:'上传文件大小不能超过 20M !',
modelManage: {
modelManage: '模型管理',
modelName: '模型名称',
@@ -254,6 +283,8 @@ const zh = {
deleteModelFileConfirmTips: '请确认是否删除当前模型文件?',
modelFileDeleteFailed: '模型文件删除失败',
},
}
};



export default zh;

+ 1
- 1
web_src/vuepages/pages/model/tuomin/index.vue View File

@@ -4,7 +4,7 @@
<h2>{{ $t("dataDesensitizationModelExperience") }}</h2>
<p>
{{ $t("dataDesensitizationModelDesc") }} &nbsp;<a
href="https://git.openi.org.cn/tengxiao/tuomin"
href="https://openi.pcl.ac.cn/tengxiao/tuomin"
target="_blank"
>tengxiao / tuomin</a
>


+ 1
- 1
web_src/vuepages/pages/modelmanage/common/modelmanage-common-detail.vue View File

@@ -339,7 +339,7 @@ export default {
bootFile: trainTaskInfo.BootFile,
datasetName: trainTaskInfo.DatasetName,
parameters: parametersStr || '--',
workServerNumber: trainTaskInfo.WorkServerNumber || '--',
workServerNumber: trainTaskInfo.WorkServerNumber || '1',
specStr: sepcStr || '--',
});
}


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save