def upload_video_photo(self, request): """Handle Image file uploads for Video thumbnails. We are going to look for a Base64 encoded image if a "photo" file doesn't exist in request.FILES and add it onto the request object before relegating the request object to the superclass Since this method calls a celery task that depends on database changes made here, we must ensure that the transaction gets commited first. :param request: HttpRequest object from django """ photo_file = request.FILES.get('photo') if photo_file is None: # upload_video_photo was called, but without the "photo" file. # Let's see if we got a base64 string of the "photo" photo_b64 = request.POST.get('photo') if photo_b64 is None: return upload._render_response_bad_request( request, 'Request must include photo file or base64 encoded photo parameter' ) try: photo_file = SimpleUploadedFile('photo', base64.b64decode(photo_b64), 'image/png') photo_extension = '.png' except TypeError: # Thrown by b64decode if handed a non base64 string return upload._render_response_bad_request( request, 'Could not decode uploaded photo parameter') else: photo_extension = os.path.splitext(photo_file.name)[1] auth_token = request.POST.get('auth_token', None) video_id = int(request.POST.get('video_id', None)) if not (request.method == 'POST' and auth_token and video_id): return upload._render_response_bad_request( request, msg=( "Your request must include exactly one file, the " + "'video_id' of the video you are uploading the photo for, " + "and a variable named 'auth_token'.")) try: video = self._find_by_id(video_id) auth_token = Utils.get_auth_token_object(auth_token) facade.subsystems.Authorizer().check_update_permissions( auth_token, video, {'photo_url': 'A New Photo!'}) if getattr(settings, 'VOD_ENABLE_VIDEO_UPLOAD_WORKFLOW', True): queue_upload( video, 'photo', 'video/%d.thumbnail%s' % (video_id, photo_extension), photo_file) return upload._render_response_ok(request, msg='Image upload successful.') except exceptions.PrException, p: return upload._render_response_forbidden(request, msg=p.get_error_msg())
def upload_video_photo(self, request): """Handle Image file uploads for Video thumbnails. We are going to look for a Base64 encoded image if a "photo" file doesn't exist in request.FILES and add it onto the request object before relegating the request object to the superclass Since this method calls a celery task that depends on database changes made here, we must ensure that the transaction gets commited first. :param request: HttpRequest object from django """ photo_file = request.FILES.get('photo') if photo_file is None: # upload_video_photo was called, but without the "photo" file. # Let's see if we got a base64 string of the "photo" photo_b64 = request.POST.get('photo') if photo_b64 is None: return upload._render_response_bad_request(request, 'Request must include photo file or base64 encoded photo parameter') try: photo_file = SimpleUploadedFile('photo', base64.b64decode(photo_b64), 'image/png') photo_extension = '.png' except TypeError: # Thrown by b64decode if handed a non base64 string return upload._render_response_bad_request(request, 'Could not decode uploaded photo parameter') else: photo_extension = os.path.splitext(photo_file.name)[1] auth_token = request.POST.get('auth_token', None) video_id = int(request.POST.get('video_id', None)) if not (request.method == 'POST' and auth_token and video_id): return upload._render_response_bad_request(request, msg=("Your request must include exactly one file, the "+ "'video_id' of the video you are uploading the photo for, "+ "and a variable named 'auth_token'.")) try: video = self._find_by_id(video_id) auth_token = Utils.get_auth_token_object(auth_token) facade.subsystems.Authorizer().check_update_permissions(auth_token, video, {'photo_url' : 'A New Photo!'}) if getattr(settings, 'VOD_ENABLE_VIDEO_UPLOAD_WORKFLOW', True): queue_upload(video, 'photo', 'video/%d.thumbnail%s' % (video_id, photo_extension), photo_file) return upload._render_response_ok(request, msg='Image upload successful.') except exceptions.PrException, p: return upload._render_response_forbidden(request, msg=p.get_error_msg())
def upload_video(self, request, auth_token=None): """Handle video file uploads This method will stick the contents of the uploaded file (of which there must be exactly 1) into the database through a Video object. There is currently no validation of the Video. :param request: HttpRequest object from Django :type request: HttpRequest :param auth_token: AuthToken from an HTML form upload :type auth_token: string or None """ try: if request.method == 'GET': transaction.rollback() if auth_token is None: return upload._render_response_forbidden( request, msg= 'Your request must include an auth token in its URL.') return upload._render_response( request, 'vod_upload_video.html', { 'title': 'Video Upload', 'form': VideoUploadForm(), 'auth_token': auth_token }) elif request.method == 'POST': if auth_token is None: if 'auth_token' not in request.POST: transaction.rollback() return upload._render_response_forbidden( request, msg= 'Your request must contain a variable named \'auth_token\'.' ) else: auth_token = request.POST['auth_token'] form = VideoUploadForm(data=request.POST, files=request.FILES) if form.is_valid(): at = Utils.get_auth_token_object(auth_token) at.domain_affiliation.user = at.domain_affiliation.user.downcast_completely( ) if 'categories' in request.POST: try: categories = json.loads(request.POST['categories']) except ValueError: # Will also handle json.JSONDecodeError, depending on simplejson version used. raise exceptions.InvalidDataException, 'invalid JSON data in categories field' if not isinstance(categories, list): raise exceptions.InvalidDataException, 'categories must be a list of dictionaries mapping "id" to an integer category id' for c in categories: if not (isinstance(c, dict) and 'id' in c and type(c['id']) in (int, long)): raise exceptions.InvalidDataException, 'categories must be a list of dictionaries mapping "id" to an integer category id' categories = [c['id'] for c in categories] new_video = self.create(at, form.cleaned_data['name'], form.cleaned_data['description'], form.cleaned_data['author'], categories) new_video.src_file_size = form.files['video'].size new_video.save() # Commit the transaction before queuing a task to work on # our new Video object. transaction.commit() if getattr(settings, 'VOD_ENABLE_VIDEO_UPLOAD_WORKFLOW', True): ## Queue the task to upload the video to S3. # Let's get the notification URL here because we can do # it accurately while in the web hosting environment # but not in celeryd. notify_url = getattr(settings, 'ENCODING_NOTIFICATION_URL', False) if not notify_url: request = middleware.get_current_request() site = '%s://%s' % (request.is_secure() and 'https' or 'http', request.get_host()) notify_url = urlparse.urljoin( site, reverse('vod_aws:video_notification')) pending = prepare_upload(new_video, 'src_file', 'video/%d.src' % new_video.id, form.files['video'], callback=subtask( queue_encoding, video_id=new_video.id, notify_url=notify_url)) transaction.commit() pending.queue() if 'auth_token' not in request.POST: return upload._render_response_ok( request, msg='Video upload successful.') else: # for plain POST requests (old way), still return the video ID return HttpResponse( str(new_video.id) if new_video else None) else: transaction.rollback() logging.info(str(form.errors)) return upload._render_response(request, 'vod_upload_video.html', { 'title': 'Video Upload', 'form': form, 'auth_token': auth_token }, status=400) except exceptions.PrException, p: transaction.rollback() log_message = u'UploadManager.upload_video: pr exception code %d, msg [%s], details [%s]' %\ (p.get_error_code(), p.get_error_msg(), unicode(p.get_details())) logging.info(log_message) if p.error_code == 46: # InternalErrorException stack_trace = traceback.format_exc() logging.info(stack_trace) return upload._render_response_server_error( request, msg=p.get_error_msg()) elif p.error_code in [17, 23, 49, 114, 115, 128]: return upload._render_response_forbidden(request, msg=p.get_error_msg()) else: return upload._render_response_bad_request( request, msg=p.get_error_msg())
def upload_video(self, request, auth_token=None): """Handle video file uploads This method will stick the contents of the uploaded file (of which there must be exactly 1) into the database through a Video object. There is currently no validation of the Video. :param request: HttpRequest object from Django :type request: HttpRequest :param auth_token: AuthToken from an HTML form upload :type auth_token: string or None """ try: if request.method == 'GET': transaction.rollback() if auth_token is None: return upload._render_response_forbidden(request, msg='Your request must include an auth token in its URL.') return upload._render_response(request, 'vod_upload_video.html', {'title': 'Video Upload', 'form': VideoUploadForm(), 'auth_token': auth_token}) elif request.method == 'POST': if auth_token is None: if 'auth_token' not in request.POST: transaction.rollback() return upload._render_response_forbidden(request, msg='Your request must contain a variable named \'auth_token\'.') else: auth_token = request.POST['auth_token'] form = VideoUploadForm(data=request.POST, files=request.FILES) if form.is_valid(): at = Utils.get_auth_token_object(auth_token) at.domain_affiliation.user = at.domain_affiliation.user.downcast_completely() if 'categories' in request.POST: try: categories = json.loads(request.POST['categories']) except ValueError: # Will also handle json.JSONDecodeError, depending on simplejson version used. raise exceptions.InvalidDataException, 'invalid JSON data in categories field' if not isinstance(categories, list): raise exceptions.InvalidDataException, 'categories must be a list of dictionaries mapping "id" to an integer category id' for c in categories: if not (isinstance(c, dict) and 'id' in c and type(c['id']) in (int, long)): raise exceptions.InvalidDataException, 'categories must be a list of dictionaries mapping "id" to an integer category id' categories = [c['id'] for c in categories] new_video = self.create(at, form.cleaned_data['name'], form.cleaned_data['description'], form.cleaned_data['author'], categories) new_video.src_file_size = form.files['video'].size new_video.save() # Commit the transaction before queuing a task to work on # our new Video object. transaction.commit() if getattr(settings, 'VOD_ENABLE_VIDEO_UPLOAD_WORKFLOW', True): ## Queue the task to upload the video to S3. # Let's get the notification URL here because we can do # it accurately while in the web hosting environment # but not in celeryd. notify_url = getattr(settings, 'ENCODING_NOTIFICATION_URL', False) if not notify_url: request = middleware.get_current_request() site = '%s://%s' % ( request.is_secure() and 'https' or 'http', request.get_host()) notify_url = urlparse.urljoin(site, reverse('vod_aws:video_notification')) pending = prepare_upload(new_video, 'src_file', 'video/%d.src' % new_video.id, form.files['video'], callback=subtask(queue_encoding, video_id=new_video.id, notify_url=notify_url)) transaction.commit() pending.queue() if 'auth_token' not in request.POST: return upload._render_response_ok(request, msg='Video upload successful.') else: # for plain POST requests (old way), still return the video ID return HttpResponse(str(new_video.id) if new_video else None) else: transaction.rollback() logging.info(str(form.errors)) return upload._render_response(request, 'vod_upload_video.html', {'title': 'Video Upload', 'form': form, 'auth_token': auth_token}, status=400) except exceptions.PrException, p: transaction.rollback() log_message = u'UploadManager.upload_video: pr exception code %d, msg [%s], details [%s]' %\ (p.get_error_code(), p.get_error_msg(), unicode(p.get_details())) logging.info(log_message) if p.error_code == 46: # InternalErrorException stack_trace = traceback.format_exc() logging.info(stack_trace) return upload._render_response_server_error(request, msg=p.get_error_msg()) elif p.error_code in [17, 23, 49, 114, 115, 128]: return upload._render_response_forbidden(request, msg=p.get_error_msg()) else: return upload._render_response_bad_request(request, msg=p.get_error_msg())