Browse Source

Merge branch 'V20220616' of git.openi.org.cn:OpenI/aiforge into grampus

tags/v1.22.6.2
lewis 3 years ago
parent
commit
63223062cc
60 changed files with 2952 additions and 180 deletions
  1. +76
    -5
      custom/public/css/git.openi.css
  2. BIN
      custom/public/img/i-pic-01.jpg
  3. BIN
      custom/public/img/i-pic-02.jpg
  4. BIN
      custom/public/img/i-pic-03.jpg
  5. BIN
      custom/public/img/i-pic-04.jpg
  6. BIN
      custom/public/rotation3D/img/baseLogo.png
  7. +1250
    -0
      custom/public/rotation3D/img/baseLogo.svg
  8. BIN
      custom/public/rotation3D/img/baseMap.png
  9. +1
    -0
      custom/public/rotation3D/img/brain.svg
  10. BIN
      custom/public/rotation3D/img/idc-green.png
  11. BIN
      custom/public/rotation3D/img/idc-red.png
  12. BIN
      custom/public/rotation3D/img/idc-yellow.png
  13. +2
    -0
      custom/public/rotation3D/jquery-3.5.0.min.js
  14. +152
    -0
      custom/public/rotation3D/rotation3D.css
  15. +380
    -0
      custom/public/rotation3D/rotation3D.js
  16. +6
    -0
      custom/public/rotation3D/vue-2.6.10.min.js
  17. +3
    -2
      models/cloudbrain.go
  18. +22
    -0
      models/cloudbrain_static.go
  19. +16
    -13
      models/user_business_analysis.go
  20. +8
    -0
      modules/storage/local.go
  21. +10
    -0
      modules/storage/minio.go
  22. +134
    -0
      modules/storage/minio_ext.go
  23. +1
    -0
      modules/storage/storage.go
  24. +1
    -0
      options/locale/locale_en-US.ini
  25. +4
    -2
      options/locale/locale_zh-CN.ini
  26. +66
    -5
      public/home/home.js
  27. +1
    -0
      public/self/css/notebook/katex.min.css
  28. +86
    -0
      public/self/css/notebook/notebook.css
  29. +142
    -0
      public/self/css/notebook/prism.css
  30. +6
    -0
      public/self/js/notebook/ansi_up.min.js
  31. +7
    -0
      public/self/js/notebook/es5-shim.min.js
  32. +1
    -0
      public/self/js/notebook/katex-auto-render.min.js
  33. +1
    -0
      public/self/js/notebook/katex.min.js
  34. +1
    -0
      public/self/js/notebook/marked.min.js
  35. +1
    -0
      public/self/js/notebook/notebook.min.js
  36. +7
    -0
      public/self/js/notebook/prism.min.js
  37. +3
    -0
      public/self/js/notebook/purify.min.js
  38. +3
    -0
      routers/api/v1/api.go
  39. +16
    -0
      routers/api/v1/repo/cloudbrain_dashboard.go
  40. +33
    -0
      routers/home.go
  41. +201
    -78
      routers/repo/ai_model_manage.go
  42. +1
    -1
      routers/repo/dataset.go
  43. +4
    -0
      routers/repo/view.go
  44. +6
    -3
      routers/routes/routes.go
  45. +44
    -0
      templates/base/footer.tmpl
  46. +2
    -0
      templates/base/head_home.tmpl
  47. +4
    -4
      templates/base/head_navbar.tmpl
  48. +5
    -3
      templates/explore/datasets.tmpl
  49. +80
    -25
      templates/home.tmpl
  50. +3
    -2
      templates/repo/create.tmpl
  51. +4
    -4
      templates/repo/datasets/index.tmpl
  52. +12
    -0
      templates/repo/header.tmpl
  53. +8
    -2
      templates/repo/modelarts/trainjob/show.tmpl
  54. +85
    -8
      templates/repo/modelmanage/index.tmpl
  55. +14
    -0
      templates/repo/view_file.tmpl
  56. +4
    -11
      templates/user/dashboard/dashboard.tmpl
  57. +1
    -1
      templates/user/dashboard/feeds.tmpl
  58. +15
    -2
      web_src/js/components/Model.vue
  59. +15
    -9
      web_src/js/index.js
  60. +4
    -0
      web_src/less/_dashboard.less

+ 76
- 5
custom/public/css/git.openi.css View File

@@ -71,6 +71,19 @@
.ui.secondary.hometop.segment #navbar{
z-index: 10;
}
.ui.secondary.c2net.segment{
/* background: #f8faff;
border: none;*/
margin-bottom: 5em;
padding-top: 2em;
color: rgba(0,0,0,.87);
background-image: linear-gradient(to bottom left,var(--tw-gradient-stops));
--tw-gradient-from: #f5f3ff;
--tw-gradient-stops: var(--tw-gradient-from),#fff,var(--tw-gradient-to,hsla(0,0%,100%,0));
--tw-gradient-to: rgba(219,234,254,0.4);
border-top: 1px solid rgba(243,244,246,1)!important;
border-bottom: 1px solid rgba(243,244,246,1)!important;
}

.hometop .ui.secondary.menu .active.item{
color: #000;
@@ -134,8 +147,13 @@
.i-code-pic > img{
margin-bottom: -3.0rem;
}
.i-env .ui.cards>.card{
box-shadow:none;
}
.i-env .ui.cards>.card>.image{
background: none;
width: 60%;
margin: auto;
}
.i-env .ui.cards>.card>.content{
border-top: none;
@@ -168,7 +186,7 @@
bottom: 0;
background-color: rgba(105, 192, 255, .4);
width: 2px;
}
}
.homenews .time-since{
padding-left: 1em;
color: #888888;
@@ -185,7 +203,7 @@
padding: 0;
}
.newslist{
height: 325px;
height: 300px;
overflow: hidden;
}

@@ -208,14 +226,25 @@
height: auto;
border-top: 2px solid #3291F8;
border-right: 2px solid #3291F8;
border-bottom: 2px solid #3291F8;
border-radius: 0 4.0em 4.0em 0;
border-radius: 0 4.0em 0 0;
width: 10em;
z-index: 6;
}
.leftline02::after, .leftline02-2::after{
content: '';
position: absolute;
transform: translate(55%,50%);
right: 0;
bottom: 0;
width: 1.0em;
height: 1.0em;
background-color: #FFF;
border: 2px solid #3291F8;
border-radius: 1em;
}
.leftline03{
border-radius: 4.0em 0 0 0;
border-top: 2px solid #3291F8;
border-top: 2px solid #3291F8;
border-bottom:none;
top: -2.0em;
}
@@ -224,6 +253,9 @@
width: 7em;
z-index: 5;
}
.leftline02-2::after{
border-color: rgba(105, 192, 255, .4);
}
.leftline04{
border-radius: 0;
border-top: none;
@@ -280,6 +312,9 @@
.i-env > div{
position: relative;
}
.event-list .ui.card>.image>img{
height: 146px !important;
}

@media only screen and (max-width: 767px) {
.am-mt-30{ margin-top: 1.5rem !important;}
@@ -376,4 +411,40 @@

@media only screen and (min-width: 1920px) {

}

/* rotation3D */
#app{
width: 800px;
margin: 0 auto;
}
.rotation3D-baseMap{
position: absolute; left: 0; right: 0; top: 270px; margin: auto;
width: 800px; height: 516px;
background: url("../rotation3D/img/baseMap.png") no-repeat;
background-size: cover;
}
.rotation3D-baseMap::before{
position: absolute;
margin: auto; z-index: 99;
left:50%; top: -150px;
transform:translate(-50%,0);
width: 342px; height: 470px; display: block; content: '';
background: url("../rotation3D/img/baseLogo.svg");
/*animation: 10s bounceUpDown infinite;*/
}
.rotation3D-baseMap::after{
position: absolute;
margin: auto; z-index: 100;
left:50%; top:0;
transform:translate(-50%,0);
width: 110px; height: 86px; display: block; content: '';
background: url("../rotation3D/img/brain.svg");
animation: 6s bounceUpDown infinite;
mix-blend-mode: color-dodge;
}
@keyframes bounceUpDown{
0% {transform: translate(-50%, 0px);}
50% {transform: translate(-50%, -15px);}
100% {transform: translate(-50%, 0px);}
}

BIN
custom/public/img/i-pic-01.jpg View File

Before After
Width: 266  |  Height: 178  |  Size: 13 kB

BIN
custom/public/img/i-pic-02.jpg View File

Before After
Width: 266  |  Height: 178  |  Size: 12 kB

BIN
custom/public/img/i-pic-03.jpg View File

Before After
Width: 266  |  Height: 178  |  Size: 14 kB

BIN
custom/public/img/i-pic-04.jpg View File

Before After
Width: 266  |  Height: 178  |  Size: 17 kB

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

Before After
Width: 342  |  Height: 470  |  Size: 88 kB

+ 1250
- 0
custom/public/rotation3D/img/baseLogo.svg
File diff suppressed because it is too large
View File


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

Before After
Width: 800  |  Height: 516  |  Size: 58 kB

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


BIN
custom/public/rotation3D/img/idc-green.png View File

Before After
Width: 161  |  Height: 188  |  Size: 39 kB

BIN
custom/public/rotation3D/img/idc-red.png View File

Before After
Width: 161  |  Height: 188  |  Size: 39 kB

BIN
custom/public/rotation3D/img/idc-yellow.png View File

Before After
Width: 161  |  Height: 188  |  Size: 39 kB

+ 2
- 0
custom/public/rotation3D/jquery-3.5.0.min.js
File diff suppressed because it is too large
View File


+ 152
- 0
custom/public/rotation3D/rotation3D.css View File

@@ -0,0 +1,152 @@

/*
椭圆会使内部失真 transform: rotateX(50deg);
*/
.rotation3D{
position: relative; width: 800px; height: 600px; user-select: none;
margin: 0 auto;
/* border: 1px solid white; border-radius: 100%; */
/* cursor: move; */
}
.rotation3D .center{
display: none;
position: absolute; left: 50%; top: 50%;
transform: translate(-50%, -50%);
}

.rotation3D .itemList{ position: absolute; width: 100%; height: 100%; z-index: 20; }
.rotation3D .lineList{
position: absolute; width: 100%; height: 100%; z-index: 10;
transform-style: preserve-3d;
}

/*---------------------------点样式---------------------------*/
.rotation3D__item{
position: absolute; display: block; width: 161px; height: 188px;
text-align: center; line-height: 30px; font-size: 16px; color: white;
/*background: #2292ef; border-radius: 4px;*/
/*cursor: pointer; */
}
.rotation3D__item .scale{ position: absolute; top: 0; width: 100%; height: 100%; }
.rotation3D__item .cont{ position: relative; z-index: 2; }
.rotation3D__item .cont .iconfont { font-size: 28px; margin-top: 30px; margin-bottom: 96px; display: block; }
.rotation3D__item .cont p{ color: #101010; }
.itemList .rotation3D__item .cont p::after{
font-size: 12px;
content: '';
position: absolute;
left: 0;
right: 0;
margin-top: 60px;
color: #101010;
}
.itemList .rotation3D__item:nth-child(1) .cont p::after{
content: "鹏城云脑一号";
}
.itemList .rotation3D__item:nth-child(2) .cont p::after{
content: "鹏城云脑二号";
}
.itemList .rotation3D__item:nth-child(3) .cont p::after{
content: "北大人工智能集群系统";
}
.itemList .rotation3D__item:nth-child(4) .cont p::after{
content: "合肥类脑智能开放平台";
}
.itemList .rotation3D__item:nth-child(5) .cont p::after{
content: "武汉人工智能计算中心";
}
.itemList .rotation3D__item:nth-child(6) .cont p::after{
content: "西安未来人工智能计算中心";
}
.itemList .rotation3D__item:nth-child(7) .cont p::after{
content: "更多接入中…";
}
.itemList .rotation3D__item:nth-child(8) .cont p::after{
content: "中原人工智能计算中心";
}
.itemList .rotation3D__item:nth-child(9) .cont p::after{
content: "成都人工智能计算中心";
}
.itemList .rotation3D__item:nth-child(10) .cont p::after{
content: "横琴先进智能计算中心";
}
.itemList .rotation3D__item:nth-child(11) .cont p::after{
content: "国家超级计算济南中心";
}

.rotation3D__item.blue{ color: #01e9fc; }
.rotation3D__item.green{ color: #b4b3ca; }
.rotation3D__item.yellow{ color: #ffd200; }

/*底座*/
.rotation3D__item .baseImg{ position: absolute; width: 100%; height: 100%; z-index: 1; }
.rotation3D__item.blue .baseImg{ background: url("img/idc-red.png"); }
.rotation3D__item.green .baseImg{ background: url("img/idc-green.png"); }
.rotation3D__item.yellow .baseImg{ background: url("img/idc-yellow.png"); }

/*---------------------------
线样式
线高为总高的一般
---------------------------*/
.rotation3D__line{
position: absolute; left: 50%; top: 50%;
display: block; width: 1px; height: 50%;
padding-top: 60px; color: #fff; font-size: 50px;
/*background: #fff;*/
/*原点设置在中间*/
transform-origin: 50% 0;
transform-style: preserve-3d;
}
.rotation3D__line .pos{ position: absolute; top: 0; }
.rotation3D__line svg { position: absolute; top: 0; }
.rotation3D__line svg path {
stroke: #fff; fill: none;
stroke-width: 2;
animation: path-animation 100s linear 0s infinite normal;
}
@keyframes path-animation {
0% { stroke-dashoffset:500; }
100% { stroke-dashoffset:0; }
}
.rotation3D__line .dot {
position: absolute; top: 0; left: 0; text-align: center;
/*width: 35px; height: 35px; font-size: 35px; */
width: 19px; height: 19px; font-size: 19px;
}
.rotation3D__line .dot1,.rotation3D__line .dot3,.rotation3D__line .dot4{
animation: svg-path-animation 6s ease-in-out 0s infinite normal;
}
.rotation3D__line .dot1{
offset-path: path("M0 400, 0 0"); offset-distance: 0%;
}
.rotation3D__line .dot2{
offset-path: path("M0 200, 0 0"); offset-distance: 0%;
background: #ffd200; border-radius: 100%;
font-size: 22px; color: #000;
}
.rotation3D__line .dot3{
offset-path: path("M20 400 S 0 200, 20 0"); offset-distance: 0%;
}
.rotation3D__line .dot4{
position: relative;
offset-path: path("M20 0 S 40 200, 20 400"); offset-distance: 0%;
}
@keyframes svg-path-animation {
from {offset-distance: 100%;}
to {offset-distance: 0%;}
}
.dot1 > span{
position: absolute;
font-size: 12px;
color: #888;
transform: rotate(180deg)scale(0.80);
}

/*颜色*/
.rotation3D__line.blue { color: #07b2f9; }
.rotation3D__line.green { color: #ac94ee; }
.rotation3D__line.yellow { color: #ffd500; }

.rotation3D__line.blue svg path { stroke: #07b2f9; }
.rotation3D__line.green svg path { stroke: #ac94ee; }
.rotation3D__line.yellow svg path { stroke: #ffd500; }

+ 380
- 0
custom/public/rotation3D/rotation3D.js View File

@@ -0,0 +1,380 @@
var cancelFrame = window.cancelAnimationFrame || window.cancelRequestAnimationFrame;
var requestFrame = window.requestAnimationFrame;
var time = !window.performance || !window.performance.now ?
function () {return +new Date()}:
function () {return performance.now()};

/**
* 计算两点距离
* @param points
* @returns {number}
* distance([{x:0,y:0},{x:1,y:1}]);
*/
var distance = function(points) {
var p1=points[0];
var p2=points[1];
var a = p2.x-p1.x;
var b = p2.y-p1.y;
return Math.sqrt(a*a+b*b);
};

/**
* 圆公式
* @param rotation 弧度
* 计算公式:
* Math.PI; //圆周率
* Math.sin(); //正弦 x -左 +右
* Math.cos; //余弦 y -下 +上
*/
var circleMath = {
/**
* 根据弧度计算角度
* @param rotation 弧度
* rotation, farScale, xs, xr, ys, yr, itemWidth
*/
// parseRotate: function (rotation) {
// return (180 / Math.PI * rotation) - 180;
// },
parseRotate: function (rotation, self) {
var sin = Math.sin(rotation), cos = Math.cos(rotation);
var sin_cos = sin*cos; //得出偏移正负值,从0°向左依次 +-+-
var angle = (180 / Math.PI * rotation) - 180;
var lastAngle = angle;

// console.log('rotation',rotation)
// console.log('sin',sin)
// console.log('cos',cos)
// console.log('sin*cos',sin*cos);
// console.log('统一偏移角度',self.yr * (sin_cos/Math.PI))

lastAngle = angle + (self.yr * (sin_cos/(Math.PI+1)));

return lastAngle;
},
/**
* 计算scale,x,y
* scale 最小尺寸 + ((1 - 最小尺寸) * (sin正弦 + 1) * 0.5)
* x x起点 + (尺寸 * cos余弦 * x半径) - 元素宽度一半
* y y起点 + (尺寸 * sin正弦 * x半径) - 元素宽度一半
* farScale, xs, xr, ys, yr, itemWidth
*/
parseSXY: function (rotation, self) {
var farScale=self.farScale;
var itemWidth=self.itemWidth;
var xs=self.xs; var xr=self.xr; var ys=self.ys; var yr=self.yr;
var sin = Math.sin(rotation), cos = Math.cos(rotation);
var scale = farScale + ((1 - farScale) * (sin + 1) * 0.5); //单个尺寸

// 按设置尺寸
// var x = xs + (scale * cos * xr) - (itemWidth * 0.5);
// var y = ys + (scale * sin * yr) - (itemWidth * 0.5);
// 不使用压缩
// var x = xs + (cos * xs) - (itemWidth * 0.5);
// var y = ys + (sin * ys) - (itemWidth * 0.5);
// 使用压缩
var x = xs + (cos * xr) - (itemWidth * 0.5);
var y = ys + (sin * yr) - (itemWidth * 0.5);
var distanceNumber = distance([
{x:self.$rotation.width()/2 - self.$item.width()/2, y:self.$rotation.height()/2 - self.$item.height()/2},
{x:x,y:y}]
);

// console.log({x:self.$rotation.width()/2, y:self.$rotation.height()/2})
// console.log('x,y',x,y)
// console.log('两点距离',distanceNumber)

return {
x: x,
y: y,
scale: scale,
distanceNumber: distanceNumber,
}
},
}
/**
* 3D旋转
* @param id
*/
var Rotation3D = window.Rotation3D = function (_opts) {
var self=this;
this.$rotation = $(_opts.id)
this.$lineList = this.$rotation.find('.lineList')
this.$item = this.$rotation.find('.rotation3D__item')
this.$line = this.$rotation.find('.rotation3D__line')
this.itemWidth = this.$item.width();
this.itemHeight = this.$item.height();
this.length = this.$item.length;
// 圆计算
this.rotation = Math.PI / 2; //圆周率/2
this.destRotation = this.rotation;

var xr = this.$rotation.width() * 0.5;
var yr = this.$rotation.height() * 0.5;
var xRadius = _opts.xRadius || 0;
var yRadius = _opts.yRadius || 0;

var opts = Object.assign({
farScale: 1, // 最小尺寸
xs: xr, // x起点
ys: yr, // y起点
xr: xr - xRadius, // x半径-压缩
yr: yr - yRadius, // y半径-压缩
// 播放
autoPlay:false,
autoPlayDelay:3000,
currenIndex:-1,
fps:30,
speed:4,
},_opts)
Object.assign(this, opts)

// 遍历子元素
this.$item.each(function (index) {
$(this).click(function () {
$(this).addClass('active').siblings().removeClass('active')
self.goTo(index)
})
})
// 当前控件进入离开
this.$rotation.mouseenter(function () {
clearInterval(self.autoPlayTimer)
})
this.$rotation.mouseleave(function () {
self.onAutoPlay()
})

this.onAutoPlay()
this.onDrag()
this.render()

}
/**
* item样式
* x x起点 + (尺寸 * 余弦 * x压缩) - 元素宽度一半
* y y起点 + (尺寸 * 正弦 * y压缩) - 元素宽度一半
*/
Rotation3D.prototype.itemStyle = function($item, index, rotation) {
//console.log("itemStyle=" + rotation + " index=" + index);
var parseSXY = circleMath.parseSXY(rotation, this);
var scale = parseSXY.scale;
var x = parseSXY.x;
var y = parseSXY.y;
var $line = this.$lineList.find('.rotation3D__line').eq(index);

//设置当前子菜单的位置(left,top) = (x,y)
$item.find('.scale').css({
'transform': `scale(${scale})`,
// 'top': `${this.itemWidth * (1-scale) }`,
})
$item.css({
position: 'absolute',
display: 'inline-block',
// opacity: scale,
'z-index': parseInt(scale * 100),
'transform-origin': '0px 0px',
// 'transform': `translate(${x}px, ${y}px) scale(${scale})`,
'transform': `translate(${x}px, ${y}px)`,
});

/**
* 线样式
*/
$line.css({
height:parseSXY.distanceNumber,
})
$line.find('svg').css({
height:parseSXY.distanceNumber,
})
$line.find('.dot1').css({
'offset-path':`path("M0 ${parseSXY.distanceNumber}, 0 0")`,
})
$line.find('#path1').attr({
'd':`M0 ${parseSXY.distanceNumber}, 0 0`,
})

$line.find('.dot2').css({
'offset-path':`path("M0 ${parseSXY.distanceNumber/2}, 0 0")`,
})
$line.find('#path2').attr({
'd':`M0 ${parseSXY.distanceNumber}, 0 0`,
})

$line.find('.dot3').css({
'offset-path':`path("M20 ${parseSXY.distanceNumber} S 0 ${parseSXY.distanceNumber/2}, 20 0")`,
})
$line.find('#path3').attr({
'd':`M20 ${parseSXY.distanceNumber} S 0 ${parseSXY.distanceNumber/2}, 20 0`,
})

$line.find('.dot4').css({
'offset-path':`path("M20 0 S 40 ${parseSXY.distanceNumber/2}, 20 ${parseSXY.distanceNumber}")`,
})
$line.find('#path4').attr({
'd':`M20 0 S 40 ${parseSXY.distanceNumber/2}, 20 ${parseSXY.distanceNumber}`,
})

}
/**
* line样式
*/
Rotation3D.prototype.lineStyle = function($line, index, rotation) {
var rotate = circleMath.parseRotate(rotation, this)
//console.log("lineStyle=" + rotation + " index=" + index);

$line.css({
transform: 'rotate(' + rotate + 'deg)',
})
this.$lineList.css({
// transform: `rotateX(${this.yRadius / 3}deg)`,
})
}

/**
* 旋转至index
*/
Rotation3D.prototype.goTo = function (index) {
var self = this;
this.currenIndex = index;
//console.log('goTo currenIndex', index);
/**
* 1.计算floatIndex,用于控死amdiff
*/
var itemsRotated = this.length * ((Math.PI / 2) - this.rotation) / (2 * Math.PI);
var floatIndex = itemsRotated % this.length;
if (floatIndex < 0) { floatIndex = floatIndex + this.length; }

/**
* 2.计算diff,判断方向正反
*/
var diff = index - (floatIndex % this.length);
if (2 * Math.abs(diff) > this.length) {
diff -= (diff > 0) ? this.length : -this.length;
}
// 停止任何正在进行的旋转
this.destRotation += (2 * Math.PI / this.length) * -diff;
this.scheduleNextFrame();

}
/**
* 定时器渐近旋转
*/
Rotation3D.prototype.scheduleNextFrame = function () {
var self = this
this.lastTime = time();
// 暂停
var pause = function () {
cancelFrame ? cancelFrame(this.timer) : clearTimeout(self.timer);
self.timer = 0;
}
// 渐进播放
var playFrame = function () {
var rem = self.destRotation - self.rotation;
var now = time(), dt = (now - self.lastTime) * 0.002;
self.lastTime = now;
// console.log('rem',rem)

if (Math.abs(rem) < 0.003) {
self.rotation = self.destRotation;
pause();
} else {
// 渐近地接近目的地
self.rotation = self.destRotation - rem / (1 + (self.speed * dt));
self.scheduleNextFrame();
}
self.render();
}

this.timer = cancelFrame ?
requestFrame(playFrame) :
setTimeout(playFrame, 1000 / this.fps);
}
/**
* 更新
*/
Rotation3D.prototype.render = function () {
var self=this;
// 图形间隔:弧度
var spacing = 2 * Math.PI / this.$item.length;
var itemRotation = this.rotation;
var lineRotation = this.rotation + (Math.PI/2);

this.$item.each(function (index) {
self.itemStyle($(this), index, itemRotation)
itemRotation += spacing;
})
this.$line.each(function (index) {
self.lineStyle($(this), index, lineRotation)
lineRotation += spacing;
})
}
/**
* 自动播放
*/
Rotation3D.prototype.onAutoPlay = function () {
var self = this;

if (this.autoPlay) {
this.autoPlayTimer = setInterval(function () {
if (self.currenIndex < 0) {
self.currenIndex = self.length - 1
}
//console.log("autoPlayTimer....");
self.goTo(self.currenIndex);
self.currenIndex--; //倒叙
}, this.autoPlayDelay)
}
}
/**
* 拖拽
*/
Rotation3D.prototype.onDrag = function () {
var self = this;
var startX, startY, moveX, moveY, endX, endY;
//console.log("onDrag....");
// 拖拽:三个事件-按下 移动 抬起
//按下
this.$rotation.mousedown(function (e) {
startX = e.pageX; startY = e.pageY;
//console.log("mousedown....");
// 移动
$(document).mousemove(function (e) {
// console.log('移动');
endX = e.pageX; endY = e.pageY;
moveX = endX - startX; moveY = endY - startY;
// console.log('x,y',moveX,moveY);
})
// 抬起
$(document).mouseup(function (e) {
endX = e.pageX; endY = e.pageY;
moveX = endX - startX; moveY = endY - startY;
//console.log("mouseup....");
// 每40旋转一步
var moveIndex = parseInt(Math.abs(moveX) / 50)
//console.log('moveIndex',moveIndex)
if (moveIndex > 0) {
// console.log(moveX<0 ? '向左' : '向右')
if (moveX < 0) { //向左
self.currenIndex = self.currenIndex - moveIndex
play(moveIndex)
} else { //向右
self.currenIndex = self.currenIndex + moveIndex
play(moveIndex)
}
}

// 解绑
$(document).unbind("mousemove");
$(document).unbind("mouseup");
})

})

function play() {
if (self.currenIndex == 0) {
self.currenIndex = self.length - 1
}
self.goTo(self.currenIndex % self.length);
}

}

+ 6
- 0
custom/public/rotation3D/vue-2.6.10.min.js
File diff suppressed because it is too large
View File


+ 3
- 2
models/cloudbrain.go View File

@@ -1387,7 +1387,8 @@ func QueryModelTrainJobVersionList(jobId string) ([]*CloudbrainInfo, int, error)
builder.Eq{"cloudbrain.job_id": jobId},
)
cond = cond.And(
builder.Eq{"cloudbrain.Status": "COMPLETED"},
builder.In("cloudbrain.Status", "COMPLETED", "SUCCEEDED"),
//builder.Eq{"cloudbrain.Status": "COMPLETED"},
)

sess.OrderBy("cloudbrain.created_unix DESC")
@@ -1408,7 +1409,7 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) {
builder.Eq{"repo_id": repoId},
)
cond = cond.And(
builder.Eq{"Status": "COMPLETED"},
builder.In("Status", "COMPLETED", "SUCCEEDED"),
)
cond = cond.And(
builder.Eq{"job_type": "TRAIN"},


+ 22
- 0
models/cloudbrain_static.go View File

@@ -0,0 +1,22 @@
package models

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

func GetAllStatusCloudBrain() map[string]int {
sess := x.NewSession()
defer sess.Close()
cloudbrains := make([]*CloudbrainInfo, 0)
if err := sess.Table(&Cloudbrain{}).Unscoped().
Find(&cloudbrains); err != nil {
log.Info("find error.")
}
cloudBrainStatusResult := make(map[string]int)
for _, cloudbrain := range cloudbrains {
if _, ok := cloudBrainStatusResult[cloudbrain.Status]; !ok {
cloudBrainStatusResult[cloudbrain.Status] = 1
} else {
cloudBrainStatusResult[cloudbrain.Status] += 1
}
}
return cloudBrainStatusResult
}

+ 16
- 13
models/user_business_analysis.go View File

@@ -719,12 +719,11 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS
userIndexMap := make(map[int64]float64, 0)
maxUserIndex := 0.0
minUserIndex := 100000000.0
dateRecordBatch := make([]UserBusinessAnalysisAll, 0)
for {
sess.Select("`user`.*").Table("user").Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
userList := make([]*User, 0)
sess.Find(&userList)
dateRecordBatch := make([]UserBusinessAnalysisAll, 0)
for _, userRecord := range userList {
var dateRecordAll UserBusinessAnalysisAll
dateRecordAll.ID = userRecord.ID
@@ -789,7 +788,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS

dateRecordBatch = append(dateRecordBatch, dateRecordAll)
if len(dateRecordBatch) >= BATCH_INSERT_SIZE {
insertTable(dateRecordBatch, tableName, statictisSess)
err := insertTable(dateRecordBatch, tableName, statictisSess)
insertCount += BATCH_INSERT_SIZE
if err != nil {
log.Info("insert all data failed." + err.Error())
@@ -804,18 +803,19 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS
}
}
}
if len(dateRecordBatch) > 0 {
err := insertTable(dateRecordBatch, tableName, statictisSess)
insertCount += len(dateRecordBatch)
if err != nil {
log.Info("insert all data failed." + err.Error())
}
}
indexTotal += PAGE_SIZE
if indexTotal >= count {
break
}
}
if len(dateRecordBatch) > 0 {
insertTable(dateRecordBatch, tableName, statictisSess)
insertCount += len(dateRecordBatch)
if err != nil {
log.Info("insert all data failed." + err.Error())
}
}

if tableName == "user_business_analysis_all" {
log.Info("TotalHasActivityUser=" + fmt.Sprint(userMetrics["TotalHasActivityUser"]))
}
@@ -835,7 +835,7 @@ func updateUserIndex(tableName string, statictisSess *xorm.Session, userId int64
statictisSess.Exec(updateSql)
}

func insertTable(dateRecords []UserBusinessAnalysisAll, tableName string, statictisSess *xorm.Session) {
func insertTable(dateRecords []UserBusinessAnalysisAll, tableName string, statictisSess *xorm.Session) error {

insertBatchSql := "INSERT INTO public." + tableName +
"(id, count_date, code_merge_count, commit_count, issue_count, comment_count, focus_repo_count, star_repo_count, watched_count, gitea_age_month, commit_code_size, commit_dataset_size, " +
@@ -854,7 +854,8 @@ func insertTable(dateRecords []UserBusinessAnalysisAll, tableName string, static
}
}

statictisSess.Exec(insertBatchSql)
_, err := statictisSess.Exec(insertBatchSql)
return err
}

func RefreshUserStaticAllTabel(wikiCountMap map[string]int, userMetrics map[string]int) {
@@ -2057,7 +2058,9 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
} else {
resultMap[cloudTaskRecord.UserID] += 1
}
setMapKey("CloudBrainRunTime", cloudTaskRecord.UserID, int(cloudTaskRecord.Duration), resultItemMap)
if cloudTaskRecord.Duration < 100000000 && cloudTaskRecord.Duration > 0 {
setMapKey("CloudBrainRunTime", cloudTaskRecord.UserID, int(cloudTaskRecord.Duration), resultItemMap)
}
if cloudTaskRecord.Type == 1 { //npu
if cloudTaskRecord.JobType == "TRAIN" {
setMapKey("NpuTrainJob", cloudTaskRecord.UserID, 1, resultItemMap)


+ 8
- 0
modules/storage/local.go View File

@@ -39,6 +39,14 @@ func (l *LocalStorage) Open(path string) (io.ReadCloser, error) {
return f, nil
}

func (l *LocalStorage) DownloadAFile(bucket string, objectName string) (io.ReadCloser, error) {
f, err := os.Open(filepath.Join(l.dir, objectName))
if err != nil {
return nil, err
}
return f, nil
}

// Save save a file
func (l *LocalStorage) Save(path string, r io.Reader) (int64, error) {
p := filepath.Join(l.dir, path)


+ 10
- 0
modules/storage/minio.go View File

@@ -59,6 +59,16 @@ func (m *MinioStorage) buildMinioPath(p string) string {
return strings.TrimPrefix(path.Join(m.basePath, p), "/")
}

func (m *MinioStorage) DownloadAFile(bucket string, objectName string) (io.ReadCloser, error) {

var opts = minio.GetObjectOptions{}
object, err := m.client.GetObject(m.bucket, objectName, opts)
if err != nil {
return nil, err
}
return object, nil
}

// Open open a file
func (m *MinioStorage) Open(path string) (io.ReadCloser, error) {
var opts = minio.GetObjectOptions{}


+ 134
- 0
modules/storage/minio_ext.go View File

@@ -113,7 +113,141 @@ func GenMultiPartSignedUrl(uuid string, uploadId string, partNumber int, partSiz
objectName := strings.TrimPrefix(path.Join(minio.BasePath, path.Join(uuid[0:1], uuid[1:2], uuid)), "/")

return minioClient.GenUploadPartSignedUrl(uploadId, bucketName, objectName, partNumber, partSize, PresignedUploadPartUrlExpireTime, setting.Attachment.Minio.Location)
}

func GetAllObjectByBucketAndPrefixMinio(bucket string, prefix string) ([]FileInfo, error) {
_, core, err := getClients()
if err != nil {
log.Error("getClients failed:", err.Error())
return nil, err
}
prefixLen := len(prefix)
delimiter := ""
marker := ""
index := 1
fileInfoList := FileInfoList{}
for {
output, err := core.ListObjects(bucket, prefix, marker, delimiter, 1000)
if err == nil {
log.Info("Page:%d\n", index)
index++
for _, val := range output.Contents {
var isDir bool
if prefixLen == len(val.Key) {
continue
}
if strings.HasSuffix(val.Key, "/") {
isDir = true
} else {
isDir = false
}
fileInfo := FileInfo{
ModTime: val.LastModified.Format("2006-01-02 15:04:05"),
FileName: val.Key[prefixLen:],
Size: val.Size,
IsDir: isDir,
ParenDir: "",
}
fileInfoList = append(fileInfoList, fileInfo)
}
if output.IsTruncated {
marker = output.NextMarker
} else {
break
}
} else {
log.Info("list error." + err.Error())
return nil, err
}
}
sort.Sort(fileInfoList)
return fileInfoList, nil
}

func GetOneLevelAllObjectUnderDirMinio(bucket string, prefixRootPath string, relativePath string) ([]FileInfo, error) {
_, core, err := getClients()
if err != nil {
log.Error("getClients failed:", err.Error())
return nil, err
}

Prefix := prefixRootPath + relativePath
if !strings.HasSuffix(Prefix, "/") {
Prefix += "/"
}
log.Info("bucket=" + bucket + " Prefix=" + Prefix)
output, err := core.ListObjects(bucket, Prefix, "", "", 1000)
fileInfos := make([]FileInfo, 0)
prefixLen := len(Prefix)
if err == nil {
for _, val := range output.Contents {
log.Info("val key=" + val.Key)
var isDir bool
var fileName string
if val.Key == Prefix {
continue
}
if strings.Contains(val.Key[prefixLen:len(val.Key)-1], "/") {
continue
}
if strings.HasSuffix(val.Key, "/") {
isDir = true
fileName = val.Key[prefixLen : len(val.Key)-1]
relativePath += val.Key[prefixLen:]
} else {
isDir = false
fileName = val.Key[prefixLen:]
}
fileInfo := FileInfo{
ModTime: val.LastModified.Local().Format("2006-01-02 15:04:05"),
FileName: fileName,
Size: val.Size,
IsDir: isDir,
ParenDir: relativePath,
}
fileInfos = append(fileInfos, fileInfo)
}
return fileInfos, err
} else {

log.Error("Message:%s", err.Error())

return nil, err
}

}

func MinioPathCopy(bucketName string, srcPath string, destPath string) (int64, error) {
_, core, err := getClients()
var fileTotalSize int64
fileTotalSize = 0
if err != nil {
log.Error("getClients failed:", err.Error())
return fileTotalSize, err
}
delimiter := ""
marker := ""
for {
output, err := core.ListObjects(bucketName, srcPath, marker, delimiter, 1000)
if err == nil {
for _, val := range output.Contents {
srcObjectName := val.Key
destObjectName := destPath + srcObjectName[len(srcPath):]
log.Info("srcObjectName=" + srcObjectName + " destObjectName=" + destObjectName)
core.CopyObject(bucketName, srcObjectName, bucketName, destObjectName, val.UserMetadata)
fileTotalSize += val.Size
}
if output.IsTruncated {
marker = output.NextMarker
} else {
break
}
} else {
log.Info("list error." + err.Error())
return 0, err
}
}
return fileTotalSize, nil
}

func NewMultiPartUpload(uuid string) (string, error) {


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

@@ -22,6 +22,7 @@ const (
type ObjectStorage interface {
Save(path string, r io.Reader) (int64, error)
Open(path string) (io.ReadCloser, error)
DownloadAFile(bucket string, objectName string) (io.ReadCloser, error)
Delete(path string) error
DeleteDir(dir string) error
PresignedGetURL(path string, fileName string) (string, error)


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

@@ -1455,6 +1455,7 @@ issues.filter_sort.feweststars = Fewest stars
issues.filter_sort.mostforks = Most forks
issues.filter_sort.fewestforks = Fewest forks
issues.filter_sort.downloadtimes = Most downloaded
issues.filter_sort.citations=Citations
issues.filter_sort.mostusecount = Most Quote
issues.filter_sort.fewestusecount=Fewest Quote
issues.action_open = Open


+ 4
- 2
options/locale/locale_zh-CN.ini View File

@@ -226,7 +226,7 @@ contributors=贡献者
contributor=贡献者

page_title=探索更好的AI
page_small_title=启智AI开发协作平台
page_small_title=启智AI协作平台
page_description=面向AI领域的一站式协同开发环境,提供集代码开发、数据管理、模型调试、推理和评测为一体的AI开发流水线
page_use=立即使用
page_only_dynamic=仅展示开源项目动态
@@ -1197,7 +1197,7 @@ template.topics=主题
template.avatar=头像
template.issue_labels=任务标签
template.one_item=必须至少选择一个模板项
template.one_promise=创建项目需承诺使用协议
template.one_promise=创建项目需承诺遵守使用协议
template.invalid=必须选择一个模板项目
template.repo_adress=项目地址
template.repo_path=项目地址
@@ -1465,9 +1465,11 @@ issues.filter_sort.feweststars=点赞由少到多
issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多
issues.filter_sort.downloadtimes=下载次数
issues.filter_sort.citations=引用次数
issues.filter_sort.moststars=收藏数量
issues.filter_sort.mostusecount=最多引用
issues.filter_sort.fewestusecount=最少引用

issues.action_open=开启
issues.action_close=关闭
issues.action_label=标签


+ 66
- 5
public/home/home.js View File

@@ -9,7 +9,7 @@ if(isEmpty(token)){

var swiperNewMessage = new Swiper(".newslist", {
direction: "vertical",
slidesPerView: 10,
slidesPerView: 9,
loop: true,
autoplay: {
delay: 2500,
@@ -17,7 +17,7 @@ var swiperNewMessage = new Swiper(".newslist", {
},
});
var swiperEvent = new Swiper(".event-list", {
slidesPerView: 2,
slidesPerView: 3,
spaceBetween: 30,
pagination: {
el: ".swiper-pagination",
@@ -117,6 +117,7 @@ socket.onmessage = function (e) {
continue;
}
}
refresh3DInfo(record);
var recordPrefix = getMsg(record);
if(record.OpType == "6" || record.OpType == "10" || record.OpType == "12" || record.OpType == "13"){
html += recordPrefix + actionName;
@@ -200,6 +201,29 @@ function getTaskLink(record){
return re;
}

function refresh3DInfo(record){
if(record.OpType == "25" || record.OpType == "29" || record.OpType == "31"){
//cloudbrain one
var lines = $('.rotation3D__line');
var span = $('.rotation3D__line').find("span")[0];
//console.log(span);
span.innerText =record.RefName;
//$('.rotation3D__line').find("span").eq(0).text(record.RefName)
//console.log("cloudbrain one line length=" + lines.length);
//lines[0].find("span").text(record.RefName);
}else if(record.OpType == "26" || record.OpType == "27" || record.OpType == "28"){
//cloudbrain two
var lines = $('.rotation3D__line');
//console.log("cloudbrain two line length=" + lines.length);
var span = $('.rotation3D__line').find("span")[1];
//console.log(span);
span.innerText =record.RefName;
//$('.rotation3D__line').find("span").eq(1).text(record.RefName)
//lines[1].find("span").text(record.RefName);
}

}

function getMsg(record){
var html ="";
html += "<div class=\"swiper-slide item\">";
@@ -425,13 +449,50 @@ function queryRecommendData(){
dataType:"json",
async:false,
success:function(json){
displayOrg(json.org);
displayRepo(json.repo);
displayActivity(json.image)
displayOrg(json.org);
displayRepo(json.repo);
displayActivity(json.image);
displayCloudBrain(json.cloudbrain)
},
error:function(response) {
}
});

// $.ajax({
// type:"GET",
// url:"/recommend/repo",
// headers: {
// authorization:token,
// },
// dataType:"json",
// async:false,
// success:function(json){
// displayRepo(json);
// },
// error:function(response) {
// }
// });

// $.ajax({
// type:"GET",
// url:"/recommend/imageinfo",
// headers: {
// authorization:token,
// },
// dataType:"json",
// async:false,
// success:function(json){
// displayActivity(json);
// },
// error:function(response) {
// }
// });
}

function displayCloudBrain(json){
$('#completed_task').text(json.completed_task);
$('#running_task').text(json.running_task);
$('#wait_task').text(json.wait_task);
}

function displayActivity(json){


+ 1
- 0
public/self/css/notebook/katex.min.css
File diff suppressed because it is too large
View File


+ 86
- 0
public/self/css/notebook/notebook.css View File

@@ -0,0 +1,86 @@
.nb-notebook {
line-height: 1.5;
margin-left: 7em;
}

.nb-stdout, .nb-stderr {
white-space: pre-wrap;
margin: 1em 0;
padding: 0.1em 0.5em;
}

.nb-stderr {
background-color: #FAA;
}

.nb-cell + .nb-cell {
margin-top: 0.5em;
}

.nb-output table {
border: 1px solid #000;
border-collapse: collapse;
}

.nb-output th {
font-weight: bold;
}

.nb-output th, .nb-output td {
border: 1px solid #000;
padding: 0.25em;
text-align: left;
vertical-align: middle;
border-collapse: collapse;
}

.nb-notebook blockquote {
border-left: 5px solid #CCC;
margin-left: 0;
padding-left: 1em;
}

.nb-cell {
position: relative;
}

.nb-raw-cell {
white-space: pre-wrap;
background-color: #f5f2f0;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
padding: 1em;
margin: .5em 0;
}

.nb-output {
min-height: 1em;
width: 100%;
overflow-x: scroll;
border-right: 1px dotted #CCC;
}

.nb-output img {
max-width: 100%;
}

.nb-output:before, .nb-input:before {
position: absolute;
font-family: monospace;
color: #999;
left: -7em;
width: 7em;
text-align: right;
}

.nb-input:before {
content: "In [" attr(data-prompt-number) "]:";
}
.nb-output:before {
content: "Out [" attr(data-prompt-number) "]:";
}

// Fix pandas dataframe formatting
div[style="max-height:1000px;max-width:1500px;overflow:auto;"] {
max-height: none !important;
}


+ 142
- 0
public/self/css/notebook/prism.css View File

@@ -0,0 +1,142 @@
/* PrismJS 1.21.0
https://prismjs.com/download.html#themes=prism&languages=markup+clike+javascript+julia+python+r */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/

code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;

-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;

-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}

pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}

pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}

@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}

/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}

:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}

/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}

.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}

.token.punctuation {
color: #999;
}

.token.namespace {
opacity: .7;
}

.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}

.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}

.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
/* This background color was intended by the author of this theme. */
background: hsla(0, 0%, 100%, .5);
}

.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}

.token.function,
.token.class-name {
color: #DD4A68;
}

.token.regex,
.token.important,
.token.variable {
color: #e90;
}

.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}

.token.entity {
cursor: help;
}

+ 6
- 0
public/self/js/notebook/ansi_up.min.js View File

@@ -0,0 +1,6 @@
// ansi_up.js
// version : 1.1.0
// author : Dru Nelson
// license : MIT
// http://github.com/drudru/ansi_up
(function(a,b){function g(){this.fg=this.bg=null,this.bright=0}var c,d="1.1.0",e=typeof module!="undefined",f=[[{color:"0, 0, 0","class":"ansi-black"},{color:"187, 0, 0","class":"ansi-red"},{color:"0, 187, 0","class":"ansi-green"},{color:"187, 187, 0","class":"ansi-yellow"},{color:"0, 0, 187","class":"ansi-blue"},{color:"187, 0, 187","class":"ansi-magenta"},{color:"0, 187, 187","class":"ansi-cyan"},{color:"255,255,255","class":"ansi-white"}],[{color:"85, 85, 85","class":"ansi-bright-black"},{color:"255, 85, 85","class":"ansi-bright-red"},{color:"0, 255, 0","class":"ansi-bright-green"},{color:"255, 255, 85","class":"ansi-bright-yellow"},{color:"85, 85, 255","class":"ansi-bright-blue"},{color:"255, 85, 255","class":"ansi-bright-magenta"},{color:"85, 255, 255","class":"ansi-bright-cyan"},{color:"255, 255, 255","class":"ansi-bright-white"}]];g.prototype.escape_for_html=function(a){return a.replace(/[&<>]/gm,function(a){if(a=="&")return"&amp;";if(a=="<")return"&lt;";if(a==">")return"&gt;"})},g.prototype.linkify=function(a){return a.replace(/(https?:\/\/[^\s]+)/gm,function(a){return'<a href="'+a+'">'+a+"</a>"})},g.prototype.ansi_to_html=function(a,b){var c=a.split(/\033\[/),d=c.shift(),e=this,f=c.map(function(a){return e.process_chunk(a,b)});f.unshift(d);var g=f.reduce(function(a,b){return Array.isArray(b)?a.concat(b):(a.push(b),a)},[]),h=g.join("");return h},g.prototype.process_chunk=function(a,b){b=typeof b=="undefined"?{}:b;var c=typeof b.use_classes!="undefined"&&b.use_classes,d=c?"class":"color",e=a.match(/([\d;]*)m([^]*)/m);if(!e)return a;var g=e[2],h=e[1].split(";"),i=this;h.map(function(a){var b=parseInt(a);isNaN(b)||b===0?(i.fg=i.bg=null,i.bright=0):b===1?i.bright=1:b>=30&&b<38?i.fg=f[i.bright][b%10][d]:b>=40&&b<48&&(i.bg=f[0][b%10][d])});if(i.fg===null&&i.bg===null)return g;var j=classes=[];return i.fg&&(c?classes.push(i.fg+"-fg"):j.push("color:rgb("+i.fg+")")),i.bg&&(c?classes.push(i.bg+"-bg"):j.push("background-color:rgb("+i.bg+")")),c?['<span class="'+classes.join(" ")+'">',g,"</span>"]:['<span style="'+j.join(";")+'">',g,"</span>"]},c={escape_for_html:function(a){var b=new g;return b.escape_for_html(a)},linkify:function(a){var b=new g;return b.linkify(a)},ansi_to_html:function(a,b){var c=new g;return c.ansi_to_html(a,b)},ansi_to_html_obj:function(){return new g}},e&&(module.exports=c),typeof window!="undefined"&&typeof ender=="undefined"&&(window.ansi_up=c),typeof define=="function"&&define.amd&&define("ansi_up",[],function(){return c})})(Date);

+ 7
- 0
public/self/js/notebook/es5-shim.min.js
File diff suppressed because it is too large
View File


+ 1
- 0
public/self/js/notebook/katex-auto-render.min.js View File

@@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([function(t,r){t.exports=e},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),a=function(e,t,r){for(var n=r,o=0,a=e.length;n<t.length;){var i=t[n];if(o<=0&&t.slice(n,n+a)===e)return n;"\\"===i?n++:"{"===i?o++:"}"===i&&o--,n++}return-1},i=function(e,t,r,n){for(var o=[],i=0;i<e.length;i++)if("text"===e[i].type){var l=e[i].data,d=!0,s=0,f=void 0;for(-1!==(f=l.indexOf(t))&&(s=f,o.push({type:"text",data:l.slice(0,s)}),d=!1);;){if(d){if(-1===(f=l.indexOf(t,s)))break;o.push({type:"text",data:l.slice(s,f)}),s=f}else{if(-1===(f=a(r,l,s+t.length)))break;o.push({type:"math",data:l.slice(s+t.length,f),rawData:l.slice(s,f+r.length),display:n}),s=f+r.length}d=!d}o.push({type:"text",data:l.slice(s)})}else o.push(e[i]);return o},l=function(e,t){var r=function(e,t){for(var r=[{type:"text",data:e}],n=0;n<t.length;n++){var o=t[n];r=i(r,o.left,o.right,o.display||!1)}return r}(e,t.delimiters);if(1===r.length&&"text"===r[0].type)return null;for(var n=document.createDocumentFragment(),a=0;a<r.length;a++)if("text"===r[a].type)n.appendChild(document.createTextNode(r[a].data));else{var l=document.createElement("span"),d=r[a].data;t.displayMode=r[a].display;try{t.preProcess&&(d=t.preProcess(d)),o.a.render(d,l,t)}catch(e){if(!(e instanceof o.a.ParseError))throw e;t.errorCallback("KaTeX auto-render: Failed to parse `"+r[a].data+"` with ",e),n.appendChild(document.createTextNode(r[a].rawData));continue}n.appendChild(l)}return n};t.default=function(e,t){if(!e)throw new Error("No element provided to render");var r={};for(var n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);r.delimiters=r.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],r.ignoredTags=r.ignoredTags||["script","noscript","style","textarea","pre","code","option"],r.ignoredClasses=r.ignoredClasses||[],r.errorCallback=r.errorCallback||console.error,r.macros=r.macros||{},function e(t,r){for(var n=0;n<t.childNodes.length;n++){var o=t.childNodes[n];if(3===o.nodeType){var a=l(o.textContent,r);a&&(n+=a.childNodes.length-1,t.replaceChild(a,o))}else 1===o.nodeType&&function(){var t=" "+o.className+" ";-1===r.ignoredTags.indexOf(o.nodeName.toLowerCase())&&r.ignoredClasses.every(function(e){return-1===t.indexOf(" "+e+" ")})&&e(o,r)}()}}(e,r)}}]).default});

+ 1
- 0
public/self/js/notebook/katex.min.js
File diff suppressed because it is too large
View File


+ 1
- 0
public/self/js/notebook/marked.min.js
File diff suppressed because it is too large
View File


+ 1
- 0
public/self/js/notebook/notebook.min.js
File diff suppressed because it is too large
View File


+ 7
- 0
public/self/js/notebook/prism.min.js
File diff suppressed because it is too large
View File


+ 3
- 0
public/self/js/notebook/purify.min.js
File diff suppressed because it is too large
View File


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

@@ -573,6 +573,9 @@ func RegisterRoutes(m *macaron.Macaron) {
//cloudbrain board
m.Group("/cloudbrainboard", func() {
m.Get("/downloadAll", repo.DownloadCloudBrainBoard)
m.Group("/cloudbrain", func() {
m.Get("/status_analysis", repo.GetCloudbrainsStatusAnalysis)
})
}, operationReq)
// Users
m.Group("/users", func() {


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

@@ -11,6 +11,16 @@ import (
"github.com/360EntSecGroup-Skylar/excelize/v2"
)

type CloudbrainsStatusAnalysis struct {
JobWaitingCount int64 `json:"jobWaitingCount"`
JobRunningCount int64 `json:"jobRunningCount"`
JobStoppedCount int64 `json:"jobStoppedCount"`
JobCompletedCount int64 `json:"jobCompletedCount"`
JobFailedCount int64 `json:"jobFailedCount"`
JobKilledCount int64 `json:"jobKilledCount"`
JobInitCount int64 `json:"jobInitCount"`
}

func DownloadCloudBrainBoard(ctx *context.Context) {

page := 1
@@ -133,3 +143,9 @@ func getBrainWaitTime(rs *models.CloudbrainInfo) string {
return models.ConvertDurationToStr(int64(waitTime))
}
}
func GetCloudbrainsStatusAnalysis(ctx *context.Context) {
cloudBrainStatusResult := models.GetAllStatusCloudBrain()
ctx.JSON(http.StatusOK, map[string]interface{}{
"cloudBrainStatusResult": cloudBrainStatusResult,
})
}

+ 33
- 0
routers/home.go View File

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

import (
"bytes"
"fmt"
"net/http"
"strconv"
"strings"
@@ -750,6 +751,15 @@ func GetRankUser(index string) ([]map[string]interface{}, error) {
return resultOrg, nil
}

// func GetImageInfoFromPromote(ctx *context.Context) {
// imageInfo, err := GetImageInfo()
// if err != nil {
// ctx.ServerError("500", err)
// return
// }
// ctx.JSON(200, imageInfo)
// }

func GetUserRankFromPromote(ctx *context.Context) {
index := ctx.Params("index")
resultUserRank, err := GetRankUser(index)
@@ -773,13 +783,36 @@ func RecommendHomeInfo(ctx *context.Context) {
if err != nil {
log.Info("error." + err.Error())
}
resultCloudBrain, err := getCloudbrainNums()
if err != nil {
log.Info("error." + err.Error())
}
mapInterface := make(map[string]interface{})
mapInterface["org"] = resultOrg
mapInterface["repo"] = resultRepo
mapInterface["image"] = resultImage
mapInterface["cloudbrain"] = resultCloudBrain
ctx.JSON(http.StatusOK, mapInterface)
}

func getCloudbrainNums() (map[string]string, error) {
result := make(map[string]string)
cloudStatusMap := models.GetAllStatusCloudBrain()
result["completed_task"] = fmt.Sprint(cloudStatusMap["COMPLETED"])
result["running_task"] = fmt.Sprint(cloudStatusMap["RUNNING"])
result["wait_task"] = fmt.Sprint(cloudStatusMap["WAITING"])
return result, nil
}

// func RecommendOrgFromPromote(ctx *context.Context) {
// resultOrg, err := GetRecommendOrg()
// if err != nil {
// ctx.ServerError("500", err)
// return
// }
// ctx.JSON(200, resultOrg)
// }

func RecommendRepoFromPromote(ctx *context.Context) {
result, err := repository.GetRecommendRepoFromPromote("projects")
if err != nil {


+ 201
- 78
routers/repo/ai_model_manage.go View File

@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"path"
"strings"

@@ -27,19 +28,22 @@ const (
MODEL_NOT_LATEST = 0
)

func saveModelByParameters(jobId string, versionName string, name string, version string, label string, description string, ctx *context.Context) error {
func saveModelByParameters(jobId string, versionName string, name string, version string, label string, description string, engine int, ctx *context.Context) error {
aiTask, err := models.GetCloudbrainByJobIDAndVersionName(jobId, versionName)
if err != nil {
log.Info("query task error." + err.Error())
return err
aiTask, err = models.GetRepoCloudBrainByJobID(ctx.Repo.Repository.ID, jobId)
if err != nil {
log.Info("query task error." + err.Error())
return err
} else {
log.Info("query gpu train task.")
}
}

uuid := uuid.NewV4()
id := uuid.String()
modelPath := id
var lastNewModelId string
var modelSize int64
cloudType := models.TypeCloudBrainTwo

log.Info("find task name:" + aiTask.JobName)
aimodels := models.QueryModelByName(name, aiTask.RepoID)
@@ -53,7 +57,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
}
}
}
cloudType = aiTask.Type
cloudType := aiTask.Type
//download model zip //train type
if cloudType == models.TypeCloudBrainTwo {
modelPath, modelSize, err = downloadModelFromCloudBrainTwo(id, aiTask.JobName, "", aiTask.TrainUrl)
@@ -61,6 +65,12 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
log.Info("download model from CloudBrainTwo faild." + err.Error())
return err
}
} else if cloudType == models.TypeCloudBrainOne {
modelPath, modelSize, err = downloadModelFromCloudBrainOne(id, aiTask.JobName, "", aiTask.TrainUrl)
if err != nil {
log.Info("download model from CloudBrainOne faild." + err.Error())
return err
}
}
accuracy := make(map[string]string)
accuracy["F1"] = ""
@@ -131,7 +141,7 @@ func SaveNewNameModel(ctx *context.Context) {
return
}
SaveModel(ctx)
ctx.Status(200)
log.Info("save model end.")
}

@@ -143,8 +153,9 @@ func SaveModel(ctx *context.Context) {
version := ctx.Query("Version")
label := ctx.Query("Label")
description := ctx.Query("Description")
engine := ctx.QueryInt("Engine")
trainTaskCreate := ctx.QueryBool("trainTaskCreate")
log.Info("engine=" + fmt.Sprint(engine))
if !trainTaskCreate {
if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
//ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -163,14 +174,14 @@ func SaveModel(ctx *context.Context) {
return
}

err := saveModelByParameters(JobId, VersionName, name, version, label, description, ctx)
err := saveModelByParameters(JobId, VersionName, name, version, label, description, engine, ctx)

if err != nil {
log.Info("save model error." + err.Error())
ctx.Error(500, fmt.Sprintf("save model error. %v", err))
return
}
ctx.Status(200)
log.Info("save model end.")
}

@@ -199,6 +210,22 @@ func downloadModelFromCloudBrainTwo(modelUUID string, jobName string, parentDir
return dataActualPath, size, nil
}

func downloadModelFromCloudBrainOne(modelUUID string, jobName string, parentDir string, trainUrl string) (string, int64, error) {
modelActualPath := storage.GetMinioPath(jobName, "/model/")
log.Info("modelActualPath=" + modelActualPath)
modelSrcPrefix := setting.CBCodePathPrefix + jobName + "/model/"
destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(modelUUID) + "/"
bucketName := setting.Attachment.Minio.Bucket
log.Info("destKeyNamePrefix=" + destKeyNamePrefix + " modelSrcPrefix=" + modelSrcPrefix + " bucket=" + bucketName)
size, err := storage.MinioPathCopy(bucketName, modelSrcPrefix, destKeyNamePrefix)
if err == nil {
dataActualPath := bucketName + "/" + destKeyNamePrefix
return dataActualPath, size, nil
} else {
return "", 0, nil
}
}

func DeleteModel(ctx *context.Context) {
log.Info("delete model start.")
id := ctx.Query("ID")
@@ -277,51 +304,117 @@ func DownloadMultiModelFile(ctx *context.Context) {
}

path := Model_prefix + models.AttachmentRelativePath(id) + "/"
if task.Type == models.TypeCloudBrainTwo {
downloadFromCloudBrainTwo(path, task, ctx, id)
} else if task.Type == models.TypeCloudBrainOne {
downloadFromCloudBrainOne(path, task, ctx, id)
}
}

allFile, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, path)
func MinioDownloadManyFile(path string, ctx *context.Context, returnFileName string, allFile []storage.FileInfo) {
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(returnFileName))
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
w := zip.NewWriter(ctx.Resp)
defer w.Close()
for _, oneFile := range allFile {
if oneFile.IsDir {
log.Info("zip dir name:" + oneFile.FileName)
} else {
log.Info("zip file name:" + oneFile.FileName)
fDest, err := w.Create(oneFile.FileName)
if err != nil {
log.Info("create zip entry error, download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
}
log.Info("minio file path=" + (path + oneFile.FileName))
body, err := storage.Attachments.DownloadAFile(setting.Attachment.Minio.Bucket, path+oneFile.FileName)
if err != nil {
log.Info("download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
} else {
defer body.Close()
p := make([]byte, 1024)
var readErr error
var readCount int
// 读取对象内容
for {
readCount, readErr = body.Read(p)
if readCount > 0 {
fDest.Write(p[:readCount])
}
if readErr != nil {
break
}
}
}
}
}

}

func downloadFromCloudBrainOne(path string, task *models.AiModelManage, ctx *context.Context, id string) {
allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, path)
if err == nil {
//count++
models.ModifyModelDownloadCount(id)

returnFileName := task.Name + "_" + task.Version + ".zip"
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+returnFileName)
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
w := zip.NewWriter(ctx.Resp)
defer w.Close()
for _, oneFile := range allFile {
if oneFile.IsDir {
log.Info("zip dir name:" + oneFile.FileName)
MinioDownloadManyFile(path, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
}
}

func ObsDownloadManyFile(path string, ctx *context.Context, returnFileName string, allFile []storage.FileInfo) {
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(returnFileName))
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
w := zip.NewWriter(ctx.Resp)
defer w.Close()
for _, oneFile := range allFile {
if oneFile.IsDir {
log.Info("zip dir name:" + oneFile.FileName)
} else {
log.Info("zip file name:" + oneFile.FileName)
fDest, err := w.Create(oneFile.FileName)
if err != nil {
log.Info("create zip entry error, download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
}
body, err := storage.ObsDownloadAFile(setting.Bucket, path+oneFile.FileName)
if err != nil {
log.Info("download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
} else {
log.Info("zip file name:" + oneFile.FileName)
fDest, err := w.Create(oneFile.FileName)
if err != nil {
log.Info("create zip entry error, download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
}
body, err := storage.ObsDownloadAFile(setting.Bucket, path+oneFile.FileName)
if err != nil {
log.Info("download file failed: %s\n", err.Error())
ctx.ServerError("download file failed:", err)
return
} else {
defer body.Close()
p := make([]byte, 1024)
var readErr error
var readCount int
// 读取对象内容
for {
readCount, readErr = body.Read(p)
if readCount > 0 {
fDest.Write(p[:readCount])
}
if readErr != nil {
break
}
defer body.Close()
p := make([]byte, 1024)
var readErr error
var readCount int
// 读取对象内容
for {
readCount, readErr = body.Read(p)
if readCount > 0 {
fDest.Write(p[:readCount])
}
if readErr != nil {
break
}
}
}
}
}
}

func downloadFromCloudBrainTwo(path string, task *models.AiModelManage, ctx *context.Context, id string) {
allFile, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, path)
if err == nil {
//count++
models.ModifyModelDownloadCount(id)
returnFileName := task.Name + "_" + task.Version + ".zip"
ObsDownloadManyFile(path, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
@@ -374,42 +467,55 @@ func DownloadSingleModelFile(ctx *context.Context) {
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
if setting.PROXYURL != "" {
body, err := storage.ObsDownloadAFile(setting.Bucket, path)
if err != nil {
log.Info("download error.")
if task.Type == models.TypeCloudBrainTwo {
if setting.PROXYURL != "" {
body, err := storage.ObsDownloadAFile(setting.Bucket, path)
if err != nil {
log.Info("download error.")
} else {
//count++
models.ModifyModelDownloadCount(id)
defer body.Close()
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+fileName)
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
p := make([]byte, 1024)
var readErr error
var readCount int
// 读取对象内容
for {
readCount, readErr = body.Read(p)
if readCount > 0 {
ctx.Resp.Write(p[:readCount])
//fmt.Printf("%s", p[:readCount])
}
if readErr != nil {
break
}
}
}
} else {
url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path)
if err != nil {
log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("GetObsCreateSignedUrl", err)
return
}
//count++
models.ModifyModelDownloadCount(id)
defer body.Close()
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+fileName)
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
p := make([]byte, 1024)
var readErr error
var readCount int
// 读取对象内容
for {
readCount, readErr = body.Read(p)
if readCount > 0 {
ctx.Resp.Write(p[:readCount])
//fmt.Printf("%s", p[:readCount])
}
if readErr != nil {
break
}
}
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
}
} else {
url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path)
} else if task.Type == models.TypeCloudBrainOne {
log.Info("start to down load minio file.")
url, err := storage.Attachments.PresignedGetURL(path, fileName)
if err != nil {
log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("GetObsCreateSignedUrl", err)
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("Get minio get SignedUrl failed", err)
return
}
//count++
models.ModifyModelDownloadCount(id)
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
}

}

func ShowModelInfo(ctx *context.Context) {
@@ -684,14 +790,22 @@ func QueryModelListForPredict(ctx *context.Context) {
func QueryModelFileForPredict(ctx *context.Context) {
id := ctx.Query("ID")
model, err := models.QueryModelById(id)
if err != nil {
if err == nil {
if model.Type == models.TypeCloudBrainTwo {
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
ctx.JSON(http.StatusOK, fileinfos)
} else if model.Type == models.TypeCloudBrainOne {
prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, prefix)
ctx.JSON(http.StatusOK, fileinfos)
}
} else {
log.Error("no such model!", err.Error())
ctx.ServerError("no such model:", err)
return
}
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
ctx.JSON(http.StatusOK, fileinfos)

}

func QueryOneLevelModelFile(ctx *context.Context) {
@@ -703,7 +817,16 @@ func QueryOneLevelModelFile(ctx *context.Context) {
ctx.ServerError("no such model:", err)
return
}
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, err := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir)
ctx.JSON(http.StatusOK, fileinfos)
if model.Type == models.TypeCloudBrainTwo {
log.Info("TypeCloudBrainTwo list model file.")
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, _ := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir)
ctx.JSON(http.StatusOK, fileinfos)
} else if model.Type == models.TypeCloudBrainOne {
log.Info("TypeCloudBrainOne list model file.")
prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
fileinfos, _ := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, parentDir)
ctx.JSON(http.StatusOK, fileinfos)
}

}

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

@@ -173,7 +173,7 @@ func DatasetIndex(ctx *context.Context) {
uploader, _ := models.GetUserByID(attachment.UploaderID)
attachment.Uploader = uploader
if !strings.HasSuffix(attachment.Name, ".zip") {
attachment.DecompressState = 3 //非zip文件
attachment.DecompressState = -1 //非zip文件
}

}


+ 4
- 0
routers/repo/view.go View File

@@ -471,6 +471,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st

readmeExist := markup.IsReadmeFile(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist
isNoteBook := strings.HasSuffix(blob.Name(), ".ipynb")
ctx.Data["IsNoteBook"] = isNoteBook
if markupType := markup.Type(blob.Name()); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
@@ -480,6 +482,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["FileContent"] = strings.Replace(
gotemplate.HTMLEscapeString(string(buf)), "\n", `<br>`, -1,
)
} else if isNoteBook {
ctx.Data["FileContent"] = string(buf)
} else {
// Building code view blocks with line number on server side.
var fileContent string


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

@@ -324,7 +324,10 @@ func RegisterRoutes(m *macaron.Macaron) {
go routers.SocketManager.Run()
m.Get("/action/notification", routers.ActionNotification)
m.Get("/recommend/home", routers.RecommendHomeInfo)
//m.Get("/recommend/org", routers.RecommendOrgFromPromote)
//m.Get("/recommend/repo", routers.RecommendRepoFromPromote)
m.Get("/recommend/userrank/:index", routers.GetUserRankFromPromote)
//m.Get("/recommend/imageinfo", routers.GetImageInfoFromPromote)
m.Post("/all/search/", routers.Search)
m.Get("/all/search/", routers.EmptySearch)
m.Get("/all/dosearch/", routers.SearchApi)
@@ -1111,9 +1114,9 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/show_model_child_api", repo.ShowOneVersionOtherModel)
m.Get("/query_train_job", reqRepoCloudBrainReader, repo.QueryTrainJobList)
m.Get("/query_train_job_version", reqRepoCloudBrainReader, repo.QueryTrainJobVersionList)
m.Get("/query_model_for_predict", reqRepoCloudBrainReader, repo.QueryModelListForPredict)
m.Get("/query_modelfile_for_predict", reqRepoCloudBrainReader, repo.QueryModelFileForPredict)
m.Get("/query_onelevel_modelfile", reqRepoCloudBrainReader, repo.QueryOneLevelModelFile)
m.Get("/query_model_for_predict", reqRepoModelManageReader, repo.QueryModelListForPredict)
m.Get("/query_modelfile_for_predict", reqRepoModelManageReader, repo.QueryModelFileForPredict)
m.Get("/query_onelevel_modelfile", reqRepoModelManageReader, repo.QueryOneLevelModelFile)
m.Group("/:ID", func() {
m.Get("", repo.ShowSingleModel)
m.Get("/downloadsingle", repo.DownloadSingleModelFile)


+ 44
- 0
templates/base/footer.tmpl View File

@@ -13,6 +13,9 @@
{{template "base/footer_content" .}}

<script src="{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}"></script>


{{if .RequireSimpleMDE}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js"></script>
@@ -43,5 +46,46 @@
<script src="{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>
{{template "custom/footer" .}}
{{if .PageIsHome}}
<!--script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script-->
<script src="/rotation3D/vue-2.6.10.min.js"></script>
<script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script>
<script>
var app = new Vue({
el: "#app",
//数据 blue, green, yellow
data: {
itemList: [
{ name:'鹏城云脑一号', type:'blue', icon:'', },
{ name:'鹏城云脑二号', type:'blue', icon:'', },
{ name:'北大人工智能集群系统', type:'green', icon:'', },
{ name:'合肥类脑智能开放平台', type:'green', icon:'', },
{ name:'武汉人工智能计算中心', type:'green', icon:'', },
{ name:'西安未来人工智能计算中心', type:'green', icon:'', },
{ name:'……', type:'yellow', icon:'', },
{ name:'中原人工智能计算中心', type:'green', icon:'', },
{ name:'成都人工智能计算中心', type:'green', icon:'', },
{ name:'横琴先进智能计算中心', type:'green', icon:'', },
{ name:'国家超级计算济南中心', type:'green', icon:'', },
],
},
mounted: function () {
new Rotation3D({
id: '#rotation3D',
farScale: 0.6,
// farScale: 1,
xRadius: 0, //x半径压缩
yRadius: 130, //y半径压缩
// yRadius: 0, //y半径压缩
// autoPlay:true,
// autoPlayDelay:6000,
})
},
methods: {},
});
</script>
{{end}}

</body>
</html>

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

@@ -192,6 +192,8 @@ var _hmt = _hmt || [];
<!-- Swiper -->
<link rel="stylesheet" href="/swiper/swiper-bundle.min.css">
<script src="/swiper/swiper-bundle.min.js"></script>
<!-- rotation3D -->
<link rel="stylesheet" href="/rotation3D/rotation3D.css">
</head>
<body>
{{template "custom/body_outer_pre" .}}


+ 4
- 4
templates/base/head_navbar.tmpl View File

@@ -34,7 +34,7 @@

<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui dropdown item" id='dropdown_explore'>
<div class="ui simple dropdown item" id='dropdown_explore'>
{{.i18n.Tr "explore"}}
<i class="dropdown icon"></i>
<div class="menu">
@@ -65,7 +65,7 @@

<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui dropdown item" id='dropdown_PageHome'>
<div class="ui simple dropdown item" id='dropdown_PageHome'>
{{.i18n.Tr "explore"}}
<i class="dropdown icon"></i>
<div class="menu" >
@@ -120,7 +120,7 @@
</span>
</a>

<div class="ui dropdown jump item poping up" data-content="{{.i18n.Tr "create_new"}}" data-variation="tiny inverted">
<div class="ui simple dropdown jump item poping up" data-content="{{.i18n.Tr "create_new"}}" data-variation="tiny inverted">
<span class="text">
<span class="fitted">{{svg "octicon-plus" 16}}</span>
<span class="sr-mobile-only">{{.i18n.Tr "create_new"}}</span>
@@ -141,7 +141,7 @@
</div><!-- end content create new menu -->
</div><!-- end dropdown menu create new -->

<div class="ui dropdown jump item poping up" tabindex="-1" data-content="{{.i18n.Tr "user_profile_and_more"}}" data-variation="tiny inverted">
<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">
<img class="ui tiny avatar image" width="24" height="24" src="{{.SignedUser.RelAvatarLink}}">
<span class="sr-only">{{.i18n.Tr "user_profile_and_more"}}</span>


+ 5
- 3
templates/explore/datasets.tmpl View File

@@ -186,7 +186,7 @@
src="/img/jian.svg" style="margin-left: 0.5rem;">{{end}}
{{if $.IsSigned}}
<span
style="display: flex;align-items: center;justify-content: flex-end;cursor: pointer;font-size: 12px;font-weight: normal;flex: 1;"
style="display: flex;align-items: center;justify-content: flex-end;cursor: pointer;font-size: 12px;font-weight: normal;flex: 1;margin-left: 1.5rem;"
@click.stop="postSquareStar({{.ID}},'{{.Repo.Link}}/datasets',{{$k}})">

<div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;">
@@ -256,12 +256,14 @@
<span
style="color: #999999;font-size: 12px;margin-left: 0.5rem;">{{TimeSinceUnixShort .CreatedUnix}}</span>
<span
style="display: flex;align-items: center;justify-content: center;margin: 0 1rem;">
style="display: flex;align-items: center;justify-content: center;margin: 0 1rem;"
title="{{$.i18n.Tr "repo.issues.filter_sort.citations"}}">
<i class="ri-link"></i>
<span
style="color: #101010; font-size: 12px;margin-left: 0.2rem;">{{.UseCount}}</span>
</span>
<span style=" display: flex;align-items: center;justify-content: center;">
<span style=" display: flex;align-items: center;justify-content: center;"
title='{{$.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}'>
<i class="ri-download-line"></i>
<span
style="color: #101010;font-size: 12px;margin-left: 0.2rem;">{{.DownloadTimes}}</span>


+ 80
- 25
templates/home.tmpl View File

@@ -1,6 +1,6 @@
{{template "base/head_home" .}}
<div class="ui vertical masthead secondary hometop segment">
<div class="ui container" style="position: relative;">
<div class="ui container" style="position: relative;">
<div class="ui center homebanner">
<h1 class="ui huge header">
{{.page_title}}
@@ -17,7 +17,7 @@
{{end}}
</div>
<div class="bannerpic"><img class="ui fluid image" src="/img/gitopeni-index-01.svg"></div>
<div id="homenews" class="ui container">
<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">
@@ -35,33 +35,32 @@

<!--组织-->
<div class="ui container homeorg">
<div class="ui stackable grid">
<div class="ui stackable grid">
<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>
<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="event-list">
<div class="swiper-wrapper" id="recommendactivity">
<div class="homeorg-list">
<div class="swiper-wrapper" id="recommendorg">
</div>
<div class="swiper-pagination"></div>
</div>
</div>

<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>
<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="homeorg-list">
<div class="swiper-wrapper" id="recommendorg">
<div class="event-list">
<div class="swiper-wrapper" id="recommendactivity">
</div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
@@ -87,56 +86,112 @@
</div>

<div class="ui vertical masthead secondary c2net segment">
<div class="ui container">
<div class="ui center am-pt-30 am-pb-30">
<h2>智算网络</h2>
<p><span class="ui text grey">人工智能算力网络推进联盟已接入10家智算中心,算力总规模1542P</p>
</div>

<div id="app" v-cloak>
<!--数据
<div class="aiData">
<p>完成AI任务<br><strong id="completed_task">1716</strong></p>
<p>运行AI任务<br><strong id="running_task">120</strong></p>
<p>等待AI任务<br><strong id="wait_task">80</strong></p>
</div>-->
<!--底座-->
<div class="rotation3D-baseMap"></div>
<!--旋转3D-->
<div id="rotation3D" class="rotation3D">
<button class="center">中心</button>
<div class="itemList">
<div class="rotation3D__item" :class="item.type" v-for="item in itemList">
<div class="scale">
<div class="baseImg"></div>
<div class="cont">
<i class="iconfont" :class="item.icon"></i>
<p></p>
</div>
</div>
</div>
</div>
<div class="lineList">
<div class="rotation3D__line" v-for="item in itemList" :class="item.type">
<div v-if="item.type=='blue'" class="pos">
<svg width="50" height="400">
<path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/>
</svg>
<div class="dot dot1 ri-arrow-left-s-line"><span></span></div>
</div>
<div v-if="item.type=='yellow'" class="pos">
<svg width="10" height="400">
<path id="path2" d="M0 400, 0 0" stroke-dasharray="5,10"/>
</svg>
<div class="dot dot2"><i class="el-icon-close"></i></div>
</div>
<div v-if="item.type=='green'" class="pos">
<svg width="50" height="400">
<path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/>
</svg>
<div class="dot dot1 ri-arrow-left-s-line"></div>
</div>
</div>
</div>
</div>
</div><!--rotation3D end-->
</div>
</div>

<a name="fourth"></a>
<div class="ui container i-env">
<div class="ui center am-pb-30">
<div class="leftline03"></div>
<h2>{{.page_dev_env}}</h2>
<p><span class="ui text grey">{{.page_dev_env_desc}}</p>
</div>
<div class="ui four doubling cards">
<div class="card">
<div class="image">
<img src="/img/i-pic-01.svg">
<img src="/img/i-pic-01.jpg">
</div>
<div class="content">
<h3 class="ui centered small header">{{.page_dev_env_desc_title}}</h3>
<div class="description">
<div class="description ui text grey">
{{.page_dev_env_desc_desc}}
</div>
</div>
</div>
<div class="card">
<div class="image">
<img src="/img/i-pic-02.svg">
<img src="/img/i-pic-02.jpg">
</div>
<div class="content">
<h3 class="ui centered small header">{{.page_dev_env_desc1_title}}</h3>
<div class="description">
<div class="description ui text grey">
{{.page_dev_env_desc1_desc}}
</div>
</div>
</div>
<div class="card">
<div class="image">
<img src="/img/i-pic-03.svg">
<img src="/img/i-pic-03.jpg">
</div>
<div class="content">
<h3 class="ui centered small header">{{.page_dev_env_desc2_title}}</h3>
<div class="description">
<div class="description ui text grey">
{{.page_dev_env_desc2_desc}}
</div>
</div>
</div>
<div class="card">
<div class="image">
<img src="/img/i-pic-04.svg">
<img src="/img/i-pic-04.jpg">
</div>
<div class="content">
<h3 class="ui centered small header">{{.page_dev_env_desc3_title}}</h3>
<div class="description">
<div class="description ui text grey">
{{.page_dev_env_desc3_desc}}
</div>
</div>
@@ -172,8 +227,8 @@
</div>
</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>
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/home/home.js?v={{MD5 AppVer}}" type="text/javascript"></script>


{{template "base/footer" .}}

+ 3
- 2
templates/repo/create.tmpl View File

@@ -152,10 +152,11 @@
</div>
<div class="inline field">
<div class="ui checkbox" id="auto-init">
<input class="hidden" name="auto_agree" type="checkbox" checked="checked">
<input class="hidden" name="auto_agree" type="checkbox">
<label
style="width: 76%;text-align: justify;line-height: 1.5;">{{.i18n.Tr "repo.use_repo_agreement"}}
<a href="/home/term/">{{.i18n.Tr "repo.openi_use_agreement"}}</a></label>
<a target="_blank"
href="/home/term/">{{.i18n.Tr "repo.openi_use_agreement"}}</a></label>
</div>
</div>
</div>


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

@@ -11,7 +11,7 @@

.dataset_title {
font-size: 14px;
max-width: 80%;
/* max-width: 80%; */
display: inline-block !important;
margin-left: 6px !important;
padding-right: 0 !important;
@@ -279,7 +279,7 @@
<el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper">
<div slot="content"><span class="wrap">

{{if ne .DecompressState 3}}{{$.i18n.Tr "dataset.unzip_status"}}:{{if eq .DecompressState 1}}{{$.i18n.Tr "dataset.unzip_successed"}}{{else if eq .DecompressState 0}}{{$.i18n.Tr "dataset.unzip_stared"}}{{else}}{{$.i18n.Tr "dataset.unzip_failed"}}{{end}}
{{if ne .DecompressState -1}}{{$.i18n.Tr "dataset.unzip_status"}}:{{if eq .DecompressState 1}}{{$.i18n.Tr "dataset.unzip_successed"}}{{else if eq .DecompressState 0 2}}{{$.i18n.Tr "dataset.unzip_stared"}}{{else}}{{$.i18n.Tr "dataset.unzip_failed"}}{{end}}
&nbsp;&nbsp;{{end}}<i
class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}
{{if .Description}}&nbsp;&nbsp;{{$.i18n.Tr "dataset.description"}}:{{.Description}}{{end}}</span>
@@ -288,10 +288,10 @@
{{if eq .DecompressState 1}}
<i class="ri-folder-open-line" style="color: #5bb973;"
title='{{$.i18n.Tr "dataset.unzip_successed"}}'></i>
{{else if eq .DecompressState 0}}
{{else if eq .DecompressState 0 2}}
<i class="ri-folder-chart-2-line" style="color: #888888;"
title='{{$.i18n.Tr "dataset.unzip_stared"}}'></i>
{{else if eq .DecompressState 2}}
{{else if eq .DecompressState 3}}
<i class="ri-folder-forbid-line" style="color: #101010;"
title='{{$.i18n.Tr "dataset.unzip_failed"}}'></i>
{{else}}


+ 12
- 0
templates/repo/header.tmpl View File

@@ -182,3 +182,15 @@


<script src="{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/es5-shim.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/marked.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/purify.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/ansi_up.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/prism.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex-auto-render.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script>
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/katex.min.css" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/prism.css" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/notebook.css" />

+ 8
- 2
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -487,8 +487,8 @@
</div>
<div class="ui tab" data-tab="second{{$k}}">
<div>
<a class='{{if eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED"}}ti-download-file{{else}}disabled{{end}}'
<a id="{{.VersionName}}-log-down"
class='{{if and (.CanModify) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}}'
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span>
@@ -734,6 +734,12 @@
// detail status and duration
$('#' + version_name + '-duration').text(data.JobDuration)
$('#' + version_name + '-status').text(data.JobStatus)
console.log(data)
if (["KILLED", "FAILED", "START_FAILED", "STOPPED", "COMPLETED"].includes(data.JobStatus)) {
$(`#${version_name}-log-down`).removeClass('disabled').addClass('ti-download-file')
$('#' + version_name + '-stop').addClass('disabled')
}

loadLog(version_name)




+ 85
- 8
templates/repo/modelmanage/index.tmpl View File

@@ -130,6 +130,19 @@
<label>模型版本</label>
<input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255">
</div>
<div class="unite min_title inline field required">
<label>模型框架</label>
<div class="ui dropdown selection search width70" id="choice_Engine">
<input type="hidden" id="Engine" name="Engine" required>
<div class="default text">选择模型框架</div>
<i class="dropdown icon"></i>
<div class="menu" id="job-Engine">
</div>
</div>
</div>
<div class="inline field">
<label>模型标签</label>
<input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'>
@@ -161,7 +174,7 @@
let repoId = {{$repository}}
const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config;
$('input[name="_csrf"]').val(csrf)
let modelData;
function createModelName(){
let repoName = location.pathname.split('/')[2]
let modelName = repoName + '_model_' + Math.random().toString(36).substr(2, 4)
@@ -185,6 +198,7 @@
document.getElementById("formId").reset();
$('#choice_model').dropdown('clear')
$('#choice_version').dropdown('clear')
$('#choice_Engine').dropdown('clear')
$('.ui.dimmer').css({"background-color":""})
$('.ui.error.message').text()
$('.ui.error.message').css('display','none')
@@ -197,10 +211,24 @@
$(function(){
$('#choice_model').dropdown({
onChange:function(value){
$(".ui.dropdown.selection.search.width70").addClass("loading")
$('#choice_version').dropdown('clear')
$("#job-version").empty()
loadTrainVersion(value)
$(".ui.dropdown.selection.search.width70").addClass("loading")
$('#choice_version').dropdown('clear')
$("#job-version").empty()
loadTrainVersion(value)
}
})

$('#choice_version').dropdown({
onChange:function(value){
console.log("model version:" + value);
if(modelData != null){
for(var i=0; i < modelData.length;i++){
if(modelData[i].VersionName == value){
setEngine(modelData[i])
break;
}
}
}
}
})
})
@@ -240,7 +268,8 @@
let JobID = !value ?$('#choice_model input[name="JobId"]').val(): value
$.get(`${repolink}/modelmanage/query_train_job_version?JobID=${JobID}`, (data) => {
const n_length = data.length
let train_html=''
let train_html='';
modelData = data;
for (let i=0;i<n_length;i++){
train_html += `<div class="item" data-value="${data[i].VersionName}">${data[i].VersionName}</div>`
train_html += '</div>'
@@ -248,11 +277,59 @@
if(data.length){
$("#job-version").append(train_html)
$(".ui.dropdown.selection.search.width70").removeClass("loading")
$('#choice_version .default.text').text(data[0].VersionName)
$('#choice_version input[name="VersionName"]').val(data[0].VersionName)
var versionName = data[0].VersionName;
if(versionName==null || versionName==""){
versionName="V0001";
}
$('#choice_version .default.text').text(versionName)
$('#choice_version input[name="VersionName"]').val(versionName)
console.log("1111111111");
setEngine(data[0])
}

})
}

function setEngine(modelVersion){
console.log("modelVersion=" + modelVersion);
$('#choice_Engine').dropdown('clear')
$("#job-Engine").empty()
if(modelVersion.EngineName != null && modelVersion.EngineName != ""){
srcEngine = modelVersion.EngineName.split('-')[0]
srcEngine = srcEngine.trim();
let selectedText = "Pytorch";
let selectedValue = 0;
let itemHtml = "<option class=\"item\" data-value=\"0\">Pytorch</option>";
if(srcEngine =='TensorFlow'){
selectedText ="TensorFlow";
selectedValue = 1;
itemHtml += "<option class=\"active item\" data-value=\"1\">TensorFlow</option>";
}else{
itemHtml += "<option class=\"item\" data-value=\"1\">TensorFlow</option>";
}
if(srcEngine =='MindSpore'){
selectedText ="MindSpore";
selectedValue = 2;
itemHtml += "<option class=\"active item\" data-value=\"2\">MindSpore</option>";
}else{
itemHtml += "<option class=\"item\" data-value=\"2\">MindSpore</option>";
}
itemHtml += "<option class=\"item\" data-value=\"3\">Other</option>"
$('#choice_Engine .default.text').text(selectedText)
$('#choice_Engine input[name="Engine"]').val(selectedValue)
$("#job-Engine").append(itemHtml);
$("#choice_Engine").addClass('disabled')
}else{
let itemHtml = "<option class=\"active item\" data-value=\"0\">Pytorch</option>";
itemHtml += "<option class=\"item\" data-value=\"1\">TensorFlow</option>"
itemHtml += "<option class=\"item\" data-value=\"2\">MindSpore</option>"
itemHtml += "<option class=\"item\" data-value=\"3\">Other</option>"
$('#choice_Engine .default.text').text("Pytorch");
$('#choice_Engine input[name="Engine"]').val(0)
$("#job-Engine").append(itemHtml);
$("#choice_Engine").removeClass('disabled');
}
}
</script>


+ 14
- 0
templates/repo/view_file.tmpl View File

@@ -108,6 +108,8 @@
<tr>
{{if .IsFileTooLarge}}
<td><strong>{{.i18n.Tr "repo.file_too_large"}}</strong></td>
{{else if .IsNoteBook}}
<td id="notebook"></td>
{{else}}
<td class="lines-num">{{.LineNums}}</td>
<td class="lines-code"><pre><code class="{{.HighlightClass}}"><ol class="linenums">{{.FileContent}}</ol></code></pre></td>
@@ -128,4 +130,16 @@ function submitDeleteForm() {
$("#delete-file-form").submit()
}
}
function showNoteBook(){
var isNoteBook = {{.IsNoteBook}}
if (isNoteBook) {
var jsonStr = "{{.FileContent}}"
var notebook = nb.parse(JSON.parse(jsonStr));
var rendered = notebook.render();
$("#notebook").append(rendered);
Prism.highlightAll();
}
}
showNoteBook()

</script>

+ 4
- 11
templates/user/dashboard/dashboard.tmpl View File

@@ -10,9 +10,9 @@
{{.i18n.Tr "home.wecome_AI_plt"}}
</div>
<div class="content">
<p >{{.i18n.Tr "home.explore_AI"}} <a href="{{AppSubUrl}}/explore/repos"> {{.i18n.Tr "home.repositories"}}</a> {{.i18n.Tr "home.or_t"}} <a href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "home.datasets"}}</a></p>
<p >{{.i18n.Tr "home.use_plt__fuction"}}&nbsp;<a class="mini ui blue button" href="{{AppSubUrl}}/repo/create{{if .ContextUser.IsOrganization}}?org={{.ContextUser.ID}}{{end}}" >{{.i18n.Tr "repo.create_repo"}}</a></p>
<p > {{.i18n.Tr "home.provide_resoure"}}</p>
<p class="ui text grey">{{.i18n.Tr "home.explore_AI"}} <a href="{{AppSubUrl}}/explore/repos"> {{.i18n.Tr "home.repositories"}}</a> {{.i18n.Tr "home.or_t"}} <a href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "home.datasets"}}</a></p>
<p><span class="ui text grey">{{.i18n.Tr "home.use_plt__fuction"}}</span>&nbsp;<a class="mini ui blue button" href="{{AppSubUrl}}/repo/create{{if .ContextUser.IsOrganization}}?org={{.ContextUser.ID}}{{end}}" >{{.i18n.Tr "repo.create_repo"}}</a></p>
<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>
@@ -66,19 +66,12 @@
}
.w_title{
padding-top: 25px;
margin-bottom: 20px;
color: rgba(16, 16, 16, 100);
font-size: 20px;
text-align: left;
font-weight: 700;
}
.content{
color: rgba(80, 85, 89, 100);
font-size: 14px;
text-align: left;
font-family: SourceHanSansSC-regular;
margin-top: 20px;
}

.guide{
margin-top:30px;
padding-bottom: 30px;


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

@@ -6,7 +6,7 @@
<div class="ui grid">
<div class="ui fourteen wide column">
<div class="{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}push news{{end}}">
<p>
<p class="text truncate">
{{if gt .ActUser.ID 0}}
<a href="{{AppSubUrl}}/{{.GetActUserName}}" title="{{.GetDisplayNameTitle}}">{{.GetDisplayName}}</a>
{{else}}


+ 15
- 2
web_src/js/components/Model.vue View File

@@ -168,7 +168,7 @@ export default {
tableData= res.data
for(let i=0;i<tableData.length;i++){
TrainTaskInfo = JSON.parse(tableData[i].TrainTaskInfo)
tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0]
tableData[i].EngineName = this.getEngineName(tableData[i])
tableData[i].ComputeResource = TrainTaskInfo.ComputeResource
tableData[i].cName=tableData[i].Name
tableData[i].Name=''
@@ -218,6 +218,7 @@ export default {
$('input[name="Name"]').removeAttr('readonly')
$('#choice_model').dropdown('clear')
$('#choice_version').dropdown('clear')
$('#choice_Engine').dropdown('clear')
$('.ui.dimmer').css({"background-color":""})
$('.ui.error.message').text()
$('.ui.error.message').css('display','none')
@@ -347,6 +348,18 @@ export default {
})
.modal('show')
},
getEngineName(model){
if(model.Engine == 0){
return "Pytorch";
}else if(model.Engine == 1 || model.Engine == 121){
return "TensorFlow";
}else if(model.Engine == 2 || model.Engine == 122){
return "MindSpore";
}else{
return "Other"
}

},
getModelList(){
try {
this.$refs.table.store.states.lazyTreeNodeMap = {}
@@ -360,7 +373,7 @@ export default {
for(let i=0;i<this.tableData.length;i++){
TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo)
this.tableData[i].cName=this.tableData[i].Name
this.tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0]
this.tableData[i].EngineName = this.getEngineName(this.tableData[i])
this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource
this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true
}


+ 15
- 9
web_src/js/index.js View File

@@ -1214,7 +1214,7 @@ async function initRepository() {
files: $attachments
},
(data) => {
if (data.length === 0) {
if (data.length === 0 || data.content === '') {
$renderContent.html($('#no-content').html());
} else {
$renderContent.html(data.content);
@@ -1222,10 +1222,18 @@ async function initRepository() {
highlight(this);
});
}
let imageShow = ''
const $content = $segment.parent();
if (!$content.find('.ui.small.images').length) {
if (data.attachments !== '') {

if (data.attachments !== '' && data.attachments) {
if ($content.find('.ui.middle.aligned').length === 0) {
imageShow += '<div class="ui clearing divider"></div>'
imageShow += '<div class="ui middle aligned padded grid">'
imageShow += data.attachments
imageShow += '</div>'
$content.find('.ui.attached.segment').append(imageShow)
}
else { $content.find('.ui.middle.aligned').html(data.attachments) }
}
} else if (data.attachments === '') {
$content
@@ -5112,8 +5120,7 @@ function initChartsNpu() {
name: '时间(min)'
},
yAxis: {
min: 0,
max: 100,

show: true,
name: '占有率(%)',
axisLine: {
@@ -5126,7 +5133,6 @@ function initChartsNpu() {
};
$('.metric_chart').click(function (e) {
let versionName = $(this).data('version')
console.log("11111", versionName)
let myCharts = echarts.init(document.getElementById(`metric-${versionName}`))
$.get(`${window.config.AppSubUrl}/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/metric_statistics?version_name=${versionName}&statistic_type=each`, (res) => {
let filterDta = res.MetricsInfo.filter((item) => {
@@ -5137,6 +5143,7 @@ function initChartsNpu() {
return item.metric
})
let seriesData = filterDta.map((item) => {
let value = item.value.map((item) => { return item > 0 ? item : '0' })
let seriesOption = {
name: item.metric,
type: 'line',
@@ -5150,13 +5157,12 @@ function initChartsNpu() {
shadowBlur: 10,
shadowOffsetY: 8
},
data: item.value
data: value
}
return seriesOption
})
let xLength = res.MetricsInfo[0].value.length
console.log(legenData)
options.xAxis.data = Array.from({ length: xLength }, (_, index) => index + 1)
options.xAxis.data = Array.from({ length: xLength }, (_, index) => index)
options.legend.data = legenData
options.series = seriesData
options && myCharts.setOption(options);


+ 4
- 0
web_src/less/_dashboard.less View File

@@ -82,6 +82,10 @@

line-height: 1.2;

p {
max-width: 100%;
}
> .ui.grid {
margin-left: auto;
margin-right: auto;


Loading…
Cancel
Save