def save_draft(account_id, message_id, db_session): """ Sync a new/updated draft back to the remote backend. """ account = db_session.query(Account).get(account_id) message = db_session.query(Message).get(message_id) if message is None: log.info('tried to save nonexistent message as draft', message_id=message_id, account_id=account_id) return if not message.is_draft: log.warning('tried to save non-draft message as draft', message_id=message_id, account_id=account_id) return recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) mimemsg = create_email(account.sender_name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) if account.drafts_folder is None: # account has no detected drafts folder - create one. drafts_folder = Folder.find_or_create(db_session, account, 'Drafts', 'drafts') account.drafts_folder = drafts_folder remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_at)
def send(self, draft): """ Turn a draft object into a MIME message and send it. Parameters ---------- draft : models.message.Message object the draft message to send. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) # Note that we intentionally don't set the Bcc header in the message we # construct. msg = create_email(sender_name=self.sender_name, sender_email=self.email_address, inbox_uid=draft.inbox_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=draft.sanitized_body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments) recipient_emails = [ email for name, email in itertools.chain( draft.to_addr, draft.cc_addr, draft.bcc_addr) ] return self._send(recipient_emails, msg)
def send(self, draft): """ Turn a draft object into a MIME message and send it. Parameters ---------- draft : models.message.Message object the draft message to send. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) # Note that we intentionally don't set the Bcc header in the message we # construct. msg = create_email(sender_name=self.sender_name, sender_email=self.email_address, inbox_uid=draft.inbox_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=draft.sanitized_body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments) recipient_emails = [email for name, email in itertools.chain( draft.to_addr, draft.cc_addr, draft.bcc_addr)] return self._send(recipient_emails, msg)
def save_draft(account_id, message_id, db_session): """ Sync a new/updated draft back to the remote backend. """ account = db_session.query(Account).get(account_id) message = db_session.query(Message).get(message_id) if message is None: log.info('tried to save nonexistent message as draft', message_id=message_id, account_id=account_id) return if not message.is_draft: log.warning('tried to save non-draft message as draft', message_id=message_id, account_id=account_id) return recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) mimemsg = create_email(account.name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) if account.drafts_folder is None: # account has no detected drafts folder - create one. drafts_folder = Folder.find_or_create(db_session, account, 'Drafts', 'drafts') account.drafts_folder = drafts_folder remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_at)
def send(self, draft): """ Turn a draft object into a MIME message and send it. Parameters ---------- draft : models.message.Message object the draft message to send. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(draft, blocks) # @emfree - 3/19/2015 # # Note that we intentionally don't set the Bcc header in the message we # construct, because this would would result in a MIME message being # generated with a Bcc header which all recipients can see. # # Arguably we should send each Bcc'ed recipient a MIME message that has # a Bcc: <only them> header. This is what the Gmail web UI appears to # do. However, this would need to be carefully implemented and tested. # The current approach was chosen for its comparative simplicity. I'm # pretty sure that other clients do it this way as well. It is the # first of the three implementations described here: # http://tools.ietf.org/html/rfc2822#section-3.6.3 # # Note that we ensure in our SMTP code BCCed recipients still actually # get the message. # from_addr is only ever a list with one element from_addr = draft.from_addr[0] msg = create_email( from_name=from_addr[0], from_email=from_addr[1], reply_to=draft.reply_to, nylas_uid=draft.nylas_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=draft.body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments, ) recipient_emails = [ email for name, email in itertools.chain( draft.to_addr, draft.cc_addr, draft.bcc_addr ) ] self._send(recipient_emails, msg) # Sent to all successfully self.log.info("Sending successful", draft_id=draft.id)
def _create_email(account, message, generate_new_uid=False): recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) inbox_uid = message.inbox_uid if generate_new_uid: inbox_uid = None return create_email(account.name, account.email_address, inbox_uid, recipients, message.subject, message.sanitized_body, attachments)
def send_new(self, db_session, draft, recipients): """ Send a previously created + saved draft email from this user account. """ inbox_uid = draft.inbox_uid subject = draft.subject body = draft.sanitized_body attachments = generate_attachments(draft.attachments) smtpmsg = create_email(self.sender_name, self.email_address, inbox_uid, recipients, subject, body, attachments) return self._send_mail(db_session, draft, smtpmsg)
def send_new(self, db_session, draft, recipients): """ Send a previously created + saved draft email from this user account. """ inbox_uid = draft.inbox_uid subject = draft.subject body = draft.sanitized_body attachments = generate_attachments(draft.attachments) smtpmsg = create_gmail_email( self.sender_name, self.email_address, inbox_uid, recipients, subject, body, attachments ) return self._send_mail(db_session, draft, smtpmsg)
def send(self, draft): """ Turn a draft object into a MIME message and send it. Parameters ---------- draft : models.message.Message object the draft message to send. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) # @emfree - 3/19/2015 # # Note that we intentionally don't set the Bcc header in the message we # construct, because this would would result in a MIME message being # generated with a Bcc header which all recipients can see. # # Arguably we should send each Bcc'ed recipient a MIME message that has # a Bcc: <only them> header. This is what the Gmail web UI appears to # do. However, this would need to be carefully implemented and tested. # The current approach was chosen for its comparative simplicity. I'm # pretty sure that other clients do it this way as well. It is the # first of the three implementations described here: # http://tools.ietf.org/html/rfc2822#section-3.6.3 # # Note that we ensure in our SMTP code BCCed recipients still actually # get the message. # from_addr is only ever a list with one element from_addr = draft.from_addr[0] msg = create_email(from_name=from_addr[0], from_email=from_addr[1], reply_to=draft.reply_to, nylas_uid=draft.nylas_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=draft.body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments) recipient_emails = [email for name, email in itertools.chain( draft.to_addr, draft.cc_addr, draft.bcc_addr)] self._send(recipient_emails, msg) # Sent to all successfully self.log.info('Sending successful', sender=from_addr[1], recipients=recipient_emails)
def _create_email(account, message): blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) msg = create_email(sender_name=account.name, sender_email=account.email_address, inbox_uid=message.inbox_uid, to_addr=message.to_addr, cc_addr=message.cc_addr, bcc_addr=message.bcc_addr, subject=message.subject, html=message.sanitized_body, in_reply_to=message.in_reply_to, references=message.references, attachments=attachments) return msg
def _create_email(account, message): blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) msg = create_email(sender_name=account.name, sender_email=account.email_address, inbox_uid=message.inbox_uid, to_addr=message.to_addr, cc_addr=message.cc_addr, bcc_addr=message.bcc_addr, subject=message.subject, html=message.sanitized_body, in_reply_to=message.in_reply_to, references=message.references, attachments=attachments) return msg
def save_draft(account_id, message_id, db_session): """ Sync a new/updated draft back to the remote backend. """ account = db_session.query(Account).get(account_id) message = db_session.query(Message).get(message_id) assert message.is_draft recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) attachments = generate_attachments(message.attachments) mimemsg = create_email(account.sender_name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_at)
def save_draft(account_id, message_id, db_session): """ Sync a new/updated draft back to the remote backend. """ account = db_session.query(Account).get(account_id) message = db_session.query(Message).get(message_id) assert message.is_draft recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) attachments = generate_attachments(message.attachments) mimemsg = create_email(account.sender_name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_at)
def send_reply(self, db_session, draft, recipients): """ Send a previously created + saved draft email reply from this user account. """ inbox_uid = draft.inbox_uid subject = draft.subject body = draft.sanitized_body blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) smtpmsg = create_reply(self.sender_name, self.email_address, draft.in_reply_to, draft.references, inbox_uid, recipients, subject, body, attachments) return self._send_mail(db_session, draft, smtpmsg)
def send_reply(self, db_session, draft, recipients): """ Send a previously created + saved draft email reply from this user account. """ inbox_uid = draft.inbox_uid subject = draft.subject body = draft.sanitized_body blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) smtpmsg = create_reply(self.sender_name, self.email_address, draft.in_reply_to, draft.references, inbox_uid, recipients, subject, body, attachments) return self._send_mail(db_session, draft, smtpmsg)
def _create_email(account, message): blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) from_name, from_email = message.from_addr[0] msg = create_email(from_name=from_name, from_email=from_email, reply_to=message.reply_to, inbox_uid=message.inbox_uid, to_addr=message.to_addr, cc_addr=message.cc_addr, bcc_addr=message.bcc_addr, subject=message.subject, html=message.body, in_reply_to=message.in_reply_to, references=message.references, attachments=attachments) return msg
def _create_email(account, message): blocks = [p.block for p in message.attachments] attachments = generate_attachments(blocks) from_name, from_email = message.from_addr[0] msg = create_email(from_name=from_name, from_email=from_email, reply_to=message.reply_to, inbox_uid=message.inbox_uid, to_addr=message.to_addr, cc_addr=message.cc_addr, bcc_addr=message.bcc_addr, subject=message.subject, html=message.body, in_reply_to=message.in_reply_to, references=message.references, attachments=attachments) return msg
def send_custom(self, draft, body, recipients): """ Turn a draft object into a MIME message, replacing the body with the provided body, and send it only to the provided recipients. Parameters ---------- draft: models.message.Message object the draft message to send. body: string message body to send in place of the existing body attribute in the draft. recipient_emails: email addresses to send copies of this message to. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) from_addr = draft.from_addr[0] msg = create_email(from_name=from_addr[0], from_email=from_addr[1], reply_to=draft.reply_to, inbox_uid=draft.inbox_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments) recipient_emails = [email for name, email in recipients] self._send(recipient_emails, msg) # Sent successfully self.log.info('Sending successful', sender=from_addr[1], recipients=recipient_emails)
def save_draft(account_id, message_id, db_session): """ Sync a new/updated draft back to the remote backend. """ account = db_session.query(Account).get(account_id) message = db_session.query(Message).get(message_id) assert message.is_draft recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) attachments = generate_attachments(message.attachments) mimemsg = create_email(account.sender_name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_at) # If this draft is created by an update_draft() call, # delete the one it supercedes on the remote. # Needed because our update_draft() creates a new draft # message but the user expects to see the one # updated draft only. if message.parent_draft: return delete_draft(account_id, message.parent_draft.id, db_session)
def send_custom(self, draft, body, recipients): """ Turn a draft object into a MIME message, replacing the body with the provided body, and send it only to the provided recipients. Parameters ---------- draft: models.message.Message object the draft message to send. body: string message body to send in place of the existing body attribute in the draft. recipient_emails: email addresses to send copies of this message to. """ blocks = [p.block for p in draft.attachments] attachments = generate_attachments(blocks) from_addr = draft.from_addr[0] msg = create_email(from_name=from_addr[0], from_email=from_addr[1], reply_to=draft.reply_to, nylas_uid=draft.nylas_uid, to_addr=draft.to_addr, cc_addr=draft.cc_addr, bcc_addr=None, subject=draft.subject, html=body, in_reply_to=draft.in_reply_to, references=draft.references, attachments=attachments) recipient_emails = [email for name, email in recipients] self._send(recipient_emails, msg) # Sent successfully self.log.info('Sending successful', sender=from_addr[1], recipients=recipient_emails)
def save_draft(account_id, message_id): """ Sync a new/updated draft back to the remote backend. """ with session_scope() as db_session: account = db_session.query(Account).get(account_id) message = db_session.query(SpoolMessage).get(message_id) recipients = Recipients(message.to_addr, message.cc_addr, message.bcc_addr) attachments = generate_attachments(message.attachments) mimemsg = create_email(account.sender_name, account.email_address, message.inbox_uid, recipients, message.subject, message.sanitized_body, attachments) remote_save_draft = module_registry[account.provider].remote_save_draft remote_save_draft(account, account.drafts_folder.name, mimemsg.to_string(), message.created_date) # If this draft is created by an update_draft() call, # delete the one it supercedes on the remote. # Needed because our update_draft() creates a new draft # message but the user expects to see the one # updated draft only. if message.parent_draft: return delete_draft(account_id, message.parent_draft.id)