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
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))
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
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!"
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()
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()