From ce0db991b6a2c72ddf819542c5e3ff834385f515 Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Thu, 12 Jul 2012 13:31:06 -0400 Subject: [PATCH] Implement funding goal feature (#110) --- gittip/__init__.py | 60 +++++---- gittip/authentication.py | 1 + gittip/utils.py | 17 --- schema.sql | 23 ++-- www/%participant_id/index.html | 219 +++++++++++++++++++++++++++------ www/assets/%version/gittip.css | 50 ++++---- www/credit-card.html | 4 +- www/github/%login/index.html | 25 ++-- 8 files changed, 270 insertions(+), 129 deletions(-) diff --git a/gittip/__init__.py b/gittip/__init__.py index 1c414ed854..af5723b1f0 100644 --- a/gittip/__init__.py +++ b/gittip/__init__.py @@ -1,6 +1,11 @@ import datetime +import locale from decimal import Decimal + +locale.setlocale(locale.LC_ALL, "en_US") + + BIRTHDAY = datetime.date(2012, 6, 1) CARDINALS = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'] def age(): @@ -79,45 +84,36 @@ def get_backed_amount(participant_id): return amount -def get_tipjar(participant_id, pronoun="their", claimed=False): - """Given a participant id, return a unicode. +def get_number_of_backers(participant_id): + """Given a unicode, return an int. """ - amount = get_backed_amount(participant_id) - - - # Compute a unicode describing the amount. - # ======================================== - # This is down here because we use it in multiple places in the app, - # basically in the claimed participant page and the non-claimed GitHub page - # (hopefully soon to be Facebook and Twitter as well). + BACKED = """\ - if pronoun not in ('your', 'their'): - raise Exception("Unknown, um, pronoun: %s" % pronoun) + SELECT count(amount) AS nbackers + FROM ( SELECT DISTINCT ON (tipper) + amount + , tipper + FROM tips + JOIN participants p ON p.id = tipper + WHERE tippee=%s + AND last_bill_result = '' + ORDER BY tipper + , mtime DESC + ) AS foo + WHERE amount > 0 - if amount == 0: - if pronoun == "your": - tipjar = u"have no backed tips." - elif pronoun == "their": - tipjar = u"has no backed tips." + """ + rec = db.fetchone(BACKED, (participant_id,)) + if rec is None: + nbackers = None else: - if pronoun == "your": - tipjar = u"have $%s in backed tips." - elif pronoun == "their": - tipjar = u"has $%s in backed tips." - tipjar %= amount - - - # We're opt-in. - # ============= - # If the user hasn't claimed the tipjar then the tips are only pledges, - # we're not going to actually collect money on their behalf. - - if not claimed: - tipjar = tipjar.replace("backed", "pledged") + nbackers = rec['nbackers'] # might be None + if nbackers is None: + nbackers = 0 - return tipjar + return nbackers def get_tips_and_total(tipper, for_payday=False): diff --git a/gittip/authentication.py b/gittip/authentication.py index 30a956705a..16b890bd36 100644 --- a/gittip/authentication.py +++ b/gittip/authentication.py @@ -47,6 +47,7 @@ def load_session(where, val): , p.is_admin , p.redirect , p.balance + , p.goal , n.network , n.user_info FROM participants p diff --git a/gittip/utils.py b/gittip/utils.py index 94c7476171..98c8492765 100644 --- a/gittip/utils.py +++ b/gittip/utils.py @@ -14,23 +14,6 @@ def wrap(u): return u if u else '...' -def commaize(n, places=1): - """Given a number, return a string with commas and a decimal -- 1,000.0. - """ - out = ("%%.0%df" % places) % n - try: - whole, fraction = out.split('.') - except ValueError: - whole, fraction = (out, '') - _whole = [] - for i, digit in enumerate(reversed(whole), start=1): - _whole.insert(0, digit) - if i % 3 == 0: - _whole.insert(0, ',') - out = ''.join(_whole + ['.', fraction]).lstrip(',').rstrip('.') - return out - - def total_seconds(td): """ Python 2.7 adds a total_seconds method to timedelta objects. diff --git a/schema.sql b/schema.sql index b9cb9c529f..ca20f35610 100644 --- a/schema.sql +++ b/schema.sql @@ -1,3 +1,13 @@ +-- million trillion trillion +-- | trillion trillion +-- | | trillion +-- | | | billion +-- | | | | million +-- | | | | | thousand +-- | | | | | | +-- numeric(35,2) maxes out at $999,999,999,999,999,999,999,999,999,999,999.00. + + -- Create the initial structure. CREATE EXTENSION hstore; @@ -82,16 +92,11 @@ CREATE TABLE exchanges , participant_id text NOT NULL REFERENCES participants ON DELETE RESTRICT ); --- million trillion trillion --- | trillion trillion --- | | trillion --- | | | billion --- | | | | million --- | | | | | thousand --- | | | | | | --- numeric(34,2) maxes out at $999,999,999,999,999,999,999,999,999,999,999.00. - -- https://github.com/whit537/www.gittip.com/issues/128 ALTER TABLE participants ADD COLUMN anonymous bool NOT NULL DEFAULT FALSE; ALTER TABLE participants DROP COLUMN shares_giving; + + +-- https://github.com/whit537/www.gittip.com/issues/110 +ALTER TABLE participants ADD COLUMN goal numeric(35,2) DEFAULT NULL; diff --git a/www/%participant_id/index.html b/www/%participant_id/index.html index 7b8a6ce259..0074e71d85 100644 --- a/www/%participant_id/index.html +++ b/www/%participant_id/index.html @@ -9,9 +9,11 @@ profiles is rolled over to the new participant. """ +import locale + import requests from aspen import json, Response -from gittip import AMOUNTS, db, get_tip, get_tips_and_total, get_tipjar +from gittip import AMOUNTS, db, get_tip, get_tips_and_total, get_backed_amount from gittip.utils import wrap, dt2age from gittip.networks import github @@ -59,7 +61,7 @@ name = participant['user_info'].get('name', username) github_user_info = participant['user_info'] can_tip = True -tipjar = get_tipjar(user.id, pronoun="your", claimed=True) +backed_amount = get_backed_amount(participant['id']) tip_or_pledge = "tip" # ========================================================================== ^L @@ -78,7 +80,7 @@ height: 126pt; /* 18pt * 7 rows; overriden in js */ padding: 1% } - FORM.statement BUTTON { + FORM BUTTON { float: right; margin-left: 0.5em; } @@ -89,6 +91,19 @@ top: 2pt; line-height: 9pt; } + FORM.goal { + display: none; + } + FORM.goal TD { + text-align: left; + } + FORM.goal TD.buttons { + padding-top: 6pt; + } + #goal-custom { + text-align: right; + width: 6pc; + }