forked from OSQA/osqa
-
Notifications
You must be signed in to change notification settings - Fork 628
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* adds tldextract dependency to extract the organization name from the email domain * adds management command askbot_compile_analytics_events counts users per group as well as events per user and group todo: time on site calculation * askbot_create_per_email_domain_groups management command: - adds --silent option - per email domain groups are marked with used_for_analytics=True * models {User,Group}DailySummary: - event counts, time_on_site receive zero default values * model Event, Session, {User,Group}DailySummary: - adds compiled attribute * model Group (AskbotGroup) - adds used_for_analytics attribute * User.get_groups method: - adds used_for_analytics parameter * event summary models can add events and summaries via add_event and __add__ methods * askbot.models.user.get_organization_name_from_domain: - returns a sentence-cased organization name from the email domain using the tldextract library * askbot.utils.console.ProgressBar: - adds silent parameter to suppress output
- Loading branch information
1 parent
8d3d6e2
commit 8d7cfa1
Showing
12 changed files
with
261 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
askbot/management/commands/askbot_compile_analytics_events.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"""Management commands for Askbot Analytics Events. | ||
Compiles summaries of Askbot Analytics Events in the | ||
per-user and per-group Summary tables. | ||
""" | ||
import datetime | ||
from django.db import transaction | ||
from django.core.management.base import BaseCommand | ||
from askbot.utils.console import ProgressBar | ||
from askbot.models.analytics import Event, GroupDailySummary, UserDailySummary | ||
|
||
class Command(BaseCommand): # pylint: disable=missing-class-docstring, too-few-public-methods | ||
|
||
def add_arguments(self, parser): # pylint: disable=missing-function-docstring | ||
parser.add_argument('--silent', action='store_true', help='Print progress on the console') | ||
|
||
def handle(self, *args, **options): # pylint: disable=missing-function-docstring | ||
""" | ||
Filters uncompiled analytics events. | ||
Iterates over the events, and calculates per user summaries | ||
per date. | ||
THen iterates over the per-user summaries and combines them | ||
into the per-group summaries. | ||
""" | ||
events = Event.objects.filter(compiled=False).order_by('timestamp') # pylint: disable=no-member | ||
events_count = events.count() | ||
message = 'Compiling Events:' | ||
silent = options['silent'] | ||
for event in ProgressBar(events.iterator(), events_count, message=message, silent=silent): | ||
self.compile_event(event) | ||
|
||
daily_summaries = UserDailySummary.objects.filter(compiled=False).order_by('date') # pylint: disable=no-member | ||
message = 'Compiling User Daily Summaries:' | ||
summaries_count = daily_summaries.count() | ||
iterator = daily_summaries.iterator() | ||
for daily_summary in ProgressBar(iterator, summaries_count, message=message, silent=silent): | ||
self.compile_user_daily_summary(daily_summary) | ||
|
||
# todo: | ||
# update the time on site (how?) | ||
# update the total number of users per group | ||
# maybe: record number of active users per group within period | ||
message = 'Count users per group:' | ||
group_daily_summaries = GroupDailySummary.objects.filter(compiled=False) # pylint: disable=no-member | ||
count = group_daily_summaries.count() | ||
iterator = group_daily_summaries.iterator() # pylint: disable=no-member | ||
for group_summary in ProgressBar(iterator, count, message=message, silent=silent): | ||
self.update_users_count_per_group(group_summary) | ||
|
||
|
||
@transaction.atomic | ||
def update_users_count_per_group(self, group_summary): | ||
"""Counts the number of users in the group at the end of the day""" | ||
join_date_cutoff = group_summary.date + datetime.timedelta(days=1) | ||
users = group_summary.group.user_set.filter(date_joined__lte=join_date_cutoff) # pylint: disable=no-member | ||
group_summary.num_users = users.count() | ||
group_summary.compiled = True | ||
group_summary.save() | ||
|
||
|
||
@transaction.atomic | ||
def compile_event(self, event): | ||
"""Adds up event stats into the user daily summary""" | ||
date = event.timestamp.date() | ||
user = event.session.user | ||
user_summary, _ = UserDailySummary.objects.get_or_create(date=date, # pylint: disable=no-member | ||
user=user) | ||
user_summary.add_event(event) | ||
user_summary.save() | ||
Event.objects.filter(id=event.id).update(compiled=True) # pylint: disable=no-member | ||
|
||
|
||
@transaction.atomic | ||
def compile_user_daily_summary(self, user_daily_summary): | ||
groups = user_daily_summary.user.get_groups(used_for_analytics=True) | ||
for group in groups: | ||
date = user_daily_summary.date | ||
group_summary, _ = GroupDailySummary.objects.get_or_create(date=date, # pylint: disable=no-member | ||
group=group) | ||
group_summary += user_daily_summary | ||
group_summary.save() | ||
|
||
UserDailySummary.objects.filter(id=user_daily_summary.id).update(compiled=True) # pylint: disable=no-member | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
askbot/migrations/0030_event_compiled_group_used_for_analytics_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Generated by Django 4.2.4 on 2024-07-02 00:10 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('askbot', '0029_group_visibility'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='event', | ||
name='compiled', | ||
field=models.BooleanField(default=False, help_text='True if the event is compiled into a summary'), | ||
), | ||
migrations.AddField( | ||
model_name='group', | ||
name='used_for_analytics', | ||
field=models.BooleanField(default=False), | ||
), | ||
migrations.AddField( | ||
model_name='groupdailysummary', | ||
name='compiled', | ||
field=models.BooleanField(default=False), | ||
), | ||
migrations.AddField( | ||
model_name='userdailysummary', | ||
name='compiled', | ||
field=models.BooleanField(default=False), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.