diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index da2993e463..606569c6a6 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -2,9 +2,14 @@ from django.conf import settings from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError +import os, tempfile, zipfile +from django.http import HttpResponse +from django.core.servers.basehttp import FileWrapper DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] + + def get_modulestore(location): """ Returns the correct modulestore to use for modifying the specified location diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index adf94be656..fb6a40eff3 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -10,6 +10,10 @@ from datetime import datetime from collections import defaultdict from uuid import uuid4 from path import path +from xmodule.modulestore.xml_exporter import export_to_xml +from tempfile import mkdtemp +from django.core.servers.basehttp import FileWrapper +from django.core.files.temp import NamedTemporaryFile # to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz' from PIL import Image @@ -1303,6 +1307,44 @@ def import_course(request, org, course, name): course_module.location.name]) }) +@ensure_csrf_cookie +@login_required +def generate_export_course(request, org, course, name): + location = ['i4x', org, course, 'course', name] + course_module = modulestore().get_item(location) + # check that logged in user has permissions to this item + if not has_access(request.user, location): + raise PermissionDenied() + + loc = Location(location) + export_file = NamedTemporaryFile(prefix=name+'.', suffix=".tar.gz") + + root_dir = path(mkdtemp()) + + # export out to a tempdir + + logging.debug('root = {0}'.format(root_dir)) + + export_to_xml(modulestore('direct'), contentstore(), loc, root_dir, name) + #filename = root_dir / name + '.tar.gz' + + logging.debug('tar file being generated at {0}'.format(export_file.name)) + tf = tarfile.open(name=export_file.name, mode='w:gz') + tf.add(root_dir/name, arcname=name) + tf.close() + + # remove temp dir + shutil.rmtree(root_dir/name) + + wrapper = FileWrapper(export_file) + response = HttpResponse(wrapper, content_type='application/x-tgz') + response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(export_file.name) + response['Content-Length'] = os.path.getsize(export_file.name) + return response + + +@ensure_csrf_cookie +@login_required def export_course(request, org, course, name): location = ['i4x', org, course, 'course', name] diff --git a/cms/urls.py b/cms/urls.py index c07ae5611f..6f8736551b 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -25,6 +25,8 @@ urlpatterns = ('', url(r'^(?P[^/]+)/(?P[^/]+)/export/(?P[^/]+)$', 'contentstore.views.export_course', name='export_course'), + url(r'^(?P[^/]+)/(?P[^/]+)/generate_export/(?P[^/]+)$', + 'contentstore.views.generate_export_course', name='generate_export_course'), url(r'^preview/modx/(?P[^/]*)/(?P.*?)/(?P[^/]*)$', 'contentstore.views.preview_dispatch', name='preview_dispatch'),