def ping_registrar_users(): ''' Sends an email to our current registrar users. See templates/email/registrar_user_ping.txt ''' import json, logging from django.http import HttpRequest from perma.email import send_user_email, send_admin_email, registrar_users_plus_stats logger = logging.getLogger(__name__) users = registrar_users_plus_stats() logger.info("Begin emailing registrar users.") send_count = 0 failed_list = [] for user in users: succeeded = send_user_email(user['email'], 'email/registrar_user_ping.txt', user) if succeeded: send_count += 1 else: failed_list.append(user.id) # Another option is to use Django's send_mass_email. # It's unclear which would be more performant in real life. # send_count = send_mass_user_email('email/registrar_user_ping.txt', # [(user['email'], user) for user in users]) logger.info("Done emailing registrar users.") if len(users) != send_count: if failed_list: msg = "Some registrar users were not emailed: {}. Check log for fatal SMTP errors.".format( str(failed_list)) else: msg = "Some registrar users were not emailed. Check log for fatal SMTP errors." logger.error(msg) result = "incomplete" else: result = "ok" send_admin_email("Registrar Users Emailed", settings.DEFAULT_FROM_EMAIL, HttpRequest(), 'email/admin/pinged_registrar_users.txt', { "users": users, "result": result }) return json.dumps({"result": result, "send_count": send_count})
def ping_registrar_users(): """ Sends an email to our current registrar users. See templates/email/registrar_user_ping.txt """ import json, logging from django.http import HttpRequest from perma.email import send_user_email, send_admin_email, registrar_users_plus_stats logger = logging.getLogger(__name__) users = registrar_users_plus_stats() logger.info("Begin emailing registrar users.") send_count = 0 failed_list = [] for user in users: succeeded = send_user_email(user["email"], "email/registrar_user_ping.txt", user) if succeeded: send_count += 1 else: failed_list.append(user.id) # Another option is to use Django's send_mass_email. # It's unclear which would be more performant in real life. # send_count = send_mass_user_email('email/registrar_user_ping.txt', # [(user['email'], user) for user in users]) logger.info("Done emailing registrar users.") if len(users) != send_count: if failed_list: msg = "Some registrar users were not emailed: {}. Check log for fatal SMTP errors.".format(str(failed_list)) else: msg = "Some registrar users were not emailed. Check log for fatal SMTP errors." logger.error(msg) result = "incomplete" else: result = "ok" send_admin_email( "Registrar Users Emailed", settings.DEFAULT_FROM_EMAIL, HttpRequest(), "email/admin/pinged_registrar_users.txt", {"users": users, "result": result}, ) return json.dumps({"result": result, "send_count": send_count})
def ping_registrar_users(limit_to="", limit_by_tag="", exclude="", exclude_by_tag=""): ''' Sends an email to our current registrar users. See templates/email/registrar_user_ping.txt Arguments should be strings, with multiple values separated by semi-colons e.g. fab ping_registrar_users:limit_to="14;27;30",exclude_by_tag="opted_out" Limit filters are applied before exclude filters. ''' import json, logging from django.http import HttpRequest from perma.models import Registrar from perma.email import send_user_email, send_admin_email, registrar_users_plus_stats logger = logging.getLogger(__name__) registrars = Registrar.objects.all() if limit_to: registrars = registrars.filter(id__in=limit_to.split(";")) if limit_by_tag: registrars = registrars.filter( tags__name__in=limit_by_tag.split(";")).distinct() if exclude: registrars = registrars.exclude(id__in=exclude.split(";")) if exclude_by_tag: registrars = registrars.exclude( tags__name__in=exclude_by_tag.split(";")).distinct() users = registrar_users_plus_stats(registrars=registrars) logger.info("Begin emailing registrar users.") send_count = 0 failed_list = [] for user in users: succeeded = send_user_email(user['email'], 'email/registrar_user_ping.txt', user) if succeeded: send_count += 1 else: failed_list.append(user.id) # Another option is to use Django's send_mass_email. # It's unclear which would be more performant in real life. # send_count = send_mass_user_email('email/registrar_user_ping.txt', # [(user['email'], user) for user in users]) logger.info("Done emailing registrar users.") if len(users) != send_count: if failed_list: msg = "Some registrar users were not emailed: {}. Check log for fatal SMTP errors.".format( str(failed_list)) else: msg = "Some registrar users were not emailed. Check log for fatal SMTP errors." logger.error(msg) result = "incomplete" else: result = "ok" send_admin_email("Registrar Users Emailed", settings.DEFAULT_FROM_EMAIL, HttpRequest(), 'email/admin/pinged_registrar_users.txt', { "users": users, "result": result }) return json.dumps({"result": result, "send_count": send_count})
def ping_registrar_users(limit_to="", limit_by_tag="", exclude="", exclude_by_tag="", email="stats", year=""): ''' Sends an email to our current registrar users. See templates/email/registrar_user_ping.txt Arguments should be strings, with multiple values separated by semi-colons e.g. fab ping_registrar_users:limit_to="14;27;30",exclude_by_tag="opted_out",email="special" Limit filters are applied before exclude filters. ''' import json, logging from datetime import datetime from django.http import HttpRequest from perma.models import Registrar from perma.email import send_user_email, send_self_email, registrar_users, registrar_users_plus_stats logger = logging.getLogger(__name__) registrars = Registrar.objects.all() if limit_to: registrars = registrars.filter(id__in=limit_to.split(";")) if limit_by_tag: registrars = registrars.filter( tags__name__in=limit_by_tag.split(";")).distinct() if exclude: registrars = registrars.exclude(id__in=exclude.split(";")) if exclude_by_tag: registrars = registrars.exclude( tags__name__in=exclude_by_tag.split(";")).distinct() if year: year = int(year) else: year = datetime.now().year - 1 if email == 'stats': template = 'email/registrar_user_ping.txt' users = registrar_users_plus_stats(registrars=registrars, year=year) elif email == 'special': # update special template as desired, to send one-off emails # update email.registrar_users if you need more context variables template = 'email/special.txt' users = registrar_users(registrars=registrars) else: NotImplementedError() logger.info("Begin emailing registrar users.") send_count = 0 failed_list = [] for user in users: context = {} context.update(user) context["year"] = year succeeded = send_user_email(user['email'], template, context) if succeeded: send_count += 1 else: failed_list.append(user.id) # Another option is to use Django's send_mass_email. # It's unclear which would be more performant in real life. # send_count = send_mass_user_email('email/registrar_user_ping.txt', # [(user['email'], user) for user in users]) logger.info("Done emailing registrar users.") if len(users) != send_count: if failed_list: msg = "Some registrar users were not emailed: {}. Check log for fatal SMTP errors.".format( str(failed_list)) else: msg = "Some registrar users were not emailed. Check log for fatal SMTP errors." logger.error(msg) result = "incomplete" else: result = "ok" send_self_email("Registrar Users Emailed", HttpRequest(), 'email/admin/pinged_registrar_users.txt', { "users": users, "result": result }) return json.dumps({"result": result, "send_count": send_count})
def ping_all_users(limit_to="", exclude="", batch_size="500"): ''' Sends an email to all our current users. See templates/email/special.txt Arguments should be strings, with multiple values separated by semi-colons e.g. fab ping_all_users:limit_to="14;27;30",batch_size="1000" Limit filters are applied before exclude filters. ''' import logging from tqdm import tqdm from perma.models import LinkUser from perma.email import send_user_email logger = logging.getLogger(__name__) logger.info("BEGIN: ping_all_users") # load desired Perma users if limit_to: users = LinkUser.objects.filter(id__in=limit_to.split(";")) else: users = LinkUser.objects.filter(is_confirmed=True, is_active=True) if exclude: users = users.exclude(id__in=exclude.split(";")) # exclude users we have already emailed already_emailed_path = '/tmp/perma_emailed_user_list' already_emailed = set() if os.path.exists(already_emailed_path): logging.info("Loading list of already-emailed users.") with open(already_emailed_path) as f: lines = f.read().splitlines() for line in lines: already_emailed.add(int(line)) if already_emailed: users = users.exclude(id__in=already_emailed) # limit to our desired batch size not_yet_emailed = users.count() batch_size = int(batch_size) if not_yet_emailed > batch_size: logger.info("{} users to email: limiting to first {}".format( not_yet_emailed, batch_size)) users = users[:batch_size] to_send_count = users.count() if not to_send_count: logger.info("No users to email.") return sent_count = 0 failed_list = [] logger.info("Begin emailing {} users.".format(to_send_count)) with open(already_emailed_path, 'a') as f: for user in tqdm(users): succeeded = send_user_email(user.email, 'email/special.txt', {'user': user}) if succeeded: sent_count += 1 f.write(str(user.id) + "\n") else: failed_list.append(user.id) logger.info("Emailed {} users".format(sent_count)) if to_send_count != sent_count: if failed_list: msg = "Some users were not emailed: {}. Check log for fatal SMTP errors.".format( str(failed_list)) else: msg = "Some users were not emailed. Check log for fatal SMTP errors." logger.error(msg) # offer to send another batch if there are any users left to email remaining_to_email = not_yet_emailed - sent_count if remaining_to_email: if input("\nSend another batch of size {}? [y/n]\n".format( batch_size)).lower() == 'y': ping_all_users(batch_size=str(batch_size)) else: logger.info("Stopped with ~ {} remaining users to email".format( remaining_to_email)) else: logger.info( "Done! Run me again, to catch anybody who signed up while this was running!" )
def ping_registrar_users(limit_to="", limit_by_tag="", exclude="", exclude_by_tag="", email="stats", year=""): ''' Sends an email to our current registrar users. See templates/email/registrar_user_ping.txt Arguments should be strings, with multiple values separated by semi-colons e.g. fab ping_registrar_users:limit_to="14;27;30",exclude_by_tag="opted_out",email="special" Limit filters are applied before exclude filters. ''' import json, logging from datetime import datetime from django.http import HttpRequest from perma.models import Registrar from perma.email import send_user_email, send_admin_email, registrar_users, registrar_users_plus_stats logger = logging.getLogger(__name__) registrars = Registrar.objects.all() if limit_to: registrars = registrars.filter(id__in=limit_to.split(";")) if limit_by_tag: registrars = registrars.filter(tags__name__in=limit_by_tag.split(";")).distinct() if exclude: registrars = registrars.exclude(id__in=exclude.split(";")) if exclude_by_tag: registrars = registrars.exclude(tags__name__in=exclude_by_tag.split(";")).distinct() if year: year = int(year) else: year = datetime.now().year - 1 if email == 'stats': template = 'email/registrar_user_ping.txt' users = registrar_users_plus_stats(registrars=registrars, year=year) elif email == 'special': # update special template as desired, to send one-off emails # update email.registrar_users if you need more context variables template = 'email/special.txt' users = registrar_users(registrars=registrars) else: NotImplementedError() logger.info("Begin emailing registrar users.") send_count = 0 failed_list = [] for user in users: context = {} context.update(user) context["year"] = year succeeded = send_user_email(user['email'], template, context) if succeeded: send_count += 1 else: failed_list.append(user.id) # Another option is to use Django's send_mass_email. # It's unclear which would be more performant in real life. # send_count = send_mass_user_email('email/registrar_user_ping.txt', # [(user['email'], user) for user in users]) logger.info("Done emailing registrar users.") if len(users) != send_count: if failed_list: msg = "Some registrar users were not emailed: {}. Check log for fatal SMTP errors.".format(str(failed_list)) else: msg = "Some registrar users were not emailed. Check log for fatal SMTP errors." logger.error(msg) result = "incomplete" else: result = "ok" send_admin_email("Registrar Users Emailed", settings.DEFAULT_FROM_EMAIL, HttpRequest(), 'email/admin/pinged_registrar_users.txt', {"users": users, "result": result}) return json.dumps({"result": result, "send_count": send_count})
def ping_all_users(limit_to="", exclude="", batch_size="500"): ''' Sends an email to all our current users. See templates/email/special.txt Arguments should be strings, with multiple values separated by semi-colons e.g. fab ping_all_users:limit_to="14;27;30",batch_size="1000" Limit filters are applied before exclude filters. ''' import logging from tqdm import tqdm from perma.models import LinkUser from perma.email import send_user_email logger = logging.getLogger(__name__) logger.info("BEGIN: ping_all_users") # load desired Perma users if limit_to: users = LinkUser.objects.filter(id__in=limit_to.split(";")) else: users = LinkUser.objects.filter(is_confirmed=True, is_active=True) if exclude: users = users.exclude(id__in=exclude.split(";")) # exclude users we have already emailed already_emailed_path = '/tmp/perma_emailed_user_list' already_emailed = set() if os.path.exists(already_emailed_path): logging.info("Loading list of already-emailed users.") with open(already_emailed_path) as f: lines = f.read().splitlines() for line in lines: already_emailed.add(int(line)) if already_emailed: users = users.exclude(id__in=already_emailed) # limit to our desired batch size not_yet_emailed = users.count() batch_size = int(batch_size) if not_yet_emailed > batch_size: logger.info("{} users to email: limiting to first {}".format(not_yet_emailed, batch_size)) users = users[:batch_size] to_send_count = users.count() if not to_send_count: logger.info("No users to email.") return sent_count = 0 failed_list = [] logger.info("Begin emailing {} users.".format(to_send_count)) with open(already_emailed_path, 'a') as f: for user in tqdm(users): succeeded = send_user_email(user.email, 'email/special.txt', {'user': user}) if succeeded: sent_count += 1 f.write(str(user.id)+"\n") else: failed_list.append(user.id) logger.info("Emailed {} users".format(sent_count)) if to_send_count != sent_count: if failed_list: msg = "Some users were not emailed: {}. Check log for fatal SMTP errors.".format(str(failed_list)) else: msg = "Some users were not emailed. Check log for fatal SMTP errors." logger.error(msg) # offer to send another batch if there are any users left to email remaining_to_email = not_yet_emailed - sent_count if remaining_to_email: if input("\nSend another batch of size {}? [y/n]\n".format(batch_size)).lower() == 'y': ping_all_users(batch_size=str(batch_size)) else: logger.info("Stopped with ~ {} remaining users to email".format(remaining_to_email)) else: logger.info("Done! Run me again, to catch anybody who signed up while this was running!")