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
e26b86de
Commit
e26b86de
authored
Oct 07, 2014
by
Brian Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make sure temporary course directory uses safe characters.
parent
2ebed452
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
20 additions
and
14 deletions
+20
-14
lms/djangoapps/courseware/management/commands/export_course.py
+20
-14
No files found.
lms/djangoapps/courseware/management/commands/export_course.py
View file @
e26b86de
...
@@ -6,6 +6,7 @@ If <filename> is '-', it pipes the file to stdout
...
@@ -6,6 +6,7 @@ If <filename> is '-', it pipes the file to stdout
"""
"""
import
os
import
os
import
re
import
shutil
import
shutil
import
tarfile
import
tarfile
from
tempfile
import
mktemp
,
mkdtemp
from
tempfile
import
mktemp
,
mkdtemp
...
@@ -18,7 +19,7 @@ from django.core.management.base import BaseCommand, CommandError
...
@@ -18,7 +19,7 @@ from django.core.management.base import BaseCommand, CommandError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.xml_exporter
import
export_to_xml
from
xmodule.modulestore.xml_exporter
import
export_to_xml
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.
locations
import
SlashSeparated
CourseKey
from
opaque_keys.edx.
keys
import
CourseKey
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
...
@@ -30,9 +31,9 @@ class Command(BaseCommand):
...
@@ -30,9 +31,9 @@ class Command(BaseCommand):
help
=
dedent
(
__doc__
)
.
strip
()
help
=
dedent
(
__doc__
)
.
strip
()
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
course_
id
,
filename
,
pipe_results
=
self
.
_parse_arguments
(
args
)
course_
key
,
filename
,
pipe_results
=
self
.
_parse_arguments
(
args
)
export_course_to_tarfile
(
course_
id
,
filename
)
export_course_to_tarfile
(
course_
key
,
filename
)
results
=
self
.
_get_results
(
filename
)
if
pipe_results
else
None
results
=
self
.
_get_results
(
filename
)
if
pipe_results
else
None
...
@@ -41,7 +42,7 @@ class Command(BaseCommand):
...
@@ -41,7 +42,7 @@ class Command(BaseCommand):
def
_parse_arguments
(
self
,
args
):
def
_parse_arguments
(
self
,
args
):
"""Parse command line arguments"""
"""Parse command line arguments"""
try
:
try
:
course_
id
=
SlashSeparatedCourseKey
.
from_deprecated
_string
(
args
[
0
])
course_
key
=
CourseKey
.
from
_string
(
args
[
0
])
filename
=
args
[
1
]
filename
=
args
[
1
]
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
CommandError
(
"Unparsable course_id"
)
raise
CommandError
(
"Unparsable course_id"
)
...
@@ -54,7 +55,7 @@ class Command(BaseCommand):
...
@@ -54,7 +55,7 @@ class Command(BaseCommand):
filename
=
mktemp
()
filename
=
mktemp
()
pipe_results
=
True
pipe_results
=
True
return
course_
id
,
filename
,
pipe_results
return
course_
key
,
filename
,
pipe_results
def
_get_results
(
self
,
filename
):
def
_get_results
(
self
,
filename
):
"""Load results from file"""
"""Load results from file"""
...
@@ -64,32 +65,37 @@ class Command(BaseCommand):
...
@@ -64,32 +65,37 @@ class Command(BaseCommand):
return
results
return
results
def
export_course_to_tarfile
(
course_
id
,
filename
):
def
export_course_to_tarfile
(
course_
key
,
filename
):
"""Exports a course into a tar.gz file"""
"""Exports a course into a tar.gz file"""
tmp_dir
=
mkdtemp
()
tmp_dir
=
mkdtemp
()
try
:
try
:
course_dir
=
export_course_to_directory
(
course_
id
,
tmp_dir
)
course_dir
=
export_course_to_directory
(
course_
key
,
tmp_dir
)
compress_directory
(
course_dir
,
filename
)
compress_directory
(
course_dir
,
filename
)
finally
:
finally
:
shutil
.
rmtree
(
tmp_dir
)
shutil
.
rmtree
(
tmp_dir
)
def
export_course_to_directory
(
course_
id
,
root_dir
):
def
export_course_to_directory
(
course_
key
,
root_dir
):
"""Export course into a directory"""
"""Export course into a directory"""
store
=
modulestore
()
store
=
modulestore
()
course
=
store
.
get_course
(
course_
id
)
course
=
store
.
get_course
(
course_
key
)
if
course
is
None
:
if
course
is
None
:
raise
CommandError
(
"Invalid course_id"
)
raise
CommandError
(
"Invalid course_id"
)
course_name
=
course
.
id
.
to_deprecated_string
()
.
replace
(
'/'
,
'-'
)
# The safest characters are A-Z, a-z, 0-9, <underscore>, <period> and <hyphen>.
export_to_xml
(
store
,
None
,
course
.
id
,
root_dir
,
course_name
)
# We represent the first four with \w, but generalize to all unicode alphanumerics.
replacement_char
=
u'-'
course_dir
=
replacement_char
.
join
([
course
.
id
.
org
,
course
.
id
.
course
,
course
.
id
.
run
])
course_dir
=
re
.
sub
(
r'[^\w\.\-]'
,
replacement_char
,
course_dir
,
flags
=
re
.
UNICODE
)
course_dir
=
path
(
root_dir
)
/
course_name
export_to_xml
(
store
,
None
,
course
.
id
,
root_dir
,
course_dir
)
return
course_dir
export_dir
=
path
(
root_dir
)
/
course_dir
return
export_dir
def
compress_directory
(
directory
,
filename
):
def
compress_directory
(
directory
,
filename
):
"""Compress a direct
r
ory into a tar.gz file"""
"""Compress a directory into a tar.gz file"""
mode
=
'w:gz'
mode
=
'w:gz'
name
=
path
(
directory
)
.
name
name
=
path
(
directory
)
.
name
with
tarfile
.
open
(
filename
,
mode
)
as
tar_file
:
with
tarfile
.
open
(
filename
,
mode
)
as
tar_file
:
...
...
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