Example #1
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data['app'])

        # Return 409 if the user has already reviewed this app.
        if self._meta.queryset.filter(addon=app, user=request.user).exists():
            raise ImmediateHttpResponse(response=http.HttpConflict())

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise ImmediateHttpResponse(response=http.HttpForbidden())

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise ImmediateHttpResponse(response=http.HttpForbidden())

        bundle.obj = Review.objects.create(**self._review_data(request, app,
                                                               form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug('[Review:%s] Created by user %s ' %
                  (bundle.obj.id, request.user.id))
        record_action('new-review', request, {'app-id': app.id})

        return bundle
Example #2
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data['app'])

        # Return 409 if the user has already reviewed this app.
        if self._meta.queryset.filter(addon=app, user=request.user).exists():
            raise ImmediateHttpResponse(response=http.HttpConflict())

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise ImmediateHttpResponse(response=http.HttpForbidden())

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise ImmediateHttpResponse(response=http.HttpForbidden())

        bundle.obj = Review.objects.create(
            **self._review_data(request, app, form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug('[Review:%s] Created by user %s ' %
                  (bundle.obj.id, request.user.id))
        record_action('new-review', request, {'app-id': app.id})

        return bundle
Example #3
0
    def obj_update(self, bundle, request, **kwargs):
        """
        Handle PUT requests to the resource. If authorized and the data
        validates, update the indicated resource with bundle data.
        """
        obj = self.get_by_resource_or_404(request, **kwargs)
        if not OwnerAuthorization().is_authorized(request, object=obj):
            raise http_error(
                http.HttpForbidden,
                'You do not have permission to update this review.')

        form = ReviewForm(bundle.data)
        if not form.is_valid():
            raise self.form_errors(form)

        if 'app' in bundle.data:
            error = ('app', "Cannot update a rating's `app`")
            raise self.non_form_errors([error])

        sup = super(RatingResource, self).obj_update(bundle, request, **kwargs)

        amo.log(amo.LOG.EDIT_REVIEW, bundle.obj.addon, bundle.obj)
        log.debug('[Review:%s] Edited by %s' % (bundle.obj.id, request.user.id))

        return sup
Example #4
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data["app"])

        # Return 409 if the user has already reviewed this app.
        qs = self._meta.queryset.filter(addon=app, user=request.user)
        if app.is_packaged:
            qs = qs.filter(version_id=bundle.data.get("version", app.current_version.id))
        if qs.exists():
            raise http_error(http.HttpConflict, "You have already reviewed this app.")

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise http_error(http.HttpForbidden, "You may not review your own app.")

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise http_error(http.HttpForbidden, "You may not review paid apps you haven't purchased.")

        bundle.obj = Review.objects.create(**self._review_data(request, app, form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug("[Review:%s] Created by user %s " % (bundle.obj.id, request.user.id))
        record_action("new-review", request, {"app-id": app.id})

        return bundle
Example #5
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        return http.HttpResponseForbidden()

    data = request.POST or None
    form = ReviewForm(data)
    if data and form.is_valid():
        review = Review.objects.create(**_review_details(request, addon, form))
        Addon.objects.invalidate(*[addon])
        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)
        messages.success(request, _('Your review was successfully added!'))

        # reply_url = addon.get_ratings_url('reply', args=[addon, review.id],
        #                                   add_prefix=False)
        # data = {'name': addon.name,
        #         'rating': '%s out of 5 stars' % details['rating'],
        #         'review': details['body'],
        #         'reply_url': absolutify(reply_url)}

        # emails = addon.values_list('email', flat=True)
        # send_mail('reviews/emails/add_review.ltxt',
        #           u'Mozilla Marketplace User Review: %s' % addon.name,
        #           emails, Context(data), 'new_review')

        return redirect(addon.get_ratings_url('list'))

    return jingo.render(request, 'ratings/add.html', {
        'product': addon,
        'form': form
    })
Example #6
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        return http.HttpResponseForbidden()

    data = request.POST or None
    form = ReviewForm(data)
    if data and form.is_valid():
        review = Review.objects.create(**_review_details(request, addon, form))
        Addon.objects.invalidate(*[addon])
        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)
        messages.success(request, _('Your review was successfully added!'))

        # reply_url = addon.get_ratings_url('reply', args=[addon, review.id],
        #                                   add_prefix=False)
        # data = {'name': addon.name,
        #         'rating': '%s out of 5 stars' % details['rating'],
        #         'review': details['body'],
        #         'reply_url': absolutify(reply_url)}

        # emails = addon.values_list('email', flat=True)
        # send_mail('reviews/emails/add_review.ltxt',
        #           u'Mozilla Marketplace User Review: %s' % addon.name,
        #           emails, Context(data), 'new_review')

        return redirect(addon.get_ratings_url('list'))

    return jingo.render(request, 'ratings/add.html',
                        {'product': addon, 'form': form})
Example #7
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        return http.HttpResponseForbidden()

    data = request.POST or None
    form = ReviewForm(data)
    if data and form.is_valid():
        review = Review.objects.create(**_review_details(request, addon, form))
        Addon.objects.invalidate(*[addon])
        amo.log(amo.LOG.ADD_REVIEW, addon, review)
        log.debug('New review: %s' % review.id)
        messages.success(request, _('Your review was successfully added!'))

        return redirect(addon.get_ratings_url('list'))

    return jingo.render(request, 'ratings/add.html',
                        {'product': addon, 'form': form})
Example #8
0
    def obj_update(self, bundle, request, **kwargs):
        """
        Handle PUT requests to the resource. If authorized and the data
        validates, update the indicated resource with bundle data.
        """
        form = ReviewForm(bundle.data)
        if not form.is_valid():
            raise self.form_errors(form)

        if 'app' in bundle.data:
            error = ('app', "Cannot update a rating's `app`")
            raise self.non_form_errors([error])

        sup = super(RatingResource, self).obj_update(bundle, request, **kwargs)

        amo.log(amo.LOG.EDIT_REVIEW, bundle.obj.addon, bundle.obj)
        log.debug('[Review:%s] Edited by %s' % (bundle.obj.id, request.user.id))

        return sup
Example #9
0
    def obj_update(self, bundle, request, **kwargs):
        """
        Handle PUT requests to the resource. If authorized and the data
        validates, update the indicated resource with bundle data.
        """
        form = ReviewForm(bundle.data)
        if not form.is_valid():
            raise self.form_errors(form)

        if 'app' in bundle.data:
            error = ('app', "Cannot update a rating's `app`")
            raise self.non_form_errors([error])

        sup = super(RatingResource, self).obj_update(bundle, request, **kwargs)

        amo.log(amo.LOG.EDIT_REVIEW, bundle.obj.addon, bundle.obj)
        log.debug('[Review:%s] Edited by %s' %
                  (bundle.obj.id, request.user.id))

        return sup
Example #10
0
    def obj_create(self, bundle, request=None, **kwargs):
        """
        Handle POST requests to the resource. If the data validates, create a
        new Review from bundle data.
        """
        form = ReviewForm(bundle.data)

        if not form.is_valid():
            raise self.form_errors(form)

        app = self.get_app(bundle.data['app'])

        # Return 409 if the user has already reviewed this app.
        qs = self._meta.queryset.filter(addon=app, user=request.user)
        if app.is_packaged:
            qs = qs.filter(
                version_id=bundle.data.get('version', app.current_version.id))
        if qs.exists():
            raise http_error(http.HttpConflict,
                             'You have already reviewed this app.')

        # Return 403 if the user is attempting to review their own app:
        if app.has_author(request.user):
            raise http_error(http.HttpForbidden,
                             'You may not review your own app.')

        # Return 403 if not a free app and the user hasn't purchased it.
        if app.is_premium() and not app.is_purchased(request.amo_user):
            raise http_error(
                http.HttpForbidden,
                "You may not review paid apps you haven't purchased.")

        bundle.obj = Review.objects.create(
            **self._review_data(request, app, form))

        amo.log(amo.LOG.ADD_REVIEW, app, bundle.obj)
        log.debug('[Review:%s] Created by user %s ' %
                  (bundle.obj.id, request.user.id))
        record_action('new-review', request, {'app-id': app.id})

        return bundle
Example #11
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        raise PermissionDenied

    # Get user agent of user submitting review. If there is an install with
    # logged user agent that matches the current user agent, hook up that
    # install's client data with the rating. If there aren't any install that
    # match, use the most recent install. This implies that user must have an
    # install to submit a review, but not sure if that logic is worked in, so
    # default client_data to None.
    client_data = None
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    install = (Installed.objects.filter(user=request.user, addon=addon)
                                .order_by('-created'))
    install_w_user_agent = (install.filter(client_data__user_agent=user_agent)
                                   .order_by('-created'))
    has_review = False
    try:
        if install_w_user_agent:
            client_data = install_w_user_agent[0].client_data
        elif install:
            client_data = install[0].client_data
    except ClientData.DoesNotExist:
        client_data = None

    data = request.POST or None

    # Try to get an existing review of the app by this user if we can.
    try:
        existing_review = Review.objects.valid().filter(addon=addon,
                                                        user=request.user)[0]
    except IndexError:
        # If one doesn't exist, set it to None.
        existing_review = None

    # If the user is posting back, try to process the submission.
    if data:
        form = ReviewForm(data)
        if form.is_valid():
            cleaned = form.cleaned_data
            if existing_review:
                # If there's a review to overwrite, overwrite it.
                if (cleaned['body'] != existing_review.body or
                    cleaned['rating'] != existing_review.rating):
                    existing_review.body = cleaned['body']
                    existing_review.rating = cleaned['rating']
                    ip = request.META.get('REMOTE_ADDR', '')
                    existing_review.ip_address = ip
                    if 'flag' in cleaned and cleaned['flag']:
                        existing_review.flag = True
                        existing_review.editorreview = True
                        rf = ReviewFlag(review=existing_review,
                                user_id=request.user.id,
                                flag=ReviewFlag.OTHER,
                                note='URLs')
                        rf.save()
                    existing_review.save()
                    # Update ratings and review counts.
                    addon_review_aggregates.delay(addon.id,
                                                  using='default')

                amo.log(amo.LOG.EDIT_REVIEW, addon, existing_review)
                log.debug('[Review:%s] Edited by %s' % (existing_review.id,
                                                        request.user.id))
                messages.success(request,
                                 _('Your review was updated successfully!'))

                # If there is a developer reply to the review, delete it. We do
                # this per bug 777059.
                try:
                    reply = existing_review.replies.all()[0]
                except IndexError:
                    pass
                else:
                    log.debug('[Review:%s] Deleted reply to %s' %
                                  (reply.id, existing_review.id))
                    reply.delete()

            else:
                # If there isn't a review to overwrite, create a new review.
                review = Review.objects.create(client_data=client_data,
                        **_review_details(request, addon, form))
                if 'flag' in cleaned and cleaned['flag']:
                    rf = ReviewFlag(review=review,
                                user_id=request.user.id,
                                flag=ReviewFlag.OTHER,
                                note='URLs')
                    rf.save()
                amo.log(amo.LOG.ADD_REVIEW, addon, review)
                log.debug('[Review:%s] Created by user %s ' %
                          (review.id, request.user.id))
                messages.success(request,
                                 _('Your review was successfully added!'))

            Addon.objects.invalidate(*[addon])
            return redirect(addon.get_ratings_url('list'))

        # If the form isn't valid, we've set `form` so that it can be used when
        # the template is rendered below.

    elif existing_review:
        # If the user isn't posting back but has an existing review, populate
        # the form with their existing review and rating.
        form = ReviewForm({'rating': existing_review.rating or 1,
                           'body': existing_review.body})
        has_review = True
    else:
        # If the user isn't posting back and doesn't have an existing review,
        # just show a blank version of the form.
        form = ReviewForm()

    # Get app's support url, either from support flow if contribution exists or
    # author's support url.
    support_email = str(addon.support_email) if addon.support_email else None
    try:
        contrib_id = (Contribution.objects
                      .filter(user=request.user, addon=addon,
                              type__in=(amo.CONTRIB_PURCHASE,
                                        amo.CONTRIB_INAPP,
                                        amo.CONTRIB_REFUND))
                      .order_by('-created')[0].id)
        support_url = reverse('support', args=[contrib_id])
    except IndexError:
        support_url = addon.support_url

    return jingo.render(request, 'ratings/add.html',
                        {'product': addon, 'form': form,
                         'support_url': support_url,
                         'has_review': has_review,
                         'support_email': support_email})
Example #12
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        raise PermissionDenied

    # Get user agent of user submitting review. If there is an install with
    # logged user agent that matches the current user agent, hook up that
    # install's client data with the rating. If there aren't any install that
    # match, use the most recent install. This implies that user must have an
    # install to submit a review, but not sure if that logic is worked in, so
    # default client_data to None.
    client_data = None
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    install = (Installed.objects.filter(user=request.user,
                                        addon=addon).order_by('-created'))
    install_w_user_agent = (install.filter(
        client_data__user_agent=user_agent).order_by('-created'))
    has_review = False
    try:
        if install_w_user_agent:
            client_data = install_w_user_agent[0].client_data
        elif install:
            client_data = install[0].client_data
    except ClientData.DoesNotExist:
        client_data = None

    data = request.POST or None

    # Try to get an existing review of the app by this user if we can.
    try:
        existing_review = Review.objects.valid().filter(addon=addon,
                                                        user=request.user)[0]
    except IndexError:
        # If one doesn't exist, set it to None.
        existing_review = None

    # If the user is posting back, try to process the submission.
    if data:
        form = ReviewForm(data)
        if form.is_valid():
            cleaned = form.cleaned_data
            if existing_review:
                # If there's a review to overwrite, overwrite it.
                if (cleaned['body'] != existing_review.body
                        or cleaned['rating'] != existing_review.rating):
                    existing_review.body = cleaned['body']
                    existing_review.rating = cleaned['rating']
                    ip = request.META.get('REMOTE_ADDR', '')
                    existing_review.ip_address = ip
                    if 'flag' in cleaned and cleaned['flag']:
                        existing_review.flag = True
                        existing_review.editorreview = True
                        rf = ReviewFlag(review=existing_review,
                                        user_id=request.user.id,
                                        flag=ReviewFlag.OTHER,
                                        note='URLs')
                        rf.save()
                    existing_review.save()
                    # Update ratings and review counts.
                    addon_review_aggregates.delay(addon.id, using='default')

                amo.log(amo.LOG.EDIT_REVIEW, addon, existing_review)
                log.debug('[Review:%s] Edited by %s' %
                          (existing_review.id, request.user.id))
                messages.success(request,
                                 _('Your review was updated successfully!'))

                # If there is a developer reply to the review, delete it. We do
                # this per bug 777059.
                try:
                    reply = existing_review.replies.all()[0]
                except IndexError:
                    pass
                else:
                    log.debug('[Review:%s] Deleted reply to %s' %
                              (reply.id, existing_review.id))
                    reply.delete()

            else:
                # If there isn't a review to overwrite, create a new review.
                review = Review.objects.create(client_data=client_data,
                                               **_review_details(
                                                   request, addon, form))
                if 'flag' in cleaned and cleaned['flag']:
                    rf = ReviewFlag(review=review,
                                    user_id=request.user.id,
                                    flag=ReviewFlag.OTHER,
                                    note='URLs')
                    rf.save()
                amo.log(amo.LOG.ADD_REVIEW, addon, review)
                log.debug('[Review:%s] Created by user %s ' %
                          (review.id, request.user.id))
                messages.success(request,
                                 _('Your review was successfully added!'))

            Addon.objects.invalidate(*[addon])
            return redirect(addon.get_ratings_url('list'))

        # If the form isn't valid, we've set `form` so that it can be used when
        # the template is rendered below.

    elif existing_review:
        # If the user isn't posting back but has an existing review, populate
        # the form with their existing review and rating.
        form = ReviewForm({
            'rating': existing_review.rating or 1,
            'body': existing_review.body
        })
        has_review = True
    else:
        # If the user isn't posting back and doesn't have an existing review,
        # just show a blank version of the form.
        form = ReviewForm()

    # Get app's support url, either from support flow if contribution exists or
    # author's support url.
    support_email = str(addon.support_email) if addon.support_email else None
    try:
        contrib_id = (Contribution.objects.filter(
            user=request.user,
            addon=addon,
            type__in=(amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP,
                      amo.CONTRIB_REFUND)).order_by('-created')[0].id)
        support_url = reverse('support', args=[contrib_id])
    except IndexError:
        support_url = addon.support_url

    return jingo.render(
        request, 'ratings/add.html', {
            'product': addon,
            'form': form,
            'support_url': support_url,
            'has_review': has_review,
            'support_email': support_email
        })
Example #13
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        raise PermissionDenied

    if (request.user.is_authenticated() and request.method == 'GET'
            and (not request.MOBILE or request.TABLET)):
        return detail(request, app_slug=addon.app_slug, add_review=True)

    # Get user agent of user submitting review. If there is an install with
    # logged user agent that matches the current user agent, hook up that
    # install's client data with the rating. If there aren't any install that
    # match, use the most recent install. This implies that user must have an
    # install to submit a review, but not sure if that logic is worked in, so
    # default client_data to None.
    client_data = None
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    install = (Installed.objects.filter(user=request.user,
                                        addon=addon).order_by('-created'))
    install_w_user_agent = (install.filter(
        client_data__user_agent=user_agent).order_by('-created'))
    has_review = False
    try:
        if install_w_user_agent:
            client_data = install_w_user_agent[0].client_data
        elif install:
            client_data = install[0].client_data
    except ClientData.DoesNotExist:
        client_data = None

    data = request.POST or None

    # Try to get an existing review of the app by this user if we can.
    filters = dict(addon=addon, user=request.user)
    if addon.is_packaged:
        filters['version'] = addon.current_version

    try:
        existing_review = Review.objects.valid().filter(**filters)[0]
    except IndexError:
        existing_review = None

    # If the user is posting back, try to process the submission.
    if data:
        form = ReviewForm(data)
        if form.is_valid():
            cleaned = form.cleaned_data
            if existing_review:
                # If there's a review to overwrite, overwrite it.
                if (cleaned['body'] != existing_review.body
                        or cleaned['rating'] != existing_review.rating):
                    existing_review.body = cleaned['body']
                    existing_review.rating = cleaned['rating']
                    ip = request.META.get('REMOTE_ADDR', '')
                    existing_review.ip_address = ip
                    if 'flag' in cleaned and cleaned['flag']:
                        existing_review.flag = True
                        existing_review.editorreview = True
                        rf = ReviewFlag(review=existing_review,
                                        user_id=request.user.id,
                                        flag=ReviewFlag.OTHER,
                                        note='URLs')
                        rf.save()
                    existing_review.save()

                amo.log(amo.LOG.EDIT_REVIEW, addon, existing_review)
                log.debug('[Review:%s] Edited by %s' %
                          (existing_review.id, request.user.id))
                messages.success(request,
                                 _('Your review was updated successfully!'))
            else:
                # If there isn't a review to overwrite, create a new review.
                review = Review.objects.create(client_data=client_data,
                                               **_review_details(
                                                   request, addon, form))
                if 'flag' in cleaned and cleaned['flag']:
                    rf = ReviewFlag(review=review,
                                    user_id=request.user.id,
                                    flag=ReviewFlag.OTHER,
                                    note='URLs')
                    rf.save()
                amo.log(amo.LOG.ADD_REVIEW, addon, review)
                log.debug('[Review:%s] Created by user %s ' %
                          (review.id, request.user.id))
                messages.success(request,
                                 _('Your review was successfully added!'))
                record_action('new-review', request, {'app-id': addon.id})

            return redirect(addon.get_ratings_url('list'))

        # If the form isn't valid, we've set `form` so that it can be used when
        # the template is rendered below.

    elif existing_review:
        # If the user isn't posting back but has an existing review, populate
        # the form with their existing review and rating.
        form = ReviewForm({
            'rating': existing_review.rating or 1,
            'body': existing_review.body
        })
        has_review = True
    else:
        # If the user isn't posting back and doesn't have an existing review,
        # just show a blank version of the form.
        form = ReviewForm()

    support_email = str(addon.support_email) if addon.support_email else None
    return jingo.render(
        request, 'ratings/add.html', {
            'product': addon,
            'form': form,
            'support_url': addon.support_url,
            'has_review': has_review,
            'support_email': support_email,
            'page_parent':
            addon.get_detail_url() if not existing_review else ''
        })
Example #14
0
def add(request, addon):
    if addon.has_author(request.user):
        # Don't let app owners review their own apps.
        raise PermissionDenied

    if (request.user.is_authenticated() and
            request.method == 'GET' and
            (not request.MOBILE or request.TABLET)):
        return detail(request, app_slug=addon.app_slug, add_review=True)

    # Get user agent of user submitting review. If there is an install with
    # logged user agent that matches the current user agent, hook up that
    # install's client data with the rating. If there aren't any install that
    # match, use the most recent install. This implies that user must have an
    # install to submit a review, but not sure if that logic is worked in, so
    # default client_data to None.
    client_data = None
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    install = (Installed.objects.filter(user=request.user, addon=addon)
                                .order_by('-created'))
    install_w_user_agent = (install.filter(client_data__user_agent=user_agent)
                                   .order_by('-created'))
    has_review = False
    try:
        if install_w_user_agent:
            client_data = install_w_user_agent[0].client_data
        elif install:
            client_data = install[0].client_data
    except ClientData.DoesNotExist:
        client_data = None

    data = request.POST or None

    # Try to get an existing review of the app by this user if we can.
    filters = dict(addon=addon, user=request.user)
    if addon.is_packaged:
        filters['version'] = addon.current_version

    try:
        existing_review = Review.objects.valid().filter(**filters)[0]
    except IndexError:
        existing_review = None

    # If the user is posting back, try to process the submission.
    if data:
        form = ReviewForm(data)
        if form.is_valid():
            cleaned = form.cleaned_data
            if existing_review:
                # If there's a review to overwrite, overwrite it.
                if (cleaned['body'] != existing_review.body or
                        cleaned['rating'] != existing_review.rating):
                    existing_review.body = cleaned['body']
                    existing_review.rating = cleaned['rating']
                    ip = request.META.get('REMOTE_ADDR', '')
                    existing_review.ip_address = ip
                    if 'flag' in cleaned and cleaned['flag']:
                        existing_review.flag = True
                        existing_review.editorreview = True
                        rf = ReviewFlag(review=existing_review,
                                        user_id=request.user.id,
                                        flag=ReviewFlag.OTHER, note='URLs')
                        rf.save()
                    existing_review.save()

                amo.log(amo.LOG.EDIT_REVIEW, addon, existing_review)
                log.debug('[Review:%s] Edited by %s' % (existing_review.id,
                                                        request.user.id))
                messages.success(request,
                                 _('Your review was updated successfully!'))
            else:
                # If there isn't a review to overwrite, create a new review.
                review = Review.objects.create(client_data=client_data,
                                               **_review_details(
                                                   request, addon, form))
                if 'flag' in cleaned and cleaned['flag']:
                    rf = ReviewFlag(review=review, user_id=request.user.id,
                                    flag=ReviewFlag.OTHER, note='URLs')
                    rf.save()
                amo.log(amo.LOG.ADD_REVIEW, addon, review)
                log.debug('[Review:%s] Created by user %s ' %
                          (review.id, request.user.id))
                messages.success(request,
                                 _('Your review was successfully added!'))
                record_action('new-review', request, {'app-id': addon.id})

            return redirect(addon.get_ratings_url('list'))

        # If the form isn't valid, we've set `form` so that it can be used when
        # the template is rendered below.

    elif existing_review:
        # If the user isn't posting back but has an existing review, populate
        # the form with their existing review and rating.
        form = ReviewForm({'rating': existing_review.rating or 1,
                           'body': existing_review.body})
        has_review = True
    else:
        # If the user isn't posting back and doesn't have an existing review,
        # just show a blank version of the form.
        form = ReviewForm()

    support_email = str(addon.support_email) if addon.support_email else None
    return jingo.render(request, 'ratings/add.html',
                        {'product': addon, 'form': form,
                         'support_url': addon.support_url,
                         'has_review': has_review,
                         'support_email': support_email,
                         'page_parent': addon.get_detail_url() if
                                        not existing_review else ''})