-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add storage and module API methods to get monthly active users and their appservices #12838
Changes from 3 commits
845721a
0023f5d
451d7be
95accd8
2211213
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add storage and module API methods to get monthly active users (and their corresponding appservices) within an optionally specified time range. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,6 +122,49 @@ def _count_users_by_service(txn: LoggingTransaction) -> Dict[str, int]: | |
"count_users_by_service", _count_users_by_service | ||
) | ||
|
||
async def get_monthly_active_users_by_service( | ||
self, start_timestamp: Optional[int] = None, end_timestamp: Optional[int] = None | ||
) -> List[Tuple[str, str]]: | ||
"""Generates list of monthly active users and their services. | ||
Please see "get_monthly_active_count_by_service" docstring for more details | ||
about services. | ||
|
||
Arguments: | ||
start_timestamp: If specified, only include users that were first active | ||
at or after this point | ||
end_timestamp: If specified, only include users that were first active | ||
at or before this point | ||
|
||
Returns: | ||
A list of tuples (appservice_id, user_id) | ||
|
||
""" | ||
if start_timestamp is not None and end_timestamp is not None: | ||
where_clause = 'WHERE "timestamp" >= ? and "timestamp" <= ?' | ||
query_params = [start_timestamp, end_timestamp] | ||
elif start_timestamp is not None: | ||
where_clause = 'WHERE "timestamp" >= ?' | ||
query_params = [start_timestamp] | ||
elif end_timestamp is not None: | ||
where_clause = 'WHERE "timestamp" <= ?' | ||
query_params = [end_timestamp] | ||
else: | ||
where_clause = "" | ||
query_params = [] | ||
|
||
def _list_users(txn: LoggingTransaction) -> List[Tuple[str, str]]: | ||
sql = f""" | ||
SELECT COALESCE(appservice_id, 'native'), user_id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could live with that, but the pre-existing get_monthly_active_count_by_service method (which this new method is modelled on) is emitting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh interesting, fair enough then. I think it probably does make more sense to be consistent then |
||
FROM monthly_active_users | ||
LEFT JOIN users ON monthly_active_users.user_id=users.name | ||
{where_clause}; | ||
""" | ||
|
||
txn.execute(sql, query_params) | ||
return cast(List[Tuple[str, str]], txn.fetchall()) | ||
|
||
return await self.db_pool.runInteraction("list_users", _list_users) | ||
|
||
async def get_registered_reserved_users(self) -> List[str]: | ||
"""Of the reserved threepids defined in config, retrieve those that are associated | ||
with registered users | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document what is returned for
appservice_id
if the user isn't from an appservice? (As per below I think we should returnNone
in that case)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping this sentence would alleviate the need to repeat what is mentioned in
get_monthly_active_count_by_service
, but for the sake of reducing the coupling between the two docstrings, I've added it here: 95accd8There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. I think the docstring should either document the return values fully, or not at all.