Esempio n. 1
0
def _update_asset(request, course_key, asset_key):
    """
    restful CRUD operations for a course asset.
    Currently only DELETE, POST, and PUT methods are implemented.

    asset_path_encoding: the odd /c4x/org/course/category/name repr of the asset (used by Backbone as the id)
    """
    if request.method == 'DELETE':
        try:
            delete_asset(course_key, asset_key)
            return JsonResponse()
        except AssetNotFoundException:
            return JsonResponse(status=404)

    elif request.method in ('PUT', 'POST'):
        if 'file' in request.FILES:
            return _upload_asset(request, course_key)
        else:
            # Update existing asset
            try:
                modified_asset = json.loads(request.body)
            except ValueError:
                return HttpResponseBadRequest()
            contentstore().set_attr(asset_key, 'locked', modified_asset['locked'])
            # Delete the asset from the cache so we check the lock status the next time it is requested.
            del_cached_content(asset_key)
            from xmodule.modulestore.django import SignalHandler
            signal_handler = SignalHandler(modulestore())
            signal_handler.send('course_published', course_key=course_key)
            return JsonResponse(modified_asset, status=201)
def set_course_mode_price(request, course_id):
    """
    set the new course price and add new entry in the CourseModesArchive Table
    """
    try:
        course_price = int(request.POST['course_price'])
    except ValueError:
        return JsonResponse(
            {'message': _("Please Enter the numeric value for the course price")},
            status=400)  # status code 400: Bad Request

    currency = request.POST['currency']
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)

    course_honor_mode = CourseMode.objects.filter(mode_slug='honor', course_id=course_key)
    if not course_honor_mode:
        return JsonResponse(
            {'message': _("CourseMode with the mode slug({mode_slug}) DoesNotExist").format(mode_slug='honor')},
            status=400)  # status code 400: Bad Request

    CourseModesArchive.objects.create(
        course_id=course_id, mode_slug='honor', mode_display_name='Honor Code Certificate',
        min_price=course_honor_mode[0].min_price, currency=course_honor_mode[0].currency,
        expiration_datetime=datetime.datetime.now(pytz.utc), expiration_date=datetime.date.today()
    )
    course_honor_mode.update(
        min_price=course_price,
        currency=currency
    )

    signal_handler = SignalHandler(modulestore())
    signal_handler.send('course_published', course_key=course_key)
    return JsonResponse({'message': _("CourseMode price updated successfully")})
Esempio n. 3
0
    def test_course_published_ccxcon_call(self, mock_upc):
        """
        Tests the async call to the ccxcon task.
        It bypasses all the other calls.
        """
        mock_response = mock.MagicMock(return_value=None)
        mock_upc.return_value = mock_response

        course_id = u'course-v1:OrgFoo+CN199+CR-FALL01'
        course_key = CourseKey.from_string(course_id)

        signal_handler = SignalHandler(modulestore())
        signal_handler.send('course_published', course_key=course_key)

        mock_upc.assert_called_once_with(course_id)
Esempio n. 4
0
    def enable_signals_by_name(cls, *signal_names):
        """
        Enable specific signals in the modulestore's SignalHandler.

        Arguments:
            signal_names (list of `str`): Names of signals to enable.
        """
        for signal_name in signal_names:
            try:
                signal = SignalHandler.signal_by_name(signal_name)
            except KeyError:
                all_signal_names = sorted(s.name for s in SignalHandler.all_signals())
                err_msg = (
                    "You tried to enable signal '{}', but I don't recognize that "
                    "signal name. Did you mean one of these?: {}"
                )
                raise ValueError(err_msg.format(signal_name, all_signal_names))
            signal.enable()
    def enable_signals_by_name(cls, *signal_names):
        """
        Enable specific signals in the modulestore's SignalHandler.

        Arguments:
            signal_names (list of `str`): Names of signals to enable.
        """
        for signal_name in signal_names:
            try:
                signal = SignalHandler.signal_by_name(signal_name)
            except KeyError:
                all_signal_names = sorted(s.name for s in SignalHandler.all_signals())
                err_msg = (
                    "You tried to enable signal '{}', but I don't recognize that "
                    "signal name. Did you mean one of these?: {}"
                )
                raise ValueError(err_msg.format(signal_name, all_signal_names))
            signal.enable()
Esempio n. 6
0
 def enable_all_signals(cls):
     """Enable all signals in the modulestore's SignalHandler."""
     for signal in SignalHandler.all_signals():
         signal.enable()
 def enable_all_signals(cls):
     """Enable all signals in the modulestore's SignalHandler."""
     for signal in SignalHandler.all_signals():
         signal.enable()
Esempio n. 8
0
def _upload_asset(request, course_key):
    '''
    This method allows for POST uploading of files into the course asset
    library, which will be supported by GridFS in MongoDB.
    '''
    # Does the course actually exist?!? Get anything from it to prove its
    # existence
    try:
        modulestore().get_course(course_key)
    except ItemNotFoundError:
        # no return it as a Bad Request response
        logging.error("Could not find course: %s", course_key)
        return HttpResponseBadRequest()

    # compute a 'filename' which is similar to the location formatting, we're
    # using the 'filename' nomenclature since we're using a FileSystem paradigm
    # here. We're just imposing the Location string formatting expectations to
    # keep things a bit more consistent
    upload_file = request.FILES['file']
    filename = upload_file.name
    mime_type = upload_file.content_type
    size = get_file_size(upload_file)

    # If file is greater than a specified size, reject the upload
    # request and send a message to the user. Note that since
    # the front-end may batch large file uploads in smaller chunks,
    # we validate the file-size on the front-end in addition to
    # validating on the backend. (see cms/static/js/views/assets.js)
    max_file_size_in_bytes = settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB * 1000 ** 2
    if size > max_file_size_in_bytes:
        return JsonResponse({
            'error': _(
                'File {filename} exceeds maximum size of '
                '{size_mb} MB. Please follow the instructions here '
                'to upload a file elsewhere and link to it instead: '
                '{faq_url}'
            ).format(
                filename=filename,
                size_mb=settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB,
                faq_url=settings.MAX_ASSET_UPLOAD_FILE_SIZE_URL,
            )
        }, status=413)

    content_loc = StaticContent.compute_location(course_key, filename)

    chunked = upload_file.multiple_chunks()
    sc_partial = partial(StaticContent, content_loc, filename, mime_type)
    if chunked:
        content = sc_partial(upload_file.chunks())
        tempfile_path = upload_file.temporary_file_path()
    else:
        content = sc_partial(upload_file.read())
        tempfile_path = None

    # first let's see if a thumbnail can be created
    (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail(
        content,
        tempfile_path=tempfile_path,
    )

    # delete cached thumbnail even if one couldn't be created this time (else
    # the old thumbnail will continue to show)
    del_cached_content(thumbnail_location)
    # now store thumbnail location only if we could create it
    if thumbnail_content is not None:
        content.thumbnail_location = thumbnail_location

    # then commit the content
    contentstore().save(content)
    del_cached_content(content.location)

    # readback the saved content - we need the database timestamp
    readback = contentstore().find(content.location)
    locked = getattr(content, 'locked', False)
    response_payload = {
        'asset': _get_asset_json(
            content.name,
            content.content_type,
            readback.last_modified_at,
            content.location,
            content.thumbnail_location,
            locked
        ),
        'msg': _('Upload completed')
    }
    from xmodule.modulestore.django import SignalHandler
    signal_handler = SignalHandler(modulestore())
    signal_handler.send('course_published', course_key=course_key)
    return JsonResponse(response_payload)