Merge lp:~sinzui/launchpad/licenses-0 into lp:launchpad/db-devel

Proposed by Curtis Hovey
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 9715
Proposed branch: lp:~sinzui/launchpad/licenses-0
Merge into: lp:launchpad/db-devel
Diff against target: 258 lines (+62/-50)
5 files modified
lib/canonical/widgets/product.py (+28/-26)
lib/canonical/widgets/templates/license.pt (+2/-2)
lib/lp/registry/doc/product-widgets.txt (+12/-8)
lib/lp/registry/interfaces/product.py (+10/-3)
lib/lp/registry/windmill/tests/test_project_licenses.py (+10/-11)
To merge this branch: bzr merge lp:~sinzui/launchpad/licenses-0
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+33916@code.launchpad.net

Description of the change

This is my branch to add the OFL and GFDL to the recognised licenses.

    lp:~sinzui/launchpad/licenses-0
    Diff size: 259
    Launchpad bug:
          https://bugs.launchpad.net/bugs/299734
          https://bugs.launchpad.net/bugs/616229
    Test command: ./bin/test -vv \
          -t product-widgets.txt -t test_project_licenses
    Pre-implementation: ~yosch
    Target release: 10.09

Add the OFL and GFDL to the recongnised licenses
------------------------------------------------

Add the OFL and GFDL licenses to the license enums and show them in the
second block of the license widget. We are doing OFL because Mark want it.
We postponed adding GFDL (no options) until after we had a license widget
that hide the rare licenses. We do, so this is a good time to add it.

Adding enums should be trivial. It is not. I was aware that the license widget
does odd things to make the licenses appear in AJAX enabled blocked. I added
an enum to learn what would break. The javascript and windmill tests both
broke because they assume that licenses 25 and 26 are the two special
licenses :(. I decided to fix the script. Then when I was done, I decided to
add the two licenses and be done quickly. Well it was not as quick as I hoped.

Rules
-----

    * Update the JS and windmill test to use the explicit other open source
      and other proprietary. Do not guess them by they number.
    * Add the enums.
    * Include them in the second block of the license widget.

QA
--

    * Visit https://staging.launchpad.net/launchpad/+edit
    * Verify you can see OFL and GFDL listed in the second block of licenses.

Lint
----

Linting changed files:
  lib/canonical/widgets/product.py
  lib/canonical/widgets/templates/license.pt
  lib/lp/registry/doc/product-widgets.txt
  lib/lp/registry/interfaces/product.py
  lib/lp/registry/windmill/tests/test_project_licenses.py

Test
----

    * lib/lp/registry/doc/product-widgets.txt
      * It was not obvious why adding two licenses change the order of several
        licenses. The answer is that the widget is creating an order for
        3 columns, and adding 2 licenses forces some licenses to the top of
        the next column :(
    * lib/lp/registry/windmill/tests/test_project_licenses.py
      * Updated the test to explicitly locate the OTHER_OPEN_SOURCE and
        OTHER_PROPRIETARY licenses...do not assume them by their number.

Implementation
--------------

    * lib/canonical/widgets/product.py
      * Added the OFL and GFDL to the "more" section of the widget. Fixed the
        dict spacing.
    * lib/canonical/widgets/templates/license.pt
      * Updated the script to locate the OTHER_OPEN_SOURCE and
        OTHER_PROPRIETARY licenses...do not assume them by their number.
    * lib/lp/registry/interfaces/product.py
      * Added the OFL and GFDL (no options) licenses to the enums.

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/widgets/product.py'
--- lib/canonical/widgets/product.py 2010-08-12 19:55:29 +0000
+++ lib/canonical/widgets/product.py 2010-08-28 15:58:43 +0000
@@ -264,33 +264,35 @@
264 allow_pending_license = False264 allow_pending_license = False
265265
266 CATEGORIES = {266 CATEGORIES = {
267 'AFFERO' : 'recommended',267 'AFFERO': 'recommended',
268 'APACHE' : 'recommended',268 'APACHE': 'recommended',
269 'BSD' : 'recommended',269 'BSD': 'recommended',
270 'GNU_GPL_V2' : 'recommended',270 'GNU_GPL_V2': 'recommended',
271 'GNU_GPL_V3' : 'recommended',271 'GNU_GPL_V3': 'recommended',
272 'GNU_LGPL_V2_1' : 'recommended',272 'GNU_LGPL_V2_1': 'recommended',
273 'GNU_LGPL_V3' : 'recommended',273 'GNU_LGPL_V3': 'recommended',
274 'MIT' : 'recommended',274 'MIT': 'recommended',
275 'CC_0' : 'recommended',275 'CC_0': 'recommended',
276 'ACADEMIC' : 'more',276 'ACADEMIC': 'more',
277 'ARTISTIC' : 'more',277 'ARTISTIC': 'more',
278 'ARTISTIC_2_0' : 'more',278 'ARTISTIC_2_0': 'more',
279 'COMMON_PUBLIC' : 'more',279 'COMMON_PUBLIC': 'more',
280 'ECLIPSE' : 'more',280 'ECLIPSE': 'more',
281 'EDUCATIONAL_COMMUNITY': 'more',281 'EDUCATIONAL_COMMUNITY': 'more',
282 'MPL' : 'more',282 'GNU_GFDL_NO_OPTIONS': 'more',
283 'OPEN_SOFTWARE' : 'more',283 'MPL': 'more',
284 'PHP' : 'more',284 'OFL': 'more',
285 'PUBLIC_DOMAIN' : 'more',285 'OPEN_SOFTWARE': 'more',
286 'PYTHON' : 'more',286 'PHP': 'more',
287 'ZPL' : 'more',287 'PUBLIC_DOMAIN': 'more',
288 'CC_BY' : 'more',288 'PYTHON': 'more',
289 'CC_BY_SA' : 'more',289 'ZPL': 'more',
290 'PERL' : 'deprecated',290 'CC_BY': 'more',
291 'OTHER_PROPRIETARY' : 'special',291 'CC_BY_SA': 'more',
292 'OTHER_OPEN_SOURCE' : 'special',292 'PERL': 'deprecated',
293 'DONT_KNOW' : 'special',293 'OTHER_PROPRIETARY': 'special',
294 'OTHER_OPEN_SOURCE': 'special',
295 'DONT_KNOW': 'special',
294 }296 }
295297
296 items_by_category = None298 items_by_category = None
297299
=== modified file 'lib/canonical/widgets/templates/license.pt'
--- lib/canonical/widgets/templates/license.pt 2010-08-10 20:02:08 +0000
+++ lib/canonical/widgets/templates/license.pt 2010-08-28 15:58:43 +0000
@@ -101,8 +101,8 @@
101101
102 // When Other/Proprietary or Other/Open Source is chosen, the102 // When Other/Proprietary or Other/Open Source is chosen, the
103 // license_info widget is displayed.103 // license_info widget is displayed.
104 var other_com = Y.get(Y.DOM.byId('field.licenses.25'));104 var other_com = Y.get('input[value=OTHER_PROPRIETARY]');
105 var other_os = Y.get(Y.DOM.byId('field.licenses.26'));105 var other_os = Y.get('input[value=OTHER_OPEN_SOURCE]');
106 var details = Y.get('#license-details');106 var details = Y.get('#license-details');
107 var proprietary = Y.get('#proprietary');107 var proprietary = Y.get('#proprietary');
108108
109109
=== modified file 'lib/lp/registry/doc/product-widgets.txt'
--- lib/lp/registry/doc/product-widgets.txt 2010-06-16 16:26:49 +0000
+++ lib/lp/registry/doc/product-widgets.txt 2010-08-28 15:58:43 +0000
@@ -250,7 +250,8 @@
250 >>> license_widget = LicenseWidget(licenses_field, vtype, request)250 >>> license_widget = LicenseWidget(licenses_field, vtype, request)
251251
252The widget has one checkbox for each license, and it also has a link to the252The widget has one checkbox for each license, and it also has a link to the
253license policy. The licenses are split up into categories.253license policy. The licenses are split up into categories, and they are
254presented ordered to appear in a 3 column list.
254255
255 >>> from canonical.launchpad.testing.pages import find_tag_by_id256 >>> from canonical.launchpad.testing.pages import find_tag_by_id
256257
@@ -268,20 +269,23 @@
268269
269 >>> print extract_text(find_tag_by_id(html, 'more'))270 >>> print extract_text(find_tag_by_id(html, 'more'))
270 Academic Free License view license271 Academic Free License view license
271 Creative Commons - Attribution Share Alike view license272 Eclipse Public License view license
272 PHP License view license273 PHP License view license
273 Artistic License 1.0 view license274 Artistic License 1.0 view license
274 Eclipse Public License view license275 Educational Community License view license
275 Public Domain view license276 Public Domain view license
276 Artistic License 2.0 view license277 Artistic License 2.0 view license
277 Educational Community License view license278 GNU GFDL no options view license
278 Python License view license279 Python License view license
279 Common Public License view license280 Common Public License view license
280 Mozilla Public License view license281 Mozilla Public License view license
281 Zope Public License view license282 Zope Public License view license
282 Creative Commons - Attribution view license283 Creative Commons - Attribution view license
284 Open Font License v1.1 view license
285 Creative Commons - Attribution Share Alike view license
283 Open Software License v 3.0 view license286 Open Software License v 3.0 view license
284287
288
285 >>> print extract_text(find_tag_by_id(html, 'special'))289 >>> print extract_text(find_tag_by_id(html, 'special'))
286 I don't know yet290 I don't know yet
287 Other/Proprietary291 Other/Proprietary
@@ -368,10 +372,10 @@
368 ...372 ...
369 [ ] Creative Commons - No Rights Reserved ...373 [ ] Creative Commons - No Rights Reserved ...
370 ...374 ...
375 [ ] Creative Commons - Attribution ...
376 ...
371 [ ] Creative Commons - Attribution Share Alike ...377 [ ] Creative Commons - Attribution Share Alike ...
372 ...378 ...
373 [ ] Creative Commons - Attribution ...
374 ...
375379
376Any of the three Creative Commons licenses can be selected.380Any of the three Creative Commons licenses can be selected.
377381
@@ -384,10 +388,10 @@
384 ...388 ...
385 [X] Creative Commons - No Rights Reserved ...389 [X] Creative Commons - No Rights Reserved ...
386 ...390 ...
391 [X] Creative Commons - Attribution ...
392 ...
387 [X] Creative Commons - Attribution Share Alike ...393 [X] Creative Commons - Attribution Share Alike ...
388 ...394 ...
389 [X] Creative Commons - Attribution ...
390 ...
391395
392The BSD License can be selected.396The BSD License can be selected.
393397
394398
=== modified file 'lib/lp/registry/interfaces/product.py'
--- lib/lp/registry/interfaces/product.py 2010-08-22 19:26:46 +0000
+++ lib/lp/registry/interfaces/product.py 2010-08-28 15:58:43 +0000
@@ -236,9 +236,10 @@
236 'ACADEMIC', 'APACHE', 'ARTISTIC', 'ARTISTIC_2_0',236 'ACADEMIC', 'APACHE', 'ARTISTIC', 'ARTISTIC_2_0',
237 'BSD', 'COMMON_PUBLIC',237 'BSD', 'COMMON_PUBLIC',
238 'CC_BY', 'CC_BY_SA', 'CC_0', 'ECLIPSE',238 'CC_BY', 'CC_BY_SA', 'CC_0', 'ECLIPSE',
239 'EDUCATIONAL_COMMUNITY', 'AFFERO', 'GNU_GPL_V2', 'GNU_GPL_V3',239 'EDUCATIONAL_COMMUNITY', 'AFFERO', 'GNU_GFDL_NO_OPTIONS',
240 'GNU_LGPL_V2_1', 'GNU_LGPL_V3', 'MIT', 'MPL', 'OPEN_SOFTWARE', 'PERL',240 'GNU_GPL_V2', 'GNU_GPL_V3', 'GNU_LGPL_V2_1', 'GNU_LGPL_V3', 'MIT',
241 'PHP', 'PUBLIC_DOMAIN', 'PYTHON', 'ZPL',241 'MPL', 'OFL', 'OPEN_SOFTWARE', 'PERL', 'PHP', 'PUBLIC_DOMAIN',
242 'PYTHON', 'ZPL',
242 'DONT_KNOW', 'OTHER_PROPRIETARY', 'OTHER_OPEN_SOURCE')243 'DONT_KNOW', 'OTHER_PROPRIETARY', 'OTHER_OPEN_SOURCE')
243244
244 ACADEMIC = DBItem(245 ACADEMIC = DBItem(
@@ -316,6 +317,12 @@
316 CC_0 = DBItem(317 CC_0 = DBItem(
317 320, 'Creative Commons - No Rights Reserved',318 320, 'Creative Commons - No Rights Reserved',
318 url='http://creativecommons.org/about/cc0')319 url='http://creativecommons.org/about/cc0')
320 GNU_GFDL_NO_OPTIONS = DBItem(
321 330, "GNU GFDL no options",
322 url='http://www.gnu.org/copyleft/fdl.html')
323 OFL = DBItem(
324 340, "Open Font License v1.1",
325 url='http://scripts.sil.org/OFL')
319 # This is a placeholder "license" for users who know they want something326 # This is a placeholder "license" for users who know they want something
320 # open source but haven't yet chosen a license for their project. We do327 # open source but haven't yet chosen a license for their project. We do
321 # not want to block them from registering their project, but this choice328 # not want to block them from registering their project, but this choice
322329
=== modified file 'lib/lp/registry/windmill/tests/test_project_licenses.py'
--- lib/lp/registry/windmill/tests/test_project_licenses.py 2010-08-20 20:31:18 +0000
+++ lib/lp/registry/windmill/tests/test_project_licenses.py 2010-08-28 15:58:43 +0000
@@ -22,10 +22,9 @@
22 def test_project_licenses(self):22 def test_project_licenses(self):
23 """Test the dynamic aspects of the project license picker."""23 """Test the dynamic aspects of the project license picker."""
24 # The firefox project is as good as any.24 # The firefox project is as good as any.
25 self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit')
26 self.client.waits.forPageLoad(timeout=u'20000')
27
28 lpuser.SAMPLE_PERSON.ensure_login(self.client)25 lpuser.SAMPLE_PERSON.ensure_login(self.client)
26 self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit')
27 self.client.waits.forPageLoad(timeout=u'20000')
2928
30 # The Recommended table is visible.29 # The Recommended table is visible.
31 self.client.waits.forElementProperty(30 self.client.waits.forElementProperty(
@@ -64,7 +63,7 @@
64 option='className|lazr-closed')63 option='className|lazr-closed')
6564
66 # But clicking on one of the Other/* licenses exposes it.65 # But clicking on one of the Other/* licenses exposes it.
67 self.client.click(id='field.licenses.26')66 self.client.click(xpath='//input[@value = "OTHER_OPEN_SOURCE"]')
68 self.client.waits.forElementProperty(67 self.client.waits.forElementProperty(
69 id=u'license-details',68 id=u'license-details',
70 option='className|lazr-opened')69 option='className|lazr-opened')
@@ -75,7 +74,7 @@
75 id=u'proprietary',74 id=u'proprietary',
76 option='className|lazr-closed')75 option='className|lazr-closed')
7776
78 self.client.click(id='field.licenses.25')77 self.client.click(xpath='//input[@value = "OTHER_PROPRIETARY"]')
79 self.client.waits.forElementProperty(78 self.client.waits.forElementProperty(
80 id=u'license-details',79 id=u'license-details',
81 option='className|lazr-opened')80 option='className|lazr-opened')
@@ -85,12 +84,12 @@
8584
86 # Only when all Other/* items are unchecked does the details box get85 # Only when all Other/* items are unchecked does the details box get
87 # hidden.86 # hidden.
88 self.client.click(id='field.licenses.26')87 self.client.click(xpath='//input[@value = "OTHER_OPEN_SOURCE"]')
89 self.client.waits.forElementProperty(88 self.client.waits.forElementProperty(
90 id=u'license-details',89 id=u'license-details',
91 option='className|lazr-opened')90 option='className|lazr-opened')
9291
93 self.client.click(id='field.licenses.25')92 self.client.click(xpath='//input[@value = "OTHER_PROPRIETARY"]')
94 self.client.waits.forElementProperty(93 self.client.waits.forElementProperty(
95 id=u'license-details',94 id=u'license-details',
96 option='className|lazr-closed')95 option='className|lazr-closed')
@@ -101,17 +100,17 @@
101 # Clicking on "I haven't specified..." unchecks everything and100 # Clicking on "I haven't specified..." unchecks everything and
102 # closes the details box, but leaves the sections opened.101 # closes the details box, but leaves the sections opened.
103102
104 self.client.click(id='field.licenses.25')103 self.client.click(xpath='//input[@value = "OTHER_PROPRIETARY"]')
105 self.client.waits.forElementProperty(104 self.client.waits.forElementProperty(
106 id=u'license-details',105 id=u'license-details',
107 option='className|lazr-opened')106 option='className|lazr-opened')
108107
109 self.client.asserts.assertChecked(108 self.client.asserts.assertChecked(
110 id=u'field.licenses.25')109 xpath='//input[@value = "OTHER_PROPRIETARY"]')
111110
112 self.client.click(id='license_pending')111 self.client.click(id='license_pending')
113 self.client.asserts.assertNotChecked(112 self.client.asserts.assertNotChecked(
114 id=u'field.licenses.25')113 xpath='//input[@value = "OTHER_PROPRIETARY"]')
115114
116 self.client.asserts.assertProperty(115 self.client.asserts.assertProperty(
117 id=u'license-details',116 id=u'license-details',
@@ -121,7 +120,7 @@
121 # time the page is visited, those sections will be open. The120 # time the page is visited, those sections will be open. The
122 # Recommended section is always open.121 # Recommended section is always open.
123122
124 self.client.click(id='field.licenses.25')123 self.client.click(xpath='//input[@value = "OTHER_PROPRIETARY"]')
125 self.client.type(id='field.license_info', text='Foo bar')124 self.client.type(id='field.license_info', text='Foo bar')
126 self.client.click(id='field.licenses.3')125 self.client.click(id='field.licenses.3')
127 self.client.click(id='field.actions.change')126 self.client.click(id='field.actions.change')

Subscribers

People subscribed via source and target branches

to status/vote changes: