Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
bb009249
Commit
bb009249
authored
Oct 07, 2013
by
Julian Arni
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use requirejs for import.js
And fixes for rebase-breakage.
parent
5cfec75e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
123 additions
and
87 deletions
+123
-87
cms/djangoapps/contentstore/tests/test_import_export.py
+1
-7
cms/djangoapps/contentstore/views/import_export.py
+4
-1
cms/static/js/base.js
+4
-4
cms/static/js/views/assets.js
+0
-1
cms/static/js/views/import.js
+97
-62
cms/templates/import.html
+17
-12
No files found.
cms/djangoapps/contentstore/tests/test_import_export.py
View file @
bb009249
...
...
@@ -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
.
assert
True
(
import_status
==
3
or
import_status
==
0
)
self
.
assert
In
(
import_status
,
(
0
,
3
)
)
cms/djangoapps/contentstore/views/import_export.py
View file @
bb009249
...
...
@@ -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
...
...
cms/static/js/base.js
View file @
bb009249
...
...
@@ -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 {
...
...
cms/static/js/views/assets.js
View file @
bb009249
define
([
"backbone"
,
"js/views/asset"
],
function
(
Backbone
,
AssetView
)
{
"use strict"
;
var
AssetsView
=
Backbone
.
View
.
extend
({
// takes AssetCollection as model
...
...
cms/static/js/views/import.js
View file @
bb009249
/**
* 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
;
});
cms/templates/import.html
View file @
bb009249
...
...
@@ -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
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment