private void downloadSaneBody(Folder remoteFolder, BackendFolder backendFolder, Message message) throws MessagingException { /* * The provider was unable to get the structure of the message, so * we'll download a reasonable portion of the messge and mark it as * incomplete so the entire thing can be downloaded later if the user * wishes to download it. */ FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY_SANE); /* * TODO a good optimization here would be to make sure that all Stores set * the proper size after this fetch and compare the before and after size. If * they equal we can mark this SYNCHRONIZED instead of PARTIALLY_SYNCHRONIZED */ remoteFolder.fetch(Collections.singletonList(message), fp, null); // Store the updated message locally backendFolder.savePartialMessage(message); }
if (fp.contains(FetchProfile.Item.ENVELOPE)) { fetchEnvelope(messages, fp.size() == 1 ? listener : null); Pop3Message pop3Message = messages.get(i); try { if (listener != null && !fp.contains(FetchProfile.Item.ENVELOPE)) { listener.messageStarted(pop3Message.getUid(), i, count); if (fp.contains(FetchProfile.Item.BODY)) { fetchBody(pop3Message, -1); } else if (fp.contains(FetchProfile.Item.BODY_SANE)) { fetchBody(pop3Message, -1); } else if (fp.contains(FetchProfile.Item.STRUCTURE)) { if (listener != null && !(fp.contains(FetchProfile.Item.ENVELOPE) && fp.size() == 1)) { listener.messageFinished(pop3Message, i, count);
private FetchProfile createFetchProfile(Item... items) { FetchProfile fetchProfile = new FetchProfile(); Collections.addAll(fetchProfile, items); return fetchProfile; }
@Override public Void doDbWork(final SQLiteDatabase db) throws WrappedException { try { open(OPEN_MODE_RW); if (fp.contains(FetchProfile.Item.BODY)) { for (Message message : messages) { LocalMessage localMessage = (LocalMessage) message; loadMessageParts(db, localMessage); } } } catch (MessagingException e) { throw new WrappedException(e); } return null; } });
@Test public void sync_withUnsyncedNewSmallMessage_shouldFetchStructureAndLimitedBodyOfLargeMessage() throws Exception { Message largeMessage = buildLargeNewMessage(); messageCountInRemoteFolder(1); hasUnsyncedRemoteMessage(); when(remoteFolder.supportsFetchingFlags()).thenReturn(false); respondToFetchEnvelopesWithMessage(largeMessage); imapSync.sync(FOLDER_NAME, syncConfig, listener, remoteFolder); //TODO: Don't bother fetching messages of a size we don't have verify(remoteFolder, atLeast(4)).fetch(any(List.class), fetchProfileCaptor.capture(), nullable(MessageRetrievalListener.class)); assertEquals(1, fetchProfileCaptor.getAllValues().get(2).size()); assertEquals(FetchProfile.Item.STRUCTURE, fetchProfileCaptor.getAllValues().get(2).get(0)); assertEquals(1, fetchProfileCaptor.getAllValues().get(3).size()); assertEquals(FetchProfile.Item.BODY_SANE, fetchProfileCaptor.getAllValues().get(3).get(0)); }
if (fp.contains(FetchProfile.Item.ENVELOPE)) { fetchEnvelope(messages, listener); if (fp.contains(FetchProfile.Item.FLAGS)) { fetchFlags(messages, listener); if (fp.contains(FetchProfile.Item.BODY_SANE)) { int maximumAutoDownloadSize = store.getStoreConfig().getMaximumAutoDownloadMessageSize(); if (maximumAutoDownloadSize > 0) { if (fp.contains(FetchProfile.Item.BODY)) { fetchMessages(messages, listener, -1);
private void loadSearchResultsSynchronous(Account account, List<String> messageServerIds, LocalFolder localFolder) throws MessagingException { FetchProfile fetchProfile = new FetchProfile(); fetchProfile.add(FetchProfile.Item.FLAGS); fetchProfile.add(FetchProfile.Item.ENVELOPE); fetchProfile.add(FetchProfile.Item.STRUCTURE); Backend backend = getBackend(account); String folderServerId = localFolder.getServerId(); for (String messageServerId : messageServerIds) { LocalMessage localMessage = localFolder.getMessage(messageServerId); if (localMessage == null) { Message message = backend.fetchMessage(folderServerId, messageServerId, fetchProfile); localFolder.appendMessages(Collections.singletonList(message)); } } }
@Test public void sync_shouldFetchUnsynchronizedMessagesListAndFlags() throws Exception { messageCountInRemoteFolder(1); hasUnsyncedRemoteMessage(); when(remoteFolder.supportsFetchingFlags()).thenReturn(true); imapSync.sync(FOLDER_NAME, syncConfig, listener, remoteFolder); verify(remoteFolder, atLeastOnce()).fetch(any(List.class), fetchProfileCaptor.capture(), nullable(MessageRetrievalListener.class)); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.FLAGS)); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.ENVELOPE)); assertEquals(2, fetchProfileCaptor.getAllValues().get(0).size()); }
@Override public Void answer(InvocationOnMock invocation) { FetchProfile fetchProfile = (FetchProfile) invocation.getArguments()[1]; if (invocation.getArguments()[2] != null) { MessageRetrievalListener listener = (MessageRetrievalListener) invocation.getArguments()[2]; if (fetchProfile.contains(FetchProfile.Item.ENVELOPE)) { listener.messageStarted("UID", 1, 1); listener.messageFinished(message, 1, 1); listener.messagesFinished(1); } } return null; } }).when(remoteFolder).fetch(any(List.class), any(FetchProfile.class), nullable(MessageRetrievalListener.class));
@Nullable private LocalMessage loadLocalMessageByMessageId(long messageId) throws MessagingException { Map<String, List<String>> foldersAndUids = getFoldersAndUids(Collections.singletonList(messageId), false); if (foldersAndUids.isEmpty()) { return null; } Map.Entry<String,List<String>> entry = foldersAndUids.entrySet().iterator().next(); String folderServerId = entry.getKey(); String uid = entry.getValue().get(0); LocalFolder folder = getFolder(folderServerId); LocalMessage localMessage = folder.getMessage(uid); FetchProfile fp = new FetchProfile(); fp.add(Item.BODY); folder.fetch(Collections.singletonList(localMessage), fp, null); return localMessage; }
@Test public void sync_withUnsyncedNewSmallMessage_shouldFetchBodyOfSmallMessage() throws Exception { Message smallMessage = buildSmallNewMessage(); messageCountInRemoteFolder(1); hasUnsyncedRemoteMessage(); when(remoteFolder.supportsFetchingFlags()).thenReturn(false); respondToFetchEnvelopesWithMessage(smallMessage); imapSync.sync(FOLDER_NAME, syncConfig, listener, remoteFolder); verify(remoteFolder, atLeast(2)).fetch(any(List.class), fetchProfileCaptor.capture(), nullable(MessageRetrievalListener.class)); assertEquals(1, fetchProfileCaptor.getAllValues().get(1).size()); assertTrue(fetchProfileCaptor.getAllValues().get(1).contains(FetchProfile.Item.BODY)); }
fetchFields.add("UID"); if (fetchProfile.contains(FetchProfile.Item.FLAGS)) { fetchFields.add("FLAGS"); if (fetchProfile.contains(FetchProfile.Item.ENVELOPE)) { fetchFields.add("INTERNALDATE"); fetchFields.add("RFC822.SIZE"); if (fetchProfile.contains(FetchProfile.Item.STRUCTURE)) { fetchFields.add("BODYSTRUCTURE"); if (fetchProfile.contains(FetchProfile.Item.BODY_SANE)) { int maximumAutoDownloadMessageSize = store.getStoreConfig().getMaximumAutoDownloadMessageSize(); if (maximumAutoDownloadMessageSize > 0) { if (fetchProfile.contains(FetchProfile.Item.BODY)) { fetchFields.add("BODY.PEEK[]"); if (fetchProfile.contains(FetchProfile.Item.BODY) || fetchProfile.contains(FetchProfile.Item.BODY_SANE)) { callback = new FetchBodyCallback(messageMap);
public LocalMessage loadMessageMetadata(Account account, String folderServerId, String uid) throws MessagingException { LocalStore localStore = localStoreProvider.getInstance(account); LocalFolder localFolder = localStore.getFolder(folderServerId); localFolder.open(Folder.OPEN_MODE_RW); LocalMessage message = localFolder.getMessage(uid); if (message == null || message.getDatabaseId() == 0) { throw new IllegalArgumentException("Message not found: folder=" + folderServerId + ", uid=" + uid); } FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.ENVELOPE); localFolder.fetch(Collections.singletonList(message), fp, null); localFolder.close(); return message; }
private void refreshLocalMessageFlags( SyncConfig syncConfig, final Folder remoteFolder, final BackendFolder backendFolder, List<Message> syncFlagMessages, final AtomicInteger progress, final int todo, SyncListener listener ) throws MessagingException { final String folder = remoteFolder.getServerId(); Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.FLAGS); List<Message> undeletedMessages = new LinkedList<>(); for (Message message : syncFlagMessages) { if (!message.isSet(Flag.DELETED)) { undeletedMessages.add(message); } } remoteFolder.fetch(undeletedMessages, fp, null); for (Message remoteMessage : syncFlagMessages) { boolean messageChanged = syncFlags(syncConfig, backendFolder, remoteMessage); if (messageChanged) { listener.syncFlagChanged(folder, remoteMessage.getUid()); } progress.incrementAndGet(); listener.syncProgress(folder, progress.get(), todo); } }
FetchProfile fp = new FetchProfile(); if (remoteFolder.supportsFetchingFlags()) { fp.add(FetchProfile.Item.FLAGS); fp.add(FetchProfile.Item.ENVELOPE); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); fp = new FetchProfile(); fp.add(FetchProfile.Item.STRUCTURE); downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener); largeMessages.clear();
Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.FLAGS);
FetchProfile fp = new FetchProfile(); if (remoteFolder.supportsFetchingFlags()) { fp.add(FetchProfile.Item.FLAGS); fp.add(FetchProfile.Item.ENVELOPE); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); fp = new FetchProfile(); fp.add(FetchProfile.Item.STRUCTURE); downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener); largeMessages.clear();
Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.FLAGS);
@Test public void folder_can_fetch_more_than_10_envelopes() throws MessagingException { when(mockStore.processRequest(anyString(), anyString(), anyString(), anyMapOf(String.class, String.class))) .thenReturn(mockDataSet); List<WebDavMessage> messages = new ArrayList<>(); for (int i = 0; i < 15; i++) { WebDavMessage mockMessage = createWebDavMessage(i); messages.add(mockMessage); } FetchProfile profile = new FetchProfile(); profile.add(FetchProfile.Item.ENVELOPE); folder.fetch(messages, profile, listener); }
@Test public void folder_can_fetch_less_than_10_envelopes() throws MessagingException { when(mockStore.processRequest(anyString(), anyString(), anyString(), anyMapOf(String.class, String.class))) .thenReturn(mockDataSet); List<WebDavMessage> messages = new ArrayList<>(); for (int i = 0; i < 5; i++) { WebDavMessage mockMessage = createWebDavMessage(i); messages.add(mockMessage); } FetchProfile profile = new FetchProfile(); profile.add(FetchProfile.Item.ENVELOPE); folder.fetch(messages, profile, listener); }