From 8c89d7b1b1cf66da3d5705bc38a8eae86f4dad5e Mon Sep 17 00:00:00 2001 From: Changaco Date: Tue, 2 Sep 2014 12:02:13 +0200 Subject: [PATCH] make get_tip_to and set_tip_to return a dict instead of only the amount --- gratipay/models/participant.py | 26 +++++++------ templates/participant.tip.html | 2 +- tests/py/test_close.py | 2 +- tests/py/test_participant.py | 28 ++++++++------ www/%username/tip.json.spt | 38 +++++++++---------- www/%username/tips.json.spt | 4 +- www/%username/widget.html.spt | 2 +- www/about/pricing.spt | 2 +- .../%platform/%user_name/%endpoint.json.spt | 2 +- 9 files changed, 56 insertions(+), 50 deletions(-) diff --git a/gratipay/models/participant.py b/gratipay/models/participant.py index 9c1bd24b35..626eab709a 100644 --- a/gratipay/models/participant.py +++ b/gratipay/models/participant.py @@ -657,7 +657,7 @@ def update_is_free_rider(self, is_free_rider, cursor=None): def set_tip_to(self, tippee, amount, update_self=True, update_tippee=True, cursor=None): - """Given a Participant or username, and amount as str, return a tuple. + """Given a Participant or username, and amount as str, returns a dict. We INSERT instead of UPDATE, so that we have history to explore. The COALESCE function returns the first of its arguments that is not NULL. @@ -665,9 +665,10 @@ def set_tip_to(self, tippee, amount, update_self=True, update_tippee=True, curso tip from this user to that. I believe this is used to determine the order of transfers during payday. - The tuple returned is the amount as a Decimal and a boolean indicating - whether this is the first time this tipper has tipped (we want to track - that as part of our conversion funnel). + The dict returned represents the row inserted in the tips table, with + an additional boolean indicating whether this is the first time this + tipper has tipped (we want to track that as part of our conversion + funnel). """ assert self.is_claimed # sanity check @@ -700,12 +701,12 @@ def set_tip_to(self, tippee, amount, update_self=True, update_tippee=True, curso ), CURRENT_TIMESTAMP) , %(tipper)s, %(tippee)s, %(amount)s ) - RETURNING ( SELECT count(*) = 0 FROM tips WHERE tipper=%(tipper)s ) - AS first_time_tipper + RETURNING * + , ( SELECT count(*) = 0 FROM tips WHERE tipper=%(tipper)s ) AS first_time_tipper """ args = dict(tipper=self.username, tippee=tippee.username, amount=amount) - first_time_tipper = (cursor or self.db).one(NEW_TIP, args) + t = (cursor or self.db).one(NEW_TIP, args) if update_self: # Update giving/pledging amount of tipper @@ -720,22 +721,23 @@ def set_tip_to(self, tippee, amount, update_self=True, update_tippee=True, curso # Update whether the tipper is using Gratipay for free self.update_is_free_rider(None if amount == 0 else False, cursor) - return amount, first_time_tipper + return t._asdict() def get_tip_to(self, tippee): - """Given two user ids, return a Decimal. + """Given a username, returns a dict. """ + default = dict(amount=Decimal('0.00')) return self.db.one("""\ - SELECT amount + SELECT * FROM tips WHERE tipper=%s AND tippee=%s ORDER BY mtime DESC LIMIT 1 - """, (self.username, tippee), default=Decimal('0.00')) + """, (self.username, tippee), back_as=dict, default=default) def get_tip_distribution(self): @@ -1416,7 +1418,7 @@ def to_dict(self, details=False, inquirer=None): if inquirer.username == self.username: my_tip = 'self' else: - my_tip = inquirer.get_tip_to(self.username) + my_tip = inquirer.get_tip_to(self.username)['amount'] output['my_tip'] = str(my_tip) # Key: elsewhere diff --git a/templates/participant.tip.html b/templates/participant.tip.html index 3e37bb5edc..09a4a917d2 100644 --- a/templates/participant.tip.html +++ b/templates/participant.tip.html @@ -18,7 +18,7 @@

{{ _("Your Weekly Pledge") if path.decoded.startswith('/on/') else _("Your W {% else %} - {% set my_tip = format_decimal(user.participant.get_tip_to(participant.username)) %} + {% set my_tip = format_decimal(user.participant.get_tip_to(participant.username)['amount']) %} {% set tippee = participant.username %}

{{ _("Your Weekly Pledge") if path.decoded.startswith('/on/') else _("Your Weekly Gift") }}

{% include "templates/my-tip.html" %} diff --git a/tests/py/test_close.py b/tests/py/test_close.py index 3cab0786e4..c49fd7d77f 100644 --- a/tests/py/test_close.py +++ b/tests/py/test_close.py @@ -26,7 +26,7 @@ def test_close_closes(self): alice.close('downstream') - assert carl.get_tip_to('alice') == 0 + assert carl.get_tip_to('alice')['amount'] == 0 assert alice.balance == 0 def test_close_raises_for_unknown_disbursement_strategy(self): diff --git a/tests/py/test_participant.py b/tests/py/test_participant.py index d2d74986e6..ba051eb098 100644 --- a/tests/py/test_participant.py +++ b/tests/py/test_participant.py @@ -89,7 +89,7 @@ def test_bob_has_two_dollars_in_tips(self): def test_alice_gives_to_bob_now(self): expected = Decimal('1.00') - actual = self.alice.get_tip_to('bob') + actual = self.alice.get_tip_to('bob')['amount'] assert actual == expected def test_deadbeef_is_archived(self): @@ -101,12 +101,12 @@ def test_deadbeef_is_archived(self): def test_alice_doesnt_gives_to_deadbeef_anymore(self): expected = Decimal('0.00') - actual = self.alice.get_tip_to('deadbeef') + actual = self.alice.get_tip_to('deadbeef')['amount'] assert actual == expected def test_alice_doesnt_give_to_whatever_deadbeef_was_archived_as_either(self): expected = Decimal('0.00') - actual = self.alice.get_tip_to(self.deadbeef_archived.username) + actual = self.alice.get_tip_to(self.deadbeef_archived.username)['amount'] assert actual == expected def test_there_is_no_more_deadbeef(self): @@ -235,7 +235,7 @@ def test_alice_ends_up_tipping_bob_two_dollars(self): self.alice.set_tip_to(self.carl, '1.00') self.bob.take_over(('twitter', str(self.carl.id)), have_confirmation=True) expected = Decimal('2.00') - actual = self.alice.get_tip_to('bob') + actual = self.alice.get_tip_to('bob')['amount'] assert actual == expected def test_bob_ends_up_tipping_alice_two_dollars(self): @@ -243,7 +243,7 @@ def test_bob_ends_up_tipping_alice_two_dollars(self): self.carl.set_tip_to(self.alice, '1.00') self.bob.take_over(('twitter', str(self.carl.id)), have_confirmation=True) expected = Decimal('2.00') - actual = self.bob.get_tip_to('alice') + actual = self.bob.get_tip_to('alice')['amount'] assert actual == expected def test_ctime_comes_from_the_older_tip(self): @@ -374,13 +374,13 @@ def test_getting_tips_actually_made(self): user2 = self.make_participant('user2') self.participant.set_as_claimed() self.participant.set_tip_to(user2, expected) - actual = self.participant.get_tip_to('user2') + actual = self.participant.get_tip_to('user2')['amount'] assert actual == expected def test_getting_tips_not_made(self): expected = Decimal('0.00') self.make_participant('user2') - actual = self.participant.get_tip_to('user2') + actual = self.participant.get_tip_to('user2')['amount'] assert actual == expected @@ -423,21 +423,25 @@ def test_stt_sets_tip_to(self): bob = self.make_participant('bob') alice.set_tip_to(bob, '1.00') - actual = alice.get_tip_to('bob') + actual = alice.get_tip_to('bob')['amount'] assert actual == Decimal('1.00') - def test_stt_returns_a_Decimal_and_a_boolean(self): + def test_stt_returns_a_dict(self): alice = self.make_participant('alice', claimed_time='now', last_bill_result='') bob = self.make_participant('bob') actual = alice.set_tip_to(bob, '1.00') - assert actual == (Decimal('1.00'), True) + assert isinstance(actual, dict) + assert isinstance(actual['amount'], Decimal) + assert actual['amount'] == 1 + assert actual['first_time_tipper'] is True def test_stt_returns_False_for_second_time_tipper(self): alice = self.make_participant('alice', claimed_time='now', last_bill_result='') bob = self.make_participant('bob') alice.set_tip_to(bob, '1.00') actual = alice.set_tip_to(bob, '2.00') - assert actual == (Decimal('2.00'), False) + assert actual['amount'] == 2 + assert actual['first_time_tipper'] is False def test_stt_doesnt_allow_self_tipping(self): alice = self.make_participant('alice', claimed_time='now', last_bill_result='') @@ -452,7 +456,7 @@ def test_stt_allows_higher_tip_to_plural_receiver(self): alice = self.make_participant('alice', claimed_time='now', last_bill_result='') bob = self.make_participant('bob', number='plural') actual = alice.set_tip_to(bob, '1000.00') - assert actual == (Decimal('1000.00'), True) + assert actual['amount'] == 1000 def test_stt_still_caps_tips_to_plural_receivers(self): alice = self.make_participant('alice', claimed_time='now', last_bill_result='') diff --git a/www/%username/tip.json.spt b/www/%username/tip.json.spt index 7dac477403..828bd13d16 100644 --- a/www/%username/tip.json.spt +++ b/www/%username/tip.json.spt @@ -6,6 +6,7 @@ from aspen import Response from babel.numbers import NumberFormatError from gratipay.exceptions import BadAmount, UserDoesntAcceptTips from gratipay.models.participant import Participant +from gratipay.utils import get_participant [-----------------------------------------------------------------------------] @@ -18,41 +19,40 @@ if not user.ANON: # accounts. tipper = user.participant - tippee = Participant.from_username(path['username']) + tippee = get_participant(request, restrict=False) # Get and maybe set amount. # ========================= - first_time_tipper = None - if tippee == tipper: - amount = None - elif POST and 'amount' in body: + if POST and 'amount' in body and tippee != tipper: try: - amount, first_time_tipper = tipper.set_tip_to( tippee - , parse_decimal(body['amount']) - ) + out = tipper.set_tip_to(tippee, parse_decimal(body['amount'])) except (InvalidOperation, ValueError, BadAmount, NumberFormatError): raise Response(400, "bad amount") except UserDoesntAcceptTips: raise Response(400, "user doesn't accept tips") else: - amount = tipper.get_tip_to(tippee.username) + out = tipper.get_tip_to(tippee.username) + amount = out['amount'] total_giving = tipper.giving total_receiving = tipper.receiving total_receiving_tippee = tippee.receiving - out = { "amount": str(amount) - , "total_giving": str(total_giving) - , "total_giving_l": format_currency(total_giving, 'USD') - , "total_receiving": str(total_receiving) - , "total_receiving_l": format_currency(total_receiving, 'USD') - , "total_receiving_tippee": str(total_receiving_tippee) - , "total_receiving_tippee_l": format_currency(total_receiving_tippee, 'USD') - } - if first_time_tipper is not None: - out["first_time"] = first_time_tipper + out["amount"] = str(amount) + out["amount_l"] = format_currency(amount, 'USD') + out["total_giving"] = str(total_giving) + out["total_giving_l"] = format_currency(total_giving, 'USD') + out["total_receiving"] = str(total_receiving) + out["total_receiving_l"] = format_currency(total_receiving, 'USD') + out["total_receiving_tippee"] = str(total_receiving_tippee) + out["total_receiving_tippee_l"] = format_currency(total_receiving_tippee, 'USD') + if 'ctime' in out: + out["ctime"] = str(out['ctime']) + out["mtime"] = str(out['mtime']) + else: + out["ctime"] = out["mtime"] = None [---] application/json via json_dump diff --git a/www/%username/tips.json.spt b/www/%username/tips.json.spt index 468327a087..85e59ec160 100644 --- a/www/%username/tips.json.spt +++ b/www/%username/tips.json.spt @@ -21,11 +21,11 @@ if POST: try: if tip['platform'] != 'gratipay': raise BadPlatform - amount = participant.set_tip_to(tip['username'], parse_decimal(tip['amount'])) + amount = participant.set_tip_to(tip['username'], parse_decimal(tip['amount']))['amount'] except Exception, exc: amount = "error" one['error'] = exc.__class__.__name__ - one['amount'] = str(amount[0]) + one['amount'] = str(amount) out.append(one) if qs.get('also_prune', 'false').lower() in ('true', '1', 'yes'): diff --git a/www/%username/widget.html.spt b/www/%username/widget.html.spt index 13515e992d..87afbb27ae 100644 --- a/www/%username/widget.html.spt +++ b/www/%username/widget.html.spt @@ -9,7 +9,7 @@ if user.ANON: elif user.participant == participant: button_text = "You!" else: - button_text = user.participant.get_tip_to(participant.username) + button_text = user.participant.get_tip_to(participant.username)['amount'] if button_text == 0: button_text = "Gratipay" response.headers['X-Frame-Options'] = "ALLOWALL" diff --git a/www/about/pricing.spt b/www/about/pricing.spt index dfab880260..59f6de3b44 100644 --- a/www/about/pricing.spt +++ b/www/about/pricing.spt @@ -44,7 +44,7 @@ title = "Pricing" {% if not user.ANON %} {% set p = user.participant %} - {% set payment = p.get_tip_to('Gratipay') %} + {% set payment = p.get_tip_to('Gratipay')['amount'] %}
{% if payment > 0 %} diff --git a/www/on/%platform/%user_name/%endpoint.json.spt b/www/on/%platform/%user_name/%endpoint.json.spt index 4fb7617d7c..a58acf8d05 100644 --- a/www/on/%platform/%user_name/%endpoint.json.spt +++ b/www/on/%platform/%user_name/%endpoint.json.spt @@ -63,7 +63,7 @@ if not user.ANON: if user.participant.username == participant.username: my_tip = "self" else: - my_tip = user.participant.get_tip_to(participant.username) + my_tip = user.participant.get_tip_to(participant.username)['amount'] out["my_tip"] = str(my_tip)