Commit bb009249 by Julian Arni

Use requirejs for import.js

    And fixes for rebase-breakage.
parent 5cfec75e
......@@ -6,12 +6,9 @@ import shutil
import tarfile
import tempfile
import copy
<<<<<<< HEAD
from path import path
=======
import json
import logging
>>>>>>> Review fixes
from uuid import uuid4
from pymongo import MongoClient
......@@ -25,10 +22,7 @@ from xmodule.contentstore.django import _CONTENTSTORE
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
<<<<<<< HEAD
=======
log = logging.getLogger(__name__)
>>>>>>> Review fixes
@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
class ImportTestCase(CourseTestCase):
......@@ -213,4 +207,4 @@ class ImportTestCase(CourseTestCase):
})
resp_status = self.client.get(status_url)
import_status = json.loads(resp_status.content)["ImportStatus"]
self.assertTrue(import_status == 3 or import_status == 0)
self.assertIn(import_status, (0, 3))
......@@ -154,10 +154,13 @@ def import_course(request, org, course, name):
return JsonResponse(
{
'ErrMsg': 'Unsafe tar file. Aborting import.',
'SuspiciousFileOperationMsg': exc.args[0]
'SuspiciousFileOperationMsg': exc.args[0],
'Stage': 1
},
status=400
)
finally:
tar_file.close()
session_status[key] = 2
request.session.modified = True
......
......@@ -127,10 +127,10 @@ $(document).ready(function() {
$('.sync-date').bind('click', syncReleaseDate);
// import form setup
$('.import .file-input').bind('change', showImportSubmit);
$('.import .choose-file-button, .import .choose-file-button-inline').bind('click', function(e) {
$('.view-import .file-input').bind('change', showImportSubmit);
$('.view-import .choose-file-button, .view-import .choose-file-button-inline').bind('click', function(e) {
e.preventDefault();
$('.import .file-input').click();
$('.view-import .file-input').click();
});
$('.new-course-button').bind('click', addNewCourse);
......@@ -227,7 +227,7 @@ function showImportSubmit(e) {
$('.error-block').hide();
$('.file-name').html($(this).val().replace('C:\\fakepath\\', ''));
$('.file-name-block').show();
$('.import .choose-file-button').hide();
$('.view-import .choose-file-button').hide();
$('.submit-button').show();
$('.progress').show();
} else {
......
define(["backbone", "js/views/asset"], function(Backbone, AssetView) {
"use strict";
var AssetsView = Backbone.View.extend({
// takes AssetCollection as model
......
/**
* Course import-related js.
*/
define(
["jquery", "underscore", "gettext"],
function($, _, gettext) {
"use strict";
/**
* Entry point for server feedback. Makes status list visible and starts
* sending requests to the server for status updates.
* @param {string} url The url to send Ajax GET requests for updates.
*/
var startServerFeedback = function (url){
$('div.wrapper-status').removeClass('is-hidden');
$('.status-info').show();
getStatus(url, 500);
};
/********** Private functions ************************************************/
/**
* Toggle the spin on the progress cog.
......@@ -24,6 +19,7 @@ var updateCog = function (elem, isSpinning) {
else { cogI.removeClass("icon-spin");}
};
/**
* Manipulate the DOM to reflect current status of upload.
* @param {int} stageNo Current stage.
......@@ -32,7 +28,10 @@ var updateStage = function (stageNo){
var all = $('ol.status-progress').children();
var prevList = all.slice(0, stageNo);
_.map(prevList, function (elem){
$(elem).removeClass("is-not-started").removeClass("is-started").addClass("is-complete");
$(elem).
removeClass("is-not-started").
removeClass("is-started").
addClass("is-complete");
updateCog($(elem), false);
});
var curList = all.eq(stageNo);
......@@ -41,26 +40,6 @@ var updateStage = function (stageNo){
};
/**
* Give error message at the list element that corresponds to the stage where
* the error occurred.
* @param {int} stageNo Stage of import process at which error occured.
* @param {string} msg Error message to display.
*/
var stageError = function (stageNo, msg) {
var all = $('ol.status-progress').children();
// Make all stages up to, and including, the error stage 'complete'.
var prevList = all.slice(0, stageNo + 1);
_.map(prevList, function (elem){
$(elem).removeClass("is-not-started").removeClass("is-started").addClass("is-complete");
updateCog($(elem), false);
});
var message = msg || "There was an error with the upload";
var elem = $('ol.status-progress').children().eq(stageNo);
elem.removeClass('is-started').addClass('has-error');
elem.find('p.copy').hide().after("<p class='copy error'>" + message + "</p>");
};
/**
* Check for import status updates every `timemout` milliseconds, and update
* the page accordingly.
* @param {string} url Url to call for status updates.
......@@ -69,47 +48,103 @@ var stageError = function (stageNo, msg) {
* @param {int} stage Starting stage.
*/
var getStatus = function (url, timeout, stage) {
if (currentStage == 3 ) { return ;}
if (window.stopGetStatus) { return ;}
var currentStage = stage || 0;
if (CourseImport.stopGetStatus) { return ;}
updateStage(currentStage);
if (currentStage == 3 ) { return ;}
var time = timeout || 1000;
$.getJSON(url,
function (data) {
setTimeout(function () {
getStatus(url, time, data["ImportStatus"]);
getStatus(url, time, data.ImportStatus);
}, time);
}
);
};
/**
* Update DOM to set all stages as complete, and stop asking for status
* updates.
*/
var displayFinishedImport = function () {
window.stopGetStatus = true;
var all = $('ol.status-progress').children();
_.map(all, function (elem){
$(elem).removeClass("is-not-started").removeClass("is-started").addClass("is-complete");
updateCog($(elem), false);
});
};
/**
* Update DOM to set all stages as not-started (for retrying an upload that
* failed).
*/
var clearImportDisplay = function () {
var all = $('ol.status-progress').children();
_.map(all, function (elem){
$(elem).removeClass("is-complete").
removeClass("is-started").
removeClass("has-error").
addClass("is-not-started");
$(elem).find('p.error').remove(); // remove error messages
$(elem).find('p.copy').show();
updateCog($(elem), false);
});
window.stopGetStatus = false;
/********** Public functions *************************************************/
var CourseImport = {
/**
* Whether to stop sending AJAX requests for updates on the import
* progress.
*/
stopGetStatus: false,
/**
* Update DOM to set all stages as not-started (for retrying an upload that
* failed).
*/
clearImportDisplay: function () {
var all = $('ol.status-progress').children();
_.map(all, function (elem){
$(elem).removeClass("is-complete").
removeClass("is-started").
removeClass("has-error").
addClass("is-not-started");
$(elem).find('p.error').remove(); // remove error messages
$(elem).find('p.copy').show();
updateCog($(elem), false);
});
this.stopGetStatus = false;
},
/**
* Update DOM to set all stages as complete, and stop asking for status
* updates.
*/
displayFinishedImport: function () {
this.stopGetStatus = true;
var all = $('ol.status-progress').children();
_.map(all, function (elem){
$(elem).
removeClass("is-not-started").
removeClass("is-started").
addClass("is-complete");
updateCog($(elem), false);
});
},
/**
* Entry point for server feedback. Makes status list visible and starts
* sending requests to the server for status updates.
* @param {string} url The url to send Ajax GET requests for updates.
*/
startServerFeedback: function (url){
this.stopGetStatus = false;
$('div.wrapper-status').removeClass('is-hidden');
$('.status-info').show();
getStatus(url, 500, 0);
},
/**
* Give error message at the list element that corresponds to the stage
* where the error occurred.
* @param {int} stageNo Stage of import process at which error occured.
* @param {string} msg Error message to display.
*/
stageError: function (stageNo, msg) {
var all = $('ol.status-progress').children();
// Make all stages up to, and including, the error stage 'complete'.
var prevList = all.slice(0, stageNo + 1);
_.map(prevList, function (elem){
$(elem).
removeClass("is-not-started").
removeClass("is-started").
addClass("is-complete");
updateCog($(elem), false);
});
var message = msg || gettext("There was an error with the upload");
var elem = $('ol.status-progress').children().eq(stageNo);
elem.removeClass('is-started').addClass('has-error');
elem.find('p.copy').hide().after("<p class='copy error'>" + message + "</p>");
}
};
return CourseImport;
});
......@@ -33,6 +33,7 @@
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}" />
## Translators: ".tar.gz" is a file extension, and files with that extension are called "gzipped tar files": these terms should not be translated
<h2 class="title">${_("Select a File (.tar.gz format) to Replace Your Course Content")}</h2>
<p class="error-block"></p>
......@@ -41,7 +42,7 @@
<div class="wrapper wrapper-file-name file-name-block">
<h3 class="title">
<span class="label">File Chosen:</span>
<span class="label">${_("File Chosen:")}</span>
<span class="file-name"></span>
</h3>
......@@ -142,7 +143,9 @@
<%block name="jsextra">
<script>
require(["jquery", "jquery.fileupload"], function($) {
require(
["js/views/import", "jquery", "jquery.fileupload"],
function(CourseImport, $) {
var file;
var bar = $('.progress-bar');
......@@ -174,7 +177,7 @@ $('#fileupload').fileupload({
autoUpload: false,
add: function(e, data) {
clearImportDisplay();
CourseImport.clearImportDisplay();
submitBtn.unbind('click');
file = data.files[0];
if (file.name.match(/tar\.gz$/)) {
......@@ -182,21 +185,23 @@ $('#fileupload').fileupload({
e.preventDefault();
submitBtn.hide();
data.submit().complete(function(result, textStatus, xhr) {
CourseImport.stopGetStatus = true;
window.onbeforeunload = null;
if (xhr.status != 200) {
window.stopGetStatus = true;
window.onbeforeunload = null;
var serverMsg = JSON.parse(result["responseText"]);
var errMsg = serverMsg.hasOwnProperty("ErrMsg") ? serverMsg["ErrMsg"] : "" ;
var serverMsg = $.parseJSON(result.responseText);
var errMsg = serverMsg.hasOwnProperty("ErrMsg") ? serverMsg.ErrMsg : "" ;
if (serverMsg.hasOwnProperty("Stage")) {
var stage = serverMsg["Stage"]
stageError(stage, defaults[stage] + errMsg);
var stage = serverMsg.Stage;
CourseImport.stageError(stage, defaults[stage] + errMsg);
}
else {
alert('${_("Your import has failed.")}\n\n' + errMsg);
}
bar.hide();
chooseBtn.html('${_("Choose new file")}').show();
bar.hide();
}
chooseBtn.html('${_("Choose new file")}').show();
bar.hide();
});
});
} else {
......@@ -218,7 +223,7 @@ $('#fileupload').fileupload({
}
if (percentInt >= doneAt) {
bar.hide();
startServerFeedback(feedbackUrl.replace("fillerName", file.name));
CourseImport.startServerFeedback(feedbackUrl.replace("fillerName", file.name));
} else {
bar.show();
fill.width(percentVal);
......@@ -228,7 +233,7 @@ $('#fileupload').fileupload({
done: function(e, data){
bar.hide();
window.onbeforeunload = null;
displayFinishedImport();
CourseImport.displayFinishedImport();
},
start: function(e) {
window.onbeforeunload = function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment