mirror of https://github.com/zulip/zulip.git
Annotation of zerver/lib/statistics.py
This commit is contained in:
parent
2cf8731444
commit
038af80889
|
@ -5,13 +5,16 @@ from __future__ import division
|
|||
from zerver.models import UserProfile, UserActivity, UserActivityInterval, Message
|
||||
|
||||
from django.utils.timezone import utc
|
||||
from typing import Any
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from datetime import timedelta
|
||||
from itertools import chain
|
||||
from six.moves import range
|
||||
import six
|
||||
|
||||
def median(data):
|
||||
# type: (List[float]) -> float
|
||||
data = sorted(data)
|
||||
|
||||
size = len(data)
|
||||
|
@ -27,29 +30,35 @@ users_who_sent_query = Message.objects.select_related("sender") \
|
|||
.exclude(sending_client__name__contains="API")
|
||||
|
||||
def active_users():
|
||||
# type: () -> List[UserProfile]
|
||||
# Return a list of active users we want to count towards various
|
||||
# statistics.
|
||||
return UserProfile.objects.filter(is_bot=False, is_active=True).select_related()
|
||||
|
||||
def users_who_sent_between(begin, end):
|
||||
# type: (datetime, datetime) -> Set[int]
|
||||
sender_objs = users_who_sent_query.filter(pub_date__gt=begin, pub_date__lt=end) \
|
||||
.values("sender__id")
|
||||
return set(s["sender__id"] for s in sender_objs)
|
||||
|
||||
def users_who_sent_ever():
|
||||
# type: () -> Set[int]
|
||||
return set(s["sender__id"] for s in users_who_sent_query.values("sender__id"))
|
||||
|
||||
def active_users_to_measure():
|
||||
# type: () -> List[UserProfile]
|
||||
senders = users_who_sent_ever()
|
||||
return [u for u in active_users() if u.id in senders]
|
||||
|
||||
def active_users_who_sent_between(begin, end):
|
||||
# type: (datetime, datetime) -> List[UserProfile]
|
||||
senders = users_who_sent_between(begin, end)
|
||||
return [u for u in active_users() if u.id in senders]
|
||||
|
||||
# Return the amount of Zulip usage for this user between the two
|
||||
# given dates
|
||||
def seconds_usage_between(user_profile, begin, end):
|
||||
# type: (UserProfile, datetime, datetime) -> timedelta
|
||||
intervals = UserActivityInterval.objects.filter(user_profile=user_profile, end__gte=begin, start__lte=end)
|
||||
duration = timedelta(0)
|
||||
for interval in intervals:
|
||||
|
@ -60,6 +69,7 @@ def seconds_usage_between(user_profile, begin, end):
|
|||
|
||||
# Return a list of how many seconds each user has been engaging with the app on a given day
|
||||
def seconds_active_during_day(day):
|
||||
# type: (datetime) -> List[float]
|
||||
begin_day = day.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=utc)
|
||||
end_day = day.replace(hour=23, minute=59, second=59, microsecond=0, tzinfo=utc)
|
||||
active_users = active_users_to_measure()
|
||||
|
@ -67,6 +77,7 @@ def seconds_active_during_day(day):
|
|||
return [seconds_usage_between(user, begin_day, end_day).total_seconds() for user in active_users]
|
||||
|
||||
def users_active_nosend_during_day(day):
|
||||
# type: (datetime) -> List[UserProfile]
|
||||
begin_day = day.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=utc)
|
||||
end_day = day.replace(hour=23, minute=59, second=59, microsecond=0, tzinfo=utc)
|
||||
active_users = active_users_to_measure()
|
||||
|
@ -82,6 +93,7 @@ def users_active_nosend_during_day(day):
|
|||
return [u for u in today_users if not u.id in today_senders]
|
||||
|
||||
def calculate_stats(data, all_users):
|
||||
# type: (List[float], List[UserProfile]) -> Dict[str, Any]
|
||||
if len(data) == 0:
|
||||
return {"# data points": 0}
|
||||
|
||||
|
@ -97,6 +109,7 @@ def calculate_stats(data, all_users):
|
|||
|
||||
# Return an info dict {mean: , median} containing the mean/median seconds users were active on a given day
|
||||
def activity_averages_during_day(day):
|
||||
# type: (datetime) -> Dict[str, Any]
|
||||
users_to_measure = active_users_to_measure()
|
||||
seconds_active = seconds_active_during_day(day)
|
||||
return calculate_stats(seconds_active, all_users=users_to_measure)
|
||||
|
@ -104,6 +117,7 @@ def activity_averages_during_day(day):
|
|||
# Returns an info dict {mean: , median} with engagement numbers for all users according
|
||||
# to active_users_to_measure.
|
||||
def activity_averages_between(begin, end, by_day=True):
|
||||
# type: (datetime, datetime, bool) -> Dict[str, Any]
|
||||
seconds_active = {}
|
||||
users_to_measure = active_users_to_measure()
|
||||
for i in range((end - begin).days):
|
||||
|
|
Loading…
Reference in New Issue