From 61ec9db6a2f1914af9a74345d35845270f261c1d Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:06:04 -0400 Subject: [PATCH 1/9] tab->spaces --- core/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/models.py b/core/models.py index fcbe59ad..88c03267 100755 --- a/core/models.py +++ b/core/models.py @@ -269,10 +269,10 @@ class Campaign(models.Model): def rightsholder(self): """returns the name of the rights holder for an active or initialized campaign""" try: - if self.status=='ACTIVE' or self.status=='INITIALIZED': - q = Q(status='ACTIVE') | Q(status='INITIALIZED') - rh = self.work.claim.filter(q)[0].rights_holder.rights_holder_name - return rh + if self.status=='ACTIVE' or self.status=='INITIALIZED': + q = Q(status='ACTIVE') | Q(status='INITIALIZED') + rh = self.work.claim.filter(q)[0].rights_holder.rights_holder_name + return rh except: pass return '' From 62c1d805477bcffde0bb8c0eaa39119a661e9cde Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:08:04 -0400 Subject: [PATCH 2/9] changed wording to be more open to non NC licenses [#29884981] --- frontend/templates/press.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/press.html b/frontend/templates/press.html index 8842a5f5..c5324a86 100644 --- a/frontend/templates/press.html +++ b/frontend/templates/press.html @@ -47,7 +47,7 @@
What?
Unglue.it offers a win-win solution to readers, who want to read and share their favorite books conveniently, and rights holders, who want to be rewarded for their work.

-We will run crowdfunding campaigns to raise money for specific, already-published books. When we reach goals set by the rights holders, we'll pay them to unglue their work. They'll issue an electronic edition with a Creative Commons BY-NC-ND license. This license will make the edition free and legal for everyone to read, copy, and share, noncommercially, worldwide.

+We will run crowdfunding campaigns to raise money for specific, already-published books. When we reach goals set by the rights holders, we'll pay them to unglue their work. They'll issue an electronic edition with a Creative Commons license as specified during the campaign. These licenses will make the edition free and legal for everyone to read, copy, and share, worldwide.

At present, in our alpha phase, we're not running live campaigns (though you may see some fake campaign data for testing purposes). However, most of the other features of the site -- such as searching for books, adding them to your wishlist, and personalizing your user profile -- work. We invite you to try them out and give us feedback.

Once we've fully tested our payment processes and user experience, we'll have a beta launch. At this point we'll announce our founding rights holders, run live campaigns, and invite everyone to join the site.
Why?
From f72796acdfe615387035fbb3ec606e84da46e302 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:10:56 -0400 Subject: [PATCH 3/9] factor license URL and badge into one class [#29884981] --- core/models.py | 97 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/core/models.py b/core/models.py index 88c03267..3294c22d 100755 --- a/core/models.py +++ b/core/models.py @@ -111,9 +111,10 @@ class CampaignAction(models.Model): type = models.CharField(max_length=15) comment = models.TextField(null=True, blank=True) campaign = models.ForeignKey("Campaign", related_name="actions", null=False) - -class Campaign(models.Model): - LICENSE_CHOICES = (('CC BY-NC-ND','CC BY-NC-ND'), + +class CCLicense(): + CCCHOICES = ( + ('CC BY-NC-ND','CC BY-NC-ND'), ('CC BY-ND','CC BY-ND'), ('CC BY','CC BY'), ('CC BY-NC','CC BY-NC'), @@ -121,6 +122,53 @@ class Campaign(models.Model): ( 'CC BY-SA','CC BY-SA'), ( 'CC0','CC0'), ) + CHOICES = CCCHOICES+(('PD-US', 'Public Domain, US'),) + + @classmethod + def url(klass, license): + if license == 'PD-US': + return 'http://creativecommons.org/publicdomain/mark/1.0/' + elif license == 'CC0': + return 'http://creativecommons.org/publicdomain/zero/1.0/' + elif license == 'CC BY': + return 'http://creativecommons.org/licenses/by/3.0/' + elif license == 'CC BY-NC-ND': + return 'http://creativecommons.org/licenses/by-nc-nd/3.0/' + elif license == 'CC BY-NC-SA': + return 'http://creativecommons.org/licenses/by-nc-sa/3.0/' + elif license == 'CC BY-NC': + return 'http://creativecommons.org/licenses/by-nc/3.0/' + elif license == 'CC BY-SA': + return 'http://creativecommons.org/licenses/by-sa/3.0/' + elif license == 'CC BY-ND': + return 'http://creativecommons.org/licenses/by-nd/3.0/' + else: + return '' + + @classmethod + def badge(klass,license): + if license == 'PD-US': + return 'https://i.creativecommons.org/p/mark/1.0/88x31.png' + elif license == 'CC0': + return 'https://i.creativecommons.org/p/zero/1.0/88x31.png' + elif license == 'CC BY': + return 'https://i.creativecommons.org/l/by/3.0/88x31.png' + elif license == 'CC BY-NC-ND': + return 'https://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png' + elif license == 'CC BY-NC-SA': + return 'https://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png' + elif license == 'CC BY-NC': + return 'https://i.creativecommons.org/l/by-nc/3.0/88x31.png' + elif license == 'CC BY-SA': + return 'https://i.creativecommons.org/l/by-sa/3.0/88x31.png' + elif license == 'CC BY-ND': + return 'https://i.creativecommons.org/l/by-nd/3.0/88x31.png' + else: + return '' + + +class Campaign(models.Model): + LICENSE_CHOICES = CCLicense.CCCHOICES created = models.DateTimeField(auto_now_add=True) name = models.CharField(max_length=500, null=True, blank=False) description = models.TextField(null=True, blank=False) @@ -276,6 +324,15 @@ class Campaign(models.Model): except: pass return '' + + @property + def license_url(self): + return CCLicense.url(self.license) + + @property + def license_badge(self): + return CCLicense.badge(self.license) + class Identifier(models.Model): # olib, ltwk, goog, gdrd, thng, isbn, oclc, olwk, olib, gute, glue @@ -610,15 +667,7 @@ class WasWork(models.Model): class Ebook(models.Model): FORMAT_CHOICES = (('pdf','PDF'),( 'epub','EPUB'), ('html','HTML'), ('text','TEXT'), ('mobi','MOBI')) - RIGHTS_CHOICES = (('PD-US', 'Public Domain, US'), - ('CC BY-NC-ND','CC BY-NC-ND'), - ('CC BY-ND','CC BY-ND'), - ('CC BY','CC BY'), - ('CC BY-NC','CC BY-NC'), - ( 'CC BY-NC-SA','CC BY-NC-SA'), - ( 'CC BY-SA','CC BY-SA'), - ( 'CC0','CC0'), - ) + RIGHTS_CHOICES = CCLicense.CHOICES url = models.URLField(max_length=1024) created = models.DateTimeField(auto_now_add=True) format = models.CharField(max_length=25, choices = FORMAT_CHOICES) @@ -635,27 +684,9 @@ class Ebook(models.Model): @property def rights_badge(self): - my_rights=self.rights - if not my_rights: - return 'https://i.creativecommons.org/p/mark/1.0/88x31.png' - if my_rights == 'PD-US': - return 'https://i.creativecommons.org/p/mark/1.0/88x31.png' - elif my_rights == 'CC0': - return 'https://i.creativecommons.org/p/zero/1.0/88x31.png' - elif my_rights == 'CC BY': - return 'https://i.creativecommons.org/l/by/3.0/88x31.png' - elif my_rights == 'CC BY-NC-ND': - return 'https://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png' - elif my_rights == 'CC BY-NC-SA': - return 'https://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png' - elif my_rights == 'CC BY-NC': - return 'https://i.creativecommons.org/l/by-nc/3.0/88x31.png' - elif my_rights == 'CC BY-SA': - return 'https://i.creativecommons.org/l/by-sa/3.0/88x31.png' - elif my_rights == 'CC BY-ND': - return 'https://i.creativecommons.org/l/by-nd/3.0/88x31.png' - else: - return '' + if self.rights is None : + return CCLicense.badge('PD-US') + return CCLicense.badge(self.rights) @classmethod def infer_provider(klass, url): From c61bc9985dc4f6e2783e04c632a36d925cc07671 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:12:16 -0400 Subject: [PATCH 4/9] test for factored license url [#29884981] --- core/tests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/tests.py b/core/tests.py index fdeaa71c..e8c920a9 100755 --- a/core/tests.py +++ b/core/tests.py @@ -350,7 +350,11 @@ class CampaignTests(TestCase): w = Work() w.save() c = Campaign(target=D('1000.00'), deadline=datetime(2013, 1, 1), work=w) + c.license = 'CC BY-NC' c.save() + self.assertEqual(c.license_url, 'http://creativecommons.org/licenses/by-nc/3.0/') + self.assertEqual(c.license_badge, 'https://i.creativecommons.org/l/by-nc/3.0/88x31.png') + def test_campaign_status(self): From bd5b062d24c6554ff3a6a53dda8c55feeae09a72 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:13:12 -0400 Subject: [PATCH 5/9] change manage_campaign to allow active campaigns to remove license restrictions [#29884981] --- frontend/forms.py | 16 +++++++++++++++- frontend/templates/manage_campaign.html | 5 +++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/frontend/forms.py b/frontend/forms.py index ce5701c8..a3b46716 100644 --- a/frontend/forms.py +++ b/frontend/forms.py @@ -241,7 +241,21 @@ def getManageCampaignForm ( instance, data=None, *args, **kwargs ): new_license = self.cleaned_data['license'] if self.instance: if self.instance.status == 'ACTIVE' and self.instance.license != new_license: - raise forms.ValidationError(_('The license for an ACTIVE campaign cannot be changed.')) + # should only allow change to a less restrictive license + if self.instance.license == 'CC BY-ND' and new_license == 'CC BY-NC-ND': + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC BY' and new_license != 'CC0': + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC BY-NC' and new_license in ['CC BY-NC-ND','CC BY-NC-SA','CC BY-SA','CC BY-ND']: + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC BY-ND' and new_license in ['CC BY-NC-ND','CC BY-NC-SA','CC BY-SA','CC BY-NC']: + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC BY-SA' and new_license in ['CC BY-NC-ND','CC BY-NC-SA','CC BY-ND','CC BY-NC']: + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC BY-NC-SA' and new_license in ['CC BY-NC-ND','CC BY-ND']: + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) + elif self.instance.license == 'CC0' : + raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) return new_license return ManageCampaignForm(instance = instance, data=data) diff --git a/frontend/templates/manage_campaign.html b/frontend/templates/manage_campaign.html index c6b3a38e..46c8d6b0 100644 --- a/frontend/templates/manage_campaign.html +++ b/frontend/templates/manage_campaign.html @@ -169,8 +169,9 @@ Please fix the following before launching your campaign: ${{ form.target.errors }}{{ form.target }}

License being offered

-

If your campaign succeeds, you will be offering your ebook under a {{ campaign.license }} license.

- {{ form.license.errors }}{{ form.license }} +

If your campaign succeeds, you will be offering your ebook under a {{ campaign.license }} license.

+

During a campaign, you may only change the license to remove restrictions. For more info on the licenses you can use, see Creative Commons: About the Licenses.

+ {{ form.license.errors }}{{ form.license }}

Ending date

The ending date of your campaign is {{ campaign.deadline }}. Your campaign will conclude on this date or when you meet your target price, whichever is earlier. You may not change the ending date of an active campaign.

{{ form.deadline.errors }}{{ form.deadline }} From 3de07e973f3dae84232a9848384efe41f3ab5f9a Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:22:12 -0400 Subject: [PATCH 6/9] [finish #29780503] add link to CC licence to rights tab of campaign page --- frontend/templates/work.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/work.html b/frontend/templates/work.html index 25b4b293..c1f3e004 100644 --- a/frontend/templates/work.html +++ b/frontend/templates/work.html @@ -278,7 +278,7 @@ $j(document).ready(function(){ {{ claim.rights_holder.rights_holder_name }} {% endif %} {% endfor %} - , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) if ungluers can join together to raise ${{ work.last_campaign.target|intcomma }} by {{ work.last_campaign.deadline }}. + , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) if ungluers can join together to raise ${{ work.last_campaign.target|intcomma }} by {{ work.last_campaign.deadline }}. You can help!

Campaign details: the fine print

From e61a818ad3cf79fab46ca4cce59f40028aa288b1 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 00:55:41 -0400 Subject: [PATCH 7/9] [finish #29885177] redirect user after login instead of just displaying link --- frontend/templates/registration/registration_base.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/templates/registration/registration_base.html b/frontend/templates/registration/registration_base.html index 62882f39..01cc28ee 100644 --- a/frontend/templates/registration/registration_base.html +++ b/frontend/templates/registration/registration_base.html @@ -21,7 +21,8 @@ $j(document).ready(function() { next = next.replace(/[\x22\x27\x3c\x3e]/g,''); $j.cookie('next', next, {path: '/'}); } else if(saved_next!=null){ - $j('#link-to-next').html(" Click to continue after logging in..."); + var do_next = $j('#link-to-next'); + if (do_next.length) window.location.replace(saved_next); } }); From 22933b4ff5beb6c1151921c90c6e061a342cdb0a Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 20 May 2012 13:35:06 -0400 Subject: [PATCH 8/9] Corrected api documentation error; added test for identifier api [finish #29892487] --- api/templates/api_help.html | 2 +- api/tests.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/api/templates/api_help.html b/api/templates/api_help.html index 0b921cec..c2a3336e 100644 --- a/api/templates/api_help.html +++ b/api/templates/api_help.html @@ -23,7 +23,7 @@ {{base_url}}/api/v1/campaign/?format=json&api_key={api_key}&username={username}

Identifier Resolution

JSON to get work/edition data for an isbn

- {{base_url}}/api/v1/identifier/?format=json&api_key={api_key}&ype=isbn&value=9780441012039 + {{base_url}}/api/v1/identifier/?format=json&api_key={api_key}&username={username}&ype=isbn&value=9780441012039

In addition to isbn, you can use 'goog' if you have a google books id, and 'oclc' for oclc numbers.

{% endif %} diff --git a/api/tests.py b/api/tests.py index 7d04ee89..755340d8 100755 --- a/api/tests.py +++ b/api/tests.py @@ -70,6 +70,16 @@ class ApiTests(TestCase): self.assertEqual(j['meta']['logged_in_username'], None) self.assertEqual(j['objects'][0]['in_wishlist'], False) + def test_identifier_lookup(self): + r = self.client.get('/api/v1/identifier/', data={ + 'format': 'json', + 'value': regluit.core.isbn.convert_10_to_13('0441012035'), + 'type': 'isbn', + 'username': self.user.username, + 'api_key': self.user.api_key.key + }) + self.assertEqual(r.status_code, 200) + def test_logged_in_user_info(self): # login and see if adding a work to the users wishlist causes # it to show up as in_wishlist in the campaign info From 04d8c80cfff117cbd57cfdd674b29d9d60cbb988 Mon Sep 17 00:00:00 2001 From: eric Date: Mon, 21 May 2012 09:25:38 -0400 Subject: [PATCH 9/9] correct license test with correction from AY [#29884981] --- frontend/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/forms.py b/frontend/forms.py index a3b46716..783a5464 100644 --- a/frontend/forms.py +++ b/frontend/forms.py @@ -242,7 +242,7 @@ def getManageCampaignForm ( instance, data=None, *args, **kwargs ): if self.instance: if self.instance.status == 'ACTIVE' and self.instance.license != new_license: # should only allow change to a less restrictive license - if self.instance.license == 'CC BY-ND' and new_license == 'CC BY-NC-ND': + if self.instance.license == 'CC BY-ND' and new_license in ['CC BY-NC-ND','CC BY-NC-SA','CC BY-NC']: raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.')) elif self.instance.license == 'CC BY' and new_license != 'CC0': raise forms.ValidationError(_('The proposed license for an ACTIVE campaign may not add restrictions.'))