mirror of https://github.com/zulip/zulip.git
activity: Add separate page for remote server information/table.
Moves the "Remote Zulip servers" tab in the "/activity" page for an installation to a separate page, "/activity/remote". Prototype for moving other tabs in "/activity" to separate pages.
This commit is contained in:
parent
91f81d3962
commit
afc1d2a409
|
@ -31,10 +31,14 @@ class ActivityTest(ZulipTestCase):
|
|||
user_profile.is_staff = True
|
||||
user_profile.save(update_fields=["is_staff"])
|
||||
|
||||
with self.assert_database_query_count(18):
|
||||
with self.assert_database_query_count(17):
|
||||
result = self.client_get("/activity")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with self.assert_database_query_count(4):
|
||||
result = self.client_get("/activity/remote")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with self.assert_database_query_count(8):
|
||||
result = self.client_get("/realm_activity/zulip/")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
|
|
@ -4,7 +4,10 @@ from django.conf.urls import include
|
|||
from django.urls import path
|
||||
from django.urls.resolvers import URLPattern, URLResolver
|
||||
|
||||
from analytics.views.installation_activity import get_installation_activity
|
||||
from analytics.views.installation_activity import (
|
||||
get_installation_activity,
|
||||
get_remote_server_activity,
|
||||
)
|
||||
from analytics.views.realm_activity import get_realm_activity
|
||||
from analytics.views.stats import (
|
||||
get_chart_data,
|
||||
|
@ -25,6 +28,7 @@ from zerver.lib.rest import rest_path
|
|||
i18n_urlpatterns: List[Union[URLPattern, URLResolver]] = [
|
||||
# Server admin (user_profile.is_staff) visible stats pages
|
||||
path("activity", get_installation_activity),
|
||||
path("activity/remote", get_remote_server_activity),
|
||||
path("activity/support", support, name="support"),
|
||||
path("realm_activity/<realm_str>/", get_realm_activity),
|
||||
path("user_activity/<user_profile_id>/", get_user_activity),
|
||||
|
|
|
@ -95,7 +95,7 @@ def remote_installation_stats_link(server_id: int, hostname: str) -> Markup:
|
|||
from analytics.views.stats import stats_for_remote_installation
|
||||
|
||||
url = reverse(stats_for_remote_installation, kwargs=dict(remote_server_id=server_id))
|
||||
return Markup('<a href="{url}"><i class="fa fa-pie-chart"></i>{hostname}</a>').format(
|
||||
return Markup('<a href="{url}"><i class="fa fa-pie-chart"></i></a> {hostname}').format(
|
||||
url=url, hostname=hostname
|
||||
)
|
||||
|
||||
|
|
|
@ -355,52 +355,51 @@ def user_activity_intervals() -> Tuple[Markup, Dict[str, float]]:
|
|||
return content, realm_minutes
|
||||
|
||||
|
||||
def ad_hoc_queries() -> List[Dict[str, str]]:
|
||||
def get_page(
|
||||
query: Composable, cols: Sequence[str], title: str, totals_columns: Sequence[int] = []
|
||||
) -> Dict[str, str]:
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
rows = cursor.fetchall()
|
||||
rows = list(map(list, rows))
|
||||
cursor.close()
|
||||
def get_page(
|
||||
query: Composable, cols: Sequence[str], title: str, totals_columns: Sequence[int] = []
|
||||
) -> Dict[str, str]:
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
rows = cursor.fetchall()
|
||||
rows = list(map(list, rows))
|
||||
cursor.close()
|
||||
|
||||
def fix_rows(
|
||||
i: int, fixup_func: Union[Callable[[str], Markup], Callable[[datetime], str]]
|
||||
) -> None:
|
||||
def fix_rows(
|
||||
i: int, fixup_func: Union[Callable[[str], Markup], Callable[[datetime], str]]
|
||||
) -> None:
|
||||
for row in rows:
|
||||
row[i] = fixup_func(row[i])
|
||||
|
||||
total_row = []
|
||||
for i, col in enumerate(cols):
|
||||
if col == "Realm":
|
||||
fix_rows(i, realm_activity_link)
|
||||
elif col in ["Last time", "Last visit"]:
|
||||
fix_rows(i, format_date_for_activity_reports)
|
||||
elif col == "Hostname":
|
||||
for row in rows:
|
||||
row[i] = fixup_func(row[i])
|
||||
|
||||
total_row = []
|
||||
for i, col in enumerate(cols):
|
||||
if col == "Realm":
|
||||
fix_rows(i, realm_activity_link)
|
||||
elif col in ["Last time", "Last visit"]:
|
||||
fix_rows(i, format_date_for_activity_reports)
|
||||
elif col == "Hostname":
|
||||
for row in rows:
|
||||
row[i] = remote_installation_stats_link(row[0], row[i])
|
||||
if len(totals_columns) > 0:
|
||||
if i == 0:
|
||||
total_row.append("Total")
|
||||
elif i in totals_columns:
|
||||
total_row.append(str(sum(row[i] for row in rows if row[i] is not None)))
|
||||
else:
|
||||
total_row.append("")
|
||||
row[i] = remote_installation_stats_link(row[0], row[i])
|
||||
if len(totals_columns) > 0:
|
||||
rows.insert(0, total_row)
|
||||
if i == 0:
|
||||
total_row.append("Total")
|
||||
elif i in totals_columns:
|
||||
total_row.append(str(sum(row[i] for row in rows if row[i] is not None)))
|
||||
else:
|
||||
total_row.append("")
|
||||
if len(totals_columns) > 0:
|
||||
rows.insert(0, total_row)
|
||||
|
||||
content = make_table(title, cols, rows)
|
||||
content = make_table(title, cols, rows)
|
||||
|
||||
return dict(
|
||||
content=content,
|
||||
title=title,
|
||||
)
|
||||
return dict(
|
||||
content=content,
|
||||
title=title,
|
||||
)
|
||||
|
||||
|
||||
def ad_hoc_queries() -> List[Dict[str, str]]:
|
||||
pages = []
|
||||
|
||||
###
|
||||
|
||||
for mobile_type in ["Android", "ZulipiOS"]:
|
||||
title = f"{mobile_type} usage"
|
||||
|
||||
|
@ -548,7 +547,32 @@ def ad_hoc_queries() -> List[Dict[str, str]]:
|
|||
|
||||
pages.append(get_page(query, cols, title))
|
||||
|
||||
title = "Remote Zulip servers"
|
||||
return pages
|
||||
|
||||
|
||||
@require_server_admin
|
||||
@has_request_variables
|
||||
def get_installation_activity(request: HttpRequest) -> HttpResponse:
|
||||
duration_content, realm_minutes = user_activity_intervals()
|
||||
counts_content: str = realm_summary_table(realm_minutes)
|
||||
data = [
|
||||
("Counts", counts_content),
|
||||
("Durations", duration_content),
|
||||
*((page["title"], page["content"]) for page in ad_hoc_queries()),
|
||||
]
|
||||
|
||||
title = "Activity"
|
||||
|
||||
return render(
|
||||
request,
|
||||
"analytics/activity.html",
|
||||
context=dict(data=data, title=title, is_home=True),
|
||||
)
|
||||
|
||||
|
||||
@require_server_admin
|
||||
def get_remote_server_activity(request: HttpRequest) -> HttpResponse:
|
||||
title = "Remote servers"
|
||||
|
||||
query = SQL(
|
||||
"""
|
||||
|
@ -590,26 +614,10 @@ def ad_hoc_queries() -> List[Dict[str, str]]:
|
|||
"Last update time",
|
||||
]
|
||||
|
||||
pages.append(get_page(query, cols, title, totals_columns=[3, 4]))
|
||||
|
||||
return pages
|
||||
|
||||
|
||||
@require_server_admin
|
||||
@has_request_variables
|
||||
def get_installation_activity(request: HttpRequest) -> HttpResponse:
|
||||
duration_content, realm_minutes = user_activity_intervals()
|
||||
counts_content: str = realm_summary_table(realm_minutes)
|
||||
data = [
|
||||
("Counts", counts_content),
|
||||
("Durations", duration_content),
|
||||
*((page["title"], page["content"]) for page in ad_hoc_queries()),
|
||||
]
|
||||
|
||||
title = "Activity"
|
||||
remote_servers = get_page(query, cols, title, totals_columns=[3, 4])
|
||||
|
||||
return render(
|
||||
request,
|
||||
"analytics/activity.html",
|
||||
context=dict(data=data, title=title, is_home=True),
|
||||
"analytics/activity_details_template.html",
|
||||
context=dict(data=remote_servers["content"], title=remote_servers["title"], is_home=False),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{% extends "zerver/base.html" %}
|
||||
{% set entrypoint = "activity" %}
|
||||
|
||||
{# Template for installation activity pages #}
|
||||
|
||||
{% block title %}
|
||||
<title>{{ title }} | Zulip analytics</title>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if not is_home %}
|
||||
<a class="show-all" href="/activity">Home</a>
|
||||
<br />
|
||||
{% endif %}
|
||||
|
||||
<div class="container">
|
||||
{{ data|safe }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
<p style="text-align: center;">{{ utctime }}</p>
|
||||
|
||||
<h4>Installation information:</h4>
|
||||
<ul>
|
||||
<li><a href="/stats/installation">Server total /stats style graphs</a></li>
|
||||
<li><a href="/activity/remote">Remote servers</a></li>
|
||||
</ul>
|
||||
|
||||
<h4>Counts chart key:</h4>
|
||||
<ul>
|
||||
<li><strong>active (site)</strong> - has ≥5 DAUs</li>
|
||||
<li>sites are listed if ≥1 users active in last 2 weeks</li>
|
||||
|
@ -20,7 +27,6 @@
|
|||
<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><a href="/stats/installation">Server total /stats style graphs</a></li>
|
||||
</ul>
|
||||
|
||||
<table class="table summary-table sortable table-striped table-bordered">
|
||||
|
|
Loading…
Reference in New Issue