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")})
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)
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_all_signals(cls): """Enable all signals in the modulestore's SignalHandler.""" for signal in SignalHandler.all_signals(): signal.enable()
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)