def test_recompute_thread_labels(db): # This is smoke test that checks that a lone label gets # added to a thread's labels. thread = db.session.query(Thread).get(THREAD_ID) g_labels = thread.messages[-1].imapuids[-1].g_labels g_labels.append('Random-label-1') recompute_thread_labels(thread, db.session) folders = {folder.name: folder for folder in thread.folders} assert 'Random-label-1' in folders
def test_recompute_thread_labels(db): # This is smoke test that checks that a lone label gets # added to a thread's labels. thread = db.session.query(Thread).get(THREAD_ID) g_labels = thread.messages[-1].imapuids[-1].g_labels g_labels.append('Random-label-1') recompute_thread_labels(thread, db.session) folders = {folder.name: folder for folder in thread.folders} assert 'random-label-1' in folders
def test_recompute_thread_labels(db, thread, default_namespace): # This is smoke test that checks that a lone label gets # added to a thread's labels. account = default_namespace.account message = add_fake_message(db.session, default_namespace.id, thread) add_fake_imapuid(db.session, account.id, message, account.inbox_folder, 22) g_labels = thread.messages[-1].imapuids[-1].g_labels g_labels.append('Random-label-1') recompute_thread_labels(thread, db.session) folders = {folder.name: folder for folder in thread.folders} assert 'Random-label-1' in folders
def test_adding_message_to_thread(db): """recompute_thread_labels is not invoked when a new message is added (only when UID metadata changes, or when a UID is deleted). Test that tag changes work when adding messages to a thread.""" account = db.session.query(Account).get(ACCOUNT_ID) account.namespace.create_canonical_tags() thread = db.session.query(Thread).get(THREAD_ID) account.trash_folder = Folder(name='Trash', account=account) fld_item = FolderItem(thread=thread, folder=account.trash_folder) folder_names = [folder.name for folder in thread.folders] m = Message(namespace_id=account.namespace.id, subject='test message', thread_id=thread.id, received_date=datetime.datetime.now(), size=64, sanitized_body="body", snippet="snippet") uid = ImapUid(account=account, message=m, g_labels=['\\Inbox', 'test-label'], msg_uid=22L, folder_id=account.inbox_folder.id) uid.folder = account.inbox_folder uid2 = ImapUid(account=account, message=m, g_labels=['test-2'], msg_uid=24L, folder_id=account.trash_folder.id) uid2.folder = account.trash_folder thread.messages.append(m) add_any_new_thread_labels(thread, uid, db.session) add_any_new_thread_labels(thread, uid2, db.session) folder_names = [folder.name for folder in thread.folders] for folder in folder_names: assert folder in ['Inbox', 'Trash', 'test-label', 'test-2', '[Gmail]/All Mail', '[Gmail]/Important'],\ "all folders should be present" # Now, remove the message m.imapuids.remove(uid2) db.session.delete(uid2) db.session.flush() recompute_thread_labels(thread, db.session) folder_names = [folder.name for folder in thread.folders] assert 'test-2' not in folder_names,\ "test-2 label should have been removed from thread"
def test_recompute_thread_labels_removes_trash(db): account = db.session.query(Account).get(ACCOUNT_ID) thread = db.session.query(Thread).get(THREAD_ID) account.trash_folder = Folder(name='Trash', account_id=account.id) db.session.flush() # Check that the we remove the trash folder from a thread # if the latest message has the inbox flag. # To do this, we manufacture this situation. g_labels = thread.messages[-1].imapuids[-1].g_labels if '\\Inbox' not in g_labels: g_labels.append('\\Inbox') thread.folders.add(account.trash_folder) recompute_thread_labels(thread, db.session) assert account.trash_folder not in thread.folders,\ "should have removed trash folder from thread"
def test_recompute_thread_labels_removes_trash(db, default_account, thread): default_account.trash_folder = Folder(name='Trash', account_id=default_account.id) message = add_fake_message(db.session, default_account.namespace.id, thread) add_fake_imapuid(db.session, default_account.id, message, default_account.inbox_folder, 22) db.session.commit() # Check that the we remove the trash folder from a thread # if the latest message has the inbox flag. # To do this, we manufacture this situation. g_labels = thread.messages[-1].imapuids[-1].g_labels if '\\Inbox' not in g_labels: g_labels.append('\\Inbox') thread.folders.add(default_account.trash_folder) recompute_thread_labels(thread, db.session) assert default_account.trash_folder not in thread.folders,\ "should have removed trash folder from thread"
def test_adding_message_to_thread(db): """recompute_thread_labels is not invoked when a new message is added (only when UID metadata changes, or when a UID is deleted). Test that tag changes work when adding messages to a thread.""" account = db.session.query(Account).get(ACCOUNT_ID) account.namespace.create_canonical_tags() thread = db.session.query(Thread).get(THREAD_ID) account.trash_folder = Folder(name='Trash', account=account) FolderItem(thread=thread, folder=account.trash_folder) folder_names = [folder.name for folder in thread.folders] m = Message(namespace_id=account.namespace.id, subject='test message', thread_id=thread.id, received_date=datetime.datetime.now(), size=64, body="body", snippet="snippet") uid = ImapUid(account=account, message=m, g_labels=['\\Inbox', 'test-label'], msg_uid=22L, folder_id=account.inbox_folder.id) uid.folder = account.inbox_folder uid2 = ImapUid(account=account, message=m, g_labels=['test-2'], msg_uid=24L, folder_id=account.trash_folder.id) uid2.folder = account.trash_folder thread.messages.append(m) add_any_new_thread_labels(thread, uid, db.session) add_any_new_thread_labels(thread, uid2, db.session) folder_names = [folder.name for folder in thread.folders] for folder in folder_names: assert folder in ['Inbox', 'Trash', 'test-label', 'test-2', '[Gmail]/All Mail', '[Gmail]/Important'],\ "all folders should be present" # Now, remove the message m.imapuids.remove(uid2) db.session.delete(uid2) db.session.flush() recompute_thread_labels(thread, db.session) folder_names = [folder.name for folder in thread.folders] assert 'test-2' not in folder_names,\ "test-2 label should have been removed from thread"
def add_new_imapuids(crispin_client, 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: with mailsync_session_scope() as db_session: # 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( ImapUid.account_id == crispin_client.account_id, 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: acc = db_session.query(GmailAccount).get( crispin_client.account_id) # collate message objects to relate the new imapuids to imapuid_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_for[m.g_msgid], m) for m in db_session.query(Message).join(ImapThread) .filter( Message.g_msgid.in_(imapuid_g_msgids), ImapThread.namespace_id == acc.namespace.id)]) # Stop Folder.find_or_create()'s query from triggering a flush. with db_session.no_autoflush: new_imapuids = [ImapUid( account=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 if uid in message_for] for item in new_imapuids: # skip uids which have disappeared in the meantime if item.msg_uid in flags: item.update_flags_and_labels( flags[item.msg_uid].flags, flags[item.msg_uid].labels) item.message.is_draft = item.is_draft common.update_unread_status(item) db_session.add_all(new_imapuids) db_session.flush() # Don't forget to update thread labels. messages = set(message_for.values()) unique_threads = set([message.thread for message in messages]) for thread in unique_threads: common.recompute_thread_labels(thread, db_session) db_session.commit()
def add_new_imapuids(crispin_client, 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: with mailsync_session_scope() as db_session: # 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(ImapUid.account_id == crispin_client.account_id, 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: acc = db_session.query(GmailAccount).get( crispin_client.account_id) # collate message objects to relate the new imapuids to imapuid_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_for[m.g_msgid], m) for m in db_session.query(Message).join(ImapThread).filter( Message.g_msgid.in_(imapuid_g_msgids), ImapThread.namespace_id == acc.namespace.id) ]) # Stop Folder.find_or_create()'s query from triggering a flush. with db_session.no_autoflush: new_imapuids = [ ImapUid(account=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 if uid in message_for ] for item in new_imapuids: # skip uids which have disappeared in the meantime if item.msg_uid in flags: item.update_flags_and_labels( flags[item.msg_uid].flags, flags[item.msg_uid].labels) item.message.is_draft = item.is_draft common.update_unread_status(item) db_session.add_all(new_imapuids) db_session.flush() # Don't forget to update thread labels. messages = set(message_for.values()) unique_threads = set([message.thread for message in messages]) for thread in unique_threads: common.recompute_thread_labels(thread, db_session) db_session.commit()