Search in sources :

Example 16 with WebDavMessage

use of com.fsck.k9.mail.store.webdav.WebDavMessage in project k-9 by k9mail.

the class WebDavFolder method appendWebDavMessages.

public List<? extends Message> appendWebDavMessages(List<? extends Message> messages) throws MessagingException {
    List<Message> retMessages = new ArrayList<Message>(messages.size());
    WebDavHttpClient httpclient = store.getHttpClient();
    for (Message message : messages) {
        HttpGeneric httpmethod;
        HttpResponse response;
        StringEntity bodyEntity;
        int statusCode;
        try {
            ByteArrayOutputStream out;
            long size = message.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new MessagingException("message size > Integer.MAX_VALUE!");
            }
            out = new ByteArrayOutputStream((int) size);
            open(Folder.OPEN_MODE_RW);
            EOLConvertingOutputStream msgOut = new EOLConvertingOutputStream(new BufferedOutputStream(out, 1024));
            message.writeTo(msgOut);
            msgOut.flush();
            bodyEntity = new StringEntity(out.toString(), "UTF-8");
            bodyEntity.setContentType("message/rfc822");
            String messageURL = mFolderUrl;
            if (!messageURL.endsWith("/")) {
                messageURL += "/";
            }
            messageURL += encodeUtf8(message.getUid() + ":" + System.currentTimeMillis() + ".eml");
            Log.i(LOG_TAG, "Uploading message as " + messageURL);
            store.sendRequest(messageURL, "PUT", bodyEntity, null, true);
            WebDavMessage retMessage = new WebDavMessage(message.getUid(), this);
            retMessage.setUrl(messageURL);
            retMessages.add(retMessage);
        } catch (Exception e) {
            throw new MessagingException("Unable to append", e);
        }
    }
    return retMessages;
}
Also used : EOLConvertingOutputStream(com.fsck.k9.mail.filter.EOLConvertingOutputStream) Message(com.fsck.k9.mail.Message) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) HttpResponse(org.apache.http.HttpResponse) ByteArrayOutputStream(java.io.ByteArrayOutputStream) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) StringEntity(org.apache.http.entity.StringEntity) BufferedOutputStream(java.io.BufferedOutputStream)

Example 17 with WebDavMessage

use of com.fsck.k9.mail.store.webdav.WebDavMessage in project k-9 by k9mail.

the class WebDavSync method downloadSaneBody.

private void downloadSaneBody(SyncConfig syncConfig, WebDavFolder remoteFolder, BackendFolder backendFolder, WebDavMessage 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
         */
    int maxDownloadSize = syncConfig.getMaximumAutoDownloadMessageSize();
    remoteFolder.fetch(Collections.singletonList(message), fp, null, maxDownloadSize);
    boolean completeMessage = false;
    // Certain (POP3) servers give you the whole message even when you ask for only the first x Kb
    if (!message.isSet(Flag.X_DOWNLOADED_FULL)) {
        /*
             * Mark the message as fully downloaded if the message size is smaller than
             * the account's autodownload size limit, otherwise mark as only a partial
             * download.  This will prevent the system from downloading the same message
             * twice.
             *
             * If there is no limit on autodownload size, that's the same as the message
             * being smaller than the max size
             */
        if (syncConfig.getMaximumAutoDownloadMessageSize() == 0 || message.getSize() < syncConfig.getMaximumAutoDownloadMessageSize()) {
            completeMessage = true;
        }
    }
    // Store the updated message locally
    if (completeMessage) {
        backendFolder.saveMessage(message, MessageDownloadState.FULL);
    } else {
        backendFolder.saveMessage(message, MessageDownloadState.PARTIAL);
    }
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile)

Example 18 with WebDavMessage

use of com.fsck.k9.mail.store.webdav.WebDavMessage in project k-9 by k9mail.

the class WebDavSync method downloadMessages.

private int downloadMessages(final SyncConfig syncConfig, final WebDavFolder remoteFolder, final BackendFolder backendFolder, List<WebDavMessage> inputMessages, final SyncListener listener) throws MessagingException {
    final Date earliestDate = syncConfig.getEarliestPollDate();
    // now
    Date downloadStarted = new Date();
    if (earliestDate != null) {
        Timber.d("Only syncing messages after %s", earliestDate);
    }
    final String folder = remoteFolder.getServerId();
    List<WebDavMessage> syncFlagMessages = new ArrayList<>();
    List<WebDavMessage> unsyncedMessages = new ArrayList<>();
    final AtomicInteger newMessages = new AtomicInteger(0);
    List<WebDavMessage> messages = new ArrayList<>(inputMessages);
    for (WebDavMessage message : messages) {
        evaluateMessageForDownload(message, folder, backendFolder, unsyncedMessages, syncFlagMessages, listener);
    }
    final AtomicInteger progress = new AtomicInteger(0);
    final int todo = unsyncedMessages.size() + syncFlagMessages.size();
    listener.syncProgress(folder, progress.get(), todo);
    Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
    messages.clear();
    final List<WebDavMessage> largeMessages = new ArrayList<>();
    final List<WebDavMessage> smallMessages = new ArrayList<>();
    if (!unsyncedMessages.isEmpty()) {
        int visibleLimit = backendFolder.getVisibleLimit();
        int listSize = unsyncedMessages.size();
        if ((visibleLimit > 0) && (listSize > visibleLimit)) {
            unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
        }
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.FLAGS);
        fp.add(FetchProfile.Item.ENVELOPE);
        Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
        fetchUnsyncedMessages(syncConfig, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp, listener);
        Timber.d("SYNC: Synced unsynced messages for folder %s", folder);
    }
    Timber.d("SYNC: Have %d large messages and %d small messages out of %d unsynced messages", largeMessages.size(), smallMessages.size(), unsyncedMessages.size());
    unsyncedMessages.clear();
    /*
         * Grab the content of the small messages first. This is going to
         * be very fast and at very worst will be a single up of a few bytes and a single
         * download of 625k.
         */
    FetchProfile fp = new FetchProfile();
    // TODO: Only fetch small and large messages if we have some
    fp.add(FetchProfile.Item.BODY);
    // fp.add(FetchProfile.Item.FLAGS);
    // fp.add(FetchProfile.Item.ENVELOPE);
    downloadSmallMessages(remoteFolder, backendFolder, smallMessages, progress, newMessages, todo, fp, listener);
    smallMessages.clear();
    /*
         * Now do the large messages that require more round trips.
         */
    fp = new FetchProfile();
    fp.add(FetchProfile.Item.STRUCTURE);
    downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener);
    largeMessages.clear();
    /*
         * Refresh the flags for any messages in the local store that we didn't just
         * download.
         */
    refreshLocalMessageFlags(syncConfig, remoteFolder, backendFolder, syncFlagMessages, progress, todo, listener);
    Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
    return newMessages.get();
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) WebDavMessage(com.fsck.k9.mail.store.webdav.WebDavMessage) Date(java.util.Date)

Example 19 with WebDavMessage

use of com.fsck.k9.mail.store.webdav.WebDavMessage in project k-9 by k9mail.

the class WebDavSync method fetchUnsyncedMessages.

private void fetchUnsyncedMessages(final SyncConfig syncConfig, final WebDavFolder remoteFolder, List<WebDavMessage> unsyncedMessages, final List<WebDavMessage> smallMessages, final List<WebDavMessage> largeMessages, final AtomicInteger progress, final int todo, FetchProfile fp, final SyncListener listener) throws MessagingException {
    final String folder = remoteFolder.getServerId();
    final Date earliestDate = syncConfig.getEarliestPollDate();
    remoteFolder.fetch(unsyncedMessages, fp, new MessageRetrievalListener<WebDavMessage>() {

        @Override
        public void messageFinished(WebDavMessage message, int number, int ofTotal) {
            try {
                if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
                    if (message.isSet(Flag.DELETED)) {
                        Timber.v("Newly downloaded message %s:%s:%s was marked deleted on server, " + "skipping", accountName, folder, message.getUid());
                    } else {
                        Timber.d("Newly downloaded message %s is older than %s, skipping", message.getUid(), earliestDate);
                    }
                    progress.incrementAndGet();
                    // TODO: This might be the source of poll count errors in the UI. Is todo always the same as ofTotal
                    listener.syncProgress(folder, progress.get(), todo);
                    return;
                }
                if (syncConfig.getMaximumAutoDownloadMessageSize() > 0 && message.getSize() > syncConfig.getMaximumAutoDownloadMessageSize()) {
                    largeMessages.add(message);
                } else {
                    smallMessages.add(message);
                }
            } catch (Exception e) {
                Timber.e(e, "Error while storing downloaded message.");
            }
        }

        @Override
        public void messageStarted(String uid, int number, int ofTotal) {
        }

        @Override
        public void messagesFinished(int total) {
        // FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
        }
    }, syncConfig.getMaximumAutoDownloadMessageSize());
}
Also used : WebDavMessage(com.fsck.k9.mail.store.webdav.WebDavMessage) Date(java.util.Date) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Example 20 with WebDavMessage

use of com.fsck.k9.mail.store.webdav.WebDavMessage in project k-9 by k9mail.

the class WebDavFolderTest method folder_can_fetch_more_than_20_flags.

@Test
public void folder_can_fetch_more_than_20_flags() throws MessagingException {
    when(mockStore.processRequest(anyString(), anyString(), anyString(), anyMap())).thenReturn(mockDataSet);
    List<WebDavMessage> messages = new ArrayList<>();
    for (int i = 0; i < 25; i++) {
        WebDavMessage mockMessage = createWebDavMessage(i);
        messages.add(mockMessage);
    }
    FetchProfile profile = new FetchProfile();
    profile.add(FetchProfile.Item.FLAGS);
    folder.fetch(messages, profile, listener, MAX_DOWNLOAD_SIZE);
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

FetchProfile (com.fsck.k9.mail.FetchProfile)11 ArrayList (java.util.ArrayList)11 Test (org.junit.Test)9 WebDavMessage (com.fsck.k9.mail.store.webdav.WebDavMessage)7 HttpResponse (org.apache.http.HttpResponse)7 MessagingException (com.fsck.k9.mail.MessagingException)5 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 IOException (java.io.IOException)4 StatusLine (org.apache.http.StatusLine)4 HttpUriRequest (org.apache.http.client.methods.HttpUriRequest)4 HttpContext (org.apache.http.protocol.HttpContext)4 InvocationOnMock (org.mockito.invocation.InvocationOnMock)4 Message (com.fsck.k9.mail.Message)3 WebDavFolder (com.fsck.k9.mail.store.webdav.WebDavFolder)3 URISyntaxException (java.net.URISyntaxException)3 Date (java.util.Date)3 BasicHttpEntity (org.apache.http.entity.BasicHttpEntity)3 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)2 Flag (com.fsck.k9.mail.Flag)2