233 lines
7.5 KiB
JavaScript
233 lines
7.5 KiB
JavaScript
CodeOceanEditorSubmissions = {
|
|
FILENAME_URL_PLACEHOLDER: '{filename}',
|
|
|
|
AUTOSAVE_INTERVAL: 15 * 1000,
|
|
autosaveTimer: null,
|
|
autosaveLabel: "#autosave-label span",
|
|
|
|
/**
|
|
* Submission-Creation
|
|
*/
|
|
createSubmission: function (initiator, filter, callback) {
|
|
this.showSpinner(initiator);
|
|
var url = $(initiator).data('url') || $('#editor').data('submissions-url');
|
|
|
|
if (url === undefined) {
|
|
const data = {
|
|
initiator: initiator,
|
|
filter: filter,
|
|
}
|
|
Sentry.captureException(JSON.stringify(data));
|
|
return;
|
|
}
|
|
var jqxhr = this.ajax({
|
|
data: {
|
|
submission: {
|
|
cause: $(initiator).data('cause') || $(initiator).prop('id'),
|
|
exercise_id: $('#editor').data('exercise-id'),
|
|
files_attributes: (filter || _.identity)(this.collectFiles())
|
|
},
|
|
annotations_arr: []
|
|
},
|
|
dataType: 'json',
|
|
method: 'POST',
|
|
url: url + '.json'
|
|
});
|
|
jqxhr.always(this.hideSpinner.bind(this));
|
|
jqxhr.done(this.createSubmissionCallback.bind(this));
|
|
if(callback != null){
|
|
jqxhr.done(callback.bind(this));
|
|
}
|
|
|
|
jqxhr.fail(this.ajaxError.bind(this));
|
|
},
|
|
|
|
collectFiles: function() {
|
|
var editable_editors = _.filter(this.editors, function(editor) {
|
|
return !editor.getReadOnly();
|
|
});
|
|
return _.map(editable_editors, function(editor) {
|
|
return {
|
|
content: editor.getValue(),
|
|
file_id: $(editor.container).data('file-id')
|
|
};
|
|
});
|
|
},
|
|
|
|
createSubmissionCallback: function(data){
|
|
// set all frames context types to submission
|
|
$('.frame').each(function(index, element) {
|
|
$(element).data('context-type', 'Submission');
|
|
});
|
|
|
|
// update the ids of the editors and reload the annotations
|
|
for (var i = 0; i < this.editors.length; i++) {
|
|
|
|
// set the data attribute to submission
|
|
//$(editors[i].container).data('context-type', 'Submission');
|
|
|
|
var file_id_old = $(this.editors[i].container).data('file-id');
|
|
|
|
// file_id_old is always set. Either it is a reference to a teacher supplied given file, or it is the actual id of a new user created file.
|
|
// This is the case, since it is set via a call to ancestor_id on the model, which returns either file_id if set, or id if it is not set.
|
|
// therefore the else part is not needed any longer...
|
|
|
|
// if we have an file_id set (the file is a copy of a teacher supplied given file) and the new file-ids are present in the response
|
|
if (file_id_old != null && data.files){
|
|
// if we find file_id_old (this is the reference to the base file) in the submission, this is the match
|
|
for(var j = 0; j< data.files.length; j++){
|
|
if(data.files[j].file_id == file_id_old){
|
|
//$(editors[i].container).data('id') = data.files[j].id;
|
|
$(this.editors[i].container).data('id', data.files[j].id );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// toggle button states (it might be the case that the request for comments button has to be enabled
|
|
this.toggleButtonStates();
|
|
|
|
this.updateSaveStateLabel();
|
|
},
|
|
|
|
/**
|
|
* File-Management
|
|
*/
|
|
destroyFile: function() {
|
|
this.createSubmission($('#destroy-file'), function(files) {
|
|
return _.reject(files, function(file) {
|
|
return file.file_id === CodeOceanEditor.active_file.id;
|
|
});
|
|
}, window.CodeOcean.refresh);
|
|
},
|
|
|
|
downloadCode: function(event) {
|
|
event.preventDefault();
|
|
this.createSubmission('#download', null,function(response) {
|
|
var url = response.download_url;
|
|
|
|
// to download just a single file, use the following url
|
|
//var url = response.download_file_url.replace(FILENAME_URL_PLACEHOLDER, active_file.filename);
|
|
window.location = url;
|
|
});
|
|
},
|
|
|
|
resetCode: function(onlyActiveFile = false) {
|
|
this.showSpinner(this);
|
|
this.ajax({
|
|
method: 'GET',
|
|
url: $('#start-over').data('url')
|
|
}).done(function(response) {
|
|
this.hideSpinner();
|
|
_.each(this.editors, function(editor) {
|
|
var file_id = $(editor.container).data('file-id');
|
|
var file = _.find(response.files, function(file) {
|
|
return file.id === file_id;
|
|
});
|
|
if(file && !onlyActiveFile || file && file.id === CodeOceanEditor.active_file.id){
|
|
editor.setValue(file.content);
|
|
}
|
|
}.bind(this));
|
|
}.bind(this));
|
|
},
|
|
|
|
renderCode: function(event) {
|
|
event.preventDefault();
|
|
if ($('#render').is(':visible')) {
|
|
this.createSubmission('#render', null, function (response) {
|
|
var url = response.render_url.replace(this.FILENAME_URL_PLACEHOLDER, CodeOceanEditor.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
|
|
var pop_up_window = window.open(url);
|
|
if (pop_up_window) {
|
|
pop_up_window.onerror = function (message) {
|
|
this.clearOutput();
|
|
this.printOutput({
|
|
stderr: message
|
|
}, true, 0);
|
|
this.sendError(message, response.id);
|
|
this.showOutputBar();
|
|
};
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Execution-Logic
|
|
*/
|
|
runCode: function(event) {
|
|
event.preventDefault();
|
|
this.stopCode(event);
|
|
if ($('#run').is(':visible')) {
|
|
this.createSubmission('#run', null, this.runSubmission.bind(this));
|
|
}
|
|
},
|
|
|
|
runSubmission: function (submission) {
|
|
//Run part starts here
|
|
$('#stop').data('url', submission.stop_url);
|
|
this.running = true;
|
|
this.showSpinner($('#run'));
|
|
$('#score_div').addClass('d-none');
|
|
this.toggleButtonStates();
|
|
var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, CodeOceanEditor.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
|
|
this.initializeSocketForRunning(url);
|
|
},
|
|
|
|
saveCode: function(event) {
|
|
event.preventDefault();
|
|
this.createSubmission('#save', null, function() {
|
|
$.flash.success({
|
|
text: $('#save').data('message-success')
|
|
});
|
|
});
|
|
},
|
|
|
|
testCode: function(event) {
|
|
event.preventDefault();
|
|
if ($('#test').is(':visible')) {
|
|
this.createSubmission('#test', null, function(response) {
|
|
this.showSpinner($('#test'));
|
|
$('#score_div').addClass('d-none');
|
|
var url = response.test_url.replace(this.FILENAME_URL_PLACEHOLDER, CodeOceanEditor.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
|
|
this.initializeSocketForTesting(url);
|
|
}.bind(this));
|
|
}
|
|
},
|
|
|
|
submitCode: function() {
|
|
this.createSubmission($('#submit'), null, function (response) {
|
|
if (response.redirect) {
|
|
Turbolinks.clearCache();
|
|
Turbolinks.visit(response.redirect);
|
|
}
|
|
})
|
|
},
|
|
|
|
/**
|
|
* Autosave-Logic
|
|
*/
|
|
resetSaveTimer: function () {
|
|
clearTimeout(this.autosaveTimer);
|
|
this.autosaveTimer = setTimeout(this.autosave.bind(this), this.AUTOSAVE_INTERVAL);
|
|
},
|
|
|
|
unloadAutoSave: function() {
|
|
if(this.autosaveTimer != null){
|
|
this.autosave();
|
|
clearTimeout(this.autosaveTimer);
|
|
}
|
|
},
|
|
|
|
updateSaveStateLabel: function() {
|
|
var date = new Date();
|
|
var autosaveLabel = $(this.autosaveLabel);
|
|
autosaveLabel.parent().css("visibility", "visible");
|
|
autosaveLabel.text(date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds());
|
|
autosaveLabel.text(date.toLocaleTimeString());
|
|
},
|
|
|
|
autosave: function () {
|
|
this.autosaveTimer = null;
|
|
this.createSubmission($('#autosave'), null);
|
|
}
|
|
};
|