analytics: Remove Durations tab and hourly columns.

This commit is contained in:
Lauryn Menard
2023-10-27 17:13:27 +02:00
committed by Tim Abbott
parent 01392a57dd
commit b19a7a8b8a
4 changed files with 8 additions and 96 deletions

View File

@@ -31,7 +31,7 @@ class ActivityTest(ZulipTestCase):
user_profile.is_staff = True user_profile.is_staff = True
user_profile.save(update_fields=["is_staff"]) user_profile.save(update_fields=["is_staff"])
with self.assert_database_query_count(12): with self.assert_database_query_count(11):
result = self.client_get("/activity") result = self.client_get("/activity")
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)

View File

@@ -1,9 +1,5 @@
import itertools
import time
from collections import defaultdict from collections import defaultdict
from contextlib import suppress from typing import Dict, Optional
from datetime import timedelta
from typing import Dict, Optional, Tuple
from django.conf import settings from django.conf import settings
from django.db import connection from django.db import connection
@@ -26,8 +22,7 @@ from analytics.views.activity_common import (
from analytics.views.support import get_plan_name from analytics.views.support import get_plan_name
from zerver.decorator import require_server_admin from zerver.decorator import require_server_admin
from zerver.lib.request import has_request_variables from zerver.lib.request import has_request_variables
from zerver.lib.timestamp import timestamp_to_datetime from zerver.models import Realm, get_org_type_display_name
from zerver.models import Realm, UserActivityInterval, get_org_type_display_name
if settings.BILLING_ENABLED: if settings.BILLING_ENABLED:
from corporate.lib.stripe import ( from corporate.lib.stripe import (
@@ -92,7 +87,7 @@ def get_realm_day_counts() -> Dict[str, Dict[str, Markup]]:
return result return result
def realm_summary_table(realm_minutes: Dict[str, float]) -> str: def realm_summary_table() -> str:
now = timezone_now() now = timezone_now()
query = SQL( query = SQL(
@@ -230,17 +225,6 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
for row in rows: for row in rows:
row["org_type_string"] = get_org_type_display_name(row["org_type"]) row["org_type_string"] = get_org_type_display_name(row["org_type"])
# augment data with realm_minutes
total_hours = 0.0
for row in rows:
string_id = row["string_id"]
minutes = realm_minutes.get(string_id, 0.0)
hours = minutes / 60.0
total_hours += hours
row["hours"] = str(int(hours))
with suppress(Exception):
row["hours_per_user"] = "{:.1f}".format(hours / row["dau_count"])
# formatting # formatting
for row in rows: for row in rows:
row["realm_url"] = realm_url_link(row["string_id"]) row["realm_url"] = realm_url_link(row["string_id"])
@@ -275,7 +259,6 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
dau_count=total_dau_count, dau_count=total_dau_count,
user_profile_count=total_user_profile_count, user_profile_count=total_user_profile_count,
bot_count=total_bot_count, bot_count=total_bot_count,
hours=int(total_hours),
wau_count=total_wau_count, wau_count=total_wau_count,
) )
@@ -293,74 +276,15 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
return content return content
def user_activity_intervals() -> Tuple[Markup, Dict[str, float]]:
day_end = timestamp_to_datetime(time.time())
day_start = day_end - timedelta(hours=24)
output = Markup()
output += "Per-user online duration for the last 24 hours:\n"
total_duration = timedelta(0)
all_intervals = (
UserActivityInterval.objects.filter(
end__gte=day_start,
start__lte=day_end,
)
.select_related(
"user_profile",
"user_profile__realm",
)
.only(
"start",
"end",
"user_profile__delivery_email",
"user_profile__realm__string_id",
)
.order_by(
"user_profile__realm__string_id",
"user_profile__delivery_email",
)
)
by_string_id = lambda row: row.user_profile.realm.string_id
by_email = lambda row: row.user_profile.delivery_email
realm_minutes = {}
for string_id, realm_intervals in itertools.groupby(all_intervals, by_string_id):
realm_duration = timedelta(0)
output += Markup("<hr>") + f"{string_id}\n"
for email, intervals in itertools.groupby(realm_intervals, by_email):
duration = timedelta(0)
for interval in intervals:
start = max(day_start, interval.start)
end = min(day_end, interval.end)
duration += end - start
total_duration += duration
realm_duration += duration
output += f" {email:<37}{duration}\n"
realm_minutes[string_id] = realm_duration.total_seconds() / 60
output += f"\nTotal duration: {total_duration}\n"
output += f"\nTotal duration in minutes: {total_duration.total_seconds() / 60.}\n"
output += f"Total duration amortized to a month: {total_duration.total_seconds() * 30. / 60.}"
content = Markup("<pre>{}</pre>").format(output)
return content, realm_minutes
@require_server_admin @require_server_admin
@has_request_variables @has_request_variables
def get_installation_activity(request: HttpRequest) -> HttpResponse: def get_installation_activity(request: HttpRequest) -> HttpResponse:
duration_content, realm_minutes = user_activity_intervals() counts_content: str = realm_summary_table()
counts_content: str = realm_summary_table(realm_minutes)
data = [ data = [
("Counts", counts_content), ("Counts", counts_content),
("Durations", duration_content),
] ]
title = "Activity" title = "Installation Activity"
return render( return render(
request, request,

View File

@@ -17,7 +17,7 @@
<h4>{{ title }} {% if realm_stats_link %}{{ realm_stats_link }}{% endif %}</h4> <h4>{{ title }} {% if realm_stats_link %}{{ realm_stats_link }}{% endif %}</h4>
{% if not is_home %}
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
{% for name, activity in data %} {% for name, activity in data %}
<li {% if loop.first %} class="active" {% endif %}> <li {% if loop.first %} class="active" {% endif %}>
@@ -25,6 +25,7 @@
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %}
<div class="tab-content"> <div class="tab-content">

View File

@@ -26,7 +26,6 @@
</li> </li>
<li><strong>DAU</strong> (daily active users) - users active in last 24hr</li> <li><strong>DAU</strong> (daily active users) - users active in last 24hr</li>
<li><strong>WAU</strong> (weekly active users) - users active in last 7 * 24hr</li> <li><strong>WAU</strong> (weekly active users) - users active in last 7 * 24hr</li>
<li><strong>DAT</strong> (daily active time) - total user-activity time in last 24hr</li>
<li><strong>Human message</strong> - message sent by non-bot user, and not with known-bot client</li> <li><strong>Human message</strong> - message sent by non-bot user, and not with known-bot client</li>
</ul> </ul>
@@ -47,8 +46,6 @@
<th>WAU</th> <th>WAU</th>
<th>Total users</th> <th>Total users</th>
<th>Bots</th> <th>Bots</th>
<th>DAT/DAU (hr)</th>
<th>DAT (hr)</th>
<th></th> <th></th>
<th colspan=8>Human messages sent, last 8 UTC days (today-so-far first)</th> <th colspan=8>Human messages sent, last 8 UTC days (today-so-far first)</th>
</tr> </tr>
@@ -114,16 +111,6 @@
{{ row.bot_count }} {{ row.bot_count }}
</td> </td>
<td class="number">
{% if row.hours_per_user %}
{{ row.hours_per_user }}
{% endif %}
</td>
<td class="number">
{{ row.hours }}
</td>
<td>&nbsp;</td> <td>&nbsp;</td>
{% if row.history %} {% if row.history %}