mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 16:37:23 +00:00
analytics: Extract analytics/views/user_activity.py.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from django.conf.urls import include
|
from django.conf.urls import include
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from analytics.views.legacy import get_activity, get_user_activity
|
from analytics.views.legacy import get_activity
|
||||||
from analytics.views.realm_activity import get_realm_activity
|
from analytics.views.realm_activity import get_realm_activity
|
||||||
from analytics.views.stats import (
|
from analytics.views.stats import (
|
||||||
get_chart_data,
|
get_chart_data,
|
||||||
@@ -16,6 +16,7 @@ from analytics.views.stats import (
|
|||||||
stats_for_remote_realm,
|
stats_for_remote_realm,
|
||||||
)
|
)
|
||||||
from analytics.views.support import support
|
from analytics.views.support import support
|
||||||
|
from analytics.views.user_activity import get_user_activity
|
||||||
from zerver.lib.rest import rest_path
|
from zerver.lib.rest import rest_path
|
||||||
|
|
||||||
i18n_urlpatterns = [
|
i18n_urlpatterns = [
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def format_date_for_activity_reports(date: Optional[datetime]) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def user_activity_link(email: str) -> mark_safe:
|
def user_activity_link(email: str) -> mark_safe:
|
||||||
from analytics.views.legacy import get_user_activity
|
from analytics.views.user_activity import get_user_activity
|
||||||
|
|
||||||
url = reverse(get_user_activity, kwargs=dict(email=email))
|
url = reverse(get_user_activity, kwargs=dict(email=email))
|
||||||
email_link = f'<a href="{escape(url)}">{escape(email)}</a>'
|
email_link = f'<a href="{escape(url)}">{escape(email)}</a>'
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ import itertools
|
|||||||
import time
|
import time
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
|
from typing import Callable, Dict, List, Optional, Sequence, Tuple, Union
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.db.models.query import QuerySet
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
@@ -18,7 +17,6 @@ from analytics.lib.counts import COUNT_STATS
|
|||||||
from analytics.views.activity_common import (
|
from analytics.views.activity_common import (
|
||||||
dictfetchall,
|
dictfetchall,
|
||||||
format_date_for_activity_reports,
|
format_date_for_activity_reports,
|
||||||
get_user_activity_summary,
|
|
||||||
make_table,
|
make_table,
|
||||||
realm_activity_link,
|
realm_activity_link,
|
||||||
realm_stats_link,
|
realm_stats_link,
|
||||||
@@ -28,7 +26,7 @@ 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.lib.timestamp import timestamp_to_datetime
|
||||||
from zerver.models import Realm, UserActivity, UserActivityInterval, UserProfile
|
from zerver.models import Realm, UserActivityInterval, UserProfile
|
||||||
|
|
||||||
if settings.BILLING_ENABLED:
|
if settings.BILLING_ENABLED:
|
||||||
from corporate.lib.stripe import (
|
from corporate.lib.stripe import (
|
||||||
@@ -614,89 +612,3 @@ def get_activity(request: HttpRequest) -> HttpResponse:
|
|||||||
"analytics/activity.html",
|
"analytics/activity.html",
|
||||||
context=dict(data=data, title=title, is_home=True),
|
context=dict(data=data, title=title, is_home=True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_user_activity_records_for_email(email: str) -> List[QuerySet]:
|
|
||||||
fields = [
|
|
||||||
"user_profile__full_name",
|
|
||||||
"query",
|
|
||||||
"client__name",
|
|
||||||
"count",
|
|
||||||
"last_visit",
|
|
||||||
]
|
|
||||||
|
|
||||||
records = UserActivity.objects.filter(
|
|
||||||
user_profile__delivery_email=email,
|
|
||||||
)
|
|
||||||
records = records.order_by("-last_visit")
|
|
||||||
records = records.select_related("user_profile", "client").only(*fields)
|
|
||||||
return records
|
|
||||||
|
|
||||||
|
|
||||||
def raw_user_activity_table(records: List[QuerySet]) -> str:
|
|
||||||
cols = [
|
|
||||||
"query",
|
|
||||||
"client",
|
|
||||||
"count",
|
|
||||||
"last_visit",
|
|
||||||
]
|
|
||||||
|
|
||||||
def row(record: QuerySet) -> List[Any]:
|
|
||||||
return [
|
|
||||||
record.query,
|
|
||||||
record.client.name,
|
|
||||||
record.count,
|
|
||||||
format_date_for_activity_reports(record.last_visit),
|
|
||||||
]
|
|
||||||
|
|
||||||
rows = list(map(row, records))
|
|
||||||
title = "Raw data"
|
|
||||||
return make_table(title, cols, rows)
|
|
||||||
|
|
||||||
|
|
||||||
def user_activity_summary_table(user_summary: Dict[str, Dict[str, Any]]) -> str:
|
|
||||||
rows = []
|
|
||||||
for k, v in user_summary.items():
|
|
||||||
if k == "name":
|
|
||||||
continue
|
|
||||||
client = k
|
|
||||||
count = v["count"]
|
|
||||||
last_visit = v["last_visit"]
|
|
||||||
row = [
|
|
||||||
format_date_for_activity_reports(last_visit),
|
|
||||||
client,
|
|
||||||
count,
|
|
||||||
]
|
|
||||||
rows.append(row)
|
|
||||||
|
|
||||||
rows = sorted(rows, key=lambda r: r[0], reverse=True)
|
|
||||||
|
|
||||||
cols = [
|
|
||||||
"last_visit",
|
|
||||||
"client",
|
|
||||||
"count",
|
|
||||||
]
|
|
||||||
|
|
||||||
title = "User activity"
|
|
||||||
return make_table(title, cols, rows)
|
|
||||||
|
|
||||||
|
|
||||||
@require_server_admin
|
|
||||||
def get_user_activity(request: HttpRequest, email: str) -> HttpResponse:
|
|
||||||
records = get_user_activity_records_for_email(email)
|
|
||||||
|
|
||||||
data: List[Tuple[str, str]] = []
|
|
||||||
user_summary = get_user_activity_summary(records)
|
|
||||||
content = user_activity_summary_table(user_summary)
|
|
||||||
|
|
||||||
data += [("Summary", content)]
|
|
||||||
|
|
||||||
content = raw_user_activity_table(records)
|
|
||||||
data += [("Info", content)]
|
|
||||||
|
|
||||||
title = email
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"analytics/activity.html",
|
|
||||||
context=dict(data=data, title=title),
|
|
||||||
)
|
|
||||||
|
|||||||
103
analytics/views/user_activity.py
Normal file
103
analytics/views/user_activity.py
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
from typing import Any, Dict, List, Tuple
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from analytics.views.activity_common import (
|
||||||
|
format_date_for_activity_reports,
|
||||||
|
get_user_activity_summary,
|
||||||
|
make_table,
|
||||||
|
)
|
||||||
|
from zerver.decorator import require_server_admin
|
||||||
|
from zerver.models import UserActivity
|
||||||
|
|
||||||
|
if settings.BILLING_ENABLED:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_activity_records_for_email(email: str) -> List[QuerySet]:
|
||||||
|
fields = [
|
||||||
|
"user_profile__full_name",
|
||||||
|
"query",
|
||||||
|
"client__name",
|
||||||
|
"count",
|
||||||
|
"last_visit",
|
||||||
|
]
|
||||||
|
|
||||||
|
records = UserActivity.objects.filter(
|
||||||
|
user_profile__delivery_email=email,
|
||||||
|
)
|
||||||
|
records = records.order_by("-last_visit")
|
||||||
|
records = records.select_related("user_profile", "client").only(*fields)
|
||||||
|
return records
|
||||||
|
|
||||||
|
|
||||||
|
def raw_user_activity_table(records: List[QuerySet]) -> str:
|
||||||
|
cols = [
|
||||||
|
"query",
|
||||||
|
"client",
|
||||||
|
"count",
|
||||||
|
"last_visit",
|
||||||
|
]
|
||||||
|
|
||||||
|
def row(record: QuerySet) -> List[Any]:
|
||||||
|
return [
|
||||||
|
record.query,
|
||||||
|
record.client.name,
|
||||||
|
record.count,
|
||||||
|
format_date_for_activity_reports(record.last_visit),
|
||||||
|
]
|
||||||
|
|
||||||
|
rows = list(map(row, records))
|
||||||
|
title = "Raw data"
|
||||||
|
return make_table(title, cols, rows)
|
||||||
|
|
||||||
|
|
||||||
|
def user_activity_summary_table(user_summary: Dict[str, Dict[str, Any]]) -> str:
|
||||||
|
rows = []
|
||||||
|
for k, v in user_summary.items():
|
||||||
|
if k == "name":
|
||||||
|
continue
|
||||||
|
client = k
|
||||||
|
count = v["count"]
|
||||||
|
last_visit = v["last_visit"]
|
||||||
|
row = [
|
||||||
|
format_date_for_activity_reports(last_visit),
|
||||||
|
client,
|
||||||
|
count,
|
||||||
|
]
|
||||||
|
rows.append(row)
|
||||||
|
|
||||||
|
rows = sorted(rows, key=lambda r: r[0], reverse=True)
|
||||||
|
|
||||||
|
cols = [
|
||||||
|
"last_visit",
|
||||||
|
"client",
|
||||||
|
"count",
|
||||||
|
]
|
||||||
|
|
||||||
|
title = "User activity"
|
||||||
|
return make_table(title, cols, rows)
|
||||||
|
|
||||||
|
|
||||||
|
@require_server_admin
|
||||||
|
def get_user_activity(request: HttpRequest, email: str) -> HttpResponse:
|
||||||
|
records = get_user_activity_records_for_email(email)
|
||||||
|
|
||||||
|
data: List[Tuple[str, str]] = []
|
||||||
|
user_summary = get_user_activity_summary(records)
|
||||||
|
content = user_activity_summary_table(user_summary)
|
||||||
|
|
||||||
|
data += [("Summary", content)]
|
||||||
|
|
||||||
|
content = raw_user_activity_table(records)
|
||||||
|
data += [("Info", content)]
|
||||||
|
|
||||||
|
title = email
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"analytics/activity.html",
|
||||||
|
context=dict(data=data, title=title),
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user