realm_stats: restrict some usage stats to only active users.

They are more meaningful this way -- the fact that your bots that
never log in or inactive users don't have colored streams shouldn't
impact that statistic.

(imported from commit b39debda338cbbad06957bc969b42862a888026a)
This commit is contained in:
Jessica McKellar 2013-03-08 11:11:35 -05:00
parent 85086b6662
commit 4f1bf1b2f2
1 changed files with 38 additions and 12 deletions

View File

@ -2,11 +2,20 @@ import datetime
import pytz import pytz
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zephyr.models import UserProfile, Realm, Stream, Message, Recipient, StreamColor from zephyr.models import UserProfile, Realm, Stream, Message, Recipient, StreamColor, UserActivity
class Command(BaseCommand): class Command(BaseCommand):
help = "Generate statistics on realm activity." help = "Generate statistics on realm activity."
def active_users(self, realm):
# Has been active (on the website, for now) in the last 7 days.
activity_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=7)
return [activity.user_profile for activity in \
UserActivity.objects.filter(user_profile__realm=realm,
last_visit__gt=activity_cutoff,
query="/json/update_pointer",
client__name="website")]
def messages_sent_by(self, user, days_ago): def messages_sent_by(self, user, days_ago):
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago) sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
return Message.objects.filter(sender=user, pub_date__gt=sent_time_cutoff).count() return Message.objects.filter(sender=user, pub_date__gt=sent_time_cutoff).count()
@ -26,6 +35,13 @@ class Command(BaseCommand):
return Message.objects.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude( return Message.objects.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.PERSONAL).count() recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.PERSONAL).count()
def report_percentage(self, numerator, denominator, text):
if not denominator:
fraction = 0.0
else:
fraction = numerator / float(denominator)
print "%.2f%% of" % (fraction * 100,), text
def handle(self, *args, **options): def handle(self, *args, **options):
if args: if args:
try: try:
@ -38,8 +54,12 @@ class Command(BaseCommand):
for realm in realms: for realm in realms:
print realm.domain print realm.domain
user_profiles = UserProfile.objects.filter(realm=realm) user_profiles = UserProfile.objects.filter(realm=realm)
print "%d users" % (len(user_profiles),) active_users = self.active_users(realm)
num_active = len(active_users)
print "%d active users (%d total)" % (num_active, len(user_profiles))
print "%d streams" % (Stream.objects.filter(realm=realm).count(),) print "%d streams" % (Stream.objects.filter(realm=realm).count(),)
for days_ago in (1, 7, 30): for days_ago in (1, 7, 30):
@ -52,20 +72,26 @@ class Command(BaseCommand):
print "%d stream messages" % (self.stream_messages(realm, days_ago),) print "%d stream messages" % (self.stream_messages(realm, days_ago),)
print "%d one-on-one private messages" % (self.private_messages(realm, days_ago),) print "%d one-on-one private messages" % (self.private_messages(realm, days_ago),)
print "%d group private messages" % (self.group_private_messages(realm, days_ago),) print "%d group private messages" % (self.group_private_messages(realm, days_ago),)
print "%.2f%% have desktop notifications enabled" % (float(len(user_profiles.filter(
enable_desktop_notifications=True))) * 100 /len(user_profiles),) num_notifications_enabled = len(filter(lambda x: x.enable_desktop_notifications == True,
active_users))
self.report_percentage(num_notifications_enabled, num_active,
"active users have desktop notifications enabled")
colorizers = 0 colorizers = 0
for profile in user_profiles: for profile in active_users:
if StreamColor.objects.filter(subscription__user_profile=profile).count() > 0: if StreamColor.objects.filter(subscription__user_profile=profile).count() > 0:
colorizers += 1 colorizers += 1
print "%.2f%% have colorized streams" % (float(colorizers) * 100/len(user_profiles),) self.report_percentage(colorizers, num_active,
"active users have colorized streams")
print "%.2f%% have Enter sends" % ( num_enter_sends = len(filter(lambda x: x.enter_sends, active_users))
float(len(filter(lambda x: x.enter_sends, user_profiles))) * 100 / len(user_profiles),) self.report_percentage(num_enter_sends, num_active,
"active users have enter-sends")
all_message_count = Message.objects.filter(sender__realm=realm).count() all_message_count = Message.objects.filter(sender__realm=realm).count()
multi_paragraph_message_count = Message.objects.filter(sender__realm=realm, multi_paragraph_message_count = Message.objects.filter(
content__contains="\n\n").count() sender__realm=realm, content__contains="\n\n").count()
print "%.2f%% of all messages are multi-paragraph" % ( self.report_percentage(multi_paragraph_message_count, all_message_count,
float(multi_paragraph_message_count) * 100 / all_message_count) "all messages are multi-paragraph")
print "" print ""