def _log(self, auth_token, level, message):
        """
        Log a message with the specified level.
        """

        if self.authorizer.actor_is_guest(auth_token):
            request = get_current_request()
            if request and 'REMOTE_ADDR' in request.META:
                ip_address = request.META['REMOTE_ADDR']
            else:
                ip_address = '0.0.0.0'
        else:
            ip_address = auth_token.ip
        if isinstance(message, basestring) and isinstance(level, int):
            self._get_logger(auth_token).log(level,
                                             '%s: %s' % (ip_address, message))
        else:
            raise exceptions.ValidationException
    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())