Exemple #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.server.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = create_message(db_session, log, account, msg.uid, folder.name,
                             msg.internaldate, msg.flags, msg.body,
                             msg.created)

    if new_msg:
        imapuid = ImapUid(imapaccount=account,
                          folder=folder,
                          msg_uid=msg.uid,
                          message=new_msg)
        imapuid.update_imap_flags(msg.flags)

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

        # NOTE: This might be a good place to add FolderItem entries for
        # non-Gmail backends.

        return imapuid
Exemple #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.server.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = create_message(db_session, log, account, msg.uid, folder.name,
                             msg.internaldate, msg.flags, msg.body,
                             msg.created)

    if new_msg:
        imapuid = ImapUid(imapaccount=account, folder=folder,
                          msg_uid=msg.uid, message=new_msg)
        imapuid.update_imap_flags(msg.flags)

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

        # NOTE: This might be a good place to add FolderItem entries for
        # non-Gmail backends.

        return imapuid
Exemple #3
0
def add_new_imapuid(db_session, log, gmessage, folder_name, acc):
    """ Add ImapUid object for this GMessage if we don't already have one.

    Parameters
    ----------
    message : GMessage
        Message to add ImapUid for.
    folder_name : str
        Which folder to add the ImapUid in.
    acc : ImapAccount
        Which account to associate the message with. (Not looking this up
        within this function is a db access optimization.)
    """
    if not db_session.query(ImapUid.msg_uid).join(Folder).filter(
            Folder.name == folder_name,
            ImapUid.msg_uid == gmessage.uid).all():
        message = db_session.query(Message).filter_by(
            g_msgid=gmessage.g_metadata.msgid).one()
        new_imapuid = ImapUid(
            imapaccount=acc,
            folder=Folder.find_or_create(db_session, acc, folder_name),
            msg_uid=gmessage.uid, message=message)
        new_imapuid.update_imap_flags(gmessage.flags, gmessage.labels)
        db_session.add(new_imapuid)
        db_session.commit()
    else:
        log.debug("Skipping {} imapuid creation for UID {}".format(
            folder_name, gmessage.uid))
Exemple #4
0
def create_imap_message(db_session, log, account, folder_name, 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.server.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = create_message(db_session, log, account, msg.uid, folder_name,
                             msg.internaldate, msg.flags, msg.body,
                             msg.created)

    if new_msg:
        imapuid = ImapUid(imapaccount=account, folder_name=folder_name,
                          msg_uid=msg.uid, message=new_msg)
        imapuid.update_imap_flags(msg.flags)

        new_msg.is_draft = imapuid.is_draft
        # NOTE: If we're going to make the Inbox datastore API support "read"
        # status, this is the place to add that data to Message, e.g.
        # new_msg.is_read = imapuid.is_seen.

        return imapuid
Exemple #5
0
def test_soft_delete(db, config):
    from inbox.server.models.tables.base import Folder, Message
    from inbox.server.models.tables.imap import ImapUid
    f = Folder(name='DOES NOT EXIST', account_id=ACCOUNT_ID)
    db.session.add(f)
    db.session.flush()
    m = Message(thread_id=1, received_date=datetime.datetime.utcnow(),
                size=0, sanitized_body="", snippet="")
    u = ImapUid(message=m, imapaccount_id=ACCOUNT_ID, folder_id=f.id,
                msg_uid=9999, extra_flags="")
    db.session.add_all([m, u])
    f.mark_deleted()
    u.mark_deleted()
    db.session.commit()
    m_id = m.id

    # bypass custom query method to confirm creation
    db.new_session(ignore_soft_deletes=False)
    f = db.session.query(Folder).filter_by(name='DOES NOT EXIST').one()
    assert f, "Can't find Folder object"
    assert f.deleted_at is not None, "Folder not marked as deleted"

    db.new_session(ignore_soft_deletes=True)

    with pytest.raises(NoResultFound):
        folders = db.session.query(Folder).filter(
            Folder.name == 'DOES NOT EXIST').one()

    count = db.session.query(Folder).filter(
        Folder.name == 'DOES NOT EXIST').count()
    assert count == 0, "Shouldn't find any deleted folders!"

    m = db.session.query(Message).filter_by(id=m_id).one()
    assert not m.imapuids, "imapuid was deleted!"
Exemple #6
0
def add_new_imapuid(db_session, log, gmessage, folder_name, acc):
    """ Add ImapUid object for this GMessage if we don't already have one.

    Parameters
    ----------
    message : GMessage
        Message to add ImapUid for.
    folder_name : str
        Which folder to add the ImapUid in.
    acc : ImapAccount
        Which account to associate the message with. (Not looking this up
        within this function is a db access optimization.)
    """
    if not db_session.query(ImapUid.msg_uid).join(Folder).filter(
            Folder.name == folder_name,
            ImapUid.msg_uid == gmessage.uid).all():
        message = db_session.query(Message).filter_by(
            g_msgid=gmessage.g_metadata.msgid).one()
        new_imapuid = ImapUid(
            imapaccount=acc,
            folder=Folder.find_or_create(db_session, acc, folder_name),
            msg_uid=gmessage.uid, message=message)
        new_imapuid.update_imap_flags(gmessage.flags, gmessage.labels)
        db_session.add(new_imapuid)
        db_session.commit()
    else:
        log.debug("Skipping {} imapuid creation for UID {}".format(
            folder_name, gmessage.uid))
Exemple #7
0
def test_soft_delete(db, config):
    from inbox.server.models.tables.base import Folder, Message
    from inbox.server.models.tables.imap import ImapUid
    f = Folder(name='DOES NOT EXIST', account_id=ACCOUNT_ID)
    db.session.add(f)
    db.session.flush()
    m = Message(thread_id=1,
                received_date=datetime.datetime.utcnow(),
                size=0,
                sanitized_body="",
                snippet="")
    u = ImapUid(message=m,
                imapaccount_id=ACCOUNT_ID,
                folder_id=f.id,
                msg_uid=9999,
                extra_flags="")
    db.session.add_all([m, u])
    f.mark_deleted()
    u.mark_deleted()
    db.session.commit()
    m_id = m.id

    # bypass custom query method to confirm creation
    db.new_session(ignore_soft_deletes=False)
    f = db.session.query(Folder).filter_by(name='DOES NOT EXIST').one()
    assert f, "Can't find Folder object"
    assert f.deleted_at is not None, "Folder not marked as deleted"

    db.new_session(ignore_soft_deletes=True)

    with pytest.raises(NoResultFound):
        folders = db.session.query(Folder).filter(
            Folder.name == 'DOES NOT EXIST').one()

    count = db.session.query(Folder).filter(
        Folder.name == 'DOES NOT EXIST').count()
    assert count == 0, "Shouldn't find any deleted folders!"

    m = db.session.query(Message).filter_by(id=m_id).one()
    assert not m.imapuids, "imapuid was deleted!"
Exemple #8
0
def add_new_imapuid(db_session, gmessage, folder_name, acc):
    """ Add ImapUid object for this GMessage if we don't already have one.

    Parameters
    ----------
    message : GMessage
        Message to add ImapUid for.
    folder_name : str
        Which folder to add the ImapUid in.
    acc : ImapAccount
        Which account to associate the message with. (Not looking this up
        within this function is a db access optimization.)
    """
    if not db_session.query(ImapUid.msg_uid).filter_by(
            msg_uid=gmessage.uid).all():
        message = db_session.query(Message).filter_by(
            g_msgid=gmessage.g_metadata.msgid).one()
        new_imapuid = ImapUid(
            imapaccount=acc, folder_name=folder_name,
            msg_uid=gmessage.uid, message=message)
        new_imapuid.update_imap_flags(gmessage.flags, gmessage.labels)
        db_session.add(new_imapuid)
        db_session.commit()
Exemple #9
0
def add_new_imapuids(crispin_client, log, db_session, remote_g_metadata,
                     syncmanager_lock, uids):
    """ Add ImapUid entries only for (already-downloaded) messages.

    If a message has already been downloaded via another folder, we only need
    to add `ImapUid` accounting for the current folder. `Message` objects
    etc. have already been created.
    """
    flags = crispin_client.flags(uids)

    with syncmanager_lock:
        log.debug("add_new_imapuids acquired syncmanager_lock")
        # Since we prioritize download for messages in certain threads, we may
        # already have ImapUid entries despite calling this method.
        local_folder_uids = {uid for uid, in
                             db_session.query(ImapUid.msg_uid).join(Folder)
                             .filter(
                                 Folder.name ==
                                 crispin_client.selected_folder_name,
                                 ImapUid.msg_uid.in_(uids))}
        uids = [uid for uid in uids if uid not in local_folder_uids]

        if uids:
            # collate message objects to relate the new imapuids
            imapuid_uid_for = dict([(metadata.msgid, uid) for (uid, metadata)
                                    in remote_g_metadata.items()
                                    if uid in uids])
            imapuid_g_msgids = [remote_g_metadata[uid].msgid for uid in uids]
            message_for = dict([(imapuid_uid_for[mm.g_msgid], mm) for mm in
                                db_session.query(Message).filter(
                                    Message.g_msgid.in_(imapuid_g_msgids))])

            acc = db_session.query(ImapAccount).get(crispin_client.account_id)
            # Folder.find_or_create()'s query will otherwise trigger a flush.
            with db_session.no_autoflush:
                new_imapuids = [ImapUid(
                    imapaccount=acc,
                    folder=Folder.find_or_create(
                        db_session, acc, crispin_client.selected_folder_name),
                    msg_uid=uid, message=message_for[uid]) for uid in uids]
                for item in new_imapuids:
                    item.update_imap_flags(flags[item.msg_uid].flags,
                                           flags[item.msg_uid].labels)
            db_session.add_all(new_imapuids)
            db_session.commit()