From 642d606c1673e8cd74901539a522cffe113039e1 Mon Sep 17 00:00:00 2001 From: Kelly Lockhart <2926089+kelockhart@users.noreply.github.com> Date: Fri, 26 May 2023 15:31:09 -0400 Subject: [PATCH] Add option to disable emails that bounceback --- config.py | 4 +++ run.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/config.py b/config.py index 910d016..4a71555 100644 --- a/config.py +++ b/config.py @@ -20,6 +20,7 @@ API_VAULT_MYADS_USERS = API_ENDPOINT + '/v1/vault/myads-users/%s' API_VAULT_MYADS_SETUP = API_ENDPOINT + '/v1/vault/get-myads/%s' API_VAULT_MYADS_SETUP_DATE = API_ENDPOINT + '/v1/vault/get-myads/%s/%s' +API_VAULT_MYADS_STATUS_UPDATE = API_ENDPOINT + '/v1/vault/myads-status-update/%s' API_ADSWS_USER_EMAIL = API_ENDPOINT + '/v1/user/%s' ARXIV_URL = 'https://ui.adsabs.harvard.edu/link_gateway/{0}/EPRINT_HTML?utm_source=myads&utm_medium=email&utm_campaign=type:{1}&utm_term={2}&utm_content=rank:{3}' @@ -52,6 +53,9 @@ ASTRO_INCOMING_DIR = '/proj/ads/abstracts/ast/index/current/' ASTRO_SAMPLE_SIZE = 3 +# Directory for email bouncebacks +BOUNCEBACK_EMAIL_DIR = '/proj/ads/ads/procmail/' + MAIL_DEFAULT_SENDER = 'ads@cfa.harvard.edu' MAIL_PASSWORD = None MAIL_PORT = 25 diff --git a/run.py b/run.py index 222303c..c470ead 100644 --- a/run.py +++ b/run.py @@ -371,6 +371,54 @@ def process_myads(since=None, user_ids=None, user_emails=None, test_send_to=None print('Done submitting {0} myADS processing tasks for {1} users.'.format(frequency, len(all_users))) logger.info('Done submitting {0} myADS processing tasks for {1} users.'.format(frequency, len(all_users))) +def notifications_status_update(user_emails=None, active=False): + """ + Enable/disable all notifications for a given user(s) + + :param user_emails: list, users to enable/disable (given as email addresses) + :param active: boolean (default: False), set to True to enable all notifications for a given user, or False to disable + :return: dictionary; {'updated': [], 'failed': []} + """ + + updated = [] + failed = [] + + user_ids = {} + for email in user_emails: + r = app.client.get(config.get('API_ADSWS_USER_EMAIL') % email, + headers={'Accept': 'application/json', + 'Authorization': 'Bearer {0}'.format(config.get('API_TOKEN'))} + ) + if r.status_code == 200: + user_id = r.json()['id'] + else: + failed.append(email) + logger.warning('Error getting user ID with email {0} from the API. Processing aborted for this user'.format(email)) + continue + + user_ids[user_id] = email + + if user_ids: + for uid in user_ids.keys(): + payload = {'active': active} + r = app.client.put(config.put('API_VAULT_MYADS_STATUS_UPDATE') % uid, + headers={'Accept': 'application/json', + 'Authorization': 'Bearer {0}'.format(config.get('API_TOKEN'))}, + data=json.dumps(payload) + ) + + if r.status_code == 200 or r.status_code == 204: + updated.append(user_ids[uid]) + else: + failed.append(user_ids[uid]) + logger.warning('Failed disabling notifications for user {0}. Processing aborted for this user'.format(user_ids[uid])) + continue + else: + return {} + + logger.info('Disabled myADS notifications for the following users: %s', updated) + return {'updated': updated, 'failed': failed} + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Process user input.') @@ -408,6 +456,12 @@ def process_myads(since=None, user_ids=None, user_emails=None, test_send_to=None action='store_true', help='Process weekly myADS notifications') + parser.add_argument('-b', + '--bounceback_disable', + dest='bouceback_disable', + action='store_true', + help='Disable all notifications for users on the bounceback list') + parser.add_argument('-t', '--test_send_to', dest='test_send_to', @@ -502,3 +556,31 @@ def process_myads(since=None, user_ids=None, user_emails=None, test_send_to=None else: logger.warning('astro ingest: failed.') sys.exit(1) + + if args.bounceback_disable: + bounceback_email_file = os.path.join(config.get('BOUNCEBACK_EMAIL_DIR'), 'myADS.bounces.emails') + bounceback_emails = [] + try: + with open(bounceback_email_file, 'rt') as flist: + for l in flist.readlines(): + bounceback_emails.append(l) + except IOError: + logger.warning('Bounceback email file not found. Exiting.') + # exit with error + sys.exit(1) + + if bounceback_emails: + disabled_dict = notifications_status_update(user_emails=bounceback_emails, active=False) + if len(disabled_dict['updated']) == 0 and len(disabled_dict['failed']) != 0: + logger.warning('Failed disabling bounceback emails; exiting.') + else: + # note: we're ignoring failed disabling from here on - there's a possibility that this email address is + # dead, so we can ignore. If it's not dead, then it'll just show back up in the bounceback file next time + # and we can try it again then + old_file = os.path.join(config.get('BOUNCEBACK_EMAIL_DIR'), + 'myADS.bounces.emails' + '.' + get_date().strftime('%Y%m%d')) + os.rename(bounceback_email_file, old_file) + else: + logger.info('No bounceback emails to process; exiting.') + # exit without error + sys.exit(0)