This commit is contained in:
Chris Van 2011-07-26 12:28:31 -07:00
Родитель 4f7711a78d
Коммит 08d7b82bf6
26 изменённых файлов: 122 добавлений и 106 удалений

Просмотреть файл

@ -30,7 +30,7 @@ def _install_button(context, addon, version=None, show_eula=True,
or request.GET.get('collection_uuid')) or request.GET.get('collection_uuid'))
button = install_button_factory(addon, app, lang, version, button = install_button_factory(addon, app, lang, version,
show_eula, show_contrib, show_warning, show_eula, show_contrib, show_warning,
src, collection, size, detailed) src, collection, size, detailed, impala)
installed = (request.user.is_authenticated() and installed = (request.user.is_authenticated() and
addon.id in request.amo_user.mobile_addons) addon.id in request.amo_user.mobile_addons)
c = {'button': button, 'addon': addon, 'version': button.version, c = {'button': button, 'addon': addon, 'version': button.version,
@ -110,7 +110,7 @@ class InstallButton(object):
def __init__(self, addon, app, lang, version=None, show_eula=True, def __init__(self, addon, app, lang, version=None, show_eula=True,
show_contrib=True, show_warning=True, src='', collection=None, show_contrib=True, show_warning=True, src='', collection=None,
size='', detailed=False): size='', detailed=False, impala=False):
self.addon, self.app, self.lang = addon, app, lang self.addon, self.app, self.lang = addon, app, lang
self.latest = version is None self.latest = version is None
self.version = version or addon.current_version self.version = version or addon.current_version
@ -118,6 +118,7 @@ class InstallButton(object):
self.collection = collection self.collection = collection
self.size = size self.size = size
self.detailed = detailed self.detailed = detailed
self.impala = impala
self.is_beta = self.version and self.version.is_beta self.is_beta = self.version and self.version.is_beta
version_unreviewed = self.version and self.version.is_unreviewed version_unreviewed = self.version and self.version.is_unreviewed
@ -200,14 +201,15 @@ class InstallButton(object):
if self.show_eula: if self.show_eula:
# L10n: please keep   in the string so → does not wrap. # L10n: please keep   in the string so → does not wrap.
text = jinja2.Markup(_('Continue to Download →')) text = jinja2.Markup(_('Continue to Download →'))
url = file.eula_url() url = file.eula_url(impala=self.impala)
elif self.accept_eula: elif self.accept_eula:
text = _('Accept and Download') text = _('Accept and Download')
elif self.show_contrib: elif self.show_contrib:
# The eula doesn't exist or has been hit already. # The eula doesn't exist or has been hit already.
# L10n: please keep   in the string so → does not wrap. # L10n: please keep   in the string so → does not wrap.
text = jinja2.Markup(_('Continue to Download →')) text = jinja2.Markup(_('Continue to Download →'))
roadblock = reverse('addons.roadblock', args=[self.addon.id]) u = '%saddons.roadblock' % ('i_' if self.impala else '')
roadblock = reverse(u, args=[self.addon.id])
url = urlparams(roadblock, eula='', version=self.version.version) url = urlparams(roadblock, eula='', version=self.version.version)
return text, url, os return text, url, os

Просмотреть файл

@ -356,16 +356,17 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
return urls return urls
def get_url_path(self, impala=False): def get_url_path(self, impala=False):
if impala: u = '%saddons.detail' % ('i_' if impala else '')
return reverse('addons.i_detail', args=[self.slug]) return reverse(u, args=[self.slug])
return reverse('addons.detail', args=[self.slug])
def meet_the_dev_url(self): def meet_the_dev_url(self, impala=False):
return reverse('addons.meet', args=[self.slug]) u = '%saddons.meet' % ('i_' if impala else '')
return reverse(u, args=[self.slug])
@property @property
def reviews_url(self): def reviews_url(self, impala=False):
return reverse('reviews.list', args=[self.slug]) u = '%sreviews.list' % ('i_' if impala else '')
return reverse(u, args=[self.slug])
def type_url(self, impala=False): def type_url(self, impala=False):
"""The url for this add-on's AddonType.""" """The url for this add-on's AddonType."""

Просмотреть файл

@ -36,7 +36,7 @@
show_eula=False, show_warning=False) }} show_eula=False, show_warning=False) }}
<p class="policy-link"> <p class="policy-link">
<a href ="{{ url('addons.detail', addon.slug) }}"> <a href ="{{ url('addons.detail', addon.slug) }}">
{{ _('Cancel Installation')|f(addon.name) }} {{ _('Cancel Installation') }}
</a> </a>
</p> </p>
<p class="policy-link"> <p class="policy-link">

Просмотреть файл

@ -43,7 +43,7 @@
<a class="button {{ b.button_class|join(' ') }} {{ extra }}" <a class="button {{ b.button_class|join(' ') }} {{ extra }}"
data-hash="{{ link.file.hash }}" data-hash="{{ link.file.hash }}"
{% if b.show_warning %} {% if b.show_warning %}
href="{{ b.addon.get_url_path() }}" href="{{ b.addon.get_url_path(impala=True) }}"
data-realurl="{{ link.url }}" data-realurl="{{ link.url }}"
{% else %} {% else %}
href="{{ link.url }}" href="{{ link.url }}"
@ -67,7 +67,7 @@
{% if b.detailed %} {% if b.detailed %}
{% if addon.privacy_policy %} {% if addon.privacy_policy %}
<a class="privacy-policy badge" href="{{ url('addons.i_privacy', addon.slug) }}"> <a class="privacy-policy badge" href="{{ url('i_addons.privacy', addon.slug) }}">
<strong>{{ _('Privacy Policy') }}</strong> <strong>{{ _('Privacy Policy') }}</strong>
</a> </a>
{% endif %} {% endif %}

Просмотреть файл

@ -1,4 +1,4 @@
{% set meet_url = url('addons.i_meet', addon.slug) %} {% set meet_url = url('i_addons.meet', addon.slug) %}
{% if addon.charity %} {% if addon.charity %}
{% set charity_url = addon.charity.outgoing_url %} {% set charity_url = addon.charity.outgoing_url %}
{% set charity_name = addon.charity.name %} {% set charity_name = addon.charity.name %}

Просмотреть файл

@ -13,8 +13,9 @@
{% include "reviews/grouped_ratings.html" %} {% include "reviews/grouped_ratings.html" %}
{% set amo_user = request.amo_user if user.is_authenticated() else None %} {% set amo_user = request.amo_user if user.is_authenticated() else None %}
{% if not addon.has_author(amo_user) %} {% if not addon.has_author(amo_user) %}
{% set r_add = '%sreviews.add' % ('i_' if settings.IMPALA_REVIEWS else '') %}
<div> <div>
<a class="button" id="add-review" href="{{ url('reviews.add', addon.slug) }}">{{ _('Write a review') }}</a> <a class="button" id="add-review" href="{{ url(r_add) }}">{{ _('Write a review') }}</a>
</div> </div>
{% endif %} {% endif %}
<a id="report-abuse" href="{{ remora_url('developers/docs/policies/contact') }}" <a id="report-abuse" href="{{ remora_url('developers/docs/policies/contact') }}"
@ -36,7 +37,7 @@
<ul> <ul>
{% for category in categories %} {% for category in categories %}
<li> <li>
<a href="{{ category.get_url_path() }}"> <a href="{{ category.get_url_path(impala=True) }}">
{{ category }} {{ category }}
</a> </a>
</li> </li>

Просмотреть файл

@ -14,12 +14,13 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(None, addon.name)]) }} (None, addon.name)]) }}
<aside class="secondary addon-vitals"> <aside class="secondary addon-vitals">
{{ addon.average_rating|stars(large=True) }} {{ addon.average_rating|stars(large=True) }}
<div><a id="reviews-link" href="{{ url('reviews.list', addon.slug) }}"> {% set r_list = '%sreviews.list' % ('i_' if settings.IMPALA_REVIEWS else '') %}
<div><a id="reviews-link" href="{{ url(r_list, addon.slug) }}">
{% trans cnt=addon.total_reviews, num=addon.total_reviews|numberfmt %} {% trans cnt=addon.total_reviews, num=addon.total_reviews|numberfmt %}
{{ num }} user review {{ num }} user review
{% pluralize %} {% pluralize %}
@ -86,7 +87,7 @@
<h3> <h3>
{% trans count=addon.listed_authors|length, {% trans count=addon.listed_authors|length,
name=single_dev.name, name=single_dev.name,
url=addon.meet_the_dev_url() %} url=addon.meet_the_dev_url(impala=settings.IMPALA_MEET) %}
Meet the Developer: <a href="{{ url }}">{{ name }}</a> Meet the Developer: <a href="{{ url }}">{{ name }}</a>
{% pluralize %} {% pluralize %}
<a href="{{ url }}">Meet the Developers</a> <a href="{{ url }}">Meet the Developers</a>

Просмотреть файл

@ -6,12 +6,14 @@
{{ page_title(_('End-User License Agreement for {0}')|f(addon.name)) }} {{ page_title(_('End-User License Agreement for {0}')|f(addon.name)) }}
{% endblock %} {% endblock %}
{% set detail_url = url('i_addons.detail', addon.slug) %}
{% block primary %} {% block primary %}
<section class="primary"> <section class="primary">
<hgroup class="hero"> <hgroup class="hero">
{# L10n: EULA stand for End User License Agreement #} {# L10n: EULA stand for End User License Agreement #}
{{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(url('addons.i_detail', addon.slug), addon.name), (detail_url, addon.name),
(None, _('EULA'))]) }} (None, _('EULA'))]) }}
{{ addon_heading(addon, version) }} {{ addon_heading(addon, version) }}
</hgroup> </hgroup>
@ -23,15 +25,14 @@
End-User License Agreement before installation can proceed: End-User License Agreement before installation can proceed:
{% endtrans %} {% endtrans %}
</p> </p>
<div class="policy-statement">{{ addon.eula|nl2br }}</div> <div class="policy-statement">{{ addon.eula|clean|nl2br }}</div>
{{ install_button(addon, version=version, show_contrib=False, {{ install_button(addon, version=version, show_contrib=False,
show_eula=False, show_warning=False, impala=True) }} show_eula=False, show_warning=False, impala=True) }}
<p class="policy-cancel"> <p class="policy-cancel">
<a href="{{ url('addons.i_detail', addon.slug) }}"> <a href="{{ detail_url }}">{{ _('Cancel Installation') }}</a>
{{ _('Cancel Installation')|f(addon.name) }}</a>
</p> </p>
<p class="policy-back"> <p class="policy-back">
&#x25C2; <a href="{{ url('addons.i_detail', addon.slug) }}">{{ _('Back to {0}...')|f(addon.name) }}</a> <a href="{{ detail_url }}">{{ _('Back to {0}&hellip;')|f(addon.name)|safe }}</a>
</p> </p>
</div> </div>
</section> </section>

Просмотреть файл

@ -12,17 +12,17 @@
<hgroup class="hero"> <hgroup class="hero">
{# L10n: The License for this add-on. #} {# L10n: The License for this add-on. #}
{{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(url('addons.i_detail', addon.slug), addon.name), (url('i_addons.detail', addon.slug), addon.name),
(None, _('License'))]) }} (None, _('License'))]) }}
{{ addon_heading(addon, version) }} {{ addon_heading(addon, version) }}
</hgroup> </hgroup>
<div class="prose"> <div class="prose">
<h3>{{ _('Source Code License') }}</h3> <h3>{{ _('Source Code License') }}</h3>
{% if license.url %} {% if license.url %}
<p><a href="{{ license.url }}">{{ license.name }}</a><//p> <p><a href="{{ license.url }}">{{ license.name }}</a></p>
{% else %} {% else %}
<h4>{{ license.name }}</h4> <h4>{{ license.name }}</h4>
<pre class="license" width="100%">{{ license.text|nl2br }}</pre> <pre class="license">{{ license.text|clean|nl2br }}</pre>
{% endif %} {% endif %}
</div> </div>
</section> </section>

Просмотреть файл

@ -7,21 +7,22 @@
{% endblock %} {% endblock %}
{% set version = addon.current_version %} {% set version = addon.current_version %}
{% set detail_url = url('i_addons.detail', addon.slug) %}
{% block primary %} {% block primary %}
<section class="primary"> <section class="primary">
<hgroup class="hero"> <hgroup class="hero">
{# L10n: The Privacy Policy for this add-on. #} {# L10n: The Privacy Policy for this add-on. #}
{{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(url('addons.i_detail', addon.slug), addon.name), (detail_url, addon.name),
(None, _('Privacy Policy'))]) }} (None, _('Privacy Policy'))]) }}
{{ addon_heading(addon, version) }} {{ addon_heading(addon, version) }}
</hgroup> </hgroup>
<div class="prose"> <div class="prose">
<h3>{{ _('Privacy Policy') }}</h3> <h3>{{ _('Privacy Policy') }}</h3>
<div class="policy-statement">{{ addon.privacy_policy|nl2br }}</div> <div class="policy-statement">{{ addon.privacy_policy|clean|nl2br }}</div>
<p class="policy-back"> <p class="policy-back">
&#x25C2; <a href="{{ url('addons.i_detail', addon.slug) }}">{{ _('Back to {0}...')|f(addon.name) }}</a> <a href="{{ detail_url }}">{{ _('Back to {0}&hellip;')|f(addon.name)|safe }}</a>
</p> </p>
</div> </div>
</section> </section>

Просмотреть файл

@ -40,18 +40,18 @@ detail_patterns = patterns('',
impala_detail_patterns = patterns('', impala_detail_patterns = patterns('',
url('^$', views.impala_addon_detail, name='addons.i_detail'), url('^$', views.impala_addon_detail, name='i_addons.detail'),
url('^eula/(?P<file_id>\d+)?$', views.impala_eula, name='addons.i_eula'), url('^eula/(?P<file_id>\d+)?$', views.impala_eula, name='i_addons.eula'),
url('^license/(?P<version>[^/]+)?', views.impala_license, url('^license/(?P<version>[^/]+)?', views.impala_license,
name='addons.i_license'), name='i_addons.license'),
url('^privacy/', views.impala_privacy, name='addons.i_privacy'), url('^privacy/', views.impala_privacy, name='i_addons.privacy'),
url('^developers$', views.impala_developers, {'page': 'developers'}, url('^developers$', views.impala_developers, {'page': 'developers'},
name='addons.i_meet'), name='i_addons.meet'),
url('^contribute/roadblock/', views.impala_developers, url('^contribute/roadblock/', views.impala_developers,
{'page': 'roadblock'}, name='addons.i_roadblock'), {'page': 'roadblock'}, name='i_addons.roadblock'),
url('^contribute/installed/', views.impala_developers, url('^contribute/installed/', views.impala_developers,
{'page': 'installed'}, name='addons.i_installed'), {'page': 'installed'}, name='i_addons.installed'),
('^reviews/', include('reviews.impala_urls')), ('^reviews/', include('reviews.impala_urls')),
) )

Просмотреть файл

@ -120,7 +120,7 @@ def impala_addon_detail(request, addon):
prefixer = urlresolvers.get_url_prefix() prefixer = urlresolvers.get_url_prefix()
prefixer.app = new_app.short prefixer.app = new_app.short
return http.HttpResponsePermanentRedirect(reverse( return http.HttpResponsePermanentRedirect(reverse(
'addons.i_detail', args=[addon.slug])) 'i_addons.detail', args=[addon.slug]))
def extension_detail(request, addon): def extension_detail(request, addon):
@ -520,11 +520,10 @@ def eula(request, addon, file_id=None):
def impala_eula(request, addon, file_id=None): def impala_eula(request, addon, file_id=None):
if not addon.eula: if not addon.eula:
return http.HttpResponseRedirect(addon.get_url_path(impala=True)) return http.HttpResponseRedirect(addon.get_url_path(impala=True))
if file_id is not None: if file_id:
version = get_object_or_404(addon.versions, files__id=file_id) version = get_object_or_404(addon.versions, files__id=file_id)
else: else:
version = addon.current_version version = addon.current_version
return jingo.render(request, 'addons/impala/eula.html', return jingo.render(request, 'addons/impala/eula.html',
{'addon': addon, 'version': version}) {'addon': addon, 'version': version})

Просмотреть файл

@ -14,6 +14,7 @@ from babel.support import Format
import caching.base as caching import caching.base as caching
import jinja2 import jinja2
from jingo import register, env from jingo import register, env
from jingo.helpers import nl2br
from tower import ugettext as _ from tower import ugettext as _
import amo import amo

Просмотреть файл

@ -24,7 +24,11 @@ from django.utils.translation import trans_real
from django.utils.functional import Promise from django.utils.functional import Promise
from django.utils.encoding import smart_str, smart_unicode from django.utils.encoding import smart_str, smart_unicode
import bleach
from easy_thumbnails import processors from easy_thumbnails import processors
import html5lib
from html5lib.serializer.htmlserializer import HTMLSerializer
import jinja2
import pytz import pytz
from PIL import Image, ImageFile, PngImagePlugin from PIL import Image, ImageFile, PngImagePlugin
@ -283,6 +287,48 @@ def clear_messages(request):
pass pass
def clean_nl(string):
"""
This will clean up newlines so that nl2br can properly be called on the
cleaned text.
"""
html_blocks = ['blockquote', 'ol', 'li', 'ul']
if not string:
return string
def parse_html(tree):
prev_tag = ''
for i, node in enumerate(tree.childNodes):
if node.type == 4: # Text node
value = node.value
# Strip new lines directly inside block level elements.
if node.parent.name in html_blocks:
value = value.strip('\n')
# Remove the first new line after a block level element.
if (prev_tag in html_blocks and value.startswith('\n')):
value = value[1:]
tree.childNodes[i].value = value
else:
tree.insertBefore(parse_html(node), node)
tree.removeChild(node)
prev_tag = node.name
return tree
parse = parse_html(html5lib.parseFragment(string))
walker = html5lib.treewalkers.getTreeWalker('simpletree')
stream = walker(parse)
serializer = HTMLSerializer(quote_attr_values=True,
omit_optional_tags=False)
return jinja2.Markup(serializer.render(stream)).unescape()
# From: http://bit.ly/eTqloE # From: http://bit.ly/eTqloE
# Without this, you'll notice a slight grey line on the edges of # Without this, you'll notice a slight grey line on the edges of
# the adblock plus icon. # the adblock plus icon.

Просмотреть файл

@ -25,7 +25,7 @@
<a href="{{ services_url('discovery.addons.detail', addon.slug, <a href="{{ services_url('discovery.addons.detail', addon.slug,
src='discovery-promo') }}" target="_self"> src='discovery-promo') }}" target="_self">
{% else %} {% else %}
<a href="{{ url('addons.i_detail', addon.slug, <a href="{{ url('i_addons.detail', addon.slug,
src='hp-dl-promo') }}" target="_self"> src='hp-dl-promo') }}" target="_self">
{% endif %} {% endif %}
{% if addon.type == amo.ADDON_PERSONA %} {% if addon.type == amo.ADDON_PERSONA %}

Просмотреть файл

@ -192,8 +192,9 @@ class File(amo.models.OnChangeMixin, amo.models.ModelBase):
url = reverse('downloads.latest', kwargs=kw) url = reverse('downloads.latest', kwargs=kw)
return os.path.join(url, 'addon-%s-latest%s' % (addon, self.extension)) return os.path.join(url, 'addon-%s-latest%s' % (addon, self.extension))
def eula_url(self): def eula_url(self, impala=False):
return reverse('addons.eula', args=[self.version.addon_id, self.id]) u = '%saddons.eula' % ('i_' if impala else '')
return reverse(u, args=[self.version.addon_id, self.id])
@property @property
def file_path(self): def file_path(self):

Просмотреть файл

@ -8,7 +8,7 @@
{% block content %} {% block content %}
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(addon.get_url_path(impala=True), addon.name), (addon.get_url_path(impala=True), addon.name),
(url('i_reviews.list', addon.slug), _('Reviews')), (url('i_reviews.list', addon.slug), _('Reviews')),
(None, _('Add'))]) }} (None, _('Add'))]) }}

Просмотреть файл

@ -8,7 +8,7 @@
{% block content %} {% block content %}
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(addon.get_url_path(impala=True), addon.name), (addon.get_url_path(impala=True), addon.name),
(url('i_reviews.list', addon.slug), _('Reviews')), (url('i_reviews.list', addon.slug), _('Reviews')),
(None, _('Reply'))]) }} (None, _('Reply'))]) }}

Просмотреть файл

@ -11,7 +11,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]), {{ impala_breadcrumbs([(addon.type_url(impala=True), amo.ADDON_TYPES[addon.type]),
(addon.get_url_path(impala=True), addon.name), (addon.get_url_path(impala=True), addon.name),
(link, _('Reviews'))]) }} (link, _('Reviews'))]) }}
@ -40,7 +40,7 @@
{% block review_header %} {% block review_header %}
<header> <header>
{# Give a link back to reviews if we're looking at user reviews or a detail page. #} {# Give a link back to reviews if we're looking at user reviews or a detail page. #}
{% with link = None if page == 'list' else url('reviews.list', addon.slug) %} {% with link = None if page == 'list' else url('i_reviews.list', addon.slug) %}
{% endwith %} {% endwith %}
<hgroup> <hgroup>
{% if page == "list" %} {% if page == "list" %}
@ -70,7 +70,7 @@
{% block review_list %} {% block review_list %}
{% if not reviews.object_list %} {% if not reviews.object_list %}
<p><a href="{{ url('reviews.add', addon.slug) }}"> <p><a href="{{ url('i_reviews.add', addon.slug) }}">
{{ _('Be the first to write a review.') }}</a><p> {{ _('Be the first to write a review.') }}</a><p>
{% endif %} {% endif %}
{% for review in reviews.object_list %} {% for review in reviews.object_list %}

Просмотреть файл

@ -1,4 +1,4 @@
{% set base = url('addons.i_detail', addon.slug)|urlparams('reviews') %} {% set base = url('i_addons.detail', addon.slug)|urlparams('reviews') %}
{% if collection_uuid %} {% if collection_uuid %}
{% set base = base|urlparams(collection_uuid=collection_uuid) %} {% set base = base|urlparams(collection_uuid=collection_uuid) %}
{% endif %} {% endif %}

Просмотреть файл

@ -7,8 +7,6 @@ import bleach
import jinja2 import jinja2
import jingo import jingo
from .models import clean_nl
jingo.register.filter(to_language) jingo.register.filter(to_language)
@ -72,4 +70,5 @@ def all_locales(addon, field_name, nl2br=False):
@jingo.register.filter @jingo.register.filter
def clean(string): def clean(string):
return jinja2.Markup(clean_nl(bleach.clean(string)).strip()) from amo.utils import clean_nl
return jinja2.Markup(clean_nl(bleach.clean(unicode(string))).strip())

Просмотреть файл

@ -2,8 +2,6 @@ from django.db import models, connection
from django.utils import encoding from django.utils import encoding
import bleach import bleach
import html5lib
from html5lib.serializer.htmlserializer import HTMLSerializer
import amo.models import amo.models
from amo import urlresolvers from amo import urlresolvers
@ -117,6 +115,7 @@ class PurifiedTranslation(Translation):
return unicode(self) return unicode(self)
def clean(self): def clean(self):
from amo.utils import clean_nl
super(PurifiedTranslation, self).clean() super(PurifiedTranslation, self).clean()
cleaned = bleach.clean(self.localized_string) cleaned = bleach.clean(self.localized_string)
linkified = bleach.linkify(cleaned, nofollow=True, linkified = bleach.linkify(cleaned, nofollow=True,
@ -157,44 +156,3 @@ def delete_translation(obj, fieldname):
obj.update(**{field.name: None}) obj.update(**{field.name: None})
if trans: if trans:
Translation.objects.filter(id=trans.id).delete() Translation.objects.filter(id=trans.id).delete()
def clean_nl(string):
""" This will clean up newlines so that nl2br can properly
be called on the cleaned text. """
html_blocks = ['blockquote', 'ol', 'li', 'ul']
if not string:
return string
def parse_html(tree):
prev_tag = ''
for i, node in enumerate(tree.childNodes):
if node.type == 4: # Text node
value = node.value
# Strip new lines directly inside block level elements.
if node.parent.name in html_blocks:
value = value.strip('\n')
# Remove the first new line after a block level element
if (prev_tag in html_blocks and value.startswith('\n')):
value = value[1:]
tree.childNodes[i].value = value
else:
tree.insertBefore(parse_html(node), node)
tree.removeChild(node)
prev_tag = node.name
return tree
parse = parse_html(html5lib.parseFragment(string))
walker = html5lib.treewalkers.getTreeWalker('simpletree')
stream = walker(parse)
serializer = HTMLSerializer(quote_attr_values=True,
omit_optional_tags=False)
return serializer.render(stream)

Просмотреть файл

@ -139,7 +139,7 @@ class Version(amo.models.ModelBase):
return os.path.join(settings.MIRROR_STAGE_PATH, str(self.addon_id)) return os.path.join(settings.MIRROR_STAGE_PATH, str(self.addon_id))
def license_url(self, impala=False): def license_url(self, impala=False):
u = 'addons.i_license' if impala else 'addons.license' u = '%saddons.license' % ('i_' if impala else '')
return reverse(u, args=[self.addon.slug, self.version]) return reverse(u, args=[self.addon.slug, self.version])
def flush_urls(self): def flush_urls(self):

Просмотреть файл

@ -483,7 +483,8 @@ img.icon {
.hero h2:first-child { .hero h2:first-child {
margin-top: 1em; margin-top: 1em;
} }
hgroup.hero h2 { hgroup.hero h2,
header.hero h2 {
margin-bottom: 1em; margin-bottom: 1em;
} }
&.about { &.about {
@ -526,12 +527,16 @@ img.icon {
border: 1px solid @border-black; border: 1px solid @border-black;
color: @medium-gray; color: @medium-gray;
line-height: 1.4; line-height: 1.4;
margin: 1.5em 0;
max-height: 300px; max-height: 300px;
overflow: auto; overflow: auto;
padding: 2px 5px; padding: 2px 5px;
} }
.policy-statement,
pre.license {
margin: 1.5em 0;
}
p.policy-cancel { p.policy-cancel {
margin: 0; margin: 0;
} }
@ -539,7 +544,3 @@ p.policy-cancel {
p.policy-back a { p.policy-back a {
color: @dark-gray; color: @dark-gray;
} }
pre.license {
margin-top: 1em;
}

Просмотреть файл

@ -53,6 +53,7 @@ pre, code, kbd, tt, samp, tt {
pre { pre {
line-height: 1.4; line-height: 1.4;
white-space: pre-wrap;
} }
.primary, .modal { .primary, .modal {

Просмотреть файл

@ -971,8 +971,11 @@ UNLINK_SITE_STATS = True
# Use the new featured add-ons system which makes use of featured collections. # Use the new featured add-ons system which makes use of featured collections.
NEW_FEATURES = False NEW_FEATURES = False
# Impala flags.
IMPALA_BROWSE = False IMPALA_BROWSE = False
IMPALA_REVIEWS = False IMPALA_REVIEWS = False
IMPALA_MEET = False # Meet the Developer page.
# Set to True if we're allowed to use X-SENDFILE. # Set to True if we're allowed to use X-SENDFILE.
XSENDFILE = True XSENDFILE = True