diff --git a/core/fixtures/initial_data.json b/core/fixtures/initial_data.json index 70f557cc..67497d15 100644 --- a/core/fixtures/initial_data.json +++ b/core/fixtures/initial_data.json @@ -99,7 +99,15 @@ "model": "core.badge", "fields": { "name": "pledger", - "description": "has made a pledge in at least one ungluing campaign" + "description": "a pledger" + } + }, + { + "pk": 2, + "model": "core.badge", + "fields": { + "name": "pledger2", + "description": "a repeat pledger" } } ] diff --git a/core/lookups.py b/core/lookups.py index a65e6134..0a4c5203 100644 --- a/core/lookups.py +++ b/core/lookups.py @@ -5,6 +5,6 @@ from django.contrib.auth.models import User class OwnerLookup(ModelLookup): model = User - search_field = 'username__icontains' + search_fields = ('username__icontains',) registry.register(OwnerLookup) \ No newline at end of file diff --git a/core/management/commands/initialize_pledge_badges.py b/core/management/commands/initialize_pledge_badges.py new file mode 100644 index 00000000..3ef6cd5c --- /dev/null +++ b/core/management/commands/initialize_pledge_badges.py @@ -0,0 +1,34 @@ +""" +set the 'pledged' badge for people who've pledged +""" + +from django.core.management.base import BaseCommand +from django.contrib.auth.models import User +from regluit.core.models import Badge +from regluit.payment.models import Transaction + +class Command(BaseCommand): + help = "for people who've pledged, give them a badge!" + + + def handle(self, **options): + pledger= Badge.objects.get(name='pledger') + pledger2= Badge.objects.get(name='pledger2') + print 'start' + print 'pledger badges: %s' % pledger.holders.all().count() + print 'pledger2 badges: %s' % pledger2.holders.all().count() + pledges=Transaction.objects.exclude(status='NONE').exclude(status='Canceled',reason=None).exclude(anonymous=True) + for pledge in pledges: + if pledge.user.profile.badges.all().count(): + if pledge.user.profile.badges.all()[0].id == pledger.id: + pledge.user.profile.badges.remove(pledger) + pledge.user.profile.badges.add(pledger2) + else: + pledge.user.profile.badges.add(pledger) + print 'end' + print 'pledger badges: %s' % pledger.holders.all().count() + print 'pledger2 badges: %s' % pledger2.holders.all().count() + + + + diff --git a/core/models.py b/core/models.py index 94416c28..1d7a4c8b 100755 --- a/core/models.py +++ b/core/models.py @@ -957,6 +957,25 @@ class Wishes(models.Model): class Meta: db_table = 'core_wishlist_works' +class Badge(models.Model): + name = models.CharField(max_length=72, blank=True) + description = models.TextField(default='', null=True) + + @property + def path(self): + return '/static/images/%s.png' % self.name + +def pledger(): + if not pledger.instance: + pledger.instance = Badge.objects.get(name='pledger') + return pledger.instance +pledger.instance=None +def pledger2(): + if not pledger2.instance: + pledger2.instance = Badge.objects.get(name='pledger2') + return pledger2.instance +pledger2.instance=None + class UserProfile(models.Model): created = models.DateTimeField(auto_now_add=True) user = models.OneToOneField(User, related_name='profile') @@ -972,12 +991,23 @@ class UserProfile(models.Model): goodreads_user_name = models.CharField(max_length=200, null=True, blank=True) goodreads_auth_token = models.TextField(null=True, blank=True) goodreads_auth_secret = models.TextField(null=True, blank=True) - goodreads_user_link = models.CharField(max_length=200, null=True, blank=True) - -class Badge(models.Model): - name = models.CharField(max_length=72, blank=True) - description = models.TextField(default='', null=True) + goodreads_user_link = models.CharField(max_length=200, null=True, blank=True) + def reset_pledge_badge(self): + #count user pledges + n_pledges = self.pledge_count + if self.badges.exists(): + self.badges.remove(pledger()) + self.badges.remove(pledger2()) + if n_pledges == 1: + self.badges.add(pledger()) + elif n_pledges > 1: + self.badges.add(pledger2()) + + @property + def pledge_count(self): + return self.user.transaction_set.exclude(status='NONE').exclude(status='Canceled',reason=None).exclude(anonymous=True).count() + #class CampaignSurveyResponse(models.Model): # # generic # campaign = models.ForeignKey("Campaign", related_name="surveyresponse", null=False) diff --git a/core/signals.py b/core/signals.py index 03e3f869..afebdbc1 100644 --- a/core/signals.py +++ b/core/signals.py @@ -177,6 +177,8 @@ def handle_pledge_modified(sender, transaction=None, up_or_down=None, **kwargs): # up_or_down is 'increased', 'decreased', or 'canceled' if transaction==None or up_or_down==None: return + if up_or_down == 'canceled': + transaction.user.profile.reset_pledge_badge() notification.queue([transaction.user], "pledge_status_change", { 'site':Site.objects.get_current(), 'transaction': transaction, @@ -190,6 +192,11 @@ pledge_modified.connect(handle_pledge_modified) def handle_you_have_pledged(sender, transaction=None, **kwargs): if transaction==None: return + + #give user a badge + if not transaction.anonymous: + transaction.user.profile.reset_pledge_badge() + notification.queue([transaction.user], "pledge_you_have_pledged", { 'site':Site.objects.get_current(), 'transaction': transaction diff --git a/frontend/forms.py b/frontend/forms.py index 80ec80be..9a4161b5 100644 --- a/frontend/forms.py +++ b/frontend/forms.py @@ -307,7 +307,7 @@ class CampaignPledgeForm(forms.Form): decimal_places=2, label="Pledge Amount", ) - anonymous = forms.BooleanField(required=False, label=_("Don't display my name in the acknowledgements")) + anonymous = forms.BooleanField(required=False, label=_("Make this pledge anonymous, please")) ack_name = forms.CharField(required=False, max_length=64, label=_("What name should we display?")) ack_dedication = forms.CharField(required=False, max_length=140, label=_("Your dedication:")) diff --git a/frontend/templates/manage_campaign.html b/frontend/templates/manage_campaign.html index 13f39a01..c515c93c 100644 --- a/frontend/templates/manage_campaign.html +++ b/frontend/templates/manage_campaign.html @@ -214,13 +214,14 @@ Please fix the following before launching your campaign:

{{ form.paypal_receiver.errors }}{{ form.paypal_receiver }}

- {% if not is_preview or request.user.is_staff %} - {% ifequal campaign_status 'ACTIVE' %} + {% ifequal campaign_status 'ACTIVE' %}
When you click this button, your changes will be visible to supporters immediately. Make sure to proofread!

- {% else %} + {% else %}

- {% endifequal %} + {% endifequal %} + + {% if not is_preview or request.user.is_staff %} {% if campaign_status == 'INITIALIZED' %} {% endif %} @@ -240,7 +241,6 @@ Please fix the following before launching your campaign: ${{ premium.amount|intcomma }} {{ premium.description }} - {% if premium.type %}
Type: {{ premium.get_type_display }}
{% endif %} {% ifnotequal premium.limit 0 %}
Limit: {{ premium.limit }}{% endifnotequal %} {% ifequal premium.type 'CU' %}
Deactivate? {% endifequal %} @@ -251,9 +251,7 @@ Please fix the following before launching your campaign: {% endif %} -

Editing premiums

-

At this time, you can't edit a premium you've created. But you can deactivate a premium and add a new one to replace it. So be sure to double-check your spelling before adding it.

-

Add a custom premium for this campaign

+

Add a premium for this campaign

{% csrf_token %} Pledge Amount: {{ premium_form.amount.errors }}${{ premium_form.amount }}
@@ -264,6 +262,8 @@ Please fix the following before launching your campaign:
+

Editing premiums

+

At this time, you can't edit a premium you've created. But you can deactivate a premium and add a new one to replace it. So be sure to double-check your spelling before adding it.

{% ifequal campaign_status 'INITIALIZED' %} diff --git a/frontend/templates/pledge.html b/frontend/templates/pledge.html index fc6db727..84173b09 100644 --- a/frontend/templates/pledge.html +++ b/frontend/templates/pledge.html @@ -109,11 +109,12 @@
Depending on your pledge amount, you'll also get these acknowledgements.
Any amount
The unglued ebook will be delivered to your inbox.
-
$25+
You'll be listed on the acknowledgements page of the unglued ebook. {{ form.ack_name.label_tag }} {{ form.ack_name.errors }}{{ form.ack_name }}
{{ form.anonymous.label_tag }} {{ form.anonymous.errors }}{{ form.anonymous }}
+
$25+
You'll be listed on the acknowledgements page of the unglued ebook. {{ form.ack_name.label_tag }} {{ form.ack_name.errors }}{{ form.ack_name }}
$100+
Your acknowledgement can include a dedication (140 characters max). {{ form.ack_dedication.label_tag }} {{ form.ack_dedication.errors }}{{ form.ack_dedication }}
- +
{{ form.anonymous.label_tag }} {{ form.anonymous.errors }}{{ form.anonymous }}
+ {% comment %} When the pledge amount and premium are in an inconsistent state, the real button is disabled and (via css) hidden; instead we display this fake button with a helpful message. It's a button so we can reuse all the existing CSS for buttons, so that it looks like the real button has just changed in appearance. It's hidden and the other one un-disabled and un-hidden when the pledge & premium return to a correct state. People without javascript enabled will miss out on the front-end corrections but form validation will catch it. diff --git a/frontend/templates/rh_tools.html b/frontend/templates/rh_tools.html index aaa47ccc..37daada2 100644 --- a/frontend/templates/rh_tools.html +++ b/frontend/templates/rh_tools.html @@ -2,10 +2,10 @@ {% block title %}Tools for Rightsholders {% endblock %} {% block extra_extra_head %} - + - + {% endblock %} diff --git a/frontend/templates/supporter.html b/frontend/templates/supporter.html index 158f8670..d89b2c06 100644 --- a/frontend/templates/supporter.html +++ b/frontend/templates/supporter.html @@ -22,8 +22,7 @@ var $j = jQuery.noConflict(); $j(document).ready(function(){ $j('#user-block-hide').hide(); - $j('#user-block1 span').click(function() { - $j(this).toggleClass("active"); + $j('#edit_profile').click(function() { $j("#user-block-hide").slideToggle(300); }); }); @@ -66,8 +65,6 @@ function highlightTarget(targetdiv) { {% comment %} To do: create topsection file for inclusion in multiple contexts, if needed -figure out how to configure date display - decide if we're even including date joined in profile Goodreads be sure words display correctlydja do I need both add-wishlist and remove-wishlist classes? do they differ? @@ -91,46 +88,51 @@ there's no tab for seeing ALL my books, only the filters! huh.
- {% ifequal supporter request.user %}
-
- My Profile -
+
+ {% if supporter.profile.pic_url %} + Picture of {{ supporter }} + {% else %} + Generic Ungluer Avatar + {% endif %} + + {{ supporter.username }} + +
+ + {% if supporter.profile.badges.all %} + {% for badge in supporter.profile.badges.all %} + {{ badge.description }} + {% endfor %} + {% endif %} +
+
- {% if supporter.profile.pic_url %} - Picture of {{ supporter }} - {% else %} - Generic Ungluer Avatar - {% endif %} - {{ supporter.username|truncatechars:20 }} - {{ date }} - {{ supporter.profile.tagline }} + + {% with supporter.profile.tagline as tagline %}{% if tagline %}{{ tagline }}{% else %} {% endif %}{% endwith %} +
- {% else %} -
-
- {% if supporter.profile.pic_url %} - Picture of {{ supporter }} - {% else %} - Generic Ungluer Avatar - {% endif %} - {{ supporter.username }} - {{ date }} -
-
-
- {% with supporter.profile.tagline as tagline %}{% if tagline %}{{ tagline }}{% else %} {% endif %}{% endwith %} -
- {% endifequal %} +
- I've unglued {{ backed }} - I'm ungluing {{ backing }} - I'm wishing for {{ wished }} + {% ifequal request.user supporter %} + I've unglued {{ backed }} + I'm ungluing {{ backing }} + I'm wishing for {{ wished }} + {% else %} + has unglued {{ backed }} + is ungluing {{ backing }} + is wishing for {{ wished }} + {% endifequal %}
+ {% ifequal request.user supporter %} +
+ Edit Your Profile +
+ {% endifequal %}