From e9158f1fc71afe74af4e7eb231fcb497c29e1dbf Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Mon, 31 Aug 2015 17:07:43 -0400 Subject: [PATCH] Add an "Active Teams" chart I discovered in the process that we were computing nusers wrong. --- gratipay/billing/payday.py | 13 ++++++++++--- gratipay/utils/__init__.py | 6 +++--- gratipay/utils/fake_data.py | 2 +- sql/branch.sql | 6 ++++++ sql/update-payday-numbers.sql | 12 ++++++------ tests/py/test_paydays_json.py | 2 +- www/about/charts.json.spt | 7 ++++--- www/about/paydays.json.spt | 3 ++- www/about/stats.spt | 19 +++++++++++++------ 9 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 sql/branch.sql diff --git a/gratipay/billing/payday.py b/gratipay/billing/payday.py index 5e25085eda..85afdbf353 100644 --- a/gratipay/billing/payday.py +++ b/gratipay/billing/payday.py @@ -391,10 +391,17 @@ def update_stats(self): WITH our_payments AS (SELECT * FROM payments WHERE payday=%(payday)s) UPDATE paydays p - SET nactive = (SELECT DISTINCT count(*) FROM ( - SELECT participant FROM our_payments WHERE payday=p.id + SET nusers = (SELECT count(*) FROM ( + SELECT DISTINCT ON (participant) participant FROM our_payments GROUP BY participant ) AS foo) - , volume = (SELECT COALESCE(sum(amount), 0) FROM our_payments WHERE payday=p.id) + , nteams = (SELECT count(*) FROM ( + SELECT DISTINCT ON (team) team FROM our_payments GROUP BY team + ) AS foo) + , volume = ( + SELECT COALESCE(sum(amount), 0) + FROM our_payments + WHERE payday=p.id AND direction='to-team' + ) WHERE id=%(payday)s """, {'payday': self.id}) diff --git a/gratipay/utils/__init__.py b/gratipay/utils/__init__.py index 5da4dbe156..ed2a5adb80 100644 --- a/gratipay/utils/__init__.py +++ b/gratipay/utils/__init__.py @@ -133,8 +133,8 @@ def get_team(state): def update_cta(website): - nactive = website.db.one(""" - SELECT nactive FROM paydays + nusers = website.db.one(""" + SELECT nusers FROM paydays ORDER BY ts_end DESC LIMIT 1 """, default=(0.0, 0)) nreceiving_from = website.db.one(""" @@ -142,7 +142,7 @@ def update_cta(website): FROM teams WHERE slug = 'Gratipay' """, default=0) - website.support_current = cur = int(round(nreceiving_from / nactive * 100)) if nactive else 0 + website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0 if cur < 10: goal = 20 elif cur < 15: goal = 30 elif cur < 25: goal = 40 diff --git a/gratipay/utils/fake_data.py b/gratipay/utils/fake_data.py index 6e701bf580..8648888f87 100644 --- a/gratipay/utils/fake_data.py +++ b/gratipay/utils/fake_data.py @@ -374,7 +374,7 @@ def populate_db(db, num_participants=100, ntips=200, num_teams=5, num_transfers= payday = { 'ts_start': date, 'ts_end': end_date, - 'nactive': len(actives), + 'nusers': len(actives), 'volume': sum(x['amount'] for x in week_transfers) } _fake_thing(db, "paydays", **payday) diff --git a/sql/branch.sql b/sql/branch.sql new file mode 100644 index 0000000000..dd2ca7aafe --- /dev/null +++ b/sql/branch.sql @@ -0,0 +1,6 @@ +BEGIN; + + ALTER TABLE paydays RENAME COLUMN nactive TO nusers; + ALTER TABLE paydays ADD COLUMN nteams integer NOT NULL DEFAULT 0; + +END; diff --git a/sql/update-payday-numbers.sql b/sql/update-payday-numbers.sql index 31e7dd99cc..ad7f0fd61a 100644 --- a/sql/update-payday-numbers.sql +++ b/sql/update-payday-numbers.sql @@ -1,9 +1,9 @@ --- Reset post-Gratipocalypse values +-- Fix nusers and backfill nteams for post-Gratipocalypse paydays UPDATE paydays p - SET nactive = (SELECT DISTINCT count(*) FROM ( - SELECT participant FROM payments WHERE payday=p.id + SET nteams = (SELECT count(*) FROM ( + SELECT DISTINCT ON (team) team FROM payments WHERE payday=p.id GROUP BY team + ) AS foo) + , nusers = (SELECT count(*) FROM ( + SELECT DISTINCT ON (participant) participant FROM payments WHERE payday=p.id GROUP BY participant ) AS foo) - , volume = (SELECT COALESCE(sum(amount), 0) - FROM payments - WHERE payday=p.id AND direction='to-team') WHERE ts_start > '2015-05-07'::timestamptz; diff --git a/tests/py/test_paydays_json.py b/tests/py/test_paydays_json.py index 1e14e8e3a9..908b4584bb 100644 --- a/tests/py/test_paydays_json.py +++ b/tests/py/test_paydays_json.py @@ -14,4 +14,4 @@ def test_paydays_json_gives_paydays(self): response = self.client.GET("/about/paydays.json") paydays = json.loads(response.body) - assert paydays[0]['nactive'] == 0 + assert paydays[0]['nusers'] == 0 diff --git a/www/about/charts.json.spt b/www/about/charts.json.spt index bd2dd706a6..9d5b1d7895 100644 --- a/www/about/charts.json.spt +++ b/www/about/charts.json.spt @@ -3,9 +3,10 @@ charts = website.db.all("""\ SELECT ts_start::date AS date , ts_start::date AS xTitle - , volume::text AS weekly_volume - , nactive::text AS active_users - FROM paydays p + , volume::text + , nusers::text + , nteams::text + FROM paydays ORDER BY ts_start DESC """, back_as=dict) diff --git a/www/about/paydays.json.spt b/www/about/paydays.json.spt index 1295590d5b..f5a38b219e 100644 --- a/www/about/paydays.json.spt +++ b/www/about/paydays.json.spt @@ -4,7 +4,8 @@ paydays = website.db.all("""\ SELECT ts_start , ts_end , volume - , nactive + , nusers + , nteams FROM paydays ORDER BY ts_start DESC diff --git a/www/about/stats.spt b/www/about/stats.spt index 71f21021c9..3229d1cd9b 100644 --- a/www/about/stats.spt +++ b/www/about/stats.spt @@ -7,13 +7,12 @@ banner = _("About") title = _("Stats") one = website.db.one -volume, nusers = one(""" - SELECT volume, nactive +volume, nusers, nteams = one(""" + SELECT volume, nusers, nteams FROM paydays ORDER BY ts_end DESC LIMIT 1 - """, default=(0.0, 0)) -nteams = one("SELECT count(*) FROM teams WHERE is_approved IS true AND receiving > 0") + """, default=(0.0, 0, 0)) total = one("SELECT sum(amount) FROM exchanges WHERE amount > 0", default=0) age_in_years = (date.today() - birthday).days // 365 escrow = one("SELECT sum(balance) FROM participants", default=0) @@ -82,10 +81,18 @@ average_number_of_payments = average_number_of_payments or 0
- +

Active ~users

~users that gave and/or took money on Gratipay (per week)

-
+
+
weeks
+
+ +
+ +

Active Teams

+

Teams that received and shared money on Gratipay (per week)

+
weeks