Search in sources :

Example 6 with Backend

use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.

the class MessagingController method sendPendingMessagesSynchronous.

/**
 * Attempt to send any messages that are sitting in the Outbox.
 */
@VisibleForTesting
protected void sendPendingMessagesSynchronous(final Account account) {
    Exception lastFailure = null;
    boolean wasPermanentFailure = false;
    try {
        ServerSettings serverSettings = account.getOutgoingServerSettings();
        if (serverSettings.isMissingCredentials()) {
            handleAuthenticationFailure(account, false);
            return;
        }
        LocalStore localStore = localStoreProvider.getInstance(account);
        OutboxStateRepository outboxStateRepository = localStore.getOutboxStateRepository();
        LocalFolder localFolder = localStore.getFolder(account.getOutboxFolderId());
        if (!localFolder.exists()) {
            Timber.w("Outbox does not exist");
            return;
        }
        localFolder.open();
        long outboxFolderId = localFolder.getDatabaseId();
        List<LocalMessage> localMessages = localFolder.getMessages(null);
        int progress = 0;
        int todo = localMessages.size();
        for (MessagingListener l : getListeners()) {
            l.synchronizeMailboxProgress(account, outboxFolderId, progress, todo);
        }
        /*
             * The profile we will use to pull all of the content
             * for a given local message into memory for sending.
             */
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        fp.add(FetchProfile.Item.BODY);
        Timber.i("Scanning Outbox folder for messages to send");
        Backend backend = getBackend(account);
        for (LocalMessage message : localMessages) {
            if (message.isSet(Flag.DELETED)) {
                // FIXME: When uploading a message to the remote Sent folder the move code creates a placeholder
                // message in the Outbox. This code gets rid of these messages. It'd be preferable if the
                // placeholder message was never created, though.
                message.destroy();
                continue;
            }
            try {
                long messageId = message.getDatabaseId();
                OutboxState outboxState = outboxStateRepository.getOutboxState(messageId);
                if (outboxState.getSendState() != SendState.READY) {
                    Timber.v("Skipping sending message %s", message.getUid());
                    notificationController.showSendFailedNotification(account, new MessagingException(message.getSubject()));
                    continue;
                }
                Timber.i("Send count for message %s is %d", message.getUid(), outboxState.getNumberOfSendAttempts());
                localFolder.fetch(Collections.singletonList(message), fp, null);
                try {
                    if (message.getHeader(K9.IDENTITY_HEADER).length > 0 || message.isSet(Flag.DRAFT)) {
                        Timber.v("The user has set the Outbox and Drafts folder to the same thing. " + "This message appears to be a draft, so K-9 will not send it");
                        continue;
                    }
                    outboxStateRepository.incrementSendAttempts(messageId);
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
                    Timber.i("Sending message with UID %s", message.getUid());
                    backend.sendMessage(message);
                    message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
                    message.setFlag(Flag.SEEN, true);
                    progress++;
                    for (MessagingListener l : getListeners()) {
                        l.synchronizeMailboxProgress(account, outboxFolderId, progress, todo);
                    }
                    moveOrDeleteSentMessage(account, localStore, message);
                    outboxStateRepository.removeOutboxState(messageId);
                } catch (AuthenticationFailedException e) {
                    outboxStateRepository.decrementSendAttempts(messageId);
                    lastFailure = e;
                    wasPermanentFailure = false;
                    handleAuthenticationFailure(account, false);
                    handleSendFailure(account, localFolder, message, e);
                } catch (CertificateValidationException e) {
                    outboxStateRepository.decrementSendAttempts(messageId);
                    lastFailure = e;
                    wasPermanentFailure = false;
                    notifyUserIfCertificateProblem(account, e, false);
                    handleSendFailure(account, localFolder, message, e);
                } catch (MessagingException e) {
                    lastFailure = e;
                    wasPermanentFailure = e.isPermanentFailure();
                    if (wasPermanentFailure) {
                        String errorMessage = e.getMessage();
                        outboxStateRepository.setSendAttemptError(messageId, errorMessage);
                    } else if (outboxState.getNumberOfSendAttempts() + 1 >= MAX_SEND_ATTEMPTS) {
                        outboxStateRepository.setSendAttemptsExceeded(messageId);
                    }
                    handleSendFailure(account, localFolder, message, e);
                } catch (Exception e) {
                    lastFailure = e;
                    wasPermanentFailure = true;
                    handleSendFailure(account, localFolder, message, e);
                }
            } catch (Exception e) {
                lastFailure = e;
                wasPermanentFailure = false;
                Timber.e(e, "Failed to fetch message for sending");
                notifySynchronizeMailboxFailed(account, localFolder, e);
            }
        }
        if (lastFailure != null) {
            if (wasPermanentFailure) {
                notificationController.showSendFailedNotification(account, lastFailure);
            } else {
                notificationController.showSendFailedNotification(account, lastFailure);
            }
        }
    } catch (Exception e) {
        Timber.v(e, "Failed to send pending messages");
    } finally {
        if (lastFailure == null) {
            notificationController.clearSendFailedNotification(account);
        }
    }
}
Also used : LocalMessage(com.fsck.k9.mailstore.LocalMessage) FetchProfile(com.fsck.k9.mail.FetchProfile) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) OutboxStateRepository(com.fsck.k9.mailstore.OutboxStateRepository) LocalStore(com.fsck.k9.mailstore.LocalStore) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) SuppressLint(android.annotation.SuppressLint) OutboxState(com.fsck.k9.mailstore.OutboxState) LocalFolder(com.fsck.k9.mailstore.LocalFolder) Backend(com.fsck.k9.backend.api.Backend) ServerSettings(com.fsck.k9.mail.ServerSettings) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) VisibleForTesting(androidx.annotation.VisibleForTesting)

Example 7 with Backend

use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.

the class MessagingController method processPendingSetFlag.

/**
 * Processes a pending mark read or unread command.
 */
void processPendingSetFlag(PendingSetFlag command, Account account) throws MessagingException {
    Backend backend = getBackend(account);
    String folderServerId = getFolderServerId(account, command.folderId);
    backend.setFlag(folderServerId, command.uids, command.flag, command.newState);
}
Also used : Backend(com.fsck.k9.backend.api.Backend)

Example 8 with Backend

use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.

the class MessagingController method synchronizeMailboxSynchronous.

private void synchronizeMailboxSynchronous(Account account, long folderId, boolean notify, MessagingListener listener, NotificationState notificationState) {
    refreshFolderListIfStale(account);
    Backend backend = getBackend(account);
    syncFolder(account, folderId, notify, listener, backend, notificationState);
}
Also used : Backend(com.fsck.k9.backend.api.Backend)

Example 9 with Backend

use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.

the class MessagingController method refreshFolderListSynchronous.

public void refreshFolderListSynchronous(Account account) {
    try {
        ServerSettings serverSettings = account.getIncomingServerSettings();
        if (serverSettings.isMissingCredentials()) {
            handleAuthenticationFailure(account, true);
            return;
        }
        Backend backend = getBackend(account);
        backend.refreshFolderList();
        long now = System.currentTimeMillis();
        Timber.d("Folder list successfully refreshed @ %tc", now);
        account.setLastFolderListRefreshTime(now);
        preferences.saveAccount(account);
    } catch (Exception e) {
        Timber.e(e);
    }
}
Also used : Backend(com.fsck.k9.backend.api.Backend) ServerSettings(com.fsck.k9.mail.ServerSettings) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Example 10 with Backend

use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.

the class MessagingController method processPendingDelete.

void processPendingDelete(PendingDelete command, Account account) throws MessagingException {
    long folderId = command.folderId;
    List<String> uids = command.uids;
    Backend backend = getBackend(account);
    String folderServerId = getFolderServerId(account, folderId);
    backend.deleteMessages(folderServerId, uids);
    if (backend.getSupportsExpunge() && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) {
        backend.expungeMessages(folderServerId, uids);
    }
    LocalStore localStore = localStoreProvider.getInstance(account);
    LocalFolder localFolder = localStore.getFolder(folderId);
    localFolder.open();
    destroyPlaceholderMessages(localFolder, uids);
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) Backend(com.fsck.k9.backend.api.Backend) LocalStore(com.fsck.k9.mailstore.LocalStore)

Aggregations

Backend (com.fsck.k9.backend.api.Backend)15 LocalFolder (com.fsck.k9.mailstore.LocalFolder)10 LocalStore (com.fsck.k9.mailstore.LocalStore)10 LocalMessage (com.fsck.k9.mailstore.LocalMessage)7 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)6 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)6 MessagingException (com.fsck.k9.mail.MessagingException)6 VisibleForTesting (androidx.annotation.VisibleForTesting)3 K9RobolectricTest (com.fsck.k9.K9RobolectricTest)3 ServerSettings (com.fsck.k9.mail.ServerSettings)3 Test (org.junit.Test)3 SuppressLint (android.annotation.SuppressLint)2 SyncConfig (com.fsck.k9.backend.api.SyncConfig)2 FetchProfile (com.fsck.k9.mail.FetchProfile)2 MessageStore (com.fsck.k9.mailstore.MessageStore)2 ArrayList (java.util.ArrayList)2 Account (com.fsck.k9.Account)1 PendingCommand (com.fsck.k9.controller.MessagingControllerCommands.PendingCommand)1 ExceptionHelper.getRootCauseMessage (com.fsck.k9.helper.ExceptionHelper.getRootCauseMessage)1 Message (com.fsck.k9.mail.Message)1