Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion home/templates/home/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
Download
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/data/users_agg.csv">All User Stats</a>
<a class="dropdown-item" href="/data/all_user_stats.csv">All User Stats</a>
<a class="dropdown-item" href="/data/users.csv">All User Account Info</a>
<a class="dropdown-item" href="/data/daily_walks.csv">All Walks</a>
<a class="dropdown-item" href="/data/intentional_walks.csv">All Recorded Walks</a>
Expand Down
73 changes: 69 additions & 4 deletions home/tests/integration/views/web/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ def setUpTestData(cls):
Login()

# Generate fake accounts
accounts = list(AccountGenerator().generate(2))
cls.accounts = list(AccountGenerator().generate(2))

# Device associated with accounts[0]
device0 = list(DeviceGenerator(accounts[0:1]).generate(1))
device0 = list(DeviceGenerator(cls.accounts[0:1]).generate(1))
# Device associated with accounts[1]
device1 = list(DeviceGenerator(accounts[1:2]).generate(1))
device1 = list(DeviceGenerator(cls.accounts[1:2]).generate(1))

# Generate daily walks (10 per device)
dwalks0 = DailyWalkGenerator(device0)
Expand Down Expand Up @@ -77,6 +78,70 @@ def group_by(rows: List[Dict], key: str) -> Dict[str, List]:
grouped[row[key]].append(row)
return grouped

def test_all_user_stats_csv_view(self):
client = Client()
self.assertTrue(self.login(client))

params = {
"start_baseline": date(3000, 2, 28),
"start_promo": date(3000, 3, 1),
"start": date(3000, 3, 7),
"end": date(3000, 3, 14),
}
next(ContestGenerator().generate(1, **params)).pk

response = client.get("/data/all_user_stats.csv")
self.assertEqual(200, response.status_code)
self.assertEqual("text/csv", response["Content-Type"])
content = response.content.decode("utf-8")
reader = csv.DictReader(io.StringIO(content))

headers = reader.fieldnames
self.assertEqual(
headers,
[
"Participant Name",
"Date Enrolled",
"Email",
"Zip Code",
"Sexual Orientation",
"Sexual Orientation Other",
"Gender Identity",
"Gender Identity Other",
"Race",
"Race Other",
"Is Latino",
"Age",
"Total Daily Walks",
"Total Daily Steps",
"Total Recorded Walks",
"Total Recorded Steps",
],
)

rows = list(reader)
# Order accounts in ascending order based on the name, to match
# the backend's production, which orders records by
# ascending order (created, name).
for i, account in enumerate(
sorted(self.accounts, key=lambda a: a.name)
):
row = rows[i]
self.assertEqual(account.name, row.get("Participant Name"))
self.assertEqual(account.email, row.get("Email"))
self.assertEqual(account.zip, row.get("Zip Code"))
self.assertEqual(
account.sexual_orien, row.get("Sexual Orientation")
)
self.assertEqual(account.gender, row.get("Gender Identity"))
self.assertEqual(account.is_latino, row.get("Is Latino"))
self.assertEqual(account.age, int(row.get("Age")))
self.assertEqual(set(account.race), eval(row.get("Race")))
self.assertGreater(int(row.get("Total Daily Walks")), 0)
self.assertGreater(int(row.get("Total Daily Steps")), 0)
self.assertGreater(int(row.get("Total Recorded Walks")), 0)
self.assertGreater(int(row.get("Total Recorded Steps")), 0)

def test_user_agg_csv_view(self):
c = Client()
self.assertTrue(self.login(c))
Expand Down Expand Up @@ -117,7 +182,7 @@ def test_user_agg_csv_view(self):
expected_headers = USER_AGG_CSV_BASE_HEADER[:] + [
str(date(3000, 2, 28) + timedelta(days=dt)) for dt in range(15)
]
self.assertEquals(headers, expected_headers)
self.assertEqual(headers, expected_headers)

rows = list(reader)

Expand Down
5 changes: 5 additions & 0 deletions home/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
views.user_agg_csv_view,
name="users_agg_csv_view",
),
path(
"data/all_user_stats.csv",
views.all_user_stats_csv_view,
name="all_user_stats_csv_view",
),
path("data/users.csv", views.users_csv_view, name="users_csv_view"),
path(
"data/daily_walks.csv",
Expand Down
1 change: 1 addition & 0 deletions home/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .web.home import HomeView
from .web.intentionalwalk import IntentionalWalkWebView
from .web.user import UserListView
from .web.data import all_user_stats_csv_view
from .web.data import user_agg_csv_view
from .web.data import users_csv_view
from .web.data import daily_walks_csv_view
Expand Down
64 changes: 64 additions & 0 deletions home/views/web/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,70 @@ def _get_user_daily_step_counts(
return daily_step_counts_by_user


def all_user_stats_csv_view(request) -> HttpResponse:
columns = [
"Participant Name",
"Date Enrolled",
"Email",
"Zip Code",
"Sexual Orientation",
"Sexual Orientation Other",
"Gender Identity",
"Gender Identity Other",
"Race",
"Race Other",
"Is Latino",
"Age",
"Total Daily Walks",
"Total Daily Steps",
"Total Recorded Walks",
"Total Recorded Steps",
]

users = Account.objects.order_by("created").order_by("name").all()
output = []
for user in users:
daily_walks = user.dailywalk_set.values("steps")
cnt_daily = len(daily_walks)
daily_steps = sum([w.get("steps") for w in daily_walks])

rec_walks = user.intentionalwalk_set.values("steps")
cnt_recorded = len(rec_walks)
rec_steps = sum([w.get("steps") for w in rec_walks])

output.append(
{
"Participant Name": user.name,
"Date Enrolled": user.created,
"Email": user.email,
"Zip Code": user.zip,
"Sexual Orientation": user.sexual_orien,
"Sexual Orientation Other": user.sexual_orien_other,
"Gender Identity": user.gender,
"Gender Identity Other": user.gender_other,
"Race": user.race,
"Race Other": user.race_other,
"Is Latino": user.is_latino,
"Age": user.age,
"Total Daily Walks": cnt_daily,
"Total Daily Steps": daily_steps,
"Total Recorded Walks": cnt_recorded,
"Total Recorded Steps": rec_steps,
}
)

response = HttpResponse(content_type="text/csv")
response[
"Content-Disposition"
] = 'attachment; filename="all_users_stats.csv"'

writer = csv.DictWriter(response, fieldnames=columns)
writer.writeheader()
writer.writerows(output)

return response


def user_agg_csv_view(request) -> HttpResponse:
if not request.user.is_authenticated:
return HttpResponse("You are not authorized to view this!")
Expand Down