stats: Extend get_chart_data to support charts with multiple CountStats.

This commit is contained in:
Rishi Gupta
2018-05-18 16:48:36 -07:00
committed by Tim Abbott
parent 08bf0a66b8
commit 66a589c7a7

View File

@@ -94,31 +94,32 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
aggregate_table = InstallationCount aggregate_table = InstallationCount
if chart_name == 'number_of_humans': if chart_name == 'number_of_humans':
stat = COUNT_STATS['realm_active_humans::day'] stats = [COUNT_STATS['realm_active_humans::day']]
tables = [aggregate_table] tables = [aggregate_table]
subgroup_to_label = {None: 'human'} # type: Dict[Optional[str], str] subgroup_to_label = {stats[0]: {None: 'human'}} # type: Dict[CountStat, Dict[Optional[str], str]]
labels_sort_function = None labels_sort_function = None
include_empty_subgroups = True include_empty_subgroups = True
elif chart_name == 'messages_sent_over_time': elif chart_name == 'messages_sent_over_time':
stat = COUNT_STATS['messages_sent:is_bot:hour'] stats = [COUNT_STATS['messages_sent:is_bot:hour']]
tables = [aggregate_table, UserCount] tables = [aggregate_table, UserCount]
subgroup_to_label = {'false': 'human', 'true': 'bot'} subgroup_to_label = {stats[0]: {'false': 'human', 'true': 'bot'}}
labels_sort_function = None labels_sort_function = None
include_empty_subgroups = True include_empty_subgroups = True
elif chart_name == 'messages_sent_by_message_type': elif chart_name == 'messages_sent_by_message_type':
stat = COUNT_STATS['messages_sent:message_type:day'] stats = [COUNT_STATS['messages_sent:message_type:day']]
tables = [aggregate_table, UserCount] tables = [aggregate_table, UserCount]
subgroup_to_label = {'public_stream': _('Public streams'), subgroup_to_label = {stats[0]: {'public_stream': _('Public streams'),
'private_stream': _('Private streams'), 'private_stream': _('Private streams'),
'private_message': _('Private messages'), 'private_message': _('Private messages'),
'huddle_message': _('Group private messages')} 'huddle_message': _('Group private messages')}}
labels_sort_function = lambda data: sort_by_totals(data['everyone']) labels_sort_function = lambda data: sort_by_totals(data['everyone'])
include_empty_subgroups = True include_empty_subgroups = True
elif chart_name == 'messages_sent_by_client': elif chart_name == 'messages_sent_by_client':
stat = COUNT_STATS['messages_sent:client:day'] stats = [COUNT_STATS['messages_sent:client:day']]
tables = [aggregate_table, UserCount] tables = [aggregate_table, UserCount]
# Note that the labels are further re-written by client_label_map # Note that the labels are further re-written by client_label_map
subgroup_to_label = {str(id): name for id, name in Client.objects.values_list('id', 'name')} subgroup_to_label = {stats[0]:
{str(id): name for id, name in Client.objects.values_list('id', 'name')}}
labels_sort_function = sort_client_labels labels_sort_function = sort_client_labels
include_empty_subgroups = False include_empty_subgroups = False
else: else:
@@ -142,7 +143,8 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
else: else:
start = realm.date_created start = realm.date_created
if end is None: if end is None:
end = last_successful_fill(stat.property) end = max(last_successful_fill(stat.property) or
datetime.min.replace(tzinfo=timezone_utc) for stat in stats)
if end is None or start > end: if end is None or start > end:
logging.warning("User from realm %s attempted to access /stats, but the computed " logging.warning("User from realm %s attempted to access /stats, but the computed "
"start time: %s (creation of realm or installation) is later than the computed " "start time: %s (creation of realm or installation) is later than the computed "
@@ -150,15 +152,18 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
"analytics cron job running?" % (realm.string_id, start, end)) "analytics cron job running?" % (realm.string_id, start, end))
raise JsonableError(_("No analytics data available. Please contact your server administrator.")) raise JsonableError(_("No analytics data available. Please contact your server administrator."))
end_times = time_range(start, end, stat.frequency, min_length) assert len(set([stat.frequency for stat in stats])) == 1
data = {'end_times': end_times, 'frequency': stat.frequency} end_times = time_range(start, end, stats[0].frequency, min_length)
data = {'end_times': end_times, 'frequency': stats[0].frequency} # type: Dict[str, Any]
aggregation_level = {InstallationCount: 'everyone', RealmCount: 'everyone', UserCount: 'user'} aggregation_level = {InstallationCount: 'everyone', RealmCount: 'everyone', UserCount: 'user'}
# -1 is a placeholder value, since there is no relevant filtering on InstallationCount # -1 is a placeholder value, since there is no relevant filtering on InstallationCount
id_value = {InstallationCount: -1, RealmCount: realm.id, UserCount: user_profile.id} id_value = {InstallationCount: -1, RealmCount: realm.id, UserCount: user_profile.id}
for table in tables: for table in tables:
data[aggregation_level[table]] = get_time_series_by_subgroup( data[aggregation_level[table]] = {}
stat, table, id_value[table], end_times, subgroup_to_label, include_empty_subgroups) for stat in stats:
data[aggregation_level[table]].update(get_time_series_by_subgroup(
stat, table, id_value[table], end_times, subgroup_to_label[stat], include_empty_subgroups))
if labels_sort_function is not None: if labels_sort_function is not None:
data['display_order'] = labels_sort_function(data) data['display_order'] = labels_sort_function(data)