def update_folder_info(account_id, session, folder_name, uidvalidity, highestmodseq, uidnext): cached_folder_info = get_folder_info(account_id, session, folder_name) if cached_folder_info is None: folder = session.query(Folder).filter_by(account_id=account_id, name=folder_name).one() cached_folder_info = ImapFolderInfo(account_id=account_id, folder=folder) cached_folder_info.highestmodseq = highestmodseq cached_folder_info.uidvalidity = uidvalidity cached_folder_info.uidnext = uidnext session.add(cached_folder_info) return cached_folder_info
def update_folder_info(account_id, session, folder_name, uidvalidity, highestmodseq): cached_folder_info = get_folder_info(account_id, session, folder_name) if cached_folder_info is None: folder = session.query(Folder).filter_by(account_id=account_id, name=folder_name).one() cached_folder_info = ImapFolderInfo(account_id=account_id, folder=folder) cached_folder_info.highestmodseq = highestmodseq cached_folder_info.uidvalidity = uidvalidity session.add(cached_folder_info)
def initial_sync(self): log.bind(state='initial') log.info('starting initial sync') if self.is_first_sync: self._report_initial_sync_start() self.is_first_sync = False with self.conn_pool.get() as crispin_client: crispin_client.select_folder(self.folder_name, uidvalidity_cb) # Ensure we have an ImapFolderInfo row created prior to sync start. with session_scope(self.namespace_id) as db_session: try: db_session.query(ImapFolderInfo). \ filter(ImapFolderInfo.account_id == self.account_id, ImapFolderInfo.folder_id == self.folder_id). \ one() except NoResultFound: imapfolderinfo = ImapFolderInfo( account_id=self.account_id, folder_id=self.folder_id, uidvalidity=crispin_client.selected_uidvalidity, uidnext=crispin_client.selected_uidnext) db_session.add(imapfolderinfo) db_session.commit() self.initial_sync_impl(crispin_client) if self.is_initial_sync: self._report_initial_sync_end() self.is_initial_sync = False return 'poll'
def test_generic_flags_refresh_expunges_transient_uids(db, generic_account, inbox_folder, mock_imapclient, monkeypatch): # Check that we delete UIDs which are synced but quickly deleted, so never # show up in flags refresh. uid_dict = uids.example() mock_imapclient.add_folder_data(inbox_folder.name, uid_dict) inbox_folder.imapfolderinfo = ImapFolderInfo(account=generic_account, uidvalidity=1, uidnext=1) db.session.commit() folder_sync_engine = FolderSyncEngine(generic_account.id, generic_account.namespace.id, inbox_folder.name, generic_account.email_address, 'custom', BoundedSemaphore(1)) folder_sync_engine.initial_sync() # Don't sleep at the end of poll_impl before returning. folder_sync_engine.poll_frequency = 0 folder_sync_engine.poll_impl() msg = db.session.query(Message).filter_by( namespace_id=generic_account.namespace.id).first() transient_uid = ImapUid(folder=inbox_folder, account=generic_account, message=msg, msg_uid=max(uid_dict) + 1) db.session.add(transient_uid) db.session.commit() folder_sync_engine.last_slow_refresh = None folder_sync_engine.poll_impl() with pytest.raises(ObjectDeletedError): transient_uid.id
def test_handle_uidinvalid(db, generic_account, inbox_folder, mock_imapclient): uid_dict = uids.example() mock_imapclient.add_folder_data(inbox_folder.name, uid_dict) inbox_folder.imapfolderinfo = ImapFolderInfo(account=generic_account, uidvalidity=1, uidnext=1) db.session.commit() folder_sync_engine = FolderSyncEngine( generic_account.id, generic_account.namespace.id, inbox_folder.name, generic_account.email_address, "custom", BoundedSemaphore(1), ) folder_sync_engine.initial_sync() mock_imapclient.uidvalidity = 2 with pytest.raises(UidInvalid): folder_sync_engine.poll_impl() new_state = folder_sync_engine.resync_uids() assert new_state == "initial" assert (db.session.query(ImapUid).filter( ImapUid.folder_id == inbox_folder.id).all() == [])
def add_imap_status_info_rows(folder_id, account_id, db_session): """Add placeholder ImapFolderSyncStatus and ImapFolderInfo rows for this folder_id if none exist.""" if not db_session.query(ImapFolderSyncStatus).filter_by( account_id=account_id, folder_id=folder_id).all(): db_session.add( ImapFolderSyncStatus(account_id=ACCOUNT_ID, folder_id=folder_id, state='initial')) if not db_session.query(ImapFolderInfo).filter_by( account_id=account_id, folder_id=folder_id).all(): db_session.add( ImapFolderInfo(account_id=account_id, folder_id=folder_id, uidvalidity=1, highestmodseq=22))
def test_new_uids_synced_when_polling(db, generic_account, inbox_folder, mock_imapclient): uid_dict = uids.example() mock_imapclient.add_folder_data(inbox_folder.name, uid_dict) inbox_folder.imapfolderinfo = ImapFolderInfo(account=generic_account, uidvalidity=1, uidnext=1) db.session.commit() folder_sync_engine = FolderSyncEngine(generic_account.id, inbox_folder.name, inbox_folder.id, generic_account.email_address, 'custom', BoundedSemaphore(1)) folder_sync_engine.poll_frequency = 0 folder_sync_engine.poll_impl() saved_uids = db.session.query(ImapUid).filter( ImapUid.folder_id == inbox_folder.id) assert {u.msg_uid for u in saved_uids} == set(uid_dict)
def test_handle_uidinvalid_loops(db, generic_account, inbox_folder, mock_imapclient, monkeypatch): import inbox.mailsync.backends.imap.generic as generic_import mock_imapclient.uidvalidity = 1 # We're using a list here because of weird monkeypatching shenanigans. uidinvalid_count = [] def fake_poll_function(self): uidinvalid_count.append(1) raise UidInvalid monkeypatch.setattr( "inbox.mailsync.backends.imap.generic.FolderSyncEngine.poll", fake_poll_function) uid_dict = uids.example() mock_imapclient.add_folder_data(inbox_folder.name, uid_dict) inbox_folder.imapfolderinfo = ImapFolderInfo(account=generic_account, uidvalidity=1, uidnext=1) db.session.commit() folder_sync_engine = generic_import.FolderSyncEngine( generic_account.id, generic_account.namespace.id, inbox_folder.name, generic_account.email_address, "custom", BoundedSemaphore(1), ) folder_sync_engine.state = "poll" db.session.expunge(inbox_folder.imapsyncstatus) with pytest.raises(MailsyncDone): folder_sync_engine._run() assert len(uidinvalid_count) == MAX_UIDINVALID_RESYNCS + 1