예제 #1
0
def update_course_run_asset(course_key, upload_file):
    course_exists_response = _get_error_if_course_does_not_exist(course_key)

    if course_exists_response is not None:
        return course_exists_response

    file_metadata = _get_file_metadata_as_dictionary(upload_file)

    is_file_too_large = _check_file_size_is_too_large(file_metadata)
    if is_file_too_large:
        error_message = _get_file_too_large_error_message(file_metadata['filename'])
        raise AssetSizeTooLargeException(error_message)

    content, temporary_file_path = _get_file_content_and_path(file_metadata, course_key)

    (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail(content,
                                                                                tempfile_path=temporary_file_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)

    if _check_thumbnail_uploaded(thumbnail_content):
        content.thumbnail_location = thumbnail_location

    contentstore().save(content)
    del_cached_content(content.location)

    return content
예제 #2
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)

        # 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)
        return JsonResponse(modified_asset, status=201)
예제 #3
0
def delete_asset(course_key, asset_key):
    """
    Deletes asset represented by given 'asset_key' in the course represented by given course_key.
    """
    # Make sure the item to delete actually exists.
    try:
        content = contentstore().find(asset_key)
    except NotFoundError:
        raise AssetNotFoundException

    # ok, save the content into the trashcan
    contentstore('trashcan').save(content)

    # see if there is a thumbnail as well, if so move that as well
    if content.thumbnail_location is not None:
        # We are ignoring the value of the thumbnail_location-- we only care whether
        # or not a thumbnail has been stored, and we can now easily create the correct path.
        thumbnail_location = course_key.make_asset_key('thumbnail', asset_key.name)
        try:
            thumbnail_content = contentstore().find(thumbnail_location)
            contentstore('trashcan').save(thumbnail_content)
            # hard delete thumbnail from origin
            contentstore().delete(thumbnail_content.get_id())
            # remove from any caching
            del_cached_content(thumbnail_location)
        except Exception:  # pylint: disable=broad-except
            logging.warning('Could not delete thumbnail: %s', thumbnail_location)

    # delete the original
    contentstore().delete(content.get_id())
    # remove from cache
    del_cached_content(content.location)
예제 #4
0
 def test_delete(self):
     set_cached_content(self.mockAsset)
     del_cached_content(self.nonUnicodeLocation)
     self.assertEqual(None, get_cached_content(self.unicodeLocation),
                      'should not be stored in cache with unicodeLocation')
     self.assertEqual(None, get_cached_content(self.nonUnicodeLocation),
                      'should not be stored in cache with nonUnicodeLocation')
예제 #5
0
def _upload_file(subs_file, location, filename):
    mime_type = subs_file.content_type
    content_location = StaticContent.compute_location(
        location.course_key, filename
    )
    content = StaticContent(content_location, filename, mime_type, subs_file.read())
    contentstore().save(content)
    del_cached_content(content.location)
예제 #6
0
def delete_asset(course_key, asset_key):
    content = _check_existence_and_get_asset_content(asset_key)

    _save_content_to_trash(content)

    _delete_thumbnail(content.thumbnail_location, course_key, asset_key)
    contentstore().delete(content.get_id())
    del_cached_content(content.location)
    def save_subs_to_store(self, subs, subs_id):
        """Save transcripts into `StaticContent`."""
        filedata = json.dumps(subs, indent=2)
        mime_type = 'application/json'
        filename = 'subs_{0}.srt.sjson'.format(subs_id)

        content_location = StaticContent.compute_location(self.course.id, filename)
        content = StaticContent(content_location, filename, mime_type, filedata)
        contentstore().save(content)
        del_cached_content(content_location)
        return content_location
예제 #8
0
def _clear_assets(location):
    """
    Clear all assets for location.
    """
    store = contentstore()

    assets, __ = store.get_all_content_for_course(location.course_key)
    for asset in assets:
        asset_location = asset['asset_key']
        del_cached_content(asset_location)
        store.delete(asset_location)
예제 #9
0
def _delete_thumbnail(thumbnail_location, course_key, asset_key):
    if thumbnail_location is not None:

        # We are ignoring the value of the thumbnail_location-- we only care whether
        # or not a thumbnail has been stored, and we can now easily create the correct path.
        thumbnail_location = course_key.make_asset_key('thumbnail', asset_key.block_id)

        try:
            thumbnail_content = contentstore().find(thumbnail_location)
            _save_content_to_trash(thumbnail_content)
            contentstore().delete(thumbnail_content.get_id())
            del_cached_content(thumbnail_location)
        except Exception:  # pylint: disable=broad-except
            logging.warning('Could not delete thumbnail: %s', thumbnail_location)
예제 #10
0
def update_course_run_asset(course_key, upload_file):
    filename = upload_file.name
    mime_type = upload_file.content_type
    size = get_file_size(upload_file)

    max_size_in_mb = settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB
    max_file_size_in_bytes = max_size_in_mb * 1000**2
    if size > max_file_size_in_bytes:
        msg = 'File {filename} exceeds the maximum size of {max_size_in_mb} MB.'.format(
            filename=filename, max_size_in_mb=max_size_in_mb)
        raise AssetSizeTooLargeException(msg)

    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

    # Verify 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)

    return content
예제 #11
0
def update_course_run_asset(course_key, upload_file):
    filename = upload_file.name
    mime_type = upload_file.content_type
    size = get_file_size(upload_file)

    max_size_in_mb = settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB
    max_file_size_in_bytes = max_size_in_mb * 1000 ** 2
    if size > max_file_size_in_bytes:
        msg = 'File {filename} exceeds the maximum size of {max_size_in_mb} MB.'.format(
            filename=filename,
            max_size_in_mb=max_size_in_mb
        )
        raise AssetSizeTooLargeException(msg)

    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

    # Verify 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)

    return content
예제 #12
0
def update_course_run_asset(course_key, upload_file):
    """returns contents of the uploaded file"""
    course_exists_response = _get_error_if_course_does_not_exist(course_key)

    if course_exists_response is not None:
        return course_exists_response

    file_metadata = _get_file_metadata_as_dictionary(upload_file)

    is_file_too_large = _check_file_size_is_too_large(file_metadata)
    if is_file_too_large:
        error_message = _get_file_too_large_error_message(
            file_metadata['filename'])
        raise AssetSizeTooLargeException(error_message)

    content, temporary_file_path = _get_file_content_and_path(
        file_metadata, course_key)

    (thumbnail_content,
     thumbnail_location) = contentstore().generate_thumbnail(
         content, tempfile_path=temporary_file_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)

    if _check_thumbnail_uploaded(thumbnail_content):
        content.thumbnail_location = thumbnail_location

    # lock assets by default
    if settings.ASSETS_LOCKED_BY_DEFAULT:
        setattr(content, 'locked', True)

    contentstore().save(content)
    del_cached_content(content.location)

    return content
예제 #13
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')
    }

    return JsonResponse(response_payload)
예제 #14
0
파일: assets.py 프로젝트: gopinath81/vmss
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')
    }

    return JsonResponse(response_payload)