Merge branch 'master' into ace-editor-exercise-edit
This commit is contained in:
@ -17,4 +17,4 @@ language: ruby
|
||||
rvm:
|
||||
- 2.1.5
|
||||
- 2.2.1
|
||||
script: bundle exec rspec --tag ~docker
|
||||
script: bundle exec rspec
|
||||
|
@ -14,21 +14,18 @@ $(function() {
|
||||
var REMEMBER_TAB = false;
|
||||
var AUTOSAVE_INTERVAL = 15 * 1000;
|
||||
var REQUEST_FOR_COMMENTS_DELAY = 3 * 60 * 1000;
|
||||
var NONE = 0;
|
||||
var WEBSOCKET = 1;
|
||||
var SERVER_SEND_EVENT = 2;
|
||||
|
||||
var editors = [];
|
||||
var editor_for_file = new Map();
|
||||
var regex_for_language = new Map();
|
||||
var tracepositions_regex;
|
||||
var resetTurtle = true;
|
||||
|
||||
var active_file = undefined;
|
||||
var active_frame = undefined;
|
||||
var running = false;
|
||||
var qa_api = undefined;
|
||||
var output_mode_is_streaming = true;
|
||||
var runmode = NONE;
|
||||
|
||||
var websocket,
|
||||
turtlescreen,
|
||||
@ -63,18 +60,6 @@ $(function() {
|
||||
$('#output pre').remove();
|
||||
};
|
||||
|
||||
var closeEventSource = function(event) {
|
||||
event.target.close();
|
||||
hideSpinner();
|
||||
running = false;
|
||||
toggleButtonStates();
|
||||
|
||||
if (event.type === 'error' || JSON.parse(event.data).code !== 200) {
|
||||
ajaxError();
|
||||
showTab(0);
|
||||
}
|
||||
};
|
||||
|
||||
var collectFiles = function() {
|
||||
var editable_editors = _.filter(editors, function(editor) {
|
||||
return !editor.getReadOnly();
|
||||
@ -188,44 +173,8 @@ $(function() {
|
||||
});
|
||||
};
|
||||
|
||||
var evaluateCode = function(url, streamed, callback) {
|
||||
(streamed ? evaluateCodeWithStreamedResponse : evaluateCodeWithoutStreamedResponse)(url, callback);
|
||||
};
|
||||
|
||||
var evaluateCodeWithStreamedResponse = function(url, onmessageFunction) {
|
||||
initWebsocketConnection(url, onmessageFunction);
|
||||
|
||||
// TODO only init turtle when required
|
||||
initTurtle();
|
||||
|
||||
// TODO reimplement via websocket messsages
|
||||
/*var event_source = new EventSource(url);
|
||||
event_source.addEventListener('hint', renderHint);
|
||||
event_source.addEventListener('info', storeContainerInformation);
|
||||
|
||||
if ($('#flowrHint').isPresent()) {
|
||||
event_source.addEventListener('output', handleStderrOutputForFlowr);
|
||||
event_source.addEventListener('close', handleStderrOutputForFlowr);
|
||||
}
|
||||
|
||||
if (qa_api) {
|
||||
event_source.addEventListener('close', handleStreamedResponseForCodePilot);
|
||||
}*/
|
||||
};
|
||||
|
||||
var handleStreamedResponseForCodePilot = function(event) {
|
||||
qa_api.executeCommand('syncOutput', [chunkBuffer]);
|
||||
chunkBuffer = [{streamedResponse: true}];
|
||||
}
|
||||
|
||||
var evaluateCodeWithoutStreamedResponse = function(url, callback) {
|
||||
var jqxhr = ajax({
|
||||
method: 'GET',
|
||||
url: url
|
||||
});
|
||||
jqxhr.always(hideSpinner);
|
||||
jqxhr.done(callback);
|
||||
jqxhr.fail(ajaxError);
|
||||
var evaluateCode = function(url, callback) {
|
||||
initWebsocketConnection(url, callback);
|
||||
};
|
||||
|
||||
var fileActionsAvailable = function() {
|
||||
@ -521,10 +470,6 @@ $(function() {
|
||||
}, REQUEST_FOR_COMMENTS_DELAY);
|
||||
};
|
||||
|
||||
var isActiveFileBinary = function() {
|
||||
return 'binary' in active_frame.data();
|
||||
};
|
||||
|
||||
var isActiveFileExecutable = function() {
|
||||
return 'executable' in active_frame.data();
|
||||
};
|
||||
@ -574,21 +519,6 @@ $(function() {
|
||||
panel.find('.row .col-sm-9').eq(4).find('a').attr('href', '#output-' + index);
|
||||
};
|
||||
|
||||
var chunkBuffer = [{streamedResponse: true}];
|
||||
|
||||
var printChunk = function(event) {
|
||||
var output = JSON.parse(event.data);
|
||||
if (output) {
|
||||
printOutput(output, true, 0);
|
||||
// send test response to QA
|
||||
// we are expecting an array of outputs:
|
||||
if (qa_api) {
|
||||
chunkBuffer.push(output);
|
||||
}
|
||||
} else {
|
||||
resetOutputTab();
|
||||
}
|
||||
};
|
||||
|
||||
var resetOutputTab = function() {
|
||||
clearOutput();
|
||||
@ -769,14 +699,13 @@ $(function() {
|
||||
var runCode = function(event) {
|
||||
event.preventDefault();
|
||||
if ($('#run').is(':visible')) {
|
||||
runmode = WEBSOCKET;
|
||||
createSubmission(this, null, function(response) {
|
||||
$('#stop').data('url', response.stop_url);
|
||||
running = true;
|
||||
showSpinner($('#run'));
|
||||
toggleButtonStates();
|
||||
var url = response.run_url.replace(FILENAME_URL_PLACEHOLDER, active_file.filename);
|
||||
evaluateCode(url, true, function(evt) { parseCanvasMessage(evt.data, true); });
|
||||
evaluateCode(url, function(evt) { parseCanvasMessage(evt.data, true); });
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -807,11 +736,10 @@ $(function() {
|
||||
|
||||
var scoreCode = function(event) {
|
||||
event.preventDefault();
|
||||
runmode = SERVER_SEND_EVENT;
|
||||
createSubmission(this, null, function(response) {
|
||||
showSpinner($('#assess'));
|
||||
var url = response.score_url;
|
||||
evaluateCode(url, true, handleScoringResponse);
|
||||
evaluateCode(url, handleScoringResponse);
|
||||
});
|
||||
};
|
||||
|
||||
@ -917,31 +845,11 @@ $(function() {
|
||||
|
||||
var stopCode = function(event) {
|
||||
event.preventDefault();
|
||||
if ($('#stop').is(':visible')) {
|
||||
if(runmode == WEBSOCKET){
|
||||
killWebsocketAndContainer();
|
||||
} else if (runmode == SERVER_SEND_EVENT) {
|
||||
stopCodeServerSendEvent(event);
|
||||
}
|
||||
runmode = NONE;
|
||||
if (isActiveFileStoppable()) {
|
||||
killWebsocketAndContainer();
|
||||
}
|
||||
};
|
||||
|
||||
var stopCodeServerSendEvent = function(event){
|
||||
var jqxhr = ajax({
|
||||
data: {
|
||||
container_id: $('#stop').data('container').id
|
||||
},
|
||||
url: $('#stop').data('url')
|
||||
});
|
||||
jqxhr.always(function() {
|
||||
hideSpinner();
|
||||
running = false;
|
||||
toggleButtonStates();
|
||||
});
|
||||
jqxhr.fail(ajaxError);
|
||||
};
|
||||
|
||||
var killWebsocketAndContainer = function() {
|
||||
if (websocket.readyState != WebSocket.OPEN) {
|
||||
return;
|
||||
@ -949,28 +857,17 @@ $(function() {
|
||||
websocket.send(JSON.stringify({cmd: 'exit'}));
|
||||
websocket.flush();
|
||||
websocket.close();
|
||||
|
||||
if(turtlescreen != null){
|
||||
resetTurtle = true;
|
||||
}
|
||||
|
||||
hideSpinner();
|
||||
running = false;
|
||||
toggleButtonStates();
|
||||
hidePrompt();
|
||||
}
|
||||
|
||||
// todo set this from websocket command, required to e.g. stop container
|
||||
var storeContainerInformation = function(event) {
|
||||
var container_information = JSON.parse(event.data);
|
||||
$('#stop').data('container', container_information);
|
||||
|
||||
if (_.size(container_information.port_bindings) > 0) {
|
||||
$.flash.info({
|
||||
icon: ['fa', 'fa-exchange'],
|
||||
text: _.map(container_information.port_bindings, function(key, value) {
|
||||
var url = window.location.protocol + '//' + window.location.hostname + ':' + key;
|
||||
return $('#run').data('message-network').replace('%{port}', value).replace(/%{address}/g, url);
|
||||
}).join('\n')
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var storeTab = function(event) {
|
||||
localStorage.tab = $(event.target).parent().index();
|
||||
};
|
||||
@ -990,7 +887,7 @@ $(function() {
|
||||
createSubmission(this, null, function(response) {
|
||||
showSpinner($('#test'));
|
||||
var url = response.test_url.replace(FILENAME_URL_PLACEHOLDER, active_file.filename);
|
||||
evaluateCode(url, true, handleTestResponse);
|
||||
evaluateCode(url, handleTestResponse);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -1027,10 +924,11 @@ $(function() {
|
||||
// clear canvas
|
||||
// turtlecanvas.getContext("2d").clearRect(0, 0, turtlecanvas.width, turtlecanvas.height);
|
||||
|
||||
if(resetTurtle) {
|
||||
turtlescreen = new Turtle(websocket, turtlecanvas);
|
||||
if ($('#run').isPresent()) {
|
||||
$('#run').bind('click', hideCanvas);
|
||||
}
|
||||
showCanvas();
|
||||
resetTurtle = false;
|
||||
}
|
||||
};
|
||||
|
||||
var initPrompt = function() {
|
||||
@ -1058,10 +956,12 @@ $(function() {
|
||||
printWebsocketOutput(msg);
|
||||
break;
|
||||
case 'turtle':
|
||||
initTurtle();
|
||||
showCanvas();
|
||||
handleTurtleCommand(msg);
|
||||
break;
|
||||
case 'turtlebatch':
|
||||
initTurtle();
|
||||
showCanvas();
|
||||
handleTurtlebatchCommand(msg);
|
||||
break;
|
||||
|
@ -38,7 +38,7 @@
|
||||
/ #output-col1.col-sm-12
|
||||
#output-col1
|
||||
// todo set to full width if turtle isnt used
|
||||
#prompt.input-group.hidden
|
||||
#prompt.input-group.hidden.col-lg-7.col-md-7.two-column
|
||||
span.input-group-addon data-prompt=t('exercises.editor.input') = t('exercises.editor.input')
|
||||
input#prompt-input.form-control type='text'
|
||||
span.input-group-btn
|
||||
|
@ -30,6 +30,8 @@ module CodeOcean
|
||||
|
||||
config.autoload_paths << Rails.root.join('lib')
|
||||
config.eager_load_paths << Rails.root.join('lib')
|
||||
config.assets.precompile += %w( markdown-buttons.png )
|
||||
|
||||
case (RUBY_ENGINE)
|
||||
when 'ruby'
|
||||
# ...
|
||||
|
@ -1,45 +0,0 @@
|
||||
upstream puma {
|
||||
server unix:///var/www/app/shared/tmp/sockets/puma.sock;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default deferred;
|
||||
return 301 https://codeocean.openhpi.de$request_uri;
|
||||
server_name codeocean.openhpi.de;
|
||||
}
|
||||
|
||||
server {
|
||||
client_max_body_size 4G;
|
||||
error_page 500 502 503 504 /500.html;
|
||||
keepalive_timeout 10;
|
||||
listen 443 ssl;
|
||||
root /var/www/app/current/public;
|
||||
server_name codeocean.openhpi.de;
|
||||
try_files $uri @puma;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/ssl-bundle.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||
ssl_ciphers HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_protocols SSLv3 TLSv1;
|
||||
ssl_session_timeout 5m;
|
||||
|
||||
location / {
|
||||
access_log /var/www/app/current/log/nginx.access.log;
|
||||
error_log /var/www/app/current/log/nginx.error.log;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://puma;
|
||||
proxy_read_timeout 900;
|
||||
proxy_redirect off;
|
||||
proxy_set_header Connection '';
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ^~ /assets/ {
|
||||
add_header Cache-Control public;
|
||||
expires max;
|
||||
gzip_static on;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user