diff --git a/cms/djangoapps/contentstore/views/import_export.py b/cms/djangoapps/contentstore/views/import_export.py index e1a0f613a1..ce14942273 100644 --- a/cms/djangoapps/contentstore/views/import_export.py +++ b/cms/djangoapps/contentstore/views/import_export.py @@ -55,20 +55,6 @@ def import_course(request, org, course, name): """ location = get_location_and_verify_access(request, org, course, name) - @contextmanager - def wfile(filename, dirname): - """ - A with-context that creates `filename` on entry and removes it on exit. - `filename` is truncted on creation. Additionally removes dirname on - exit. - """ - open(filename, "w").close() - try: - yield filename - finally: - os.remove(filename) - shutil.rmtree(dirname) - if request.method == 'POST': data_root = path(settings.GITHUB_REPO_ROOT) @@ -78,7 +64,10 @@ def import_course(request, org, course, name): filename = request.FILES['course-data'].name if not filename.endswith('.tar.gz'): return JsonResponse( - {'ErrMsg': 'We only support uploading a .tar.gz file.'}, + { + 'ErrMsg': 'We only support uploading a .tar.gz file.', + 'Stage': 1 + }, status=415 ) temp_filepath = course_dir / filename @@ -112,7 +101,10 @@ def import_course(request, org, course, name): size ) return JsonResponse( - {'ErrMsg': 'File upload corrupted. Please try again'}, + { + 'ErrMsg': 'File upload corrupted. Please try again', + 'Stage': 1 + }, status=409 ) # The last request sometimes comes twice. This happens because @@ -199,7 +191,10 @@ def import_course(request, org, course, name): if not dirpath: return JsonResponse( - {'ErrMsg': 'Could not find the course.xml file in the package.'}, + { + 'ErrMsg': 'Could not find the course.xml file in the package.', + 'Stage': 2 + }, status=415 ) @@ -227,6 +222,16 @@ def import_course(request, org, course, name): create_all_course_groups(request.user, course_items[0].location) logging.debug('created all course groups at {0}'.format(course_items[0].location)) + # Send errors to client with stage at which error occured. + except Exception as exception: #pylint: disable=W0703 + return JsonResponse( + { + 'ErrMsg': str(exception), + 'Stage': session_status[key] + }, + status=400 + ) + finally: shutil.rmtree(course_dir) diff --git a/cms/static/js/views/assets.js b/cms/static/js/views/assets.js index cd569307f2..b05bd556bc 100644 --- a/cms/static/js/views/assets.js +++ b/cms/static/js/views/assets.js @@ -1,60 +1,5 @@ -<<<<<<< HEAD define(["backbone", "js/views/asset"], function(Backbone, AssetView) { -======= "use strict"; -// This code is temporarily moved out of asset_index.html -// to fix AWS pipelining issues. We can move it back after RequireJS is integrated. -$(document).ready(function() { - $('.uploads .upload-button').bind('click', showUploadModal); - $('.upload-modal .close-button').bind('click', hideModal); - $('.upload-modal .choose-file-button').bind('click', showFileSelectionMenu); -}); - -var showUploadModal = function (e) { - e.preventDefault(); - resetUploadModal(); - // $modal has to be global for hideModal to work. - $modal = $('.upload-modal').show(); - $('.file-input').bind('change', startUpload); - $('.upload-modal .file-chooser').fileupload({ - dataType: 'json', - type: 'POST', - maxChunkSize: 100 * 1000 * 1000, // 100 MB - autoUpload: true, - progressall: function(e, data) { - var percentComplete = parseInt((100 * data.loaded) / data.total, 10); - showUploadFeedback(e, percentComplete); - }, - maxFileSize: 100 * 1000 * 1000, // 100 MB - maxNumberofFiles: 100, - add: function(e, data) { - data.process().done(function () { - data.submit(); - }); - }, - done: function(e, data) { - displayFinishedUpload(data.result); - } - - }); - - $modalCover.show(); -}; - -var showFileSelectionMenu = function(e) { - e.preventDefault(); - $('.file-input').click(); -}; - -var startUpload = function (e) { - var file = e.target.value; - - $('.upload-modal h1').html(gettext('Uploading…')); - $('.upload-modal .file-name').html(file.substring(file.lastIndexOf("\\") + 1)); - $('.upload-modal .choose-file-button').hide(); - $('.upload-modal .progress-bar').removeClass('loaded').show(); -}; ->>>>>>> Hook up js to css classes var AssetsView = Backbone.View.extend({ // takes AssetCollection as model diff --git a/cms/templates/import.html b/cms/templates/import.html index 4c4c046383..63c6056aec 100644 --- a/cms/templates/import.html +++ b/cms/templates/import.html @@ -101,6 +101,16 @@

${_("Replacing previous course content with imported content")}

+
  • + + + + +
    +

    ${_("Success")}

    +

    ${_("Your imported content has now replaced all other course content")}

    +
    +
  • @@ -144,6 +154,12 @@ var allStats = $('#status-infos'); var feedbackUrl = "${reverse('import_status', kwargs=dict(org=context_course.location.org, course=context_course.location.course, name='fillerName'))}" +var defaults = [ + '${_("There was an error during the upload process.")}\n', + '${_("There was an error while unpacking the file.")}\n', + '${_("There was an error while verifying the file you submitted.")}\n', + '${_("There was an error while importing the new course to our database.")}\n' +]; $('#fileupload').fileupload({ @@ -163,8 +179,17 @@ $('#fileupload').fileupload({ submitBtn.hide(); data.submit().complete(function(result, textStatus, xhr) { if (xhr.status != 200) { - var errMsg = result.hasOwnProperty("ErrMsg") ? result["ErrMsg"] : "" ; - alert('${_("Your import has failed.")}\n\n' + errMsg); + window.stopGetStatus = true; + window.onbeforeunload = null; + var serverMsg = JSON.parse(result["responseText"]); + var errMsg = serverMsg.hasOwnProperty("ErrMsg") ? serverMsg["ErrMsg"] : "" ; + if (serverMsg.hasOwnProperty("Stage")) { + var stage = serverMsg["Stage"] + stageError(stage, defaults[stage] + errMsg); + } + else { + alert('${_("Your import has failed.")}\n\n' + errMsg); + } submitBtn.show(); bar.hide(); } @@ -199,6 +224,7 @@ $('#fileupload').fileupload({ done: function(e, data){ bar.hide(); window.onbeforeunload = null; + displayFinishedImport(); alert('${_("Your import was successful.")}'); window.location = '${successful_import_redirect_url}'; },