Search in sources :

Example 1 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method addErrorMessage.

private void addErrorMessage(Account account, String subject, String body) {
    if (!K9.isDebug()) {
        return;
    }
    if (!loopCatch.compareAndSet(false, true)) {
        return;
    }
    try {
        if (body == null || body.length() < 1) {
            return;
        }
        Store localStore = account.getLocalStore();
        LocalFolder localFolder = (LocalFolder) localStore.getFolder(account.getErrorFolderName());
        MimeMessage message = new MimeMessage();
        MimeMessageHelper.setBody(message, new TextBody(body));
        message.setFlag(Flag.X_DOWNLOADED_FULL, true);
        message.setSubject(subject);
        long nowTime = System.currentTimeMillis();
        Date nowDate = new Date(nowTime);
        message.setInternalDate(nowDate);
        message.addSentDate(nowDate, K9.hideTimeZone());
        message.setFrom(new Address(account.getEmail(), "K9mail internal"));
        localFolder.appendMessages(Collections.singletonList(message));
        localFolder.clearMessagesOlderThan(nowTime - (15 * 60 * 1000));
    } catch (Throwable it) {
        Timber.e(it, "Could not save error message to %s", account.getErrorFolderName());
    } finally {
        loopCatch.set(false);
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) TextBody(com.fsck.k9.mail.internet.TextBody) Address(com.fsck.k9.mail.Address) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) LocalStore(com.fsck.k9.mailstore.LocalStore) Store(com.fsck.k9.mail.Store) Pop3Store(com.fsck.k9.mail.store.pop3.Pop3Store) Date(java.util.Date)

Example 2 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method downloadSaneBody.

private void downloadSaneBody(Account account, Folder remoteFolder, LocalFolder localFolder, 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
    localFolder.appendMessages(Collections.singletonList(message));
    Message localMessage = localFolder.getMessage(message.getUid());
    // 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 (account.getMaximumAutoDownloadMessageSize() == 0 || message.getSize() < account.getMaximumAutoDownloadMessageSize()) {
            localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
        } else {
            // Set a flag indicating that the message has been partially downloaded and
            // is ready for view.
            localMessage.setFlag(Flag.X_DOWNLOADED_PARTIAL, true);
        }
    }
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) LocalMessage(com.fsck.k9.mailstore.LocalMessage) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Message(com.fsck.k9.mail.Message)

Example 3 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method moveMessageToDraftsFolder.

private void moveMessageToDraftsFolder(Account account, Folder localFolder, Store localStore, Message message) throws MessagingException {
    LocalFolder draftsFolder = (LocalFolder) localStore.getFolder(account.getDraftsFolderName());
    localFolder.moveMessages(Collections.singletonList(message), draftsFolder);
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder)

Example 4 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method downloadMessages.

/**
     * Fetches the messages described by inputMessages from the remote store and writes them to
     * local storage.
     *
     * @param account
     *         The account the remote store belongs to.
     * @param remoteFolder
     *         The remote folder to download messages from.
     * @param localFolder
     *         The {@link LocalFolder} instance corresponding to the remote folder.
     * @param inputMessages
     *         A list of messages objects that store the UIDs of which messages to download.
     * @param flagSyncOnly
     *         Only flags will be fetched from the remote store if this is {@code true}.
     * @param purgeToVisibleLimit
     *         If true, local messages will be purged down to the limit of visible messages.
     *
     * @return The number of downloaded messages that are not flagged as {@link Flag#SEEN}.
     *
     * @throws MessagingException
     */
private int downloadMessages(final Account account, final Folder remoteFolder, final LocalFolder localFolder, List<Message> inputMessages, boolean flagSyncOnly, boolean purgeToVisibleLimit) throws MessagingException {
    final Date earliestDate = account.getEarliestPollDate();
    // now
    Date downloadStarted = new Date();
    if (earliestDate != null) {
        Timber.d("Only syncing messages after %s", earliestDate);
    }
    final String folder = remoteFolder.getName();
    int unreadBeforeStart = 0;
    try {
        AccountStats stats = account.getStats(context);
        unreadBeforeStart = stats.unreadMessageCount;
    } catch (MessagingException e) {
        Timber.e(e, "Unable to getUnreadMessageCount for account: %s", account);
    }
    List<Message> syncFlagMessages = new ArrayList<>();
    List<Message> unsyncedMessages = new ArrayList<>();
    final AtomicInteger newMessages = new AtomicInteger(0);
    List<Message> messages = new ArrayList<>(inputMessages);
    for (Message message : messages) {
        evaluateMessageForDownload(message, folder, localFolder, remoteFolder, account, unsyncedMessages, syncFlagMessages, flagSyncOnly);
    }
    final AtomicInteger progress = new AtomicInteger(0);
    final int todo = unsyncedMessages.size() + syncFlagMessages.size();
    for (MessagingListener l : getListeners()) {
        l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
    }
    Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
    messages.clear();
    final List<Message> largeMessages = new ArrayList<>();
    final List<Message> smallMessages = new ArrayList<>();
    if (!unsyncedMessages.isEmpty()) {
        /*
             * Reverse the order of the messages. Depending on the server this may get us
             * fetch results for newest to oldest. If not, no harm done.
             */
        Collections.sort(unsyncedMessages, new UidReverseComparator());
        int visibleLimit = localFolder.getVisibleLimit();
        int listSize = unsyncedMessages.size();
        if ((visibleLimit > 0) && (listSize > visibleLimit)) {
            unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
        }
        FetchProfile fp = new FetchProfile();
        if (remoteFolder.supportsFetchingFlags()) {
            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(account, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp);
        String updatedPushState = localFolder.getPushState();
        for (Message message : unsyncedMessages) {
            String newPushState = remoteFolder.getNewPushState(updatedPushState, message);
            if (newPushState != null) {
                updatedPushState = newPushState;
            }
        }
        localFolder.setPushState(updatedPushState);
        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(account, remoteFolder, localFolder, smallMessages, progress, unreadBeforeStart, newMessages, todo, fp);
    smallMessages.clear();
    /*
         * Now do the large messages that require more round trips.
         */
    fp = new FetchProfile();
    fp.add(FetchProfile.Item.STRUCTURE);
    downloadLargeMessages(account, remoteFolder, localFolder, largeMessages, progress, unreadBeforeStart, newMessages, todo, fp);
    largeMessages.clear();
    /*
         * Refresh the flags for any messages in the local store that we didn't just
         * download.
         */
    refreshLocalMessageFlags(account, remoteFolder, localFolder, syncFlagMessages, progress, todo);
    Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
    if (purgeToVisibleLimit) {
        localFolder.purgeToVisibleLimit(new MessageRemovalListener() {

            @Override
            public void messageRemoved(Message message) {
                for (MessagingListener l : getListeners()) {
                    l.synchronizeMailboxRemovedMessage(account, folder, message);
                }
            }
        });
    }
    // If the oldest message seen on this sync is newer than
    // the oldest message seen on the previous sync, then
    // we want to move our high-water mark forward
    // this is all here just for pop which only syncs inbox
    // this would be a little wrong for IMAP (we'd want a folder-level pref, not an account level pref.)
    // fortunately, we just don't care.
    Long oldestMessageTime = localFolder.getOldestMessageDate();
    if (oldestMessageTime != null) {
        Date oldestExtantMessage = new Date(oldestMessageTime);
        if (oldestExtantMessage.before(downloadStarted) && oldestExtantMessage.after(new Date(account.getLatestOldMessageSeenTime()))) {
            account.setLatestOldMessageSeenTime(oldestExtantMessage.getTime());
            account.save(Preferences.getPreferences(context));
        }
    }
    return newMessages.get();
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) LocalMessage(com.fsck.k9.mailstore.LocalMessage) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Message(com.fsck.k9.mail.Message) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) Date(java.util.Date) SuppressLint(android.annotation.SuppressLint) MessageRemovalListener(com.fsck.k9.mailstore.MessageRemovalListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AccountStats(com.fsck.k9.AccountStats)

Example 5 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method processPendingExpunge.

void processPendingExpunge(PendingExpunge command, Account account) throws MessagingException {
    String folder = command.folder;
    if (account.getErrorFolderName().equals(folder)) {
        return;
    }
    Timber.d("processPendingExpunge: folder = %s", folder);
    Store remoteStore = account.getRemoteStore();
    Folder remoteFolder = remoteStore.getFolder(folder);
    try {
        if (!remoteFolder.exists()) {
            return;
        }
        remoteFolder.open(Folder.OPEN_MODE_RW);
        if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
            return;
        }
        remoteFolder.expunge();
        Timber.d("processPendingExpunge: complete for folder = %s", folder);
    } finally {
        closeFolder(remoteFolder);
    }
}
Also used : LocalStore(com.fsck.k9.mailstore.LocalStore) Store(com.fsck.k9.mail.Store) Pop3Store(com.fsck.k9.mail.store.pop3.Pop3Store) Folder(com.fsck.k9.mail.Folder) LocalFolder(com.fsck.k9.mailstore.LocalFolder)

Aggregations

Store (com.fsck.k9.mail.Store)24 MessagingException (com.fsck.k9.mail.MessagingException)23 LocalStore (com.fsck.k9.mailstore.LocalStore)21 Pop3Store (com.fsck.k9.mail.store.pop3.Pop3Store)20 LocalFolder (com.fsck.k9.mailstore.LocalFolder)19 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)17 Folder (com.fsck.k9.mail.Folder)16 Message (com.fsck.k9.mail.Message)16 LocalMessage (com.fsck.k9.mailstore.LocalMessage)16 ArrayList (java.util.ArrayList)10 SuppressLint (android.annotation.SuppressLint)7 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)7 IOException (java.io.IOException)6 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)5 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)5 FetchProfile (com.fsck.k9.mail.FetchProfile)5 Date (java.util.Date)5 Account (com.fsck.k9.Account)4 VisibleForTesting (android.support.annotation.VisibleForTesting)3 SearchAccount (com.fsck.k9.search.SearchAccount)3