Commit 03b140d5 by Julian Arni

Review fixes

parent 509a8614
...@@ -38,9 +38,6 @@ from util.json_request import JsonResponse ...@@ -38,9 +38,6 @@ from util.json_request import JsonResponse
__all__ = ['asset_index', 'upload_asset'] __all__ = ['asset_index', 'upload_asset']
# Regex to capture Content-Range header ranges.
CONTENT_RE = re.compile(r"(?P<start>\d{1,11})-(?P<stop>\d{1,11})/(?P<end>\d{1,11})")
def assets_to_json_dict(assets): def assets_to_json_dict(assets):
""" """
Transform the results of a contentstore query into something appropriate Transform the results of a contentstore query into something appropriate
......
""" """
These views handle all actions in Studio related to import and exporting of courses These views handle all actions in Studio related to import and exporting of
courses
""" """
import logging import logging
import os import os
...@@ -8,6 +9,7 @@ import shutil ...@@ -8,6 +9,7 @@ import shutil
import re import re
from tempfile import mkdtemp from tempfile import mkdtemp
from path import path from path import path
from contextlib import contextmanager
from django.conf import settings from django.conf import settings
from django.http import HttpResponse from django.http import HttpResponse
...@@ -37,8 +39,6 @@ __all__ = ['import_course', 'generate_export_course', 'export_course'] ...@@ -37,8 +39,6 @@ __all__ = ['import_course', 'generate_export_course', 'export_course']
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
MAX_UP_LENGTH = 20000352 # Max chunk size for uploads
# Regex to capture Content-Range header ranges. # Regex to capture Content-Range header ranges.
CONTENT_RE = re.compile(r"(?P<start>\d{1,11})-(?P<stop>\d{1,11})/(?P<end>\d{1,11})") CONTENT_RE = re.compile(r"(?P<start>\d{1,11})-(?P<stop>\d{1,11})/(?P<end>\d{1,11})")
...@@ -53,6 +53,20 @@ def import_course(request, org, course, name): ...@@ -53,6 +53,20 @@ def import_course(request, org, course, name):
""" """
location = get_location_and_verify_access(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("file", "w").close()
try:
yield filename
finally:
os.remove(filename)
shutil.rmtree(dirname)
if request.method == 'POST': if request.method == 'POST':
data_root = path(settings.GITHUB_REPO_ROOT) data_root = path(settings.GITHUB_REPO_ROOT)
...@@ -76,8 +90,9 @@ def import_course(request, org, course, name): ...@@ -76,8 +90,9 @@ def import_course(request, org, course, name):
try: try:
matches = CONTENT_RE.search(request.META["HTTP_CONTENT_RANGE"]) matches = CONTENT_RE.search(request.META["HTTP_CONTENT_RANGE"])
content_range = matches.groupdict() content_range = matches.groupdict()
except KeyError: # Single chunk - no Content-Range header except KeyError: # Single chunk
content_range = {'start': 0, 'stop': 9, 'end': 10} # no Content-Range header, so make one that will work
content_range = {'start': 0, 'stop': 1, 'end': 2}
# stream out the uploaded files in chunks to disk # stream out the uploaded files in chunks to disk
if int(content_range['start']) == 0: if int(content_range['start']) == 0:
...@@ -129,16 +144,20 @@ def import_course(request, org, course, name): ...@@ -129,16 +144,20 @@ def import_course(request, org, course, name):
else: # This was the last chunk. else: # This was the last chunk.
# 'Lock' with status info. # 'Lock' with status info.
lock_filepath = data_root / (filename + ".lock") status_file = data_root / (course + filename + ".lock")
# Do everything from now on in a with-context, to be sure we've
# properly cleaned up.
with wfile(status_file, course_dir):
with open(lock_filepath, 'w+') as lf: with open(status_file, 'w+') as sf:
lf.write("Extracting") sf.write("Extracting")
tar_file = tarfile.open(temp_filepath) tar_file = tarfile.open(temp_filepath)
tar_file.extractall(course_dir + '/') tar_file.extractall(course_dir + '/')
with open(lock_filepath, 'w+') as lf: with open(status_file, 'w+') as sf:
lf.write("Verifying") sf.write("Verifying")
# find the 'course.xml' file # find the 'course.xml' file
dirpath = None dirpath = None
...@@ -189,19 +208,14 @@ def import_course(request, org, course, name): ...@@ -189,19 +208,14 @@ def import_course(request, org, course, name):
draft_store=modulestore() draft_store=modulestore()
) )
# we can blow this away when we're done importing.
shutil.rmtree(course_dir)
logging.debug('new course at {0}'.format(course_items[0].location)) logging.debug('new course at {0}'.format(course_items[0].location))
with open(lock_filepath, 'w') as lf: with open(status_file, 'w') as sf:
lf.write("Updating course") sf.write("Updating course")
create_all_course_groups(request.user, course_items[0].location) create_all_course_groups(request.user, course_items[0].location)
logging.debug('created all course groups at {0}'.format(course_items[0].location)) logging.debug('created all course groups at {0}'.format(course_items[0].location))
os.remove(lock_filepath)
return JsonResponse({'Status': 'OK'}) return JsonResponse({'Status': 'OK'})
else: else:
course_module = modulestore().get_item(location) course_module = modulestore().get_item(location)
......
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