moving to a new license schema for zamboni (bug 592548)
This commit is contained in:
Родитель
3d1c0d14dd
Коммит
0c79c717df
|
@ -38,8 +38,6 @@
|
|||
"pk": 6,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 2,
|
||||
"modified": "2009-04-30 23:48:48",
|
||||
"created": "2009-04-30 23:48:48"
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
{% if persona.license %}
|
||||
<tr>
|
||||
<th>{{ _('License') }}</th>
|
||||
<td>{{ license_link(persona.license.license_type) }}</td>
|
||||
<td>{{ license_link(persona.license) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
|
|
|
@ -323,6 +323,7 @@ class _LicenseBase(object):
|
|||
shortname = None
|
||||
icons = None # CSS classes. See zamboni.css for a list.
|
||||
linktext = None # Link text distinct from full license name.
|
||||
on_form = True
|
||||
|
||||
@classmethod
|
||||
def text(cls):
|
||||
|
@ -395,6 +396,7 @@ class LICENSE_COPYRIGHT(_LicenseBase):
|
|||
url = None
|
||||
shortname = None
|
||||
icons = ('copyr',)
|
||||
on_form = False
|
||||
|
||||
|
||||
class LICENSE_CC_BY_NC_SA(_LicenseBase):
|
||||
|
@ -404,6 +406,7 @@ class LICENSE_CC_BY_NC_SA(_LicenseBase):
|
|||
url = 'http://creativecommons.org/licenses/by-nc-sa/3.0/'
|
||||
shortname = None
|
||||
icons = ('cc-attrib', 'cc-noncom', 'cc-share')
|
||||
on_form = False
|
||||
|
||||
LICENSES = (LICENSE_CUSTOM, LICENSE_COPYRIGHT, LICENSE_MPL, LICENSE_GPL2,
|
||||
LICENSE_GPL3, LICENSE_LGPL21, LICENSE_LGPL3, LICENSE_MIT,
|
||||
|
|
|
@ -77,8 +77,7 @@
|
|||
"pk": 180,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 387641,
|
||||
"_name_field": -1,
|
||||
"text": 387641,
|
||||
"modified": "2009-05-27 16:04:05",
|
||||
"created": "2009-05-27 16:04:04"
|
||||
}
|
||||
|
|
|
@ -207,8 +207,7 @@
|
|||
"pk": 93,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 379597,
|
||||
"_name_field": -1,
|
||||
"text": 379597,
|
||||
"modified": "2009-05-11 22:06:48",
|
||||
"created": "2009-05-11 22:06:47"
|
||||
}
|
||||
|
|
|
@ -61,8 +61,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -91,8 +91,7 @@
|
|||
"pk": 312,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 447979,
|
||||
"_name_field": -1,
|
||||
"text": 447979,
|
||||
"modified": "2009-06-29 21:11:38",
|
||||
"created": "2009-06-29 21:11:38"
|
||||
}
|
||||
|
|
|
@ -148,8 +148,6 @@
|
|||
"pk": 13,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 1,
|
||||
"modified": "2009-05-01 05:00:44",
|
||||
"created": "2009-05-01 05:00:44"
|
||||
}
|
||||
|
|
|
@ -174,8 +174,6 @@
|
|||
"pk": 13,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 1,
|
||||
"modified": "2009-05-01 05:00:44",
|
||||
"created": "2009-05-01 05:00:44"
|
||||
}
|
||||
|
|
|
@ -68,8 +68,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -93,8 +93,7 @@
|
|||
"pk": 329,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 451342,
|
||||
"_name_field": -1,
|
||||
"text": 451342,
|
||||
"modified": "2009-06-30 22:09:31",
|
||||
"created": "2009-06-30 22:09:31"
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
"pk": 6,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 2,
|
||||
"modified": "2009-04-30 23:48:48",
|
||||
"created": "2009-04-30 23:48:48"
|
||||
}
|
||||
|
|
|
@ -84,8 +84,7 @@
|
|||
"pk": 282,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 436038,
|
||||
"_name_field": -1,
|
||||
"text": 436038,
|
||||
"modified": "2009-06-21 20:51:55",
|
||||
"created": "2009-06-21 20:51:54"
|
||||
}
|
||||
|
|
|
@ -71,8 +71,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -133,8 +133,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -431,8 +431,7 @@
|
|||
"pk": 345,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 456704,
|
||||
"_name_field": -1,
|
||||
"text": 456704,
|
||||
"modified": "2009-07-02 07:18:10",
|
||||
"created": "2009-07-02 07:18:10"
|
||||
}
|
||||
|
@ -441,8 +440,6 @@
|
|||
"pk": 13,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 1,
|
||||
"modified": "2009-05-01 05:00:44",
|
||||
"created": "2009-05-01 05:00:44"
|
||||
}
|
||||
|
@ -451,8 +448,7 @@
|
|||
"pk": 60,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": 377095,
|
||||
"_name_field": -1,
|
||||
"text": 377095,
|
||||
"modified": "2009-05-06 17:42:02",
|
||||
"created": "2009-05-06 17:42:01"
|
||||
}
|
||||
|
@ -461,8 +457,6 @@
|
|||
"pk": 6,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 2,
|
||||
"modified": "2009-04-30 23:48:48",
|
||||
"created": "2009-04-30 23:48:48"
|
||||
}
|
||||
|
|
|
@ -158,8 +158,6 @@
|
|||
"pk": 13,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 1,
|
||||
"modified": "2009-05-01 05:00:44",
|
||||
"created": "2009-05-01 05:00:44"
|
||||
}
|
||||
|
|
|
@ -271,21 +271,23 @@ def license_link(license):
|
|||
"""Link to a code license, incl. icon where applicable."""
|
||||
if not license:
|
||||
return ''
|
||||
if not license.builtin:
|
||||
return _('Custom License')
|
||||
lic_icon = lambda name: '<li class="icon %s"></li>' % name
|
||||
|
||||
parts = []
|
||||
parts.append('<ul class="license">')
|
||||
if license.icons:
|
||||
for i in license.icons:
|
||||
for i in license.icons.split():
|
||||
parts.append(lic_icon(i))
|
||||
|
||||
# TODO link to custom license page
|
||||
parts.append('<li class="text">')
|
||||
|
||||
if license.url:
|
||||
if license.linktext:
|
||||
title = ' title="%s"' % unicode(license.name)
|
||||
linktext = license.linktext
|
||||
if license.some_rights:
|
||||
title = ' title="%s"' % license.name
|
||||
linktext = _('Some rights reserved')
|
||||
else:
|
||||
title = ''
|
||||
linktext = license.name
|
||||
|
|
|
@ -14,6 +14,7 @@ import test_utils
|
|||
import amo
|
||||
from amo import urlresolvers, utils, helpers
|
||||
from amo.helpers import wround
|
||||
from versions.models import License
|
||||
|
||||
|
||||
def render(s, context={}):
|
||||
|
@ -212,22 +213,30 @@ def test_external_url():
|
|||
settings.REDIRECT_SECRET_KEY = secretkey
|
||||
|
||||
|
||||
def test_license_link():
|
||||
expected = {
|
||||
amo.LICENSE_MIT: (
|
||||
'<ul class="license"><li class="text"><a href="http://www.'
|
||||
'opensource.org/licenses/mit-license.php">MIT/X11 License</a>'
|
||||
'</li></ul>'),
|
||||
amo.LICENSE_COPYRIGHT: (
|
||||
'<ul class="license"><li class="icon copyr"></li><li class="text">'
|
||||
'All Rights Reserved</li></ul>'),
|
||||
amo.LICENSE_CC_BY_NC_SA: (
|
||||
'<ul class="license"><li class="icon cc-attrib"></li><li class='
|
||||
'"icon cc-noncom"></li><li class="icon cc-share"></li><li class='
|
||||
'"text"><a href="http://creativecommons.org/licenses/by-nc-sa/'
|
||||
'3.0/" title="Creative Commons Attribution-Noncommercial-Share '
|
||||
'Alike 3.0">Some rights reserved</a></li></ul>'),
|
||||
}
|
||||
for lic, ex in expected.items():
|
||||
s = render('{{ license_link(lic) }}', {'lic': lic})
|
||||
eq_(s, ex)
|
||||
class TestLicenseLink(test_utils.TestCase):
|
||||
|
||||
def test_license_link(self):
|
||||
mit = License.objects.create(
|
||||
name='MIT/X11 License', builtin=6, url='http://m.it')
|
||||
copyright = License.objects.create(
|
||||
name='All Rights Reserved', icons='copyr', builtin=7)
|
||||
cc = License.objects.create(
|
||||
name='Creative Commons', url='http://cre.at', builtin=8,
|
||||
some_rights=True, icons='cc-attrib cc-noncom cc-share')
|
||||
cc.save()
|
||||
expected = {
|
||||
mit: (
|
||||
'<ul class="license"><li class="text">'
|
||||
'<a href="http://m.it">MIT/X11 License</a></li></ul>'),
|
||||
copyright: (
|
||||
'<ul class="license"><li class="icon copyr"></li>'
|
||||
'<li class="text">All Rights Reserved</li></ul>'),
|
||||
cc: (
|
||||
'<ul class="license"><li class="icon cc-attrib"></li>'
|
||||
'<li class="icon cc-noncom"></li><li class="icon cc-share">'
|
||||
'</li><li class="text"><a href="http://cre.at" '
|
||||
'title="Creative Commons">Some rights reserved</a></li></ul>'),
|
||||
}
|
||||
for lic, ex in expected.items():
|
||||
s = render('{{ license_link(lic) }}', {'lic': lic})
|
||||
eq_(s, ex)
|
||||
|
|
|
@ -95,8 +95,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -75,8 +75,6 @@
|
|||
"pk": 1,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"id": 1,
|
||||
"_custom_text": null,
|
||||
"modified": "2004-06-11 18:23:31",
|
||||
"created": "2004-06-11 18:23:31"
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
"pk": 6,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 2,
|
||||
"modified": "2009-04-30 23:48:48",
|
||||
"created": "2009-04-30 23:48:48"
|
||||
}
|
||||
|
@ -13,8 +11,6 @@
|
|||
"pk": 5,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"_custom_text": null,
|
||||
"_name_field": 0,
|
||||
"modified": "2009-04-30 22:29:53",
|
||||
"created": "2009-04-30 22:29:53"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import translation
|
||||
|
||||
from licenses import license_text
|
||||
from tower import ugettext, activate
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Upgrade the license schema to support zamboni"
|
||||
|
||||
def handle(self, *args, **kw):
|
||||
from versions.models import License
|
||||
qs = License.objects.all()
|
||||
print 'Updating %s licenses.' % len(qs)
|
||||
for idx, license in enumerate(qs):
|
||||
if idx % 100 == 0:
|
||||
print 'Finished', idx
|
||||
if license.builtin:
|
||||
self.handle_builtin(license)
|
||||
elif not license.name:
|
||||
license.name = 'Custom License'
|
||||
license.save()
|
||||
|
||||
def handle_builtin(self, license):
|
||||
import amo
|
||||
# License.builtin is off by one!
|
||||
data = amo.LICENSE_IDS[license.builtin - 1]
|
||||
license.url = data.url
|
||||
license.on_form = data.on_form
|
||||
if data.icons:
|
||||
license.icons = ' '.join(data.icons)
|
||||
license.some_rights = bool(data.linktext)
|
||||
|
||||
if data.shortname:
|
||||
license.text = license_text(data.shortname)
|
||||
|
||||
# Gather all the translated names.
|
||||
activate('en-us')
|
||||
license.name = en_name = unicode(data.name)
|
||||
names = {}
|
||||
for lang in settings.AMO_LANGUAGES:
|
||||
activate(lang)
|
||||
trans = ugettext(en_name)
|
||||
if trans and trans != en_name:
|
||||
names[lang] = trans
|
||||
activate('en-us')
|
||||
license.name = names
|
||||
license.save()
|
|
@ -8,7 +8,8 @@ import caching.base
|
|||
import amo.models
|
||||
from applications.models import Application, AppVersion
|
||||
from files.models import File
|
||||
from translations.fields import TranslatedField, PurifiedField
|
||||
from translations.fields import (TranslatedField, PurifiedField,
|
||||
LinkifiedField)
|
||||
from users.models import UserProfile
|
||||
|
||||
from . import compare
|
||||
|
@ -99,58 +100,33 @@ class Version(amo.models.ModelBase):
|
|||
version.all_files = file_dict.get(v_id, [])
|
||||
|
||||
|
||||
class LicenseManager(amo.models.ManagerBase):
|
||||
|
||||
def builtins(self):
|
||||
return self.filter(builtin__gt=0).order_by('builtin')
|
||||
|
||||
|
||||
class License(amo.models.ModelBase):
|
||||
"""
|
||||
Custom as well as built-in licenses.
|
||||
A name of -1 indicates a custom license, all names >= 0 are built-in.
|
||||
Built-in licenses are defined in amo.__init__
|
||||
"""
|
||||
OTHER = 0
|
||||
|
||||
_name_field = models.IntegerField(null=False,
|
||||
default=amo.LICENSE_CUSTOM.id,
|
||||
db_column='name')
|
||||
_custom_text = TranslatedField(db_column='text')
|
||||
name = TranslatedField(db_column='name')
|
||||
url = models.URLField(null=True)
|
||||
builtin = models.PositiveIntegerField(default=OTHER)
|
||||
text = LinkifiedField()
|
||||
on_form = models.BooleanField(default=False,
|
||||
help_text='Is this a license choice in the devhub?')
|
||||
some_rights = models.BooleanField(default=False,
|
||||
help_text='Show "Some Rights Reserved" instead of the license name?')
|
||||
icons = models.CharField(max_length=255, null=True,
|
||||
help_text='Space-separated list of icon identifiers.')
|
||||
|
||||
class Meta(amo.models.ModelBase.Meta):
|
||||
objects = LicenseManager()
|
||||
|
||||
class Meta:
|
||||
db_table = 'licenses'
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def license_type(self):
|
||||
return amo.LICENSE_IDS.get(self._name_field, amo.LICENSE_CUSTOM)
|
||||
|
||||
@license_type.setter
|
||||
def license_type(self, license):
|
||||
assert license in amo.LICENSES
|
||||
self._name_field = license.id
|
||||
|
||||
@property
|
||||
def is_custom(self):
|
||||
"""is this a custom, not built-in, license?"""
|
||||
return self.license_type.id == amo.LICENSE_CUSTOM.id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.license_type.name
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
if self.is_custom:
|
||||
return self._custom_text
|
||||
else:
|
||||
return self.license_type.text()
|
||||
|
||||
@text.setter
|
||||
def text(self, value):
|
||||
if value:
|
||||
self.license_type = amo.LICENSE_CUSTOM
|
||||
self._custom_text = value
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return self.license_type.url
|
||||
return '%s %s' % (self.id, self.name)
|
||||
|
||||
|
||||
class VersionComment(amo.models.ModelBase):
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
{% if license.builtin %}
|
||||
{{ license_link(license) }}
|
||||
{% else %}
|
||||
{# TODO reverse URL #}
|
||||
{# TODO reverse URL, merge with license_link. #}
|
||||
<a href="{{ remora_url('/versions/license/{0}'|f(version.id)) }}">
|
||||
{{ license.name }}</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -7,7 +7,7 @@ import amo
|
|||
from amo.urlresolvers import reverse
|
||||
from addons.models import Addon
|
||||
from versions import views
|
||||
from versions.models import License, Version
|
||||
from versions.models import Version
|
||||
from versions.compare import version_int, dict_from_int
|
||||
|
||||
|
||||
|
@ -85,52 +85,6 @@ class TestVersion(test_utils.TestCase):
|
|||
assert not self._get_version(amo.STATUS_PUBLIC).is_unreviewed
|
||||
|
||||
|
||||
class TestLicense(test_utils.TestCase):
|
||||
"""Test built-in as well as custom licenses."""
|
||||
|
||||
def test_defaults(self):
|
||||
lic = License()
|
||||
lic.save()
|
||||
assert lic.is_custom, 'Custom license not recognized.'
|
||||
assert lic.license_type is amo.LICENSE_CUSTOM # default
|
||||
assert not lic.text
|
||||
|
||||
lic.license_type = amo.LICENSE_MPL
|
||||
assert not lic.is_custom, 'Built-in license not recognized.'
|
||||
assert lic.text
|
||||
eq_(lic.url, amo.LICENSE_MPL.url)
|
||||
|
||||
def test_license(self):
|
||||
"""Test getters and setters for license."""
|
||||
mylicense = amo.LICENSE_MPL
|
||||
|
||||
lic = License()
|
||||
lic.license_type = mylicense
|
||||
lic.save()
|
||||
eq_(lic.license_type, mylicense)
|
||||
|
||||
def test_custom_text(self):
|
||||
"""Test getters and setters for custom text."""
|
||||
mytext = 'OMG'
|
||||
|
||||
lic = License()
|
||||
lic.text = mytext
|
||||
lic.save()
|
||||
lic2 = License.objects.get(pk=lic.pk)
|
||||
eq_(unicode(lic2.text), mytext)
|
||||
|
||||
def test_builtin_text(self):
|
||||
"""Get license text for all built-in licenses."""
|
||||
lic = License()
|
||||
for licensetype in amo.LICENSES:
|
||||
lic.license_type = licensetype
|
||||
if licensetype in (amo.LICENSE_CUSTOM, amo.LICENSE_COPYRIGHT,
|
||||
amo.LICENSE_CC_BY_NC_SA):
|
||||
assert not lic.text
|
||||
else:
|
||||
assert lic.text, "No license text for %s" % licensetype
|
||||
|
||||
|
||||
class TestViews(test_utils.TestCase):
|
||||
fixtures = ['addons/eula+contrib-addon', 'base/apps']
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
"pk": 1,
|
||||
"model": "versions.license",
|
||||
"fields": {
|
||||
"id": 1,
|
||||
"_custom_text": null,
|
||||
"modified": "2004-06-11 18:23:31",
|
||||
"created": "2004-06-11 18:23:31"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
ALTER TABLE licenses
|
||||
ADD COLUMN `url` varchar(200),
|
||||
ADD COLUMN `builtin` integer UNSIGNED NOT NULL DEFAULT 0,
|
||||
ADD COLUMN `on_form` bool NOT NULL DEFAULT false,
|
||||
ADD COLUMN `some_rights` bool NOT NULL DEFAULT false,
|
||||
ADD COLUMN `icons` varchar(255);
|
||||
|
||||
UPDATE licenses SET builtin=(name + 1) WHERE name <> -1;
|
||||
|
||||
ALTER TABLE licenses
|
||||
DROP COLUMN `name`;
|
||||
|
||||
ALTER TABLE licenses
|
||||
ADD COLUMN `name` int(11) UNSIGNED,
|
||||
ADD CONSTRAINT FOREIGN KEY (`name`) REFERENCES `translations` (`id`);
|
||||
|
||||
CREATE INDEX builtin_idx ON licenses (builtin);
|
Загрузка…
Ссылка в новой задаче