diff --git a/apps/addons/templates/addons/details.html b/apps/addons/templates/addons/details.html index 82ddc7c5bf..2d3fcaa7b1 100644 --- a/apps/addons/templates/addons/details.html +++ b/apps/addons/templates/addons/details.html @@ -180,62 +180,7 @@ {% if not addon.is_selfhosted() and version %}

{{ _('Release Notes', 'addons_display_release_notes') }}

-
- {# TODO reverse URL #} - {% set base = remora_url('/addons/versions/{0}'|f(addon.id)) %} -

- {{ _('Version {0}', 'addon_display_header_version')|f(version.version) }} - — - {{ - version.created|datetime }} - {% if version.has_files %} - — - {{ _('{0} KB')|f(version.all_files[0].size|int|numberfmt) }} - {% endif %} -

- -
-

- {{ version.releasenotes|nl2br }} -

-
- - {# License #} - {% if version.license %} -
- {{ _('Source Code License') }} - {# TODO reverse URL #} - - {{ _("What's this?", 'addons_display_a_license_what') }} - -
- {# TODO reverse URL #} -

- - {{ version.license.name }} -

- {% endif %} - - -
+ {{ version_detail(addon, version, src="addon-detail-version") }} {% endif %} {# /primary #} diff --git a/apps/addons/urls.py b/apps/addons/urls.py index 7f8f24214b..d171cab625 100644 --- a/apps/addons/urls.py +++ b/apps/addons/urls.py @@ -23,6 +23,7 @@ detail_patterns = patterns('', ('^reviews/', include('reviews.urls')), ('^statistics/', include('stats.urls')), + ('^versions/', include('versions.urls')), ) diff --git a/apps/amo/tests/test_redirects.py b/apps/amo/tests/test_redirects.py index 3348c0a90d..bed8efaf10 100644 --- a/apps/amo/tests/test_redirects.py +++ b/apps/amo/tests/test_redirects.py @@ -23,12 +23,12 @@ class TestRedirects(test.TestCase): """`/persona/\d+` should go to `/addon/\d+`.""" r = self.client.get(u'persona/4', follow=True) assert r.redirect_chain[-1][0].endswith('/en-US/firefox/addon/4/') - + def test_contribute_installed(self): """`/addon/\d+/about` should go to `/addon/\d+/contribute/installed`.""" r = self.client.get(u'addon/5326/about', follow=True) assert r.redirect_chain[-1][0].endswith('/en-US/firefox/addon/5326/contribute/installed/') - + def test_utf8(self): """Without proper unicode handling this will fail.""" response = self.client.get(u'/api/1.5/search/ツールバー', @@ -156,3 +156,8 @@ class TestRedirects(test.TestCase): url, code = r.redirect_chain[-1] eq_(code, 301) assert url.endswith('/en-US/firefox/extensions/woo/?sort=rating') + + def test_addons_versions(self): + r = self.client.get('/addons/versions/4', follow=True) + self.assertRedirects(r, '/en-US/firefox/addon/4/versions/', + status_code=301) diff --git a/apps/versions/helpers.py b/apps/versions/helpers.py new file mode 100644 index 0000000000..c9ed77dc21 --- /dev/null +++ b/apps/versions/helpers.py @@ -0,0 +1,11 @@ +import jingo +import jinja2 + +from addons.helpers import new_context + + +@jingo.register.inclusion_tag('versions/version.html') +@jinja2.contextfunction +def version_detail(context, addon, version, src, + show_versions_link=True, itemclass='article'): + return new_context(**locals()) diff --git a/apps/versions/templates/versions/version.html b/apps/versions/templates/versions/version.html new file mode 100644 index 0000000000..d9077b040d --- /dev/null +++ b/apps/versions/templates/versions/version.html @@ -0,0 +1,61 @@ +{# addon, version, request #} +
+ {% set versions_url = url('addons.versions', addon.id) %} +

+ {{ _('Version {0}', 'addon_display_header_version')|f(version.version) }} + — + {{ + version.created|datetime }} + {% if version.has_files %} + — + {{ _('{0} KB')|f(version.all_files[0].size|int|numberfmt) }} + {% endif %} +

+ + {{ install_button(addon, version=version) }} + + {% if addon.compatible_apps %} +
{{ _('Works with:') }}
+ + {% endif %} + +
+ {{ version.releasenotes|nl2br }} +
+ + {# License #} + {% if version.license %} +
+ {{ _('Source Code License') }} + {# TODO reverse URL #} + + {{ _("What's this?", 'addons_display_a_license_what') }} + +
+ {# TODO reverse URL #} + + {{ version.license.name }} + {% endif %} + + +
diff --git a/apps/versions/templates/versions/version_list.html b/apps/versions/templates/versions/version_list.html new file mode 100644 index 0000000000..d5850c319d --- /dev/null +++ b/apps/versions/templates/versions/version_list.html @@ -0,0 +1,42 @@ +{% extends "base.html" %} + +{# L10n: {0} is an add-on name. #} +{% block title %}{{ page_title('{0} :: Versions')|f(addon.name) }}{% endblock %} + +{% block bodyclass %}versions inverse{% endblock %} + +{% block content %} +
+
+ {{ breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]), + (url('addons.detail', addon.id), addon.name), + (None, _('Versions'))]) }} + {# L10n: {0} is an add-on name. #} +
+

{{ _('{0} Version History')|f(addon.name) }}

+ {% with cnt=versions.paginator.count %} + {# L10n: {0} is a number. #} +

{{ ngettext('{0} Version', '{0} Versions', cnt)|f(cnt) }}

+ {% endwith %} +
+
+
+ {{ _('Be careful with old versions!') }} +

{% trans url=url('addons.detail', addon.id) %} + These versions are displayed for reference and testing purposes. + You should always use the latest version of an add-on. + {% endtrans %}

+
+ +
+{% endblock %} diff --git a/apps/versions/urls.py b/apps/versions/urls.py new file mode 100644 index 0000000000..0510a98295 --- /dev/null +++ b/apps/versions/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls.defaults import patterns, url + +from . import views + +urlpatterns = patterns('', + url('^$', views.versions_list, name='addons.versions'), +) diff --git a/apps/versions/views.py b/apps/versions/views.py new file mode 100644 index 0000000000..e310deda3b --- /dev/null +++ b/apps/versions/views.py @@ -0,0 +1,18 @@ +from django.shortcuts import get_object_or_404 + +import jingo + +import amo +from addons.models import Addon +from versions.models import Version + + +def versions_list(request, addon_id): + addon = get_object_or_404(Addon.objects.valid(), pk=addon_id) + qs = (addon.versions.filter(files__status__in=amo.VALID_STATUSES) + .distinct().order_by('-created')) + versions = amo.utils.paginate(request, qs) + versions.object_list = list(versions.object_list) + Version.transformer(versions.object_list) + return jingo.render(request, 'versions/version_list.html', + {'addon': addon, 'versions': versions}) diff --git a/urls.py b/urls.py index b10ccaa9f7..d607359148 100644 --- a/urls.py +++ b/urls.py @@ -71,6 +71,9 @@ urlpatterns = patterns('', ('^personas/film and tv/?$', lambda r: redirect('browse.personas', 'film-and-tv', permanent=True)), + ('^addons/versions/(\d+)/?$', + lambda r, id: redirect('addons.versions', id, permanent=True)), + # Firefox Cup page, /firefoxcup ('^firefoxcup/', include('firefoxcup.urls')) )