def go(): # Retrieve and process email-to-diagnostic-info records. # Note that `_email_diagnostic_info_records` throttles itself if/when # there are no records immediately available. for email_diagnostic_info in _email_diagnostic_info_records_iterator(): # Check if there is (yet) a corresponding diagnostic info record diagnostic_info = datastore.find_diagnostic_info( email_diagnostic_info['diagnostic_info_record_id']) if not diagnostic_info: continue # Modifies diagnostic_info _clean_diagnostic_info_for_yaml_dumping(diagnostic_info) # Convert the modified YAML back into a string for emailing. diagnostic_info_text = yaml.safe_dump(diagnostic_info, default_flow_style=False, width=75) try: diagnostic_info_html = mailformatter.format(diagnostic_info) except Exception as e: logger.error('format failed: %s' % str(e)) diagnostic_info_html = None # If we get to here, then we have a valid diagnostic email. # Reply with the decrypted content. # If this is not a reply, set a subject # If no subject is pre-determined, create one. if email_diagnostic_info.get('email_id') is None: subject = u'DiagnosticInfo: %s (%s)' % ( diagnostic_info['Metadata'].get('platform', '[NO_PLATFORM]').capitalize(), diagnostic_info['Metadata'].get('id', '[NO_ID]')) else: subject = u'Re: %s' % (email_diagnostic_info['email_subject'] or '') try: sender.send_response( config['decryptedEmailRecipient'], config['emailUsername'], subject, diagnostic_info_text, diagnostic_info_html, email_diagnostic_info.get('email_id'), # may be None None) # no attachment logger.log('decrypted formatted email sent') except smtplib.SMTPException as e: logger.exception() logger.error(str(e)) # Delete the processed record. (Note that sending the email might have # failed, but we're deleting it anyway. This is a debatable decision.) datastore.remove_email_diagnostic_info(email_diagnostic_info)
def go(): # Retrieve and process email-to-diagnostic-info records. # Note that `_email_diagnostic_info_records` throttles itself if/when # there are no records immediately available. for email_diagnostic_info in _email_diagnostic_info_records_iterator(): # Check if there is (yet) a corresponding diagnostic info record diagnostic_info = datastore.find_diagnostic_info(email_diagnostic_info['diagnostic_info_record_id']) if not diagnostic_info: continue # Modifies diagnostic_info _clean_diagnostic_info_for_yaml_dumping(diagnostic_info) # Convert the modified YAML back into a string for emailing. diagnostic_info_text = yaml.safe_dump(diagnostic_info, default_flow_style=False, width=75) try: diagnostic_info_html = mailformatter.format(diagnostic_info) except Exception as e: logger.error('format failed: %s' % str(e)) diagnostic_info_html = None # If we get to here, then we have a valid diagnostic email. # Reply with the decrypted content. # If this is not a reply, set a subject # If no subject is pre-determined, create one. if email_diagnostic_info.get('email_id') is None: subject = u'DiagnosticInfo: %s (%s)' % (diagnostic_info['Metadata'].get('platform', '[NO_PLATFORM]').capitalize(), diagnostic_info['Metadata'].get('id', '[NO_ID]')) else: subject = u'Re: %s' % (email_diagnostic_info['email_subject'] or '') try: sender.send_response(config['decryptedEmailRecipient'], config['emailUsername'], subject, diagnostic_info_text, diagnostic_info_html, email_diagnostic_info.get('email_id'), # may be None None) # no attachment logger.log('decrypted formatted email sent') except smtplib.SMTPException as e: logger.exception() logger.error(str(e)) # Delete the processed record. (Note that sending the email might have # failed, but we're deleting it anyway. This is a debatable decision.) datastore.remove_email_diagnostic_info(email_diagnostic_info)
def go(): logger.debug_log('go: enter') # Note that `_diagnostic_record_iter` throttles itself if/when there are # no records to process. for autoresponder_info in _autoresponder_record_iter(): diagnostic_info = autoresponder_info.get('diagnostic_info') email_info = autoresponder_info.get('email_info') logger.debug_log('go: got autoresponder record') # For now we don't do any interesting processing/analysis and we just # respond to every feedback with an exhortation to upgrade. reply_info = _get_email_reply_info(autoresponder_info) if not reply_info or not reply_info.address: # If we don't have any reply info, we can't reply logger.debug_log('go: no reply_info or address') continue # Check if the address is blacklisted if _check_and_add_address_blacklist(reply_info.address): logger.debug_log('go: blacklisted') continue responses = _analyze_diagnostic_info(diagnostic_info, reply_info) if not responses: logger.debug_log('go: no response') continue logger.log('Sending feedback response') for response_id in responses: response_content = _get_response_content(response_id, diagnostic_info) if not response_content: logger.debug_log('go: no response_content') continue # The original diagnostic info may have originated from an email, # in which case we have a subject to reply to. Or it may have have # originated from an uploaded data package, in which case we need # set our own subject. if type(reply_info.subject) is dict: subject = u'Re: %s' % reply_info.subject.get('text', '') else: subject = response_content['subject'] try: sender.send_response(reply_info.address, config['reponseEmailAddress'], subject, response_content['body_text'], response_content['body_html'], reply_info.message_id, response_content['attachments']) except Exception as e: logger.debug_log('go: send_response excepted') logger.exception() logger.error(str(e))
def _process_work_items(work_queue): ''' This runs in the multiprocessing forks to do the actual work. It is a long-lived loop. ''' while True: if terminate: logger.debug_log('got terminate; stopping work') break logger.debug_log('_process_work_items: dequeueing work item') # This blocks if the queue is empty email_diagnostic_info = work_queue.get() logger.debug_log('_process_work_items: dequeued work item') logger.debug_log('feedback object id: %s' % email_diagnostic_info['diagnostic_info_record_id']) # Check if there is (yet) a corresponding diagnostic info record diagnostic_info = datastore.find_diagnostic_info( email_diagnostic_info['diagnostic_info_record_id']) if not diagnostic_info: logger.debug_log('diagnostic_info not found; skipping') continue logger.log('feedback id: %s' % diagnostic_info.get('Metadata', {}).get('id')) diagnostic_info_text = pprint.pformat(diagnostic_info, indent=1, width=75) try: diagnostic_info_html = mailformatter.format(diagnostic_info) except Exception as e: logger.error('format failed: %s' % str(e)) diagnostic_info_html = None # If we get to here, then we have a valid diagnostic email. # Reply with the decrypted content. # If this is not a reply, set a subject # If no subject is pre-determined, create one. if email_diagnostic_info.get('email_id') is None: subject = u'DiagnosticInfo: %s (%s)' % ( diagnostic_info['Metadata'].get('platform', '[NO_PLATFORM]').capitalize(), diagnostic_info['Metadata'].get('id', '[NO_ID]')) else: subject = u'Re: %s' % (email_diagnostic_info['email_subject'] or '') try: sender.send_response( config['decryptedEmailRecipient'], config['emailUsername'], subject, diagnostic_info_text, diagnostic_info_html, email_diagnostic_info.get('email_id'), # may be None None) # no attachment logger.log('decrypted formatted email sent') except Exception as e: logger.exception() logger.error(str(e)) # Delete the processed record. (Note that sending the email might have # failed, but we're deleting it anyway. This is a debatable decision.) datastore.remove_email_diagnostic_info(email_diagnostic_info)