Example #1
0
def create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message.create_from_synced(account=account, mid=msg.uid,
                                         folder_name=folder.name,
                                         received_date=msg.internaldate,
                                         body_string=msg.body)

    # Check to see if this is a copy of a message that was first created
    # by the Inbox API. If so, don't create a new object; just use the old one.
    existing_copy = reconcile_message(new_msg, db_session)
    if existing_copy is not None:
        new_msg = existing_copy

    imapuid = ImapUid(account=account, folder=folder, msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_flags_and_labels(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.namespace)

    return imapuid
Example #2
0
def create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message.create_from_synced(account=account, mid=msg.uid,
                                         folder_name=folder.name,
                                         received_date=msg.internaldate,
                                         body_string=msg.body)

    # Check to see if this is a copy of a message that was first created
    # by the Inbox API. If so, don't create a new object; just use the old one.
    existing_copy = reconcile_message(new_msg, db_session)
    if existing_copy is not None:
        new_msg = existing_copy

    imapuid = ImapUid(account=account, folder=folder, msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_flags_and_labels(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.namespace)
    return imapuid
Example #3
0
 def resync_uids_impl(self):
     # NOTE: first, let's check if the UIVDALIDITY change was spurious, if
     # it is, just discard it and go on, if it isn't, drop the relevant
     # entries (filtering by account and folder IDs) from the imapuid table,
     # download messages, if necessary - in case a message has changed UID -
     # update UIDs, and discard orphaned messages. -siro
     with mailsync_session_scope() as db_session:
         folder_info = db_session.query(ImapFolderInfo). \
             filter_by(account_id=self.account_id,
                       folder_id=self.folder_id).one()
         cached_uidvalidity = folder_info.uidvalidity
         with self.conn_pool.get() as crispin_client:
             crispin_client.select_folder(self.folder_name,
                                          lambda *args: True)
             uidvalidity = crispin_client.selected_uidvalidity
             if uidvalidity <= cached_uidvalidity:
                 log.debug('UIDVALIDITY unchanged')
                 return
             invalid_uids = db_session.query(ImapUid). \
                 filter_by(account_id=self.account_id,
                           folder_id=self.folder_id)
             data_sha256_message = {
                 uid.message.data_sha256: uid.message
                 for uid in invalid_uids
             }
             for uid in invalid_uids:
                 db_session.delete(uid)
             # NOTE: this is necessary (and OK since it doesn't persist any
             # data) to maintain the order between UIDs deletion and
             # insertion. Without this, I was seeing constraints violation
             # on the imapuid table. -siro
             db_session.flush()
             remote_uids = crispin_client.all_uids()
             for remote_uid in remote_uids:
                 raw_message = crispin_client.uids([remote_uid])[0]
                 data_sha256 = sha256(raw_message.body).hexdigest()
                 if data_sha256 in data_sha256_message:
                     message = data_sha256_message[data_sha256]
                     uid = ImapUid(msg_uid=raw_message.uid,
                                   message_id=message.id,
                                   account_id=self.account_id,
                                   folder_id=self.folder_id)
                     uid.update_flags_and_labels(raw_message.flags,
                                                 raw_message.g_labels)
                     db_session.add(uid)
                     del data_sha256_message[data_sha256]
                 else:
                     self.download_and_commit_uids(crispin_client,
                                                   self.folder_name,
                                                   [remote_uid])
                 self.heartbeat_status.publish()
                 # FIXME: do we want to throttle the account when recovering
                 # from UIDVALIDITY changes? -siro
         for message in data_sha256_message.itervalues():
             db_session.delete(message)
         folder_info.uidvalidity = uidvalidity
         folder_info.highestmodseq = None
Example #4
0
 def resync_uids_impl(self):
     # NOTE: first, let's check if the UIVDALIDITY change was spurious, if
     # it is, just discard it and go on, if it isn't, drop the relevant
     # entries (filtering by account and folder IDs) from the imapuid table,
     # download messages, if necessary - in case a message has changed UID -
     # update UIDs, and discard orphaned messages. -siro
     with mailsync_session_scope() as db_session:
         folder_info = db_session.query(ImapFolderInfo). \
             filter_by(account_id=self.account_id,
                       folder_id=self.folder_id).one()
         cached_uidvalidity = folder_info.uidvalidity
         with self.conn_pool.get() as crispin_client:
             crispin_client.select_folder(self.folder_name,
                                          lambda *args: True)
             uidvalidity = crispin_client.selected_uidvalidity
             if uidvalidity <= cached_uidvalidity:
                 log.debug('UIDVALIDITY unchanged')
                 return
             invalid_uids = db_session.query(ImapUid). \
                 filter_by(account_id=self.account_id,
                           folder_id=self.folder_id)
             data_sha256_message = {uid.message.data_sha256: uid.message
                                    for uid in invalid_uids}
             for uid in invalid_uids:
                 db_session.delete(uid)
             # NOTE: this is necessary (and OK since it doesn't persist any
             # data) to maintain the order between UIDs deletion and
             # insertion. Without this, I was seeing constraints violation
             # on the imapuid table. -siro
             db_session.flush()
             remote_uids = crispin_client.all_uids()
             for remote_uid in remote_uids:
                 raw_message = crispin_client.uids([remote_uid])[0]
                 data_sha256 = sha256(raw_message.body).hexdigest()
                 if data_sha256 in data_sha256_message:
                     message = data_sha256_message[data_sha256]
                     uid = ImapUid(msg_uid=raw_message.uid,
                                   message_id=message.id,
                                   account_id=self.account_id,
                                   folder_id=self.folder_id)
                     uid.update_flags_and_labels(raw_message.flags,
                                                 raw_message.g_labels)
                     db_session.add(uid)
                     del data_sha256_message[data_sha256]
                 else:
                     self.download_and_commit_uids(crispin_client,
                                                   self.folder_name,
                                                   [remote_uid])
                 self.heartbeat_status.publish()
                 # FIXME: do we want to throttle the account when recovering
                 # from UIDVALIDITY changes? -siro
         for message in data_sha256_message.itervalues():
             db_session.delete(message)
         folder_info.uidvalidity = uidvalidity
         folder_info.highestmodseq = None