Commit 02a325b0 by Calen Pennington

First stab at an import page. Needs styling

parent ac71da15
...@@ -12,6 +12,7 @@ import tarfile ...@@ -12,6 +12,7 @@ import tarfile
import shutil import shutil
from collections import defaultdict from collections import defaultdict
from uuid import uuid4 from uuid import uuid4
from lxml import etree
# to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz' # to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz'
from PIL import Image from PIL import Image
...@@ -24,6 +25,7 @@ from django_future.csrf import ensure_csrf_cookie ...@@ -24,6 +25,7 @@ from django_future.csrf import ensure_csrf_cookie
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.conf import settings from django.conf import settings
from django import forms from django import forms
from django.shortcuts import redirect
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.x_module import ModuleSystem from xmodule.x_module import ModuleSystem
...@@ -51,6 +53,7 @@ from .utils import get_course_location_for_item, get_lms_link_for_item, compute_ ...@@ -51,6 +53,7 @@ from .utils import get_course_location_for_item, get_lms_link_for_item, compute_
from xmodule.templates import all_templates from xmodule.templates import all_templates
from xmodule.modulestore.xml_importer import import_from_xml from xmodule.modulestore.xml_importer import import_from_xml
from xmodule.modulestore.xml import edx_xml_parser
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -259,7 +262,8 @@ def edit_unit(request, location): ...@@ -259,7 +262,8 @@ def edit_unit(request, location):
published_date = None published_date = None
return render_to_response('unit.html', { return render_to_response('unit.html', {
'context_course': course, 'context_course': item,
'active_tab': 'courseware',
'unit': item, 'unit': item,
'unit_location': location, 'unit_location': location,
'components': components, 'components': components,
...@@ -845,45 +849,62 @@ def asset_index(request, org, course, name): ...@@ -845,45 +849,62 @@ def asset_index(request, org, course, name):
def edge(request): def edge(request):
return render_to_response('university_profiles/edge.html', {}) return render_to_response('university_profiles/edge.html', {})
def import_course(request):
if request.method != 'POST':
# (cdodge) @todo: Is there a way to do a - say - 'raise Http400'?
return HttpResponseBadRequest()
filename = request.FILES['file'].name def import_course(request, org, course, name):
location = ['i4x', org, course, 'course', name]
if not filename.endswith('.tar.gz'): # check that logged in user has permissions to this item
return HttpResponse(json.dumps({'ErrMsg': 'We only support uploading a .tar.gz file.'})) if not has_access(request.user, location):
raise PermissionDenied()
temp_filepath = settings.GITHUB_REPO_ROOT + '/' + filename if request.method == 'POST':
filename = request.FILES['file'].name
logging.debug('importing course to {0}'.format(temp_filepath)) if not filename.endswith('.tar.gz'):
return HttpResponse(json.dumps({'ErrMsg': 'We only support uploading a .tar.gz file.'}))
# stream out the uploaded files in chunks to disk temp_filepath = settings.GITHUB_REPO_ROOT + '/' + filename
temp_file = open(temp_filepath, 'wb+')
for chunk in request.FILES['file'].chunks():
temp_file.write(chunk)
temp_file.close()
tf = tarfile.open(temp_filepath) logging.debug('importing course to {0}'.format(temp_filepath))
tf.extractall(settings.GITHUB_REPO_ROOT + '/')
os.remove(temp_filepath) # remove the .tar.gz file # stream out the uploaded files in chunks to disk
temp_file = open(temp_filepath, 'wb+')
for chunk in request.FILES['file'].chunks():
temp_file.write(chunk)
temp_file.close()
# @todo: don't assume the top-level directory that was unziped was the same name (but without .tar.gz) tf = tarfile.open(temp_filepath)
tf.extractall(settings.GITHUB_REPO_ROOT + '/')
course_dir = filename.replace('.tar.gz','') os.remove(temp_filepath) # remove the .tar.gz file
module_store, course_items = import_from_xml(modulestore('direct'), settings.GITHUB_REPO_ROOT, # @todo: don't assume the top-level directory that was unziped was the same name (but without .tar.gz)
[course_dir], load_error_modules=False,static_content_store=contentstore())
# remove content directory - we *shouldn't* need this any longer :-) course_dir = filename.replace('.tar.gz', '')
shutil.rmtree(temp_filepath.replace('.tar.gz', ''))
logging.debug('new course at {0}'.format(course_items[0].location)) with open(temp_filepath / course_dir / 'course.xml', 'rw') as course_file:
course_data = etree.parse(course_file, parser=edx_xml_parser).getroot()
course_data.set('org', org)
course_data.set('course', course)
course_data.set('url_name', name)
course_data.write(course_file)
create_all_course_groups(request.user, course_items[0].location) module_store, course_items = import_from_xml(modulestore('direct'), settings.GITHUB_REPO_ROOT,
[course_dir], load_error_modules=False, static_content_store=contentstore())
# remove content directory - we *shouldn't* need this any longer :-)
shutil.rmtree(temp_filepath.replace('.tar.gz', ''))
logging.debug('new course at {0}'.format(course_items[0].location))
create_all_course_groups(request.user, course_items[0].location)
return HttpResponse(json.dumps({'Status': 'OK'}))
else:
course_module = modulestore().get_item(location)
return HttpResponse(json.dumps({'Status' : 'OK'})) return render_to_response('import.html', {
'context_course': course_module,
'active_tab': 'import',
})
...@@ -38,6 +38,15 @@ body.no-header { ...@@ -38,6 +38,15 @@ body.no-header {
@include active; @include active;
} }
#import-tab {
@include box-shadow(1px 0 0 #787981 inset, -1px 0 0 #3d3e44 inset, 1px 0 0 #787981, -1px 0 0 #3d3e44);
background: rgba(255, 0, 0, .5);
&:hover {
background: rgba(255, 0, 0, .7);
}
}
.left { .left {
width: 700px; width: 700px;
} }
......
...@@ -10,7 +10,5 @@ ...@@ -10,7 +10,5 @@
<section class="main-content"> <section class="main-content">
</section> </section>
<%include file="widgets/upload_assets.html"/>
</section> </section>
</%block> </%block>
...@@ -28,6 +28,4 @@ ...@@ -28,6 +28,4 @@
</section> </section>
<%include file="widgets/import-course.html"/>
</%block> </%block>
...@@ -92,7 +92,6 @@ ...@@ -92,7 +92,6 @@
% endfor % endfor
</article> </article>
</div> </div>
<%include file="widgets/upload_assets.html"/>
</div> </div>
<footer></footer> <footer></footer>
</%block> </%block>
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<li><a href="${reverse('static_pages', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, coursename=ctx_loc.name))}" id='pages-tab'>Pages</a></li> <li><a href="${reverse('static_pages', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, coursename=ctx_loc.name))}" id='pages-tab'>Pages</a></li>
<li><a href="${reverse('asset_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}" id='assets-tab'>Assets</a></li> <li><a href="${reverse('asset_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}" id='assets-tab'>Assets</a></li>
<li><a href="${reverse('manage_users', kwargs=dict(location=ctx_loc))}" id='users-tab'>Users</a></li> <li><a href="${reverse('manage_users', kwargs=dict(location=ctx_loc))}" id='users-tab'>Users</a></li>
<li><a href="${reverse('course_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}" id='import-tab' class="wip-box">Import</a></li> <li><a href="${reverse('import_course', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}" id='import-tab' class="wip-box">Import</a></li>
</ul> </ul>
% endif % endif
</div> </div>
......
...@@ -16,8 +16,14 @@ urlpatterns = ('', ...@@ -16,8 +16,14 @@ urlpatterns = ('',
url(r'^create_draft$', 'contentstore.views.create_draft', name='create_draft'), url(r'^create_draft$', 'contentstore.views.create_draft', name='create_draft'),
url(r'^publish_draft$', 'contentstore.views.publish_draft', name='publish_draft'), url(r'^publish_draft$', 'contentstore.views.publish_draft', name='publish_draft'),
url(r'^unpublish_unit$', 'contentstore.views.unpublish_unit', name='unpublish_unit'), url(r'^unpublish_unit$', 'contentstore.views.unpublish_unit', name='unpublish_unit'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<name>[^/]+)$', url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<name>[^/]+)$',
'contentstore.views.course_index', name='course_index'), 'contentstore.views.course_index', name='course_index'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/import/(?P<name>[^/]+)$',
'contentstore.views.import_course', name='import_course'),
url(r'^github_service_hook$', 'github_sync.views.github_post_receive'), url(r'^github_service_hook$', 'github_sync.views.github_post_receive'),
url(r'^preview/modx/(?P<preview_id>[^/]*)/(?P<location>.*?)/(?P<dispatch>[^/]*)$', url(r'^preview/modx/(?P<preview_id>[^/]*)/(?P<location>.*?)/(?P<dispatch>[^/]*)$',
'contentstore.views.preview_dispatch', name='preview_dispatch'), 'contentstore.views.preview_dispatch', name='preview_dispatch'),
...@@ -46,8 +52,6 @@ urlpatterns = ('', ...@@ -46,8 +52,6 @@ urlpatterns = ('',
url(r'^edge$', 'contentstore.views.edge', name='edge'), url(r'^edge$', 'contentstore.views.edge', name='edge'),
url(r'^heartbeat$', include('heartbeat.urls')), url(r'^heartbeat$', include('heartbeat.urls')),
url(r'import_course$', 'contentstore.views.import_course', name='import_course'),
) )
# User creation and updating views # User creation and updating views
......
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