diff --git a/branch.sql b/branch.sql new file mode 100644 index 0000000000..f8c05fab14 --- /dev/null +++ b/branch.sql @@ -0,0 +1,8 @@ +------------------------------------------------------------------------------- +-- https://github.com/gittip/www.gittip.com/issues/1683 + +BEGIN; + ALTER TABLE participants RENAME COLUMN anonymous TO anonymous_giving; + ALTER TABLE participants ADD COLUMN anonymous_receiving bool NOT NULL DEFAULT FALSE; + ALTER TABLE homepage_top_receivers ADD COLUMN anonymous boolean; +END; diff --git a/gittip/models/participant.py b/gittip/models/participant.py index 4677c087ca..e01a7e825b 100644 --- a/gittip/models/participant.py +++ b/gittip/models/participant.py @@ -674,9 +674,9 @@ def get_og_title(self): out = self.username receiving = self.get_dollars_receiving() giving = self.get_dollars_giving() - if (giving > receiving) and not self.anonymous: + if (giving > receiving) and not self.anonymous_giving: out += " gives $%.2f/wk" % giving - elif receiving > 0: + elif receiving > 0 and not self.anonymous_receiving: out += " receives $%.2f/wk" % receiving else: out += " is" diff --git a/gittip/testing/__init__.py b/gittip/testing/__init__.py index 099aa3d929..779f70b126 100644 --- a/gittip/testing/__init__.py +++ b/gittip/testing/__init__.py @@ -152,8 +152,12 @@ def make_participant(self, username, **kw): participant = Participant.with_random_username() participant.change_username(username) + return self.update_participant(participant, **kw) + + def update_participant(self, participant, **kw): if 'elsewhere' in kw or 'claimed_time' in kw: + username = participant.username platform = kw.pop('elsewhere', 'github') user_info = dict(login=username) self.seq += 1 diff --git a/gittip/utils/__init__.py b/gittip/utils/__init__.py index cfddc565f0..1ea281a918 100644 --- a/gittip/utils/__init__.py +++ b/gittip/utils/__init__.py @@ -365,8 +365,8 @@ def update_homepage_queries_once(db): cursor.execute("DELETE FROM homepage_top_givers") cursor.execute(""" - INSERT INTO homepage_top_givers - SELECT tipper AS username, anonymous, sum(amount) AS amount + INSERT INTO homepage_top_givers (username, anonymous, amount) + SELECT tipper, anonymous_giving, sum(amount) AS amount FROM ( SELECT DISTINCT ON (tipper, tippee) amount , tipper @@ -382,7 +382,7 @@ def update_homepage_queries_once(db): ) AS foo JOIN participants p ON p.username = tipper WHERE is_suspicious IS NOT true - GROUP BY tipper, anonymous + GROUP BY tipper, anonymous_giving ORDER BY amount DESC; """.strip()) @@ -408,8 +408,8 @@ def update_homepage_queries_once(db): cursor.execute("DELETE FROM homepage_top_receivers") cursor.execute(""" - INSERT INTO homepage_top_receivers - SELECT tippee AS username, claimed_time, sum(amount) AS amount + INSERT INTO homepage_top_receivers (username, anonymous, amount, claimed_time) + SELECT tippee, anonymous_receiving, sum(amount) AS amount, claimed_time FROM ( SELECT DISTINCT ON (tipper, tippee) amount , tippee @@ -424,7 +424,7 @@ def update_homepage_queries_once(db): ) AS foo JOIN participants p ON p.username = tippee WHERE is_suspicious IS NOT true - GROUP BY tippee, claimed_time + GROUP BY tippee, anonymous_receiving, claimed_time ORDER BY amount DESC; """.strip()) diff --git a/gittip/utils/fake_data.py b/gittip/utils/fake_data.py index 7fd8e499d1..299698c3a4 100644 --- a/gittip/utils/fake_data.py +++ b/gittip/utils/fake_data.py @@ -57,7 +57,7 @@ def fake_sentence(start=1, stop=100): return faker.sentence(random.randrange(start,stop)) -def fake_participant(db, number="singular", is_admin=False, anonymous=False): +def fake_participant(db, number="singular", is_admin=False): """Create a fake User. """ username = faker.first_name() + fake_text_id(3) @@ -70,7 +70,8 @@ def fake_participant(db, number="singular", is_admin=False, anonymous=False): , ctime=faker.date_time_this_year() , is_admin=is_admin , balance=fake_balance() - , anonymous=anonymous + , anonymous_giving=(random.randrange(5) == 0) + , anonymous_receiving=(random.randrange(5) == 0) , goal=fake_balance() , balanced_account_uri=faker.uri() , last_ach_result='' diff --git a/js/gittip/profile.js b/js/gittip/profile.js index a46ba6bfa2..da95f89f31 100644 --- a/js/gittip/profile.js +++ b/js/gittip/profile.js @@ -215,13 +215,34 @@ Gittip.profile.init = function() { // Wire up aggregate giving knob. // ============================== - $('.anonymous input').click(function() { + $('.anonymous-giving input').click(function() { jQuery.ajax( { url: 'anonymous.json' , type: 'POST' + , data: {toggle: 'giving'} , dataType: 'json' , success: function(data) { - $('.anonymous input').attr('checked', data.anonymous); + $('.anonymous-giving input').attr('checked', data.giving); + } + , error: function() { + alert("Failed to change your anonymity preference. Please try again."); + } + } + ); + }); + + + // Wire up aggregate receiving knob. + // ============================== + + $('.anonymous-receiving input').click(function() { + jQuery.ajax( + { url: 'anonymous.json' + , type: 'POST' + , data: {toggle: 'receiving'} + , dataType: 'json' + , success: function(data) { + $('.anonymous-receiving input').attr('checked', data.receiving); } , error: function() { alert("Failed to change your anonymity preference. Please try again."); diff --git a/js/gittip/tips.js b/js/gittip/tips.js index 877dbb02dd..4c49b6b0bf 100644 --- a/js/gittip/tips.js +++ b/js/gittip/tips.js @@ -85,11 +85,11 @@ Gittip.tips.init = function() { $myTip.change(); // update display - $('.total-giving').text(data.total_giving); + $('.my-total-giving').text('$'+data.total_giving); $('.total-receiving').text( // check and see if we are on our giving page or not new RegExp('/' + tippee + '/').test(window.location.href) ? - data.total_receiving_tippee : data.total_receiving); + '$'+data.total_receiving_tippee : '$'+data.total_receiving); // Increment an elsewhere receiver's "people ready to give" if(!oldAmount) diff --git a/templates/base.html b/templates/base.html index e10c2e1c8e..2db7768780 100644 --- a/templates/base.html +++ b/templates/base.html @@ -50,7 +50,10 @@

{{ user.participant.username }}sign out
- Giving: ${{ user.participant.get_dollars_giving() }}/wk
+ Giving: + ${{ user.participant.get_dollars_giving() }}/wk + +
Receiving: ${{ user.participant.get_dollars_receiving() }}/wk
diff --git a/templates/participant.html b/templates/participant.html index b3812ab0e8..a2b1c0b958 100644 --- a/templates/participant.html +++ b/templates/participant.html @@ -2,47 +2,45 @@ {% block box %} +{% set prefix = user.participant == participant and "my-" or "" %} +{% set anon_giving = participant.anonymous_giving %} +{% set g = participant.get_dollars_giving() %} +{% set giving = anon_giving and "anonymously" or "$"+str(g) %} +{% set anon_receiving = participant.anonymous_receiving %} +{% set r = participant.get_dollars_receiving() %} +{% set receiving = anon_receiving and "anonymously" or "$"+str(r) %} +
- {% set giving = participant.get_dollars_giving() %} - {% set receiving = participant.get_dollars_receiving() %} - - {% if giving > receiving and not participant.anonymous %} + {% if anon_giving and anon_receiving %} +

{{ participant.username }}

+
gives and receives anonymously
+ {% elif not anon_giving and g > 0 and (g > r or anon_receiving) %}

{{ participant.username }} gives

- {% if user.participant == participant %} - ${{ giving }} - {% else %} - ${{ giving }} - {% endif %} + {{ giving }}
-
per - week{% if receiving > 0 %}, and receives ${{ receiving }}{% endif %} +
+ per week{% if r > 0 %}, and receives {{ receiving }}{% endif %}
- {% elif receiving > 0 %} + {% elif not anon_receiving and r > 0 and (r >= g or anon_giving) %}

{{ participant.username }} receives

-
${{ receiving }}
-
per - week{% if giving > 0 %}, and gives - {% if participant.anonymous %} - anonymously - {% elif user.participant == participant %} - ${{ giving }} - {% else %} - ${{ giving }} - {% endif %} +
+ {{ receiving }} +
+
+ per week{% if g > 0 %}, and gives + {{ giving }} {% endif %}
{% else %} {% set age = participant.get_age_in_seconds() %}

{{ participant.username }} - {% if giving > 0 %} - gives anonymously - {% elif age < 60 %} + {% if age < 60 %} just joined Gittip! :D {% elif age < (60 * 60 * 24 * 7) %} joined recently diff --git a/templates/profile-edit.html b/templates/profile-edit.html index fb1f521a82..3c5b7c0848 100644 --- a/templates/profile-edit.html +++ b/templates/profile-edit.html @@ -16,11 +16,17 @@

Have you linked to your Gittip profile from other

-

diff --git a/tests/test_anonymous_json.py b/tests/test_anonymous_json.py index f3eb2e7c5d..2cc986c80b 100644 --- a/tests/test_anonymous_json.py +++ b/tests/test_anonymous_json.py @@ -10,25 +10,36 @@ def setUp(self): Harness.setUp(self) self.make_participant('alice') - def hit_anonymous(self, method='GET', expected_code=200): - response = self.client.hit(method, "/alice/anonymous.json", auth_as='alice') + def hit_anonymous(self, method='GET', expected_code=200, **kw): + response = self.client.hit(method, "/alice/anonymous.json", auth_as='alice', **kw) if response.code != expected_code: print(response.body) return response - def test_participant_can_get_their_anonymity_setting(self): + def test_participant_can_get_their_anonymity_settings(self): response = self.hit_anonymous('GET') - actual = json.loads(response.body)['anonymous'] + actual = json.loads(response.body) + assert actual == {'giving': False, 'receiving': False} + + def test_participant_can_toggle_anonymous_giving(self): + response = self.hit_anonymous('POST', data={'toggle': 'giving'}) + actual = json.loads(response.body) + assert actual['giving'] is True + + def test_participant_can_toggle_anonymous_receiving(self): + response = self.hit_anonymous('POST', data={'toggle': 'receiving'}) + actual = json.loads(response.body) + assert actual['receiving'] is True + + def test_participant_can_toggle_anonymous_giving_back(self): + response = self.hit_anonymous('POST', data={'toggle': 'giving'}) + response = self.hit_anonymous('POST', data={'toggle': 'giving'}) + actual = json.loads(response.body)['giving'] assert actual is False - def test_participant_can_toggle_their_anonymity_setting(self): - response = self.hit_anonymous('POST') - actual = json.loads(response.body)['anonymous'] - assert actual is True - - def test_participant_can_toggle_their_anonymity_setting_back(self): - response = self.hit_anonymous('POST') - response = self.hit_anonymous('POST') - actual = json.loads(response.body)['anonymous'] + def test_participant_can_toggle_anonymous_receiving_back(self): + response = self.hit_anonymous('POST', data={'toggle': 'receiving'}) + response = self.hit_anonymous('POST', data={'toggle': 'receiving'}) + actual = json.loads(response.body)['receiving'] assert actual is False diff --git a/tests/test_pages.py b/tests/test_pages.py index a4b8e27e78..480d6bf817 100644 --- a/tests/test_pages.py +++ b/tests/test_pages.py @@ -15,7 +15,18 @@ def test_homepage(self): def test_homepage_with_anonymous_giver(self): TwitterAccount(self.db, "bob", {}).opt_in("bob") - alice = self.make_participant('alice', anonymous=True, last_bill_result='') + alice = self.make_participant('alice', anonymous_giving=True, last_bill_result='') + alice.set_tip_to('bob', 1) + update_homepage_queries_once(self.db) + + actual = self.client.GET('/').body + expected = "Anonymous" + assert expected in actual + + def test_homepage_with_anonymous_receiver(self): + bob, _ = TwitterAccount(self.db, "bob", {}).opt_in("bob") + self.update_participant(bob.participant, anonymous_receiving=True, last_bill_result='') + alice = self.make_participant('alice', last_bill_result='', claimed_time='now') alice.set_tip_to('bob', 1) update_homepage_queries_once(self.db) diff --git a/tests/test_public_json.py b/tests/test_public_json.py index 29a094bbf8..83e69e7ce6 100644 --- a/tests/test_public_json.py +++ b/tests/test_public_json.py @@ -46,14 +46,25 @@ def test_anonymous_gets_giving(self): def test_anonymous_gets_null_giving_if_user_anonymous(self): alice = self.make_participant( 'alice' , last_bill_result='' - , anonymous=True - ) + , anonymous_giving=True + ) self.make_participant('bob') alice.set_tip_to('bob', '1.00') data = json.loads(self.client.GET('/alice/public.json').body) assert data['giving'] == None + def test_anonymous_gets_null_receiving_if_user_anonymous(self): + alice = self.make_participant( 'alice' + , last_bill_result='' + , anonymous_receiving=True + ) + self.make_participant('bob') + alice.set_tip_to('bob', '1.00') + data = json.loads(self.client.GET('/alice/public.json').body) + + assert data['receiving'] == None + def test_anonymous_does_not_get_goal_if_user_regifts(self): self.make_participant('alice', last_bill_result='', goal=0) data = json.loads(self.client.GET('/alice/public.json').body) diff --git a/www/%username/anonymous.json.spt b/www/%username/anonymous.json.spt index aafd884605..b1666a6ce2 100644 --- a/www/%username/anonymous.json.spt +++ b/www/%username/anonymous.json.spt @@ -4,19 +4,25 @@ if user.ANON: raise Response(404) request.allow("GET", "POST") if POST: + field = body.get("toggle", "giving") + if field not in ["giving", "receiving"]: + raise Response(400) rec = website.db.one(""" UPDATE participants - SET anonymous=not anonymous + SET anonymous_{0}=not anonymous_{0} WHERE username=%s - RETURNING anonymous + RETURNING anonymous_{0} - """, (user.participant.username,)) + """.format(field), (user.participant.username,)) + assert rec is not None + response.body = {field: rec} else: rec = website.db.one(""" - SELECT anonymous FROM participants WHERE username=%s + SELECT anonymous_giving AS giving, anonymous_receiving AS receiving + FROM participants WHERE username=%s - """, (user.participant.username,)) -assert rec is not None -response.body = {"anonymous": rec} + """, (user.participant.username,), back_as=dict) + assert rec is not None + response.body = rec diff --git a/www/%username/giving/index.html.spt b/www/%username/giving/index.html.spt index 9502cc81d6..4e3a0527dc 100644 --- a/www/%username/giving/index.html.spt +++ b/www/%username/giving/index.html.spt @@ -63,8 +63,8 @@ first_time = qs.get('first_time') == '1' {% endif %} - {% if participant == user %} -

You give ${{ total }} per + {% if participant == user.participant %} +

You give ${{ total }} per week

{% else %}

{{ participant.username }} gives ${{ total }} per week

diff --git a/www/%username/public.json.spt b/www/%username/public.json.spt index f40e292d17..0ba6bff1d1 100644 --- a/www/%username/public.json.spt +++ b/www/%username/public.json.spt @@ -12,11 +12,9 @@ callback_pattern = re.compile(r'^[_A-Za-z0-9.]+$') [-----------------------------------------------------------------------------] participant = get_participant(request, restrict=False) -receiving = participant.get_dollars_receiving() output = { "id": participant.id , "username": participant.username - , "receiving": str(receiving) , "avatar": participant.get_img_src() , "number": participant.number } @@ -38,6 +36,20 @@ if participant.goal != 0: output["goal"] = goal +# Generate receiving key +# =================== +# Display values: +# +# null - user is receiving anonymously +# 3.00 - user receives this amount in tips + +if not participant.anonymous_receiving: + receiving = str(participant.get_dollars_receiving()) +else: + receiving = None +output["receiving"] = receiving + + # Generate giving key # =================== # Display values: @@ -45,7 +57,7 @@ if participant.goal != 0: # null - user is giving anonymously # 3.00 - user gives this amount in tips -if not participant.anonymous: +if not participant.anonymous_giving: giving = str(participant.get_dollars_giving()) else: giving = None diff --git a/www/about/privacy/index.html.spt b/www/about/privacy/index.html.spt index 33fb964ab6..ad1aae1911 100644 --- a/www/about/privacy/index.html.spt +++ b/www/about/privacy/index.html.spt @@ -92,7 +92,7 @@ we may use personal information to:

Gittip makes reasonable efforts not to share your personal information with the recipients of your gifts, so that particular gifts are anonymous. We do publicly share aggregated information about your giving and receiving. You may -opt out of publicly sharing your aggregate giving.

+opt out of publicly sharing your aggregate giving and/or receiving.

We also share your personal information with these third party vendors who work on our behalf:

diff --git a/www/for/%slug/index.html.spt b/www/for/%slug/index.html.spt index 4629d675d4..8612cc2cf5 100644 --- a/www/for/%slug/index.html.spt +++ b/www/for/%slug/index.html.spt @@ -124,7 +124,7 @@ if community.nmembers >= website.NMEMBERS_THRESHOLD: givers = utter_hack(website.db, query_cache.all(""" -- top givers on community page - SELECT tipper AS username, anonymous, sum(amount) AS amount + SELECT tipper AS username, anonymous_giving AS anonymous, sum(amount) AS amount FROM ( SELECT DISTINCT ON (tipper, tippee) amount , tipper @@ -142,7 +142,7 @@ if community.nmembers >= website.NMEMBERS_THRESHOLD: ) AS foo JOIN participants p ON p.username = tipper WHERE is_suspicious IS NOT true - GROUP BY tipper, anonymous + GROUP BY tipper, anonymous_giving ORDER BY amount DESC LIMIT %s OFFSET %s @@ -155,7 +155,7 @@ if community.nmembers >= website.NMEMBERS_THRESHOLD: receivers = utter_hack(website.db, query_cache.all(""" -- top receivers on community page - SELECT tippee AS username, claimed_time, sum(amount) AS amount + SELECT tippee AS username, anonymous_receiving AS anonymous, claimed_time, sum(amount) AS amount FROM ( SELECT DISTINCT ON (tipper, tippee) amount , tippee @@ -172,7 +172,7 @@ if community.nmembers >= website.NMEMBERS_THRESHOLD: ) AS foo JOIN participants p ON p.username = tippee WHERE is_suspicious IS NOT true - GROUP BY tippee, claimed_time + GROUP BY tippee, claimed_time, anonymous_receiving ORDER BY amount DESC LIMIT %s OFFSET %s @@ -187,9 +187,7 @@ if community.nmembers >= website.NMEMBERS_THRESHOLD: {% block box %}

{{ community.name }}

-
- {{ community.nmembers }} -
+
{{ community.nmembers }}
member{{ '' if community.nmembers == 1 else 's' }}