251 lines
9.7 KiB
HTML
251 lines
9.7 KiB
HTML
<%inherit file="base.html" />
|
|
<%namespace name='static' file='static_content.html'/>
|
|
<%!
|
|
from django.core.urlresolvers import reverse
|
|
from django.utils.translation import ugettext as _
|
|
%>
|
|
<%block name="title">${_("Course Import")}</%block>
|
|
<%block name="bodyclass">is-signedin course tools view-import</%block>
|
|
|
|
<%block name="content">
|
|
<div class="wrapper-mast wrapper">
|
|
<header class="mast has-subtitle">
|
|
<h1 class="page-header">
|
|
<small class="subtitle">${_("Tools")}</small>
|
|
<span class="sr">> </span>${_("Course Import")}
|
|
</h1>
|
|
</header>
|
|
</div>
|
|
|
|
<div class="wrapper-content wrapper">
|
|
<section class="content">
|
|
<article class="content-primary" role="main">
|
|
|
|
<div class="introduction">
|
|
<p>${_("You may import existing course structure and content into Studio.")}</p>
|
|
|
|
<p>${_("Importing is not something to take lightly as the course content you successfully upload will be integrated into your course content and cannot be reversed.")}</p>
|
|
<p>${_("During the initial stages of the import process, please do not navigate away from this page.")}</p>
|
|
</div>
|
|
|
|
<form id="fileupload" method="post" enctype="multipart/form-data"
|
|
class="import-form" url="${reverse('import_course', kwargs=dict(org=context_course.location.org, course=context_course.location.course, name=context_course.location.name))}">
|
|
|
|
<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>
|
|
|
|
<a href="#" class="action action-choose-file choose-file-button">${_("Choose File")}</a>
|
|
|
|
<div class="wrapper wrapper-file-name file-name-block">
|
|
<h3 class="title">
|
|
<span class="label">${_("File Chosen:")}</span>
|
|
<span class="file-name"></span>
|
|
</h3>
|
|
|
|
<input type="file" name="course-data" class="file-input" />
|
|
|
|
<input type="submit" value="${_('Replace my course with the one above')}" class="submit-button" />
|
|
</div>
|
|
|
|
<div class="wrapper wrapper-status is-hidden">
|
|
<h3 class="title">${_("Course Import Status")}</h3>
|
|
|
|
<ol class="status-progress list-progress">
|
|
<li class="item-progresspoint item-progresspoint-upload is-complete">
|
|
<span class="deco status-visual">
|
|
<i class="icon-cog"></i>
|
|
<i class="icon-warning-sign"></i>
|
|
</span>
|
|
|
|
<div class="status-detail">
|
|
<h3 class="title">${_("Uploading")}</h3>
|
|
<p class="copy">${_("Transferring your file to our servers")}</p>
|
|
</div>
|
|
</li>
|
|
|
|
<li class="item-progresspoint item-progresspoint-unpack is-started">
|
|
<span class="deco status-visual">
|
|
<i class="icon-cog icon-spin"></i>
|
|
<i class="icon-warning-sign"></i>
|
|
</span>
|
|
|
|
<div class="status-detail">
|
|
<h3 class="title">${_("Unpacking")}</h3>
|
|
<p class="copy">${_("Expanding and preparing folder/file structure (You can now leave this page safely, but avoid making drastic changes to content until this import is complete)")}</p>
|
|
</div>
|
|
</li>
|
|
|
|
|
|
<li class="item-progresspoint item-progresspoint-verify is-not-started">
|
|
<span class="deco status-visual">
|
|
<i class="icon-cog"></i>
|
|
<i class="icon-warning-sign"></i>
|
|
</span>
|
|
|
|
<div class="status-detail">
|
|
<h3 class="title">${_("Verifying")}</h3>
|
|
<p class="copy">${_("Reviewing semantics, syntax, and required data")}</p>
|
|
</div>
|
|
</li>
|
|
|
|
<li class="item-progresspoint item-progresspoint-import is-not-started">
|
|
<span class="deco status-visual">
|
|
<i class="icon-cog"></i>
|
|
<i class="icon-warning-sign"></i>
|
|
</span>
|
|
|
|
<div class="status-detail">
|
|
<h3 class="title">${_("Updating Course")}</h3>
|
|
<p class="copy">${_("Integrating your imported content into this course. This may take a while with larger courses.")}</p>
|
|
</div>
|
|
</li>
|
|
<li class="item-progresspoint item-progresspoint-success has-actions is-not-started">
|
|
<span class="deco status-visual">
|
|
<i class="icon-check"></i>
|
|
</span>
|
|
|
|
<div class="status-detail">
|
|
<h3 class="title">${_("Success")}</h3>
|
|
<p class="copy">${_("Your imported content has now been integrated into this course")}</p>
|
|
|
|
<ul class="list-actions">
|
|
<li class="item-action">
|
|
<a href="${successful_import_redirect_url}" class="action action-primary">${_("View Updated Outline")}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
</form>
|
|
</article>
|
|
|
|
<aside class="content-supplementary" role="complimentary">
|
|
<div class="bit">
|
|
<h3 class="title-3">${_("Gzipped Tar Files (.tar.gz) Only")}</h3>
|
|
## Translators: ".tar.gz" is a file extension, and files with that extension are called "gzipped tar files": these terms should not be translated
|
|
<p>${_("File uploads must be gzipped tar files (.tar.gz) containing, at a minimum, a {filename} file.").format(filename='<code>course.xml</code>')}</p>
|
|
</div>
|
|
|
|
<div class="bit">
|
|
<h3 class="title-3">${_("Warning: Auto-generated Nodes")}</h3>
|
|
## Translators: ".tar.gz" is a file extension, and files with that extension are called "gzipped tar files": these terms should not be translated
|
|
<p>${_("Please note that if your course has any problems with auto-generated {nodename} nodes, re-importing your course could cause the loss of student data associated with those problems.").format(nodename='<code>url_name</code>')}</p>
|
|
</div>
|
|
</aside>
|
|
</section>
|
|
</div>
|
|
</%block>
|
|
|
|
<%block name="jsextra">
|
|
<script>
|
|
require(
|
|
["js/views/import", "jquery", "jquery.fileupload"],
|
|
function(CourseImport, $) {
|
|
|
|
var file;
|
|
var bar = $('.progress-bar');
|
|
var fill = $('.progress-fill');
|
|
var percent = $('.percent');
|
|
var status = $('#status');
|
|
var statusBlock = $('.status-block');
|
|
var submitBtn = $('.submit-button');
|
|
var chooseBtn = $('.choose-file-button');
|
|
|
|
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({
|
|
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
|
|
maxChunkSize: 20 * 1000000, // 20 MB
|
|
|
|
autoUpload: false,
|
|
|
|
add: function(e, data) {
|
|
CourseImport.clearImportDisplay();
|
|
submitBtn.unbind('click');
|
|
file = data.files[0];
|
|
if (file.name.match(/tar\.gz$/)) {
|
|
submitBtn.click(function(e){
|
|
e.preventDefault();
|
|
submitBtn.hide();
|
|
data.submit().complete(function(result, textStatus, xhr) {
|
|
CourseImport.stopGetStatus = true;
|
|
window.onbeforeunload = null;
|
|
if (xhr.status != 200) {
|
|
var serverMsg = $.parseJSON(result.responseText);
|
|
var errMsg = serverMsg.hasOwnProperty("ErrMsg") ? serverMsg.ErrMsg : "" ;
|
|
if (serverMsg.hasOwnProperty("Stage")) {
|
|
var stage = serverMsg.Stage;
|
|
CourseImport.stageError(stage, defaults[stage] + errMsg);
|
|
}
|
|
else {
|
|
alert('${_("Your import has failed.")}\n\n' + errMsg);
|
|
}
|
|
chooseBtn.html('${_("Choose new file")}').show();
|
|
bar.hide();
|
|
}
|
|
chooseBtn.html('${_("Choose new file")}').show();
|
|
bar.hide();
|
|
});
|
|
});
|
|
} else {
|
|
data.files = [];
|
|
}
|
|
},
|
|
|
|
progressall: function(e, data){
|
|
var doneAt;
|
|
var percentInt = data.loaded / data.total * 100
|
|
var percentVal = parseInt(percentInt, 10) + "%";
|
|
// Firefox makes ProgressEvent.loaded equal ProgressEvent.total only
|
|
// after receiving a response from the server (see Mozilla bug 637002),
|
|
// so for Firefox we jump the gun a little.
|
|
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
|
|
doneAt = 95;
|
|
} else {
|
|
doneAt = 99;
|
|
}
|
|
if (percentInt >= doneAt) {
|
|
bar.hide();
|
|
CourseImport.startServerFeedback(feedbackUrl.replace("fillerName", file.name));
|
|
} else {
|
|
bar.show();
|
|
fill.width(percentVal);
|
|
percent.html(percentVal);
|
|
}
|
|
},
|
|
done: function(e, data){
|
|
bar.hide();
|
|
window.onbeforeunload = null;
|
|
CourseImport.displayFinishedImport();
|
|
},
|
|
start: function(e) {
|
|
window.onbeforeunload = function() {
|
|
return '${_("Your import is in progress; navigating away will abort it.")}';
|
|
}
|
|
},
|
|
sequentialUploads: true,
|
|
notifyOnError: false
|
|
|
|
});
|
|
|
|
}); // end define()
|
|
</script>
|
|
</%block>
|