def send_email_update(user, list_email_freq, send_mail, mark_lists, send_old_events): global now # get the email's From: header and return path emailfromaddr = getattr(settings, 'EMAIL_UPDATES_FROMADDR', getattr(settings, 'SERVER_EMAIL', '*****@*****.**')) emailreturnpath = emailfromaddr if hasattr(settings, 'EMAIL_UPDATES_RETURN_PATH'): emailreturnpath = (settings.EMAIL_UPDATES_RETURN_PATH % user.id) # Process each of the subscription lists. all_trackers = set() eventslists = [] most_recent_event = None eventcount = 0 for sublist in user.subscription_lists.all(): # Get a list of all of the trackers this user has in all lists. We use the # complete list, even in non-email-update-lists, for rendering events. all_trackers |= set(sublist.trackers.all()) # If this list does not have email updates turned on, move on. if sublist.email not in list_email_freq: continue # For debugging, clear the last_event_mailed flag so we can find some events # to send. if send_old_events: sublist.last_event_mailed = None # Get any new events to email the user about. max_id, events = sublist.get_new_events() if len(events) > 0: eventslists.append( (sublist, events) ) eventcount += len(events) most_recent_event = max(most_recent_event, max_id) # Don't send an empty email.... less we're testing and we want to send some old events. if len(eventslists) == 0 and not send_old_events: return None if not send_mail: # don't email, don't update lists with the last emailed id return eventcount # Add a pingback image into the email to know (with some low accuracy) which # email addresses are still valid, for folks that have not logged in recently # and did not successfully recently ping back. emailpingurl = None if user.last_login < datetime.now() - timedelta(days=60) \ and not Ping.objects.filter(user=user, pingtime__gt=datetime.now() - timedelta(days=60)).exists(): emailpingurl = Ping.get_ping_url(user) # get announcement content announce = load_markdown_content("website/email/email_update_announcement.md") # send try: send_html_mail( "events/emailupdate", emailreturnpath, [user.email], { "user": user, "date": datetime.now().strftime("%b. %d").replace(" 0", " "), "eventslists": eventslists, "feed": all_trackers, # use all trackers in the user's account as context for displaying events "emailpingurl": emailpingurl, "SITE_ROOT_URL": settings.SITE_ROOT_URL, "announcement": announce }, headers = { 'From': emailfromaddr, 'Auto-Submitted': 'auto-generated', 'X-Auto-Response-Suppress': 'OOF', }, fail_silently=False ) except Exception as e: print user, e return None # skip updating what events were sent, False = did not sent if not mark_lists: return eventcount # mark each list as having mailed events up to the max id found from the # events table so that we know not to email those events in a future update. for sublist, events in eventslists: sublist.last_event_mailed = max(sublist.last_event_mailed, most_recent_event) sublist.last_email_sent = now sublist.save() return eventcount # did sent email
def send_email_update(user_id, list_email_freq, send_mail, mark_lists, send_old_events, mail_connection): global launch_time user_start_time = datetime.now() user = User.objects.get(id=user_id) # get the email's From: header and return path emailfromaddr = getattr(settings, 'EMAIL_UPDATES_FROMADDR', getattr(settings, 'SERVER_EMAIL', '*****@*****.**')) emailreturnpath = emailfromaddr if hasattr(settings, 'EMAIL_UPDATES_RETURN_PATH'): emailreturnpath = (settings.EMAIL_UPDATES_RETURN_PATH % user.id) # Process each of the subscription lists. all_trackers = set() eventslists = [] most_recent_event = None eventcount = 0 for sublist in user.subscription_lists.all(): # Get a list of all of the trackers this user has in all lists. We use the # complete list, even in non-email-update-lists, for rendering events. all_trackers |= set(sublist.trackers.all()) # If this list does not have email updates turned on, move on. if sublist.email not in list_email_freq: continue # For debugging, clear the last_event_mailed flag so we can find some events # to send. if send_old_events: sublist.last_event_mailed = None # Get any new events to email the user about. max_id, events = sublist.get_new_events() if len(events) > 0: eventslists.append( (sublist, events) ) eventcount += len(events) if most_recent_event is None: most_recent_event = max_id most_recent_event = max(most_recent_event, max_id) user_querying_end_time = datetime.now() # Don't send an empty email.... unless we're testing and we want to send some old events. if len(eventslists) == 0 and not send_old_events and announce is None: return { "total_time_querying": user_querying_end_time-user_start_time, } # Render the body of the email. body_context = { "eventslists": eventslists, "feed": all_trackers, # use all trackers in the user's account as context for displaying events "SITE_ROOT_URL": settings.SITE_ROOT_URL, "utm": utm, } body_text = template_body_text.render(context=body_context) body_html = template_body_html.render(context=body_context) user_rendering_end_time = datetime.now() # When counting what we want to send, we supress emails. if not send_mail: # don't email, don't update lists with the last emailed id return { "total_events_sent": eventcount, "total_time_querying": user_querying_end_time-user_start_time, "total_time_rendering": user_rendering_end_time-user_querying_end_time, } # Add a pingback image into the email to know (with some low accuracy) which # email addresses are still valid, for folks that have not logged in recently # and did not successfully recently ping back. emailpingurl = None if user.last_login < launch_time - timedelta(days=60) \ and not Ping.objects.filter(user=user, pingtime__gt=launch_time - timedelta(days=60)).exists(): emailpingurl = Ping.get_ping_url(user) # send try: timings = { } send_html_mail( "events/emailupdate", emailreturnpath, [user.email], { "user": user, "date": datetime.now().strftime("%b. %d").replace(" 0", " "), "emailpingurl": emailpingurl, "body_text": body_text, "body_html": body_html, "announcement": announce, "medium_posts": medium_posts, "SITE_ROOT_URL": settings.SITE_ROOT_URL, "utm": utm, }, headers={ 'Reply-To': emailfromaddr, 'Auto-Submitted': 'auto-generated', 'X-Auto-Response-Suppress': 'OOF', 'X-Unsubscribe-Link': UserProfile.objects.get(user=user).get_one_click_unsub_url(), }, fail_silently=False, connection=mail_connection, ) except Exception as e: if "recipient address was suppressed due to" in str(e): be, is_new = BouncedEmail.objects.get_or_create(user=user) if not is_new: be.bounces += 1 be.save() print(user, "user is on suppression list already") else: print(user, e) # raise - debugging - must also disable process pool to see what happened # don't update this user's lists with what events were sent because it failed return { "total_time_querying": user_querying_end_time-user_start_time, "total_time_sending": datetime.now()-user_querying_end_time, } if mark_lists: # skipped when debugging # mark each list as having mailed events up to the max id found from the # events table so that we know not to email those events in a future update. for sublist, events in eventslists: sublist.last_event_mailed = max(sublist.last_event_mailed, most_recent_event) if sublist.last_event_mailed is not None else most_recent_event sublist.last_email_sent = launch_time sublist.save() user_sending_end_time = datetime.now() return { "total_emails_sent": 1, "total_events_sent": eventcount, "total_time_querying": user_querying_end_time-user_start_time, "total_time_rendering": user_rendering_end_time-user_querying_end_time, "total_time_sending": user_sending_end_time-user_rendering_end_time, }
def send_email_update(user, list_email_freq, send_mail, mark_lists, send_old_events): global now # get the email's From: header and return path emailfromaddr = getattr( settings, 'EMAIL_UPDATES_FROMADDR', getattr(settings, 'SERVER_EMAIL', '*****@*****.**')) emailreturnpath = emailfromaddr if hasattr(settings, 'EMAIL_UPDATES_RETURN_PATH'): emailreturnpath = (settings.EMAIL_UPDATES_RETURN_PATH % user.id) # Process each of the subscription lists. all_trackers = set() eventslists = [] most_recent_event = None eventcount = 0 for sublist in user.subscription_lists.all(): # Get a list of all of the trackers this user has in all lists. We use the # complete list, even in non-email-update-lists, for rendering events. all_trackers |= set(sublist.trackers.all()) # If this list does not have email updates turned on, move on. if sublist.email not in list_email_freq: continue # For debugging, clear the last_event_mailed flag so we can find some events # to send. if send_old_events: sublist.last_event_mailed = None # Get any new events to email the user about. max_id, events = sublist.get_new_events() if len(events) > 0: eventslists.append((sublist, events)) eventcount += len(events) most_recent_event = max(most_recent_event, max_id) # Don't send an empty email.... less we're testing and we want to send some old events. if len(eventslists) == 0 and not send_old_events: return None if not send_mail: # don't email, don't update lists with the last emailed id return eventcount # Add a pingback image into the email to know (with some low accuracy) which # email addresses are still valid, for folks that have not logged in recently # and did not successfully recently ping back. emailpingurl = None if user.last_login < datetime.now() - timedelta(days=60) \ and not Ping.objects.filter(user=user, pingtime__gt=datetime.now() - timedelta(days=60)).exists(): emailpingurl = Ping.get_ping_url(user) # get announcement content announce = load_markdown_content( "website/email/email_update_announcement.md") # send try: send_html_mail( "events/emailupdate", emailreturnpath, [user.email], { "user": user, "date": datetime.now().strftime("%b. %d").replace(" 0", " "), "eventslists": eventslists, "feed": all_trackers, # use all trackers in the user's account as context for displaying events "emailpingurl": emailpingurl, "SITE_ROOT_URL": settings.SITE_ROOT_URL, "announcement": announce }, headers={ 'From': emailfromaddr, 'Auto-Submitted': 'auto-generated', 'X-Auto-Response-Suppress': 'OOF', }, fail_silently=False) except Exception as e: print user, e return None # skip updating what events were sent, False = did not sent if not mark_lists: return eventcount # mark each list as having mailed events up to the max id found from the # events table so that we know not to email those events in a future update. for sublist, events in eventslists: sublist.last_event_mailed = max(sublist.last_event_mailed, most_recent_event) sublist.last_email_sent = now sublist.save() return eventcount # did sent email
def send_email_update(user_id, list_email_freq, send_mail, mark_lists, send_old_events, mail_connection): global launch_time user_start_time = datetime.now() user = User.objects.get(id=user_id) # get the email's From: header and return path emailfromaddr = getattr(settings, 'EMAIL_UPDATES_FROMADDR', getattr(settings, 'SERVER_EMAIL', '*****@*****.**')) emailreturnpath = emailfromaddr if hasattr(settings, 'EMAIL_UPDATES_RETURN_PATH'): emailreturnpath = (settings.EMAIL_UPDATES_RETURN_PATH % user.id) # Process each of the subscription lists. all_trackers = set() eventslists = [] most_recent_event = None eventcount = 0 for sublist in user.subscription_lists.all(): # Get a list of all of the trackers this user has in all lists. We use the # complete list, even in non-email-update-lists, for rendering events. all_trackers |= set(sublist.trackers.all()) # If this list does not have email updates turned on, move on. if sublist.email not in list_email_freq: continue # For debugging, clear the last_event_mailed flag so we can find some events # to send. if send_old_events: sublist.last_event_mailed = None # Get any new events to email the user about. max_id, events = sublist.get_new_events() if len(events) > 0: eventslists.append( (sublist, events) ) eventcount += len(events) if most_recent_event is None: most_recent_event = max_id most_recent_event = max(most_recent_event, max_id) user_querying_end_time = datetime.now() # Don't send an empty email.... unless we're testing and we want to send some old events. if len(eventslists) == 0 and not send_old_events and announce is None: return { "total_time_querying": user_querying_end_time-user_start_time, } # Render the body of the email. body_context = { "eventslists": eventslists, "feed": all_trackers, # use all trackers in the user's account as context for displaying events "SITE_ROOT_URL": settings.SITE_ROOT_URL, "utm": utm, } body_text = template_body_text.render(context=body_context) body_html = template_body_html.render(context=body_context) user_rendering_end_time = datetime.now() # When counting what we want to send, we supress emails. if not send_mail: # don't email, don't update lists with the last emailed id return { "total_events_sent": eventcount, "total_time_querying": user_querying_end_time-user_start_time, "total_time_rendering": user_rendering_end_time-user_querying_end_time, } # Add a pingback image into the email to know (with some low accuracy) which # email addresses are still valid, for folks that have not logged in recently # and did not successfully recently ping back. emailpingurl = None if user.last_login < launch_time - timedelta(days=60) \ and not Ping.objects.filter(user=user, pingtime__gt=launch_time - timedelta(days=60)).exists(): emailpingurl = Ping.get_ping_url(user) # ensure smtp connection is open in case it got shut (hmm) if not mail_connection.connection: raise ValueError("the mail connection should be open already") if not mail_connection.connection.sock: # socket seems to have been closed - reopen it mail_connection.connection = None mail_connection.open() # send try: timings = { } send_html_mail( "events/emailupdate", emailreturnpath, [user.email], { "user": user, "date": datetime.now().strftime("%b. %d").replace(" 0", " "), "emailpingurl": emailpingurl, "body_text": body_text, "body_html": body_html, "announcement": announce, "medium_posts": medium_posts, }, headers={ 'Reply-To': emailfromaddr, 'Auto-Submitted': 'auto-generated', 'X-Auto-Response-Suppress': 'OOF', }, fail_silently=False, connection=mail_connection, ) except Exception as e: if "recipient address was suppressed due to" in str(e): be, is_new = BouncedEmail.objects.get_or_create(user=user) if not is_new: be.bounces += 1 be.save() print(user, "user is on suppression list already") else: print(user, e) # raise - debugging - must also disable process pool to see what happened # don't update this user's lists with what events were sent because it failed return { "total_time_querying": user_querying_end_time-user_start_time, "total_time_sending": datetime.now()-user_querying_end_time, } if mark_lists: # skipped when debugging # mark each list as having mailed events up to the max id found from the # events table so that we know not to email those events in a future update. for sublist, events in eventslists: sublist.last_event_mailed = max(sublist.last_event_mailed, most_recent_event) if sublist.last_event_mailed is not None else most_recent_event sublist.last_email_sent = launch_time sublist.save() user_sending_end_time = datetime.now() return { "total_emails_sent": 1, "total_events_sent": eventcount, "total_time_querying": user_querying_end_time-user_start_time, "total_time_rendering": user_rendering_end_time-user_querying_end_time, "total_time_sending": user_sending_end_time-user_rendering_end_time, }