Skip to content

Commit

Permalink
Merge pull request #1019 from catarial/inactive-users
Browse files Browse the repository at this point in the history
Inactive users script
  • Loading branch information
shankari authored Feb 18, 2025
2 parents 4d57b53 + a49fb0a commit b636af1
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
8 changes: 6 additions & 2 deletions bin/historical/migrations/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,21 @@
]
print(f"PROD_LIST: {PROD_LIST}")

def run_on_all_deployments(fn_to_run):
def run_on_all_deployments(fn_to_run, *args):
"""
Run the given function on the database for each deployment by setting the
DB_HOST environment variable in between each function call.
The list of deployments (PROD_LIST) is retrieved from the
nrel-openpath-deploy-configs repo upon initialization of this module.
"""
print(f'About to run {fn_to_run.__name__}{args} on {len(PROD_LIST)} deployments. Proceed? [y/n]')
if input() != 'y':
print("Aborting")
return
for prod in PROD_LIST:
prod_db_name = prod.replace("-", "_")
print(f"Running {fn_to_run.__name__} for {prod} on DB {prod_db_name}")
os.environ['DB_HOST'] = DB_HOST_TEMPLATE.replace(
"REPLACEME", prod_db_name)
importlib.reload(edb)
fn_to_run()
fn_to_run(*args)
83 changes: 83 additions & 0 deletions bin/historical/migrations/inactive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import arrow
import pymongo
import emission.core.get_database as edb
import emission.storage.timeseries.abstract_timeseries as esta
import bin.debug.common as common
from _common import run_on_all_deployments

NOW_SECONDS = arrow.now().timestamp()

def find_inactive_uuids(uuids_entries, threshold):
inactive_uuids = []
for u in uuids_entries:
print(f'Checking activity for user {u["uuid"]}')
profile_data = edb.get_profile_db().find_one({'user_id': u})
ts = esta.TimeSeries.get_time_series(u['uuid'])

if profile_data:
last_call_ts = profile_data.get('last_call_ts')
else:
last_call_ts = ts.get_first_value_for_field(
key='stats/server_api_time',
field='data.ts',
sort_order=pymongo.DESCENDING
)

print(f'for user {u["uuid"]}, last call was {last_call_ts}')
if last_call_ts > NOW_SECONDS - threshold:
continue

if profile_data:
last_loc_ts = profile_data.get('last_loc_ts')
else:
last_loc_ts = ts.get_first_value_for_field(
key='background/location',
field='data.ts',
sort_order=pymongo.DESCENDING
)

print(f'for user {u["uuid"]}, last location was {last_loc_ts}')
if last_loc_ts > NOW_SECONDS - threshold:
continue

print(f'User {u["uuid"]} is inactive')
inactive_uuids.append(u['uuid'])

return inactive_uuids

def purge_users(uuids):
print(f'About to remove {len(uuids)} users. Proceed? [y/n]')
if input() != 'y':
print("Aborting")
return
for u in uuids:
print(f'Purging user {u}')
common.purge_entries_for_user(u, True)

def start_inactive(threshold_s, purge):
total_users = edb.get_uuid_db().count_documents({})
print(f'Total users: {total_users}')
uuids_entries = edb.get_uuid_db().find()
print('Finding inactive users...')
inactive_uuids = find_inactive_uuids(uuids_entries, threshold_s)
print(f'Of {total_users} users, found {len(inactive_uuids)} inactive users:')
print(inactive_uuids)

if purge:
purge_users(inactive_uuids)

if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
prog='inactive_users',
description='Identify and perform actions on inactive users'
)
parser.add_argument('-t', '--threshold', help='amount of time in days that defines an inactive user')
parser.add_argument('-p', '--purge', action='store_true', help='purge inactive users')
args = parser.parse_args()

threshold_s = 60 * 60 * 24 * int(args.threshold)

run_on_all_deployments(start_inactive, threshold_s, args.purge)


0 comments on commit b636af1

Please sign in to comment.