def export(request, course_key_string):
    """
    Trigger the async export job
    https://github.com/edx/edx-platform/blob/open-release/juniper.master/cms/djangoapps/contentstore/views/import_export.py#L290

    POST /sn-api/courses/<course_key>/export/
    """
    course_key = CourseKey.from_string(course_key_string)
    if isinstance(course_key, LibraryLocator):
        courselike_module = modulestore().get_library(course_key)
        context = {
            'context_library':
            courselike_module,
            'courselike_home_url':
            reverse_library_url("library_handler", course_key),
            'library':
            True
        }
    else:
        courselike_module = modulestore().get_course(course_key)
        if courselike_module is None:
            raise Http404
        context = {
            'context_course': courselike_module,
            'courselike_home_url': reverse_course_url("course_handler",
                                                      course_key),
            'library': False
        }
    context['status_url'] = reverse_course_url('export_status_handler',
                                               course_key)

    export_olx.delay(request.user.id, course_key_string, request.LANGUAGE_CODE)
    return Response({'ExportStatus': 1})
Esempio n. 2
0
def export_handler(request, course_key_string):
    """
    The restful handler for exporting a course.

    GET
        html: return html page for import page
        json: not supported
    POST
        Start a Celery task to export the course

    The Studio UI uses a POST request to start the export asynchronously, with
    a link appearing on the page once it's ready.
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    if isinstance(course_key, LibraryLocator):
        courselike_module = modulestore().get_library(course_key)
        context = {
            'context_library':
            courselike_module,
            'courselike_home_url':
            reverse_library_url("library_handler", course_key),
            'library':
            True
        }
    else:
        courselike_module = modulestore().get_course(course_key)
        if courselike_module is None:
            raise Http404
        context = {
            'context_course': courselike_module,
            'courselike_home_url': reverse_course_url("course_handler",
                                                      course_key),
            'library': False
        }
    context['status_url'] = reverse_course_url('export_status_handler',
                                               course_key)

    # an _accept URL parameter will be preferred over HTTP_ACCEPT in the header.
    requested_format = request.GET.get(
        '_accept', request.META.get('HTTP_ACCEPT', 'text/html'))

    if request.method == 'POST':
        export_olx.delay(request.user.id, course_key_string,
                         request.LANGUAGE_CODE)
        return JsonResponse({'ExportStatus': 1})
    elif 'text/html' in requested_format:
        return render_to_response('export.html', context)
    else:
        # Only HTML request format is supported (no JSON).
        return HttpResponse(status=406)
Esempio n. 3
0
 def test_exception(self, mock_export):  # pylint: disable=unused-argument
     """
     The export task should fail gracefully if an exception is thrown
     """
     key = str(self.course.location.course_key)
     result = export_olx.delay(self.user.id, key, u'en')
     self._assert_failed(result, json.dumps({u'raw_error_msg': u'Boom!'}))
Esempio n. 4
0
 def test_exception(self, mock_export):  # pylint: disable=unused-argument
     """
     The export task should fail gracefully if an exception is thrown
     """
     key = str(self.course.location.course_key)
     result = export_olx.delay(self.user.id, key, u'en')
     self._assert_failed(result, json.dumps({u'raw_error_msg': u'Boom!'}))
Esempio n. 5
0
def export_handler(request, course_key_string):
    """
    The restful handler for exporting a course.

    GET
        html: return html page for import page
        json: not supported
    POST
        Start a Celery task to export the course

    The Studio UI uses a POST request to start the export asynchronously, with
    a link appearing on the page once it's ready.
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    if isinstance(course_key, LibraryLocator):
        courselike_module = modulestore().get_library(course_key)
        context = {
            'context_library': courselike_module,
            'courselike_home_url': reverse_library_url("library_handler", course_key),
            'library': True
        }
    else:
        courselike_module = modulestore().get_course(course_key)
        if courselike_module is None:
            raise Http404
        context = {
            'context_course': courselike_module,
            'courselike_home_url': reverse_course_url("course_handler", course_key),
            'library': False
        }
    context['status_url'] = reverse_course_url('export_status_handler', course_key)

    # an _accept URL parameter will be preferred over HTTP_ACCEPT in the header.
    requested_format = request.GET.get('_accept', request.META.get('HTTP_ACCEPT', 'text/html'))

    if request.method == 'POST':
        export_olx.delay(request.user.id, course_key_string, request.LANGUAGE_CODE)
        return JsonResponse({'ExportStatus': 1})
    elif 'text/html' in requested_format:
        return render_to_response('export.html', context)
    else:
        # Only HTML request format is supported (no JSON).
        return HttpResponse(status=406)
Esempio n. 6
0
 def test_non_course_author(self):
     """
     Verify that users who aren't authors of the course are unable to export it
     """
     _, nonstaff_user = self.create_non_staff_authed_user_client()
     key = str(self.course.location.course_key)
     result = export_olx.delay(nonstaff_user.id, key, u'en')
     self._assert_failed(result, u'Permission denied')
Esempio n. 7
0
 def test_invalid_user_id(self):
     """
     Verify that attempts to export a course as an invalid user fail
     """
     user_id = User.objects.order_by(u'-id').first().pk + 100
     key = str(self.course.location.course_key)
     result = export_olx.delay(user_id, key, u'en')
     self._assert_failed(result, u'Unknown User ID: {}'.format(user_id))
Esempio n. 8
0
 def test_non_course_author(self):
     """
     Verify that users who aren't authors of the course are unable to export it
     """
     _, nonstaff_user = self.create_non_staff_authed_user_client()
     key = str(self.course.location.course_key)
     result = export_olx.delay(nonstaff_user.id, key, u'en')
     self._assert_failed(result, u'Permission denied')
Esempio n. 9
0
 def test_invalid_user_id(self):
     """
     Verify that attempts to export a course as an invalid user fail
     """
     user_id = User.objects.order_by(u'-id').first().pk + 100
     key = str(self.course.location.course_key)
     result = export_olx.delay(user_id, key, u'en')
     self._assert_failed(result, u'Unknown User ID: {}'.format(user_id))
Esempio n. 10
0
 def test_success(self):
     """
     Verify that a routine library export task succeeds
     """
     key = str(self.lib_key)
     result = export_olx.delay(self.user.id, key, u'en')  # pylint: disable=no-member
     status = UserTaskStatus.objects.get(task_id=result.id)
     self.assertEqual(status.state, UserTaskStatus.SUCCEEDED)
     artifacts = UserTaskArtifact.objects.filter(status=status)
     self.assertEqual(len(artifacts), 1)
     output = artifacts[0]
     self.assertEqual(output.name, 'Output')
Esempio n. 11
0
 def test_success(self):
     """
     Verify that a routine course export task succeeds
     """
     key = str(self.course.location.course_key)
     result = export_olx.delay(self.user.id, key, u'en')
     status = UserTaskStatus.objects.get(task_id=result.id)
     self.assertEqual(status.state, UserTaskStatus.SUCCEEDED)
     artifacts = UserTaskArtifact.objects.filter(status=status)
     self.assertEqual(len(artifacts), 1)
     output = artifacts[0]
     self.assertEqual(output.name, 'Output')
Esempio n. 12
0
 def test_success(self):
     """
     Verify that a routine course export task succeeds
     """
     key = str(self.course.location.course_key)
     result = export_olx.delay(self.user.id, key, u'en')
     status = UserTaskStatus.objects.get(task_id=result.id)
     self.assertEqual(status.state, UserTaskStatus.SUCCEEDED)
     artifacts = UserTaskArtifact.objects.filter(status=status)
     self.assertEqual(len(artifacts), 1)
     output = artifacts[0]
     self.assertEqual(output.name, 'Output')
Esempio n. 13
0
 def test_success(self):
     """
     Verify that a routine library export task succeeds
     """
     key = str(self.lib_key)
     result = export_olx.delay(self.user.id, key, u'en')  # pylint: disable=no-member
     status = UserTaskStatus.objects.get(task_id=result.id)
     self.assertEqual(status.state, UserTaskStatus.SUCCEEDED)
     artifacts = UserTaskArtifact.objects.filter(status=status)
     self.assertEqual(len(artifacts), 1)
     output = artifacts[0]
     self.assertEqual(output.name, 'Output')
Esempio n. 14
0
def export_handler(request, course_key_string):
    """
    The restful handler for exporting a course.

    GET
        html: return html page for import page
        application/x-tgz: return tar.gz file containing exported course
        json: not supported
    POST
        Start a Celery task to export the course

    Note that there are 3 ways to request the tar.gz file.  The Studio UI uses
    a POST request to start the export asynchronously, with a link appearing
    on the page once it's ready.  Additionally, for backwards compatibility
    reasons the request header can specify application/x-tgz via HTTP_ACCEPT,
    or a query parameter can be used (?_accept=application/x-tgz); this will
    export the course synchronously and return the resulting file (unless the
    request times out for a large course).

    If the tar.gz file has been requested but the export operation fails, the
    import page will be returned including a description of the error.
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    if isinstance(course_key, LibraryLocator):
        courselike_module = modulestore().get_library(course_key)
        context = {
            'context_library':
            courselike_module,
            'courselike_home_url':
            reverse_library_url("library_handler", course_key),
            'library':
            True
        }
    else:
        courselike_module = modulestore().get_course(course_key)
        if courselike_module is None:
            raise Http404
        context = {
            'context_course': courselike_module,
            'courselike_home_url': reverse_course_url("course_handler",
                                                      course_key),
            'library': False
        }
    context['status_url'] = reverse_course_url('export_status_handler',
                                               course_key)

    # an _accept URL parameter will be preferred over HTTP_ACCEPT in the header.
    requested_format = request.GET.get(
        '_accept', request.META.get('HTTP_ACCEPT', 'text/html'))

    if request.method == 'POST':
        export_olx.delay(request.user.id, course_key_string,
                         request.LANGUAGE_CODE)
        return JsonResponse({'ExportStatus': 1})
    elif 'application/x-tgz' in requested_format:
        try:
            tarball = create_export_tarball(courselike_module, course_key,
                                            context)
            return send_tarball(tarball)
        except SerializationError:
            return render_to_response('export.html', context)
    elif 'text/html' in requested_format:
        return render_to_response('export.html', context)
    else:
        # Only HTML or x-tgz request formats are supported (no JSON).
        return HttpResponse(status=406)
Esempio n. 15
0
def export_handler(request, course_key_string):
    """
    The restful handler for exporting a course.

    GET
        html: return html page for import page
        application/x-tgz: return tar.gz file containing exported course
        json: not supported
    POST
        Start a Celery task to export the course

    Note that there are 3 ways to request the tar.gz file.  The Studio UI uses
    a POST request to start the export asynchronously, with a link appearing
    on the page once it's ready.  Additionally, for backwards compatibility
    reasons the request header can specify application/x-tgz via HTTP_ACCEPT,
    or a query parameter can be used (?_accept=application/x-tgz); this will
    export the course synchronously and return the resulting file (unless the
    request times out for a large course).

    If the tar.gz file has been requested but the export operation fails, the
    import page will be returned including a description of the error.
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    if isinstance(course_key, LibraryLocator):
        courselike_module = modulestore().get_library(course_key)
        context = {
            'context_library': courselike_module,
            'courselike_home_url': reverse_library_url("library_handler", course_key),
            'library': True
        }
    else:
        courselike_module = modulestore().get_course(course_key)
        if courselike_module is None:
            raise Http404
        context = {
            'context_course': courselike_module,
            'courselike_home_url': reverse_course_url("course_handler", course_key),
            'library': False
        }
    context['status_url'] = reverse_course_url('export_status_handler', course_key)

    # an _accept URL parameter will be preferred over HTTP_ACCEPT in the header.
    requested_format = request.GET.get('_accept', request.META.get('HTTP_ACCEPT', 'text/html'))

    if request.method == 'POST':
        export_olx.delay(request.user.id, course_key_string, request.LANGUAGE_CODE)
        return JsonResponse({'ExportStatus': 1})
    elif 'application/x-tgz' in requested_format:
        try:
            tarball = create_export_tarball(courselike_module, course_key, context)
            return send_tarball(tarball)
        except SerializationError:
            return render_to_response('export.html', context)
    elif 'text/html' in requested_format:
        return render_to_response('export.html', context)
    else:
        # Only HTML or x-tgz request formats are supported (no JSON).
        return HttpResponse(status=406)