Annotation of zerver/lib/statistics.py

This commit is contained in:
Ashish 2016-03-22 11:22:36 +05:30 committed by Tim Abbott
parent 2cf8731444
commit 038af80889
1 changed files with 15 additions and 1 deletions

View File

@ -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):