allow user reviews for apps (bug 691623)
This commit is contained in:
Родитель
eb97e0cc18
Коммит
c3ffe47bb1
|
@ -25,7 +25,7 @@ import amo.models
|
|||
import sharing.utils as sharing
|
||||
from amo.decorators import use_master
|
||||
from amo.fields import DecimalCharField
|
||||
from amo.helpers import absolutify
|
||||
from amo.helpers import absolutify, shared_url
|
||||
from amo.utils import (send_mail, urlparams, sorted_groupby, JSONEncoder,
|
||||
slugify, to_language)
|
||||
from amo.urlresolvers import get_outgoing_url, reverse
|
||||
|
@ -408,7 +408,7 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
|
|||
|
||||
@property
|
||||
def reviews_url(self):
|
||||
return reverse('reviews.list', args=[self.slug])
|
||||
return shared_url('reviews.list', self)
|
||||
|
||||
def type_url(self):
|
||||
"""The url for this add-on's AddonType."""
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
data-name="{{ addon.name }}"
|
||||
{{ b.attrs()|xmlattr }}
|
||||
{% if waffle.switch('marketplace') and addon.can_be_purchased() %}
|
||||
data-purchase="{{ addon_url('addons.purchase', addon) }}?"
|
||||
data-start-purchase="{{ addon_url('addons.purchase.start', addon) }}"
|
||||
data-purchase="{{ shared_url('addons.purchase', addon) }}?"
|
||||
data-start-purchase="{{ shared_url('addons.purchase.start', addon) }}"
|
||||
data-cost="{{ addon.premium.get_price() }}"
|
||||
data-login-url="{{ url('users.login_modal') }}"
|
||||
{% endif %}
|
||||
|
@ -63,7 +63,7 @@
|
|||
href="{{ b.addon.get_url_path() }}"
|
||||
data-realurl="{{ link.url }}"
|
||||
{% elif waffle.switch('marketplace') and addon.can_be_purchased() %}
|
||||
href="{{ addon_url('addons.purchase', addon) }}"
|
||||
href="{{ shared_url('addons.purchase', addon) }}"
|
||||
{% if not addon.is_webapp() %}
|
||||
data-realurl="{{ link.url }}"
|
||||
{% endif %}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
{% include "reviews/grouped_ratings.html" %}
|
||||
{% if addon.can_review(amo_user) %}
|
||||
<div>
|
||||
<a class="button" id="add-review" href="{{ url('reviews.add', addon.slug) }}">{{ _('Write a review') }}</a>
|
||||
<a class="button" id="add-review" href="{{ shared_url('reviews.add', addon) }}">{{ _('Write a review') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<a id="report-abuse" href="{{ url('devhub.docs', 'policies', 'contact') }}"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
|
||||
<form disabled method="post" action="{{ url('reviews.add', addon.slug) }}">
|
||||
<form disabled method="post" action="{{ shared_url('reviews.add', addon) }}">
|
||||
{% set attrs = {} if user.is_authenticated() else {'disabled': 'disabled'} %}
|
||||
{{ csrf() }}
|
||||
{{ field(review_form.body, _('Review:'), **attrs) }}
|
||||
|
@ -39,7 +39,7 @@
|
|||
{% endif %}
|
||||
<p><a href="{{ remora_url('/pages/review_guide') }}" target="_blank">{{ _('Review Guidelines') }}</a></p>
|
||||
<p>
|
||||
<a href="{{ url('reviews.add', addon.slug) }}">
|
||||
<a href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Detailed Review') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
{{ _('This add-on has not yet been reviewed.') }}
|
||||
{% endif %}
|
||||
{% if addon.can_review(amo_user) %}
|
||||
<a id="add-first-review" href="{{ url('reviews.add', addon.slug) }}">
|
||||
<a id="add-first-review" href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Be the first!') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
{% else %}
|
||||
<h4>{{ _('Payment completed') }}</h4>
|
||||
{% if addon.is_premium() %}
|
||||
<a href="{{ addon_url('addons.purchase.thanks', addon)|urlparams(realurl=realurl) }}"
|
||||
<a href="{{ shared_url('addons.purchase.thanks', addon)|urlparams(realurl=realurl) }}"
|
||||
id="paypal-thanks">{{ _('Thank you for purchasing the add-on') }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<p><a id="paypal-result" target="_top" href="{{ addon_url('addons.detail', addon) }}">{{ _('Return to the addon.') }}</a></p>
|
||||
<p><a id="paypal-result" target="_top" href="{{ shared_url('addons.detail', addon) }}">{{ _('Return to the addon.') }}</a></p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
{% endtrans %}
|
||||
</div>
|
||||
<button class="button prominent paypal"
|
||||
href="{{ addon_url('addons.purchase', addon) }}?"
|
||||
href="{{ shared_url('addons.purchase', addon) }}?"
|
||||
data-realurl="{{ download }}">
|
||||
{# The <small> makes it smaller, <em> makes it darker. Don't localize "PayPal". #}
|
||||
{{ _('Pay <small>with</small> Pay<em>Pal</em>') }}
|
||||
|
@ -49,7 +49,7 @@
|
|||
<p>{{ _('Complete your purchase with PayPal. No account necessary.') }}</p>
|
||||
{% else %}
|
||||
<div class="paypal-user login">
|
||||
{% with is_ajax=False, action="%s?realurl=%s" % (addon_url('addons.purchase.start', addon), download) %}
|
||||
{% with is_ajax=False, action="%s?realurl=%s" % (shared_url('addons.purchase.start', addon), download) %}
|
||||
{% include "users/login_form.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
addon.created|datetime(dt)) }}
|
||||
</p>
|
||||
{% if addon.total_reviews %}
|
||||
<a href="{{ url('reviews.list', addon.slug) }}">
|
||||
<a href="{{ shared_url('reviews.list', addon) }}">
|
||||
{{ addon.average_rating|float|stars }}
|
||||
{{ addon.total_reviews }}</a>
|
||||
{% else %}
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
</div>
|
||||
{# Building a url with a fake addon that's replaced with a js placeholder? Sketchy. #}
|
||||
<p class="older-versions">{% trans href=remora_url('/addons/versions/xxx')|replace('xxx', '{addon}') %}
|
||||
{# <p class="older-versions">{% trans href=url('reviews.list', 000)|replace(000, '{addon}') %} #}
|
||||
{# <p class="older-versions">{% trans href=url('addons.reviews.list', 000)|replace(000, '{addon}') %} #}
|
||||
or view <a href="{{ href }}">older versions of this add-on</a>.
|
||||
{% endtrans %}</p>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form method="post" action="{{ addon_url('addons.abuse', addon) }}">
|
||||
<form method="post" action="{{ shared_url('addons.abuse', addon) }}">
|
||||
<fieldset class="abuse">
|
||||
{% if hide %}
|
||||
<legend><a href="{{ url('devhub.docs', 'policies', 'contact') }}"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
|
||||
<form disabled method="post" action="{{ url('reviews.add', addon.slug) }}">
|
||||
<form disabled method="post" action="{{ shared_url('reviews.add', addon) }}">
|
||||
{% set attrs = {} if user.is_authenticated() else {'disabled': 'disabled'} %}
|
||||
{{ csrf() }}
|
||||
{{ field(review_form.body, _('Review:'), **attrs) }}
|
||||
|
@ -37,7 +37,7 @@
|
|||
{% endif %}
|
||||
<p><a href="{{ remora_url('/pages/review_guide') }}" target="_blank">{{ _('Review Guidelines') }}</a></p>
|
||||
<p>
|
||||
<a href="{{ url('reviews.add', addon.slug) }}">
|
||||
<a href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Detailed Review') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
{% endfor %}
|
||||
{% if addon %}
|
||||
<p>
|
||||
<a class="more-info" href="{{ url('reviews.list', addon.slug) }}">
|
||||
<a class="more-info" href="{{ shared_url('reviews.list', addon) }}">
|
||||
{% trans num=addon.total_reviews, cnt=addon.total_reviews|numberfmt %}
|
||||
See all reviews of this add-on
|
||||
{% pluralize %}
|
||||
|
|
|
@ -21,7 +21,7 @@ import waffle
|
|||
|
||||
import amo
|
||||
import amo.tests
|
||||
from amo.helpers import absolutify, numberfmt, urlparams, addon_url
|
||||
from amo.helpers import absolutify, numberfmt, urlparams, shared_url
|
||||
from amo.tests import addon_factory
|
||||
from amo.tests.test_helpers import get_image_path
|
||||
from amo.urlresolvers import reverse
|
||||
|
@ -450,7 +450,7 @@ class TestPaypalStart(amo.tests.TestCase):
|
|||
self.data = {'username': 'jbalogh@mozilla.com',
|
||||
'password': 'foo'}
|
||||
self.addon = Addon.objects.all()[0]
|
||||
self.url = addon_url('addons.purchase.start', self.addon)
|
||||
self.url = shared_url('addons.purchase.start', self.addon)
|
||||
self.addon, self.price = setup_premium(self.addon)
|
||||
|
||||
def test_loggedout_purchased(self):
|
||||
|
@ -919,7 +919,8 @@ class TestDetailPage(amo.tests.TestCase):
|
|||
r = self.client.get(reverse('addons.detail', args=['a3615']))
|
||||
doc = pq(r.content)
|
||||
href = doc('#review-box a[href*="reviews/add"]').attr('href')
|
||||
assert href.endswith(reverse('reviews.add', args=['a3615'])), href
|
||||
assert href.endswith(reverse('addons.reviews.add', args=['a3615'])), (
|
||||
href)
|
||||
|
||||
def test_no_listed_authors(self):
|
||||
r = self.client.get(reverse('addons.detail', args=['a59']))
|
||||
|
@ -1520,8 +1521,8 @@ class TestReportAbuse(amo.tests.TestCase):
|
|||
assert AbuseReport.objects.get(addon=addon)
|
||||
|
||||
def test_abuse_persona(self):
|
||||
addon_url = reverse('addons.detail', args=['a15663'])
|
||||
r = self.client.get(addon_url)
|
||||
shared_url = reverse('addons.detail', args=['a15663'])
|
||||
r = self.client.get(shared_url)
|
||||
doc = pq(r.content)
|
||||
assert doc("fieldset.abuse")
|
||||
|
||||
|
@ -1529,7 +1530,7 @@ class TestReportAbuse(amo.tests.TestCase):
|
|||
self.client.login(username='regular@mozilla.com', password='password')
|
||||
r = self.client.post(reverse('addons.abuse', args=['a15663']),
|
||||
{'text': 'spammy'})
|
||||
self.assertRedirects(r, addon_url)
|
||||
self.assertRedirects(r, shared_url)
|
||||
eq_(len(mail.outbox), 1)
|
||||
assert 'spammy' in mail.outbox[0].body
|
||||
assert AbuseReport.objects.get(addon=15663)
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.conf.urls.defaults import patterns, url, include
|
|||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from reviews.urls import review_patterns
|
||||
from . import views
|
||||
|
||||
ADDON_ID = r"""(?P<addon_id>[^/<>"']+)"""
|
||||
|
@ -41,7 +42,7 @@ detail_patterns = patterns('',
|
|||
addon_id, permanent=True),
|
||||
name='addons.about'),
|
||||
|
||||
('^reviews/', include('reviews.urls')),
|
||||
('^reviews/', include(review_patterns('addons'))),
|
||||
('^statistics/', include('stats.urls')),
|
||||
('^versions/', include('versions.urls')),
|
||||
)
|
||||
|
|
|
@ -89,19 +89,31 @@ def url(viewname, *args, **kwargs):
|
|||
|
||||
|
||||
@register.function
|
||||
def addon_url(viewname, addon, *args, **kwargs):
|
||||
def shared_url(viewname, addon, *args, **kwargs):
|
||||
"""
|
||||
Helper specifically for addons or apps to get urls. Requires
|
||||
the viewname, addon (or app). It's assumed that we'll pass the
|
||||
slug into the args and we'll look up the right slug (addon or app)
|
||||
for you.
|
||||
|
||||
Viewname should be a normal view eg: addons.details or apps.details,
|
||||
this will flip the first part for you. eg: addons.details > apps.details.
|
||||
Viewname should be a normal view eg: `addons.details` or `apps.details`.
|
||||
`addons.details` becomes `apps.details`, if we've passed an app, etc.
|
||||
|
||||
A viewname such as `details` becomes `addons.details` or `apps.details`,
|
||||
depending on the add-on type.
|
||||
"""
|
||||
slug = addon.app_slug if addon.is_webapp() else addon.slug
|
||||
prefix = 'apps' if addon.is_webapp() else 'addons'
|
||||
viewname = '%s.%s' % (prefix, viewname.split('.', 1)[-1])
|
||||
|
||||
namespace, dot, latter = viewname.partition('.')
|
||||
|
||||
# If `viewname` is prefixed with `addons.` but we're linking to a
|
||||
# webapp, the `viewname` magically gets prefixed with `apps.`.
|
||||
if namespace in ('addons', 'apps'):
|
||||
viewname = latter
|
||||
|
||||
# Otherwise, we just slap the appropriate prefix in front of `viewname`.
|
||||
viewname = '.'.join([prefix, viewname])
|
||||
return url(viewname, *([slug] + list(args)), **kwargs)
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ def test_urlparams_unicode():
|
|||
utils.urlparams(url)
|
||||
|
||||
|
||||
class TestAddonURL(amo.tests.TestCase):
|
||||
class TestSharedURL(amo.tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.webapp = Mock()
|
||||
|
@ -220,16 +220,26 @@ class TestAddonURL(amo.tests.TestCase):
|
|||
self.addon.is_webapp.return_value = False
|
||||
|
||||
def test_appurl(self):
|
||||
eq_(helpers.addon_url('addons.detail', self.webapp),
|
||||
'/en-US/apps/app/webapp/')
|
||||
eq_(helpers.addon_url('apps.detail', self.webapp),
|
||||
'/en-US/apps/app/webapp/')
|
||||
expected = '/en-US/apps/app/webapp/'
|
||||
eq_(helpers.shared_url('addons.detail', self.webapp), expected)
|
||||
eq_(helpers.shared_url('apps.detail', self.webapp), expected)
|
||||
eq_(helpers.shared_url('detail', self.webapp), expected)
|
||||
eq_(helpers.shared_url('detail', self.webapp, add_prefix=False),
|
||||
'/apps/app/webapp/')
|
||||
eq_(helpers.shared_url('reviews.detail', self.webapp, 1,
|
||||
add_prefix=False),
|
||||
'/apps/app/webapp/reviews/1/')
|
||||
|
||||
def test_addonurl(self):
|
||||
eq_(helpers.addon_url('addons.detail', self.addon),
|
||||
'/en-US/firefox/addon/addon/')
|
||||
eq_(helpers.addon_url('apps.detail', self.addon),
|
||||
'/en-US/firefox/addon/addon/')
|
||||
expected = '/en-US/firefox/addon/addon/'
|
||||
eq_(helpers.shared_url('addons.detail', self.addon), expected)
|
||||
eq_(helpers.shared_url('apps.detail', self.addon), expected)
|
||||
eq_(helpers.shared_url('detail', self.addon), expected)
|
||||
eq_(helpers.shared_url('detail', self.addon, add_prefix=False),
|
||||
'/addon/addon/')
|
||||
eq_(helpers.shared_url('reviews.detail', self.addon, 1,
|
||||
add_prefix=False),
|
||||
'/addon/addon/reviews/1/')
|
||||
|
||||
|
||||
def test_isotime():
|
||||
|
|
|
@ -825,7 +825,7 @@ class TestModeratedQueue(QueueTest):
|
|||
|
||||
def setUp(self):
|
||||
self.url = reverse('editors.queue_moderated')
|
||||
url_flag = reverse('reviews.flag', args=['a1865', 218468])
|
||||
url_flag = reverse('addons.reviews.flag', args=['a1865', 218468])
|
||||
|
||||
self.login_as_editor()
|
||||
response = self.client.post(url_flag, {'flag': ReviewFlag.SPAM})
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.shortcuts import get_object_or_404
|
|||
from tower import ugettext as _
|
||||
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.helpers import absolutify, url
|
||||
from amo.helpers import absolutify, shared_url, url
|
||||
|
||||
from addons.models import Addon, Review
|
||||
|
||||
|
@ -40,8 +40,7 @@ class ReviewsRss(Feed):
|
|||
|
||||
def item_link(self, review):
|
||||
"""Link for a particular review (<item><link>)"""
|
||||
return absolutify(reverse('reviews.detail', args=[self.addon.slug,
|
||||
review.id]))
|
||||
return absolutify(shared_url('reviews.detail', self.addon, review.id))
|
||||
|
||||
def item_title(self, review):
|
||||
"""Title for particular review (<item><title>)"""
|
||||
|
@ -60,7 +59,7 @@ class ReviewsRss(Feed):
|
|||
|
||||
def item_guid(self, review):
|
||||
"""Guid for a particuar review (<item><guid>)"""
|
||||
guid_url = absolutify(reverse('reviews.list', args=[self.addon.slug]))
|
||||
guid_url = absolutify(shared_url('reviews.list', self.addon))
|
||||
return guid_url + urllib.quote(str(review.id))
|
||||
|
||||
def item_author_name(self, review):
|
||||
|
|
|
@ -9,6 +9,7 @@ from celeryutils import task
|
|||
from tower import ugettext_lazy as _
|
||||
|
||||
import amo.models
|
||||
from amo.helpers import shared_url
|
||||
from amo.urlresolvers import reverse
|
||||
from translations.fields import TranslatedField
|
||||
from users.models import UserProfile
|
||||
|
@ -57,7 +58,7 @@ class Review(amo.models.ModelBase):
|
|||
ordering = ('-created',)
|
||||
|
||||
def get_url_path(self):
|
||||
return reverse('reviews.detail', args=[self.addon_id, self.id])
|
||||
return shared_url('reviews.detail', self.addon, self.id)
|
||||
|
||||
def flush_urls(self):
|
||||
urls = ['*/addon/%d/' % self.addon_id,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "impala/base.html" %}
|
||||
{% extends "impala/base_shared.html" %}
|
||||
{% from 'includes/forms.html' import pretty_field, required_note %}
|
||||
|
||||
{% set title = _('Add a review for {0}')|f(addon.name) %}
|
||||
|
@ -76,7 +76,7 @@
|
|||
{% endif %}
|
||||
</fieldset>
|
||||
<form method="post" class="review-form" id="review-form"
|
||||
action="{{ url('reviews.add', addon.slug) }}">
|
||||
action="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ csrf() }}
|
||||
<fieldset>
|
||||
<ul>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% set base = url('addons.detail', addon.slug)|urlparams('reviews') %}
|
||||
{% set base = addon.get_url_path()|urlparams('reviews') %}
|
||||
{% if collection_uuid %}
|
||||
{% set base = base|urlparams(collection_uuid=collection_uuid) %}
|
||||
{% endif %}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
{% if not amo_user %}
|
||||
<h2 id="add-review">{{ _('Add a Review') }}</h2>
|
||||
<section class="copy">
|
||||
<a href="{{ url('reviews.add', addon.slug) }}" class="login-button button">{{ _('Log in to add a review') }}</a>
|
||||
<a href="{{ shared_url('reviews.add', addon) }}" class="login-button button">{{ _('Log in to add a review') }}</a>
|
||||
</section>
|
||||
{% elif addon.can_review(amo_user) %}
|
||||
<h2 id="add-review">{{ _('Add a Review') }}</h2>
|
||||
<form method="post" class="form-mobile review-form" id="review-form"
|
||||
action="{{ url('reviews.add', addon.slug) }}">
|
||||
action="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ csrf() }}
|
||||
<p>
|
||||
<label for="id_title">{{ _('Title:') }} <span class="optional">{{ _('(optional)') }}</span></label>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% set amo_user = request.amo_user if request and request.user.is_authenticated() else None %}
|
||||
{% if addon.total_reviews %}
|
||||
<a class="listview" href="{{ url('reviews.list', addon.slug) }}">
|
||||
<a class="listview" href="{{ shared_url('reviews.list', addon) }}">
|
||||
<div class="icon">
|
||||
{{ addon.average_rating|stars }}
|
||||
</div>
|
||||
|
@ -11,6 +11,6 @@
|
|||
{% endtrans %}
|
||||
</a>
|
||||
{% elif addon.can_review(amo_user) %}
|
||||
<a class="listview" id="add-review" href="{{ url('reviews.add', addon.slug) }}">
|
||||
<a class="listview" id="add-review" href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Be the first to write a review.') }}</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "impala/base.html" %}
|
||||
{% extends "impala/base_shared.html" %}
|
||||
{% from 'includes/forms.html' import pretty_field, required_note %}
|
||||
|
||||
{% set title = _('Reply to review by {0}')|f(review.user.name) %}
|
||||
|
@ -22,7 +22,7 @@
|
|||
<div class="primary island hero" id="reviews">
|
||||
{% include "reviews/review.html" %}
|
||||
<form method="post" class="prettyform c"
|
||||
action="{{ url('reviews.reply', addon.slug, review.id) }}">
|
||||
action="{{ shared_url('reviews.reply', addon, review.id) }}">
|
||||
{{ csrf() }}
|
||||
<fieldset>
|
||||
<h2>{{ _('Write a Reply') }}</h2>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<span>[{{ review.ip_address }}]</span>
|
||||
{% endif %}
|
||||
<a class="permalink"
|
||||
href="{{ url('reviews.detail', addon.slug, review.id) }}">#</a>
|
||||
href="{{ shared_url('reviews.detail', addon, review.id) }}">#</a>
|
||||
</p>
|
||||
<p class="description">{{ review.body|nl2br }}</p>
|
||||
{% if outdated and not is_reply %}
|
||||
|
@ -45,7 +45,7 @@
|
|||
{% endif %}
|
||||
{% if page != 'user' and review.previous_count %}
|
||||
<span class="item-note">
|
||||
{% with user_review_url = url('reviews.user', addon.slug, review.user.id) %}
|
||||
{% with user_review_url = shared_url('reviews.user', addon, review.user.id) %}
|
||||
{% if review.is_latest %}
|
||||
{% trans num=review.previous_count, cnt=review.previous_count|numberfmt %}
|
||||
This user has a <a href="{{ user_review_url }}">previous review</a> of this add-on.
|
||||
|
@ -66,13 +66,13 @@
|
|||
<li class="flagged">{{ _('Flagged for review') }}</li>
|
||||
{% elif review.user_id != request.user.id %}
|
||||
<li>
|
||||
<a class="flag-review" href="{{ url('reviews.flag', addon.slug, review.id) }}">
|
||||
<a class="flag-review" href="{{ shared_url('reviews.flag', addon, review.id) }}">
|
||||
{{ _('Report this review') }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if not (is_reply or has_reply) and (perms.is_author or perms.is_admin) %}
|
||||
<li>
|
||||
<a class="review-delete" href="{{ url('reviews.reply', addon.slug, review.id) }}">
|
||||
<a class="review-delete" href="{{ shared_url('reviews.reply', addon, review.id) }}">
|
||||
{{ _('Reply to review') }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
@ -84,7 +84,7 @@
|
|||
{% endif %}
|
||||
{% if perms.can_delete %}
|
||||
<li>
|
||||
<a class="delete-review" href="{{ url('reviews.delete', addon.slug, review.id) }}">
|
||||
<a class="delete-review" href="{{ shared_url('reviews.delete', addon, review.id) }}">
|
||||
{{ _('Delete review') }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "impala/base.html" %}
|
||||
{% extends "impala/base_shared.html" %}
|
||||
{% set amo_user = request.amo_user if request.user.is_authenticated() else None %}
|
||||
|
||||
{# L10n: {0} is an add-on name. #}
|
||||
|
@ -73,7 +73,7 @@
|
|||
</section>
|
||||
<section>
|
||||
{% if amo_user and addon.can_review(amo_user) %}
|
||||
<a class="button" id="add-review" href="{{ url('reviews.add', addon.slug) }}">
|
||||
<a class="button" id="add-review" href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Write a New Review') }}</a>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
@ -82,7 +82,7 @@
|
|||
{% block review_list %}
|
||||
{% if not reviews.object_list %}
|
||||
{% if addon.can_review(amo_user) %}
|
||||
<p id="add-first-review"><a href="{{ url('reviews.add', addon.slug) }}">
|
||||
<p id="add-first-review"><a href="{{ shared_url('reviews.add', addon) }}">
|
||||
{{ _('Be the first to write a review.') }}</a><p>
|
||||
{% else %}
|
||||
<p id="no-add-first-review">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% if link_to_list %}
|
||||
{% set base = url('reviews.list', addon.slug) %}
|
||||
{% set base = shared_url('reviews.list', addon) %}
|
||||
{% else %}
|
||||
{% set base = url('addons.detail', addon.slug)|urlparams('reviews') %}
|
||||
{% set base = addon.get_url_path()|urlparams('reviews') %}
|
||||
{% if collection_uuid %}
|
||||
{% set base = base|urlparams(collection_uuid=collection_uuid) %}
|
||||
{% endif %}
|
||||
|
|
|
@ -54,7 +54,7 @@ def test_reviews_link():
|
|||
eq_(pq(s)('strong').text(), 'Not yet rated')
|
||||
|
||||
# with link
|
||||
u = reverse('reviews.list', args=['xx'])
|
||||
u = reverse('addons.reviews.list', args=['xx'])
|
||||
s = render('{{ reviews_link(myaddon, link_to_list=True) }}',
|
||||
{'myaddon': a})
|
||||
eq_(pq(s)('a').attr('href'), u)
|
||||
|
@ -66,9 +66,9 @@ def test_mobile_reviews_link():
|
|||
|
||||
a = Addon(total_reviews=0, id=1, type=1, slug='xx')
|
||||
doc = s(a)
|
||||
eq_(doc('a').attr('href'), reverse('reviews.add', args=['xx']))
|
||||
eq_(doc('a').attr('href'), reverse('addons.reviews.add', args=['xx']))
|
||||
|
||||
u = reverse('reviews.list', args=['xx'])
|
||||
u = reverse('addons.reviews.list', args=['xx'])
|
||||
|
||||
a = Addon(average_rating=4, total_reviews=37, id=1, type=1, slug='xx')
|
||||
doc = s(a)
|
||||
|
|
|
@ -5,6 +5,7 @@ from pyquery import PyQuery as pq
|
|||
|
||||
import amo.tests
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.helpers import shared_url
|
||||
from access.models import GroupUser
|
||||
from addons.models import Addon
|
||||
from devhub.models import ActivityLog
|
||||
|
@ -15,6 +16,9 @@ from users.models import UserProfile
|
|||
class ReviewTest(amo.tests.TestCase):
|
||||
fixtures = ['base/apps', 'reviews/dev-reply.json', 'base/admin']
|
||||
|
||||
def setUp(self):
|
||||
self.addon = Addon.objects.get(id=1865)
|
||||
|
||||
def login_dev(self):
|
||||
self.client.login(username='trev@adblockplus.org', password='password')
|
||||
|
||||
|
@ -30,34 +34,35 @@ class ReviewTest(amo.tests.TestCase):
|
|||
class TestViews(ReviewTest):
|
||||
|
||||
def test_dev_reply(self):
|
||||
url = reverse('reviews.detail', args=['a1865', 218468])
|
||||
url = shared_url('reviews.detail', self.addon, 218468)
|
||||
r = self.client.get(url)
|
||||
eq_(r.status_code, 200)
|
||||
|
||||
def test_404_user_page(self):
|
||||
url = reverse('reviews.user', args=['a1865', 233452342])
|
||||
url = shared_url('reviews.user', self.addon, 233452342)
|
||||
r = self.client.get(url)
|
||||
eq_(r.status_code, 404)
|
||||
|
||||
def test_feed(self):
|
||||
url = reverse('reviews.list.rss', args=['a1865'])
|
||||
url = shared_url('reviews.list.rss', self.addon)
|
||||
r = self.client.get(url)
|
||||
eq_(r.status_code, 200)
|
||||
|
||||
def test_abuse_form(self):
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
self.assertTemplateUsed(r, 'reviews/report_review.html')
|
||||
r = self.client.get(reverse('reviews.detail', args=['a1865', 218468]))
|
||||
r = self.client.get(shared_url('reviews.detail', self.addon,
|
||||
218468))
|
||||
self.assertTemplateUsed(r, 'reviews/report_review.html')
|
||||
|
||||
def test_edit_review_form(self):
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
self.assertTemplateUsed(r, 'reviews/edit_review.html')
|
||||
r = self.client.get(reverse('reviews.detail', args=['a1865', 218468]))
|
||||
r = self.client.get(shared_url('reviews.detail', self.addon, 218468))
|
||||
self.assertTemplateUsed(r, 'reviews/edit_review.html')
|
||||
|
||||
def test_list(self):
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
reviews = doc('#reviews .item')
|
||||
|
@ -84,7 +89,7 @@ class TestViews(ReviewTest):
|
|||
def test_empty_list(self):
|
||||
Review.objects.all().delete()
|
||||
eq_(Review.objects.count(), 0)
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
eq_(doc('#reviews .item').length, 0)
|
||||
|
@ -95,7 +100,7 @@ class TestViews(ReviewTest):
|
|||
def test_list_item_actions(self):
|
||||
self.login_admin()
|
||||
self.make_it_my_review()
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
reviews = pq(r.content)('#reviews .item')
|
||||
|
||||
r = Review.objects.get(id=218207)
|
||||
|
@ -116,7 +121,8 @@ class TestViews(ReviewTest):
|
|||
class TestFlag(ReviewTest):
|
||||
|
||||
def setUp(self):
|
||||
self.url = reverse('reviews.flag', args=['a1865', 218468])
|
||||
super(TestFlag, self).setUp()
|
||||
self.url = shared_url('reviews.flag', self.addon, 218468)
|
||||
self.login_admin()
|
||||
|
||||
def test_no_login(self):
|
||||
|
@ -168,7 +174,8 @@ class TestFlag(ReviewTest):
|
|||
class TestDelete(ReviewTest):
|
||||
|
||||
def setUp(self):
|
||||
self.url = reverse('reviews.delete', args=['a1865', 218207])
|
||||
super(TestDelete, self).setUp()
|
||||
self.url = shared_url('reviews.delete', self.addon, 218207)
|
||||
self.login_admin()
|
||||
|
||||
def test_no_login(self):
|
||||
|
@ -182,7 +189,7 @@ class TestDelete(ReviewTest):
|
|||
eq_(response.status_code, 403)
|
||||
|
||||
def test_404(self):
|
||||
url = reverse('reviews.delete', args=['a1865', 0])
|
||||
url = shared_url('reviews.delete', self.addon, 0)
|
||||
response = self.client.post(url)
|
||||
eq_(response.status_code, 404)
|
||||
|
||||
|
@ -204,14 +211,14 @@ class TestDelete(ReviewTest):
|
|||
class TestCreate(ReviewTest):
|
||||
|
||||
def setUp(self):
|
||||
self.addon = Addon.objects.get(slug='a1865')
|
||||
self.add = reverse('reviews.add', args=[self.addon.slug])
|
||||
super(TestCreate, self).setUp()
|
||||
self.add = shared_url('reviews.add', self.addon)
|
||||
self.client.login(username='root_x@ukr.net', password='password')
|
||||
self.user = UserProfile.objects.get(email='root_x@ukr.net')
|
||||
self.qs = Review.objects.filter(addon=1865)
|
||||
self.log_count = ActivityLog.objects.count
|
||||
self.more = reverse('addons.detail_more', args=['a1865'])
|
||||
self.list = reverse('reviews.list', args=['a1865'])
|
||||
self.more = self.addon.get_url_path(more=True)
|
||||
self.list = shared_url('reviews.list', self.addon)
|
||||
|
||||
def test_add_logged(self):
|
||||
r = self.client.get(self.add)
|
||||
|
@ -242,7 +249,7 @@ class TestCreate(ReviewTest):
|
|||
old_cnt = self.qs.count()
|
||||
log_count = self.log_count()
|
||||
r = self.client.post(self.add, {'body': 'xx', 'rating': 3})
|
||||
self.assertRedirects(r, reverse('reviews.list', args=['a1865']),
|
||||
self.assertRedirects(r, shared_url('reviews.list', self.addon),
|
||||
status_code=302)
|
||||
eq_(self.qs.count(), old_cnt + 1)
|
||||
# We should have an ADD_REVIEW entry now.
|
||||
|
@ -256,10 +263,10 @@ class TestCreate(ReviewTest):
|
|||
def test_new_reply(self):
|
||||
self.login_dev()
|
||||
Review.objects.filter(reply_to__isnull=False).delete()
|
||||
url = reverse('reviews.reply', args=['a1865', 218207])
|
||||
url = shared_url('reviews.reply', self.addon, 218207)
|
||||
r = self.client.post(url, {'body': 'unst unst'})
|
||||
self.assertRedirects(r,
|
||||
reverse('reviews.detail', args=['a1865', 218207]))
|
||||
shared_url('reviews.detail', self.addon, 218207))
|
||||
eq_(self.qs.filter(reply_to=218207).count(), 1)
|
||||
|
||||
eq_(len(mail.outbox), 1)
|
||||
|
@ -267,10 +274,10 @@ class TestCreate(ReviewTest):
|
|||
|
||||
def test_double_reply(self):
|
||||
self.login_dev()
|
||||
url = reverse('reviews.reply', args=['a1865', 218207])
|
||||
url = shared_url('reviews.reply', self.addon, 218207)
|
||||
r = self.client.post(url, {'body': 'unst unst'})
|
||||
self.assertRedirects(r,
|
||||
reverse('reviews.detail', args=['a1865', 218207]))
|
||||
shared_url('reviews.detail', self.addon, 218207))
|
||||
eq_(self.qs.filter(reply_to=218207).count(), 1)
|
||||
review = Review.objects.get(id=218468)
|
||||
eq_('%s' % review.body, 'unst unst')
|
||||
|
@ -296,7 +303,7 @@ class TestCreate(ReviewTest):
|
|||
self.client.logout()
|
||||
r = self.client.get_ajax(self.more)
|
||||
eq_(pq(r.content)('#add-review').length, 1)
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
doc = pq(r.content)
|
||||
eq_(doc('#add-review').length, 0)
|
||||
eq_(doc('#add-first-review').length, 0)
|
||||
|
@ -315,7 +322,7 @@ class TestCreate(ReviewTest):
|
|||
self.login_dev()
|
||||
r = self.client.get_ajax(self.more)
|
||||
eq_(pq(r.content)('#add-review').length, 0)
|
||||
r = self.client.get(reverse('reviews.list', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.list', self.addon))
|
||||
doc = pq(r.content)
|
||||
eq_(doc('#add-review').length, 0)
|
||||
eq_(doc('#add-first-review').length, 0)
|
||||
|
@ -421,24 +428,25 @@ class TestCreate(ReviewTest):
|
|||
class TestEdit(ReviewTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestEdit, self).setUp()
|
||||
self.client.login(username='root_x@ukr.net', password='password')
|
||||
|
||||
def test_edit(self):
|
||||
url = reverse('reviews.edit', args=['a1865', 218207])
|
||||
url = shared_url('reviews.edit', self.addon, 218207)
|
||||
r = self.client.post(url, {'rating': 2, 'body': 'woo woo'},
|
||||
X_REQUESTED_WITH='XMLHttpRequest')
|
||||
eq_(r.status_code, 200)
|
||||
eq_('%s' % Review.objects.get(id=218207).body, 'woo woo')
|
||||
|
||||
def test_edit_not_owner(self):
|
||||
url = reverse('reviews.edit', args=['a1865', 218468])
|
||||
url = shared_url('reviews.edit', self.addon, 218468)
|
||||
r = self.client.post(url, {'rating': 2, 'body': 'woo woo'},
|
||||
X_REQUESTED_WITH='XMLHttpRequest')
|
||||
eq_(r.status_code, 403)
|
||||
|
||||
def test_edit_reply(self):
|
||||
self.login_dev()
|
||||
url = reverse('reviews.edit', args=['a1865', 218468])
|
||||
url = shared_url('reviews.edit', self.addon, 218468)
|
||||
r = self.client.post(url, {'title': 'fo', 'body': 'shizzle'},
|
||||
X_REQUESTED_WITH='XMLHttpRequest')
|
||||
eq_(r.status_code, 200)
|
||||
|
@ -452,12 +460,11 @@ class TestMobileReviews(amo.tests.MobileTest, amo.tests.TestCase):
|
|||
'base/users']
|
||||
|
||||
def setUp(self):
|
||||
super(TestMobileReviews, self).setUp()
|
||||
self.addon = Addon.objects.get(id=1865)
|
||||
self.user = UserProfile.objects.get(email='regular@mozilla.com')
|
||||
self.login_regular()
|
||||
self.add = reverse('reviews.add', args=['a1865'])
|
||||
self.list = reverse('reviews.list', args=['a1865'])
|
||||
self.add = shared_url('reviews.add', self.addon)
|
||||
self.list = shared_url('reviews.list', self.addon)
|
||||
|
||||
def login_regular(self):
|
||||
self.client.login(username='regular@mozilla.com', password='password')
|
||||
|
@ -544,5 +551,5 @@ class TestMobileReviews(amo.tests.MobileTest, amo.tests.TestCase):
|
|||
def test_add_logged_out(self):
|
||||
self.client.logout()
|
||||
self.mobile_init()
|
||||
r = self.client.get(reverse('reviews.add', args=['a1865']))
|
||||
r = self.client.get(shared_url('reviews.add', self.addon))
|
||||
eq_(r.status_code, 302)
|
||||
|
|
|
@ -3,19 +3,23 @@ from reviews.feeds import ReviewsRss
|
|||
from . import views
|
||||
|
||||
|
||||
# These all start with /addon/:id/reviews/:review_id/.
|
||||
detail_patterns = patterns('',
|
||||
url('^$', views.review_list, name='reviews.detail'),
|
||||
url('^reply$', views.reply, name='reviews.reply'),
|
||||
url('^flag$', views.flag, name='reviews.flag'),
|
||||
url('^delete$', views.delete, name='reviews.delete'),
|
||||
url('^edit$', views.edit, name='reviews.edit'),
|
||||
)
|
||||
def review_detail_patterns(prefix):
|
||||
# These all start with /addon/:id/reviews/:review_id/.
|
||||
return patterns('',
|
||||
url('^$', views.review_list, name='%s.reviews.detail' % prefix),
|
||||
url('^reply$', views.reply, name='%s.reviews.reply' % prefix),
|
||||
url('^flag$', views.flag, name='%s.reviews.flag' % prefix),
|
||||
url('^delete$', views.delete, name='%s.reviews.delete' % prefix),
|
||||
url('^edit$', views.edit, name='%s.reviews.edit' % prefix),
|
||||
)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url('^$', views.review_list, name='reviews.list'),
|
||||
url('^add$', views.add, name='reviews.add'),
|
||||
url('^(?P<review_id>\d+)/', include(detail_patterns)),
|
||||
url('^format:rss$', ReviewsRss(), name='reviews.list.rss'),
|
||||
url('^user:(?P<user_id>\d+)$', views.review_list, name='reviews.user'),
|
||||
)
|
||||
|
||||
def review_patterns(prefix):
|
||||
return patterns('',
|
||||
url('^$', views.review_list, name='%s.reviews.list' % prefix),
|
||||
url('^add$', views.add, name='%s.reviews.add' % prefix),
|
||||
url('^(?P<review_id>\d+)/', include(review_detail_patterns(prefix))),
|
||||
url('^format:rss$', ReviewsRss(), name='%s.reviews.list.rss' % prefix),
|
||||
url('^user:(?P<user_id>\d+)$', views.review_list,
|
||||
name='%s.reviews.user' % prefix),
|
||||
)
|
||||
|
|
|
@ -7,9 +7,10 @@ import jingo
|
|||
from tower import ugettext as _
|
||||
from mobility.decorators import mobile_template
|
||||
|
||||
import amo
|
||||
from amo import messages
|
||||
from amo.decorators import json_view, login_required, post_required
|
||||
from amo.helpers import absolutify
|
||||
from amo.helpers import absolutify, shared_url
|
||||
from amo.urlresolvers import reverse
|
||||
import amo.utils
|
||||
from access import acl
|
||||
|
@ -150,18 +151,18 @@ def reply(request, addon, review_id):
|
|||
log.debug('%s reply to %s: %s' % (action, review_id, reply.id))
|
||||
|
||||
if new:
|
||||
reply_url = shared_url('reviews.detail', addon, review.id,
|
||||
add_prefix=False)
|
||||
data = {'name': addon.name,
|
||||
'reply_title': reply.title,
|
||||
'reply': reply.body,
|
||||
'reply_url': absolutify(reverse('reviews.detail',
|
||||
args=[addon.slug, review.id],
|
||||
add_prefix=False))}
|
||||
'reply_url': absolutify(reply_url)}
|
||||
emails = [review.user.email]
|
||||
sub = u'Mozilla Add-on Developer Reply: %s' % addon.name
|
||||
send_mail('reviews/emails/reply_review.ltxt',
|
||||
sub, emails, Context(data), 'reply')
|
||||
|
||||
return redirect('reviews.detail', addon.slug, review_id)
|
||||
return redirect(shared_url('reviews.detail', addon, review_id))
|
||||
ctx = dict(review=review, form=form, addon=addon)
|
||||
return jingo.render(request, 'reviews/reply.html', ctx)
|
||||
|
||||
|
@ -180,18 +181,19 @@ def add(request, addon, template=None):
|
|||
amo.log(amo.LOG.ADD_REVIEW, addon, review)
|
||||
log.debug('New review: %s' % review.id)
|
||||
|
||||
reply_url = shared_url('reviews.reply', addon, review.id,
|
||||
add_prefix=False)
|
||||
data = {'name': addon.name,
|
||||
'rating': '%s out of 5 stars' % details['rating'],
|
||||
'review': details['body'],
|
||||
'reply_url': absolutify(reverse('reviews.reply',
|
||||
args=[addon.slug, review.id], add_prefix=False))}
|
||||
'reply_url': absolutify(reply_url)}
|
||||
|
||||
emails = [a.email for a in addon.authors.all()]
|
||||
send_mail('reviews/emails/add_review.ltxt',
|
||||
u'Mozilla Add-on User Review: %s' % addon.name,
|
||||
emails, Context(data), 'new_review')
|
||||
|
||||
return redirect('reviews.list', addon.slug)
|
||||
return redirect(shared_url('reviews.list', addon))
|
||||
return jingo.render(request, template, dict(addon=addon, form=form))
|
||||
|
||||
|
||||
|
@ -239,7 +241,7 @@ def spam(request):
|
|||
|
||||
for reason in spam.reasons():
|
||||
spam.redis.srem(reason, review.id)
|
||||
return redirect('reviews.spam')
|
||||
return redirect(request.path)
|
||||
|
||||
buckets = {}
|
||||
for reason in spam.reasons():
|
||||
|
|
|
@ -130,9 +130,18 @@ class TestDetail(WebappTest):
|
|||
eq_(doc('#addon h1').text(), 'woo')
|
||||
eq_(doc('h2:first').text(), 'About this App')
|
||||
|
||||
def test_reviews(self):
|
||||
eq_(self.get_more_pq()('#reviews h3').remove('a').text(),
|
||||
def test_add_review_link_aside(self):
|
||||
r = self.client.get(self.url)
|
||||
eq_(pq(r.content)('#reviews-link').attr('href'),
|
||||
reverse('apps.reviews.list', args=[self.webapp.app_slug]))
|
||||
|
||||
def test_add_review_link_more(self):
|
||||
doc = self.get_more_pq()
|
||||
add_url = reverse('apps.reviews.add', args=[self.webapp.app_slug])
|
||||
eq_(doc.find('#reviews #add-first-review').attr('href'), add_url)
|
||||
eq_(doc.find('#reviews h3').remove('a').text(),
|
||||
'This app has not yet been reviewed.')
|
||||
eq_(doc.find('#add-review').attr('href'), add_url)
|
||||
|
||||
def test_other_apps(self):
|
||||
"""Ensure listed apps by the same author show up."""
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from django.conf.urls.defaults import include, patterns, url
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from . import views
|
||||
from addons import views as addons_views
|
||||
from reviews.urls import review_patterns
|
||||
|
||||
APP_SLUG = r"""(?P<app_slug>[^/<>"']+)"""
|
||||
|
||||
|
@ -22,12 +24,18 @@ detail_patterns = patterns('',
|
|||
name='apps.purchase.thanks'),
|
||||
url('^purchase/(?P<status>cancel|complete)$',
|
||||
addons_views.purchase_complete, name='apps.purchase.finished'),
|
||||
|
||||
('^reviews/', include(review_patterns('apps'))),
|
||||
)
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url('^$', views.app_home, name='apps.home'),
|
||||
url('^search/$', 'search.views.app_search', name='apps.search'),
|
||||
|
||||
# Review spam.
|
||||
url('^reviews/spam/$', 'reviews.views.spam', name='apps.reviews.spam'),
|
||||
|
||||
url('^(?P<category>[^/]+)?$', views.app_list, name='apps.list'),
|
||||
|
||||
# URLs for a single app.
|
||||
|
|
8
urls.py
8
urls.py
|
@ -90,7 +90,7 @@ urlpatterns = patterns('',
|
|||
('^compatibility/', include('compat.urls')),
|
||||
|
||||
# Review spam.
|
||||
url('^reviews/spam/$', 'reviews.views.spam', name='reviews.spam'),
|
||||
url('^reviews/spam/$', 'reviews.views.spam', name='addons.reviews.spam'),
|
||||
|
||||
# marketplace
|
||||
('^market/', include('market.urls')),
|
||||
|
@ -100,10 +100,10 @@ urlpatterns = patterns('',
|
|||
lambda r: redirect('browse.extensions', 'bookmarks', permanent=True)),
|
||||
|
||||
('^reviews/display/(\d+)',
|
||||
lambda r, id: redirect('reviews.list', id, permanent=True)),
|
||||
lambda r, id: redirect('addons.reviews.list', id, permanent=True)),
|
||||
|
||||
('^reviews/add/(\d+)',
|
||||
lambda r, id: redirect('reviews.add', id, permanent=True)),
|
||||
lambda r, id: redirect('addons.reviews.add', id, permanent=True)),
|
||||
|
||||
('^users/info/(\d+)',
|
||||
lambda r, id: redirect('users.profile', id, permanent=True)),
|
||||
|
@ -136,7 +136,7 @@ urlpatterns = patterns('',
|
|||
'versions.views.update_info_redirect'),
|
||||
|
||||
('^addons/reviews/(\d+)/format:rss$',
|
||||
lambda r, id: redirect('reviews.list.rss', id, permanent=True)),
|
||||
lambda r, id: redirect('addons.reviews.list.rss', id, permanent=True)),
|
||||
|
||||
('^search-engines.*$',
|
||||
lambda r: redirect('browse.search-tools', permanent=True)),
|
||||
|
|
Загрузка…
Ссылка в новой задаче