Merge remote-tracking branch 'origin/dev_jupyter' into dev_jupyter

# Conflicts:
#	public/react/src/modules/tpm/jupyter/index.scss
chromesetting
杨树明 5 years ago
commit 1f2b57ab47

@ -1,9 +1,35 @@
require 'base64'
class JupytersController < ApplicationController
include JupyterService
before_action :shixun, only: [:open, :open1, :test, :save]
def import_with_tpm
shixun = Shixun.find_by(identifier: params[:identifier])
upload_file = params["file"] || params["#{params[:file_param_name]}"] # 这里的file_param_name是为了方便其他插件名称
uid_logger("#########################file_params####{params["#{params[:file]}"]}")
raise "未上传文件" unless upload_file
content = Base64.encode64(upload_file.tempfile.read)
# upload to server
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/update"
tpiID = "tpm#{shixun.id}"
params = {tpiID: tpiID, content: content}
logger.info "test_juypter: uri->#{uri}, params->#{params}"
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级100")
end
render json: {status: 0}
end
def save_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
jupyter_save_with_game(myshixun, params[:jupyter_port])

@ -35,6 +35,8 @@ Rails.application.routes.draw do
get :reset_with_tpm
get :active_with_tpm
get :active_with_tpi
post :import_with_tpm
end
end

@ -75,6 +75,10 @@ export function getUploadActionUrltwo(id) {
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ? `?debug=${window._debugType || 'admin'}` : ''}`
}
export function getUploadActionUrlthree() {
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ? `?debug=${window._debugType || 'admin'}` : ''}`
}
export function getUploadActionUrlOfAuth(id) {
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ? `?debug=${window._debugType || 'admin'}` : ''}`
}

@ -3,7 +3,7 @@
// export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil';
export { getImageUrl as getImageUrl, getUrl as getUrl, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo , getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool';
export { default as queryString } from './UrlTool2';

@ -1,7 +1,7 @@
/*
* @Description: jupyter tpi
* @Author: tangjiang
* @Github:
* @Github:
* @Date: 2019-12-11 08:35:23
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-13 15:25:50
@ -71,7 +71,7 @@ function JupyterTPI (props) {
<Empty />
</div>
);
const {identifier} = params;
const {identifier} = params;
const [userInfo, setUserInfo] = useState({});
const [jupyterInfo, setJupyterInfo] = useState({});
const [updateTip, setUpdateTip] = useState(true);
@ -128,7 +128,7 @@ function JupyterTPI (props) {
if (user) {
setUserInfo(user);
}
if (myshixun_identifier) {
setMyIdentifier(myshixun_identifier);
}
@ -231,7 +231,7 @@ function JupyterTPI (props) {
saveJupyterTpi();
}
// 分页信息改变时
// 分页信息改变时
const handlePageChange = (current) => {
// 改变当前页
changeCurrentPage(current);
@ -264,13 +264,15 @@ function JupyterTPI (props) {
// title={item.file_path}
mouseLeaveDelay={0.3}
>
<Icon type="file-text" className="jupyter_icon"/>
<span className="jupyter_name ml10">{item.title}</span>
<a className={"fr color-blue"}
onClick={() => {
jsCopy("file_path"+i)
}}>复制地址</a>
<input id={"file_path"+i} className={"file_path_input"} value={item.file_path}/>
<div className="sortinxdirection">
<Icon type="file-text" className="jupyter_icon fl lineheighttaj" />
<a className="jupyter_name ml10 maxnamewidth150 lineheighttaj colorlineheighttaj" title={item.title}>{item.title}</a>
<a className={"fr color-blue lineheighttaj"}
onClick={() => {
jsCopy("file_path"+i)
}}>复制地址</a>
</div>
<input id={"file_path"+i} className={"file_path_input"} value={item.file_path}/>
</Tooltip>
</li>
);
@ -300,9 +302,9 @@ function JupyterTPI (props) {
</p>
<p className="jupyter_btn">
{/* sync | poweroff */}
<Button
className="btn_common"
type="link"
<Button
className="btn_common"
type="link"
icon="history"
onClick={handleClickResetTpi}
>重置实训</Button>
@ -314,12 +316,12 @@ function JupyterTPI (props) {
onClick={handleEnvironmentTpi}
>重置环境</Button>
<Button
className="btn_common"
type="link"
<Button
className="btn_common"
type="link"
icon="poweroff"
onClick={handleClickQuitTpi}
>退出实训</Button>
>退出实训</Button>
</p>
</div>
@ -382,7 +384,7 @@ function JupyterTPI (props) {
const mapStateToProps = (state) => {
const {
jupyter_info,
jupyter_tpi_url,
jupyter_tpi_url,
jupyter_data_set,
jupyter_tpi_url_state,
jupyter_data_set_count,

@ -14,7 +14,7 @@
-webkit-transition: all 2s ease;
transition: all 2s ease;
}
.Resizer.horizontal {
height: 11px;
margin: -5px 0;
@ -23,12 +23,12 @@
cursor: row-resize;
width: 100%;
}
.Resizer.horizontal:hover {
border-top: 5px solid rgba(0, 0, 0, 0.5);
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
}
.Resizer.vertical {
width: 11px;
margin: 0 -5px;
@ -36,7 +36,7 @@
border-right: 5px solid rgba(255, 255, 255, 0);
cursor: col-resize;
}
.Resizer.vertical:hover {
border-left: 5px solid rgba(0, 0, 0, 0.5);
border-right: 5px solid rgba(0, 0, 0, 0.5);
@ -89,7 +89,7 @@
}
}
}
.jupyter_ctx{
position: relative;
@ -122,7 +122,6 @@
.ant-drawer-wrapper-body{
padding-top: 60px;
background: #070F1A;
overflow: hidden !important;
}
.ant-pagination{
@ -159,6 +158,26 @@
}
}
.maxnamewidth150 {
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 150px;
}
.sortinxdirection{
display: flex;
flex-direction:row;
}
.lineheighttaj{
line-height: 50px !important;
}
.colorlineheighttaj{
color: #ffffff;
}
.jupytertitle_time{
.ant-statistic-content{
font-size: 20px !important;

@ -33,7 +33,7 @@
.jupyter_item{
line-height:45px;
//border-bottom: 1px solid rgba(238,238,238, 1);
padding: 0 30px 0 60px;
padding: 0 30px 0 45px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
@ -70,4 +70,4 @@
box-sizing: border-box;
border-top: 1px solid rgba(238,238,238,1);
}
}
}

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import { markdownToHTML, configShareForCustom,getImageUrl} from 'educoder'
import { Divider, Tooltip } from 'antd';
import { markdownToHTML, configShareForCustom,getImageUrl,getUploadActionUrlthree,appendFileSizeToUploadFileAll} from 'educoder'
import { Divider, Tooltip,Upload} from 'antd';
import LoadingSpin from '../../../../common/LoadingSpin';
import 'antd/lib/pagination/style/index.css';
import '../shixunchildCss/Challenges.css';
@ -26,6 +26,7 @@ class Challengesjupyter extends Component {
opentitletype:true,
isopentitletype:"Less",
enlarge:false,
fileList:[],
}
}
@ -243,18 +244,46 @@ class Challengesjupyter extends Component {
enlarge:bool
})
}
daoruzhon=()=>{
var _iframe = document.getElementById("frame");
if(_iframe == null || _iframe == undefined || _iframe == ""){
console.log("framenull");
return;
}
console.log("framego");
_iframe.contentWindow.postMessage("Parentwindow", "*");
Importingfiles=()=>{
// 导入文件
}
handleChange = (info) => {
if(info.file.status == "done" || info.file.status == "uploading" || info.file.status === 'removed'){
let fileList = info.fileList;
this.setState({
fileList: appendFileSizeToUploadFileAll(fileList),
});
if(info.file.status === 'done'){
if(info.file.response){
if(info.file.response.status===-1||info.file.response.status==="-1"){
}else{
}
}
}
if(info.file.response){
if(info.file.response.status===-1||info.file.response.status==="-1"){
}else{
if(info.file.response.status===0){
try {
this.props.showNotification('上传文件成功!');
}catch (e) {
}
}
}
}
}
}
render() {
let{ChallengesDataList,booljupyterurls,enlarge}=this.state;
let{ChallengesDataList,booljupyterurls,enlarge,fileList}=this.state;
let id = this.props.match.params.shixunId;
//老师
const is_teacher = this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false;
@ -269,7 +298,35 @@ class Challengesjupyter extends Component {
}catch (e) {
}
const uploadProps = {
width: 600,
fileList,
multiple: true,
data:{
identifier:id,
},
//multiple 是否支持多选 查重的时候不能多选 不然弹许多框出来
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUploadActionUrlthree()}`,
showUploadList:false,
onChange: this.handleChange,
beforeUpload: (file) => {
//上传前的操作
// console.log('beforeUpload', file.name);
if(file.name.indexOf('.ipynb') === -1){
this.props.showNotification('请上传正确格式文件!');
return false
}
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isLt10M) {
this.props.showNotification('文件大小必须小于10MB!');
}
return isLt10M;
},
};
return (
<React.Fragment>
<div className="">
@ -413,10 +470,23 @@ class Challengesjupyter extends Component {
marginLeft: '30px',
}} onClick={()=>this.onclki(true)}></i>
}
<div className="challenbaocun" ><p
className="challenbaocuntest" onClick={()=>this.daoruzhon()}>导入</p>
<style>
{
`
.ant-upload-list{
display:none
}
`
}
</style>
<Upload {...uploadProps}>
<div className="challenbaocun" type="upload">
<p
className="challenbaocuntest" type="upload" onClick={()=>this.Importingfiles()}>导入</p>
</div>
</Upload>
</div>
</div>
</div>
@ -463,7 +533,7 @@ class Challengesjupyter extends Component {
)
:
<iframe src={this.state.jupyter_url} className={enlarge?"fangdatwo":""}
sandbox="allow-same-origin allow-scripts allow-top-navigation " scrolling="no" id="frame"
scrolling="no" id="frame"
name="framename" width="100%" height="700" frameBorder="0"
></iframe>
}

Loading…
Cancel
Save