Merge remote-tracking branch 'origin/master' into statistics
This commit is contained in:
@@ -30,7 +30,7 @@ $(function() {
|
||||
numMessages = 0,
|
||||
turtlecanvas = $('#turtlecanvas'),
|
||||
prompt = $('#prompt'),
|
||||
commands = ['input', 'write', 'turtle', 'turtlebatch', 'exit', 'status'],
|
||||
commands = ['input', 'write', 'turtle', 'turtlebatch', 'exit', 'timeout', 'status'],
|
||||
streams = ['stdin', 'stdout', 'stderr'];
|
||||
|
||||
var ENTER_KEY_CODE = 13;
|
||||
@@ -686,8 +686,8 @@ $(function() {
|
||||
};
|
||||
|
||||
var isBrowserSupported = function() {
|
||||
// todo event streams are no longer required with websockets
|
||||
return window.EventSource !== undefined;
|
||||
// eventsource tests for server send events (used for scoring), websockets is used for run
|
||||
return Modernizr.eventsource && Modernizr.websockets;
|
||||
};
|
||||
|
||||
var populatePanel = function(panel, result, index) {
|
||||
@@ -1004,7 +1004,7 @@ $(function() {
|
||||
};
|
||||
|
||||
var showTimeoutMessage = function() {
|
||||
$.flash.danger({
|
||||
$.flash.info({
|
||||
icon: ['fa', 'fa-clock-o'],
|
||||
text: $('#editor').data('message-timeout')
|
||||
});
|
||||
@@ -1059,14 +1059,6 @@ $(function() {
|
||||
running = false;
|
||||
toggleButtonStates();
|
||||
hidePrompt();
|
||||
flashKillMessage();
|
||||
}
|
||||
|
||||
var flashKillMessage = function() {
|
||||
$.flash.info({
|
||||
icon: ['fa', 'fa-clock-o'],
|
||||
text: "Your program was stopped." // todo get data attribute
|
||||
});
|
||||
}
|
||||
|
||||
// todo set this from websocket command, required to e.g. stop container
|
||||
@@ -1125,7 +1117,7 @@ $(function() {
|
||||
};
|
||||
|
||||
var initWebsocketConnection = function(url) {
|
||||
websocket = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + url);
|
||||
websocket = new WebSocket('wss://' + window.location.hostname + ':' + window.location.port + url);
|
||||
websocket.onopen = function(evt) { resetOutputTab(); }; // todo show some kind of indicator for established connection
|
||||
websocket.onclose = function(evt) { /* expected at some point */ };
|
||||
websocket.onmessage = function(evt) { parseCanvasMessage(evt.data, true); };
|
||||
@@ -1160,7 +1152,7 @@ $(function() {
|
||||
}
|
||||
switch(msg.cmd) {
|
||||
case 'input':
|
||||
showPrompt();
|
||||
showPrompt(msg);
|
||||
break;
|
||||
case 'write':
|
||||
printWebsocketOutput(msg);
|
||||
@@ -1176,6 +1168,10 @@ $(function() {
|
||||
case 'exit':
|
||||
killWebsocketAndContainer();
|
||||
break;
|
||||
case 'timeout':
|
||||
// just show the timeout message here. Another exit command is sent by the rails backend when the socket to the docker container closes.
|
||||
showTimeoutMessage();
|
||||
break;
|
||||
case 'status':
|
||||
showStatus(msg)
|
||||
break;
|
||||
@@ -1249,11 +1245,13 @@ $(function() {
|
||||
executeWebsocketCommand(msg);
|
||||
};
|
||||
|
||||
var showPrompt = function() {
|
||||
if (prompt.isPresent() && prompt.hasClass('hidden')) {
|
||||
var showPrompt = function(msg) {
|
||||
var label = $('#prompt .input-group-addon');
|
||||
label.text(msg.data || label.data('prompt'));
|
||||
if (prompt.isPresent() && prompt.hasClass('hidden')) {
|
||||
prompt.removeClass('hidden');
|
||||
}
|
||||
prompt.focus();
|
||||
$('#prompt input').focus();
|
||||
}
|
||||
|
||||
var hidePrompt = function() {
|
||||
|
3
app/assets/javascripts/modernizr-custom.js
Normal file
3
app/assets/javascripts/modernizr-custom.js
Normal file
@@ -0,0 +1,3 @@
|
||||
/*! modernizr 3.1.0 (Custom Build) | MIT *
|
||||
* http://modernizr.com/download/?-eventsource-websockets !*/
|
||||
!function(e,n,s){function o(e,n){return typeof e===n}function a(e){var n=l.className,s=Modernizr._config.classPrefix||"";if(f&&(n=n.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+s+"no-js(\\s|$)");n=n.replace(o,"$1"+s+"js$2")}Modernizr._config.enableClasses&&(n+=" "+s+e.join(" "+s),f?l.className.baseVal=n:l.className=n)}function t(){var e,n,s,a,t,l,f;for(var r in c){if(e=[],n=c[r],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(s=0;s<n.options.aliases.length;s++)e.push(n.options.aliases[s].toLowerCase());for(a=o(n.fn,"function")?n.fn():n.fn,t=0;t<e.length;t++)l=e[t],f=l.split("."),1===f.length?Modernizr[f[0]]=a:(!Modernizr[f[0]]||Modernizr[f[0]]instanceof Boolean||(Modernizr[f[0]]=new Boolean(Modernizr[f[0]])),Modernizr[f[0]][f[1]]=a),i.push((a?"":"no-")+f.join("-"))}}var i=[],l=n.documentElement,f="svg"===l.nodeName.toLowerCase(),c=[],r={_version:"3.1.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var s=this;setTimeout(function(){n(s[e])},0)},addTest:function(e,n,s){c.push({name:e,fn:n,options:s})},addAsyncTest:function(e){c.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=r,Modernizr=new Modernizr,Modernizr.addTest("websockets","WebSocket"in e&&2===e.WebSocket.CLOSING),Modernizr.addTest("eventsource","EventSource"in e),t(),a(i),delete r.addTest,delete r.addAsyncTest;for(var u=0;u<Modernizr._q.length;u++)Modernizr._q[u]();e.Modernizr=Modernizr}(window,document);
|
@@ -90,6 +90,12 @@ class SubmissionsController < ApplicationController
|
||||
hijack do |tubesock|
|
||||
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
|
||||
|
||||
|
||||
# socket is the socket into the container, tubesock is the socket to the client
|
||||
|
||||
# give the docker_client the tubesock object, so that it can send messages (timeout)
|
||||
@docker_client.tubesock = tubesock
|
||||
|
||||
result = @docker_client.execute_run_command(@submission, params[:filename])
|
||||
tubesock.send_data JSON.dump({'cmd' => 'status', 'status' => result[:status]})
|
||||
|
||||
|
@@ -3,6 +3,6 @@ class Comment < ActiveRecord::Base
|
||||
include Creation
|
||||
attr_accessor :username
|
||||
|
||||
belongs_to :file, class: CodeOcean::File
|
||||
belongs_to :file, class_name: 'CodeOcean::File'
|
||||
belongs_to :user, polymorphic: true
|
||||
end
|
||||
|
@@ -2,7 +2,7 @@ module Context
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_many :files, as: :context, class: CodeOcean::File
|
||||
has_many :files, as: :context, class_name: 'CodeOcean::File'
|
||||
accepts_nested_attributes_for :files
|
||||
end
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
class RequestForComment < ActiveRecord::Base
|
||||
belongs_to :exercise
|
||||
belongs_to :file, class: CodeOcean::File
|
||||
belongs_to :file, class_name: 'CodeOcean::File'
|
||||
belongs_to :user, polymorphic: true
|
||||
|
||||
before_create :set_requested_timestamp
|
||||
|
@@ -39,7 +39,7 @@
|
||||
#output-col1
|
||||
// todo set to full width if turtle isnt used
|
||||
#prompt.input-group.hidden
|
||||
span.input-group-addon = t('exercises.editor.input')
|
||||
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
|
||||
button#prompt-submit.btn.btn-primary type="button" = t('exercises.editor.send')
|
||||
|
Reference in New Issue
Block a user