diff --git a/scripts/deactivate-final-rename.py b/scripts/deactivate-final-rename.py new file mode 100644 index 0000000000..ff18ad3701 --- /dev/null +++ b/scripts/deactivate-final-rename.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +"""The final rename and clear step for deactivating an account. + +If the account has a balance or is involved in active tips, +this script will report the problem and abort without making any update. + +If the first eight digits of the account's API key are not given or do not match, +this script will report the problem and abort without making any update. + +Usage: + + [gittip] $ heroku config -s -a gittip | foreman run -e /dev/stdin ./env/bin/python ./scripts/deactivate-final-rename.py "username" [first-eight-of-api-key] + +""" +from __future__ import print_function + +import sys + +from gittip import wireup +from gittip.models.participant import Participant + + +username = sys.argv[1] # will fail with KeyError if missing +if len(sys.argv) < 3: + first_eight = "unknown!" +else: + first_eight = sys.argv[2] + +db = wireup.db() + +target = Participant.from_username(username) + +INCOMING = """ + SELECT count(*) + FROM current_tips + WHERE tippee = %s + AND amount > 0 +""" + +FIELDS = """ + SELECT username, username_lower, api_key, claimed_time + FROM participants + WHERE username = %s +""" + + +incoming = db.one(INCOMING, (username,)) +fields = db.one(FIELDS, (username,)) + +print("Current balance ", target.balance) +print("Incoming tip count ", incoming) +print(fields) + +assert target.balance == 0 +assert incoming == 0 +if fields.api_key == None: + assert first_eight == "None" +else: + assert fields.api_key[0:8] == first_eight + +deactivated_name = "deactivated-" + username +print("Renaming " + username + " to " + deactivated_name) + +RENAME = """ + UPDATE participants + SET claimed_time = null + , session_token = null + , username = %s + , username_lower = %s + WHERE username = %s +""" + +print(RENAME % (deactivated_name, deactivated_name.lower(), username)) + +db.run(RENAME, (deactivated_name, deactivated_name.lower(), username)) + +print("All done.") diff --git a/scripts/final-gift.py b/scripts/final-gift.py new file mode 100644 index 0000000000..acea98224b --- /dev/null +++ b/scripts/final-gift.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +"""Distribute a balance as a final gift. This addresses part of #54. + +Usage: + + [gittip] $ heroku config -s -a gittip | foreman run -e /dev/stdin ./env/bin/python ./scripts/final-gift.py "username" + +""" +from __future__ import print_function + +import sys +from decimal import ROUND_DOWN, Decimal as D + +from gittip import wireup +from gittip.models.participant import Participant + +db = wireup.db() + +username = sys.argv[1] # will fail with KeyError if missing +tipper = Participant.from_username(username) + + +print("Distributing {} from {}.".format(tipper.balance, tipper.username)) +if tipper.balance == 0: + raise SystemExit + +claimed_tips, claimed_total, unclaimed_tips, unclaimed_total = tipper.get_giving_for_profile() +transfers = [] +distributed = D('0.00') + +for tip in claimed_tips: + if tip.amount == 0: + continue + rate = tip.amount / claimed_total + pro_rated = (tipper.balance * rate).quantize(D('0.01'), ROUND_DOWN) + distributed += pro_rated + print( tipper.username.ljust(12) + , tip.tippee.ljust(18) + , str(tip.amount).rjust(6) + , str(rate).ljust(32) + , pro_rated + ) + transfers.append([tip.tippee, pro_rated]) + +diff = tipper.balance - distributed +if diff != 0: + print("Adjusting for rounding error of {}. Giving it to {}.".format(diff, transfers[0][0])) + transfers[0][1] += diff # Give it to the highest receiver. + +with db.get_cursor() as cursor: + for tippee, amount in transfers: + assert amount > 0 + cursor.run( "UPDATE participants SET balance=balance - %s WHERE username=%s" + , (amount, tipper.username) + ) + cursor.run( "UPDATE participants SET balance=balance + %s WHERE username=%s" + , (amount, tippee) + ) + cursor.run( "INSERT INTO transfers (tipper, tippee, amount) VALUES (%s, %s, %s)" + , (tipper.username, tippee, amount) + ) diff --git a/scripts/untip.py b/scripts/untip.py new file mode 100644 index 0000000000..ba5591dfbb --- /dev/null +++ b/scripts/untip.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +"""Zero out tips to a given user. This is a workaround for #1469. + +Usage: + + [gittip] $ heroku config -s -a gittip | foreman run -e /dev/stdin ./env/bin/python ./scripts/untip.py "username" + +""" +from __future__ import print_function + +import sys + +from gittip import wireup + + +tippee = sys.argv[1] # will fail with KeyError if missing + +db = wireup.db() + +tips = db.all(""" + + SELECT amount + , ( SELECT participants.*::participants + FROM participants + WHERE username=tipper + ) AS tipper + , ( SELECT participants.*::participants + FROM participants + WHERE username=tippee + ) AS tippee + FROM current_tips + WHERE tippee = %s + AND amount > 0 + ORDER BY amount DESC + +""", (tippee,)) + + +for tip in tips: + print( tip.tipper.username.ljust(12) + , tip.tippee.username.ljust(12) + , str(tip.amount).rjust(6) + ) + tip.tipper.set_tip_to(tip.tippee.username, '0.00')