Search in sources :

Example 1 with Backend

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

the class MessagingController method loadMessageRemoteSynchronous.

private void loadMessageRemoteSynchronous(Account account, long folderId, String uid, MessagingListener listener, boolean loadPartialFromSearch) {
    try {
        LocalStore localStore = localStoreProvider.getInstance(account);
        LocalFolder localFolder = localStore.getFolder(folderId);
        localFolder.open();
        String folderServerId = localFolder.getServerId();
        LocalMessage message = localFolder.getMessage(uid);
        if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
            Timber.w("Message has local UID so cannot download fully.");
            // ASH move toast
            android.widget.Toast.makeText(context, "Message has local UID so cannot download fully", android.widget.Toast.LENGTH_LONG).show();
            // TODO: Using X_DOWNLOADED_FULL is wrong because it's only a partial message. But
            // one we can't download completely. Maybe add a new flag; X_PARTIAL_MESSAGE ?
            message.setFlag(Flag.X_DOWNLOADED_FULL, true);
            message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
        } else {
            Backend backend = getBackend(account);
            if (loadPartialFromSearch) {
                SyncConfig syncConfig = createSyncConfig(account);
                backend.downloadMessage(syncConfig, folderServerId, uid);
            } else {
                backend.downloadCompleteMessage(folderServerId, uid);
            }
            message = localFolder.getMessage(uid);
            if (!loadPartialFromSearch) {
                message.setFlag(Flag.X_DOWNLOADED_FULL, true);
            }
        }
        // now that we have the full message, refresh the headers
        for (MessagingListener l : getListeners(listener)) {
            l.loadMessageRemoteFinished(account, folderId, uid);
        }
    } catch (Exception e) {
        for (MessagingListener l : getListeners(listener)) {
            l.loadMessageRemoteFailed(account, folderId, uid, e);
        }
        notifyUserIfCertificateProblem(account, e, true);
        Timber.e(e, "Error while loading remote message");
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) Backend(com.fsck.k9.backend.api.Backend) LocalStore(com.fsck.k9.mailstore.LocalStore) SyncConfig(com.fsck.k9.backend.api.SyncConfig) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Example 2 with Backend

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

the class MessagingController method processPendingAppend.

/**
 * Process a pending append message command. This command uploads a local message to the
 * server, first checking to be sure that the server message is not newer than
 * the local message. Once the local message is successfully processed it is deleted so
 * that the server message will be synchronized down without an additional copy being
 * created.
 */
void processPendingAppend(PendingAppend command, Account account) throws MessagingException {
    LocalStore localStore = localStoreProvider.getInstance(account);
    long folderId = command.folderId;
    LocalFolder localFolder = localStore.getFolder(folderId);
    localFolder.open();
    String folderServerId = localFolder.getServerId();
    String uid = command.uid;
    LocalMessage localMessage = localFolder.getMessage(uid);
    if (localMessage == null) {
        return;
    }
    if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
        // FIXME: This should never happen. Throw in debug builds.
        return;
    }
    Backend backend = getBackend(account);
    if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED)) {
        Timber.w("Local message with uid %s has flag %s  already set, checking for remote message with " + "same message id", localMessage.getUid(), X_REMOTE_COPY_STARTED);
        String messageServerId = backend.findByMessageId(folderServerId, localMessage.getMessageId());
        if (messageServerId != null) {
            Timber.w("Local message has flag %s already set, and there is a remote message with uid %s, " + "assuming message was already copied and aborting this copy", X_REMOTE_COPY_STARTED, messageServerId);
            String oldUid = localMessage.getUid();
            localMessage.setUid(messageServerId);
            localFolder.changeUid(localMessage);
            for (MessagingListener l : getListeners()) {
                l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
            }
            return;
        } else {
            Timber.w("No remote message with message-id found, proceeding with append");
        }
    }
    /*
         * If the message does not exist remotely we just upload it and then
         * update our local copy with the new uid.
         */
    FetchProfile fp = new FetchProfile();
    fp.add(FetchProfile.Item.BODY);
    localFolder.fetch(Collections.singletonList(localMessage), fp, null);
    String oldUid = localMessage.getUid();
    localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
    String messageServerId = backend.uploadMessage(folderServerId, localMessage);
    if (messageServerId == null) {
        // We didn't get the server UID of the uploaded message. Remove the local message now. The uploaded
        // version will be downloaded during the next sync.
        localFolder.destroyMessages(Collections.singletonList(localMessage));
    } else {
        localMessage.setUid(messageServerId);
        localFolder.changeUid(localMessage);
        for (MessagingListener l : getListeners()) {
            l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
        }
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) Backend(com.fsck.k9.backend.api.Backend) FetchProfile(com.fsck.k9.mail.FetchProfile) LocalStore(com.fsck.k9.mailstore.LocalStore)

Example 3 with Backend

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

the class MessagingController method processPendingExpunge.

void processPendingExpunge(PendingExpunge command, Account account) throws MessagingException {
    Backend backend = getBackend(account);
    String folderServerId = getFolderServerId(account, command.folderId);
    backend.expunge(folderServerId);
}
Also used : Backend(com.fsck.k9.backend.api.Backend)

Example 4 with Backend

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

the class MessagingController method syncFolder.

private void syncFolder(Account account, long folderId, boolean notify, MessagingListener listener, Backend backend, NotificationState notificationState) {
    ServerSettings serverSettings = account.getIncomingServerSettings();
    if (serverSettings.isMissingCredentials()) {
        handleAuthenticationFailure(account, true);
        return;
    }
    Exception commandException = null;
    try {
        processPendingCommandsSynchronous(account);
    } catch (Exception e) {
        Timber.e(e, "Failure processing command, but allow message sync attempt");
        commandException = e;
    }
    LocalFolder localFolder;
    try {
        LocalStore localStore = localStoreProvider.getInstance(account);
        localFolder = localStore.getFolder(folderId);
        localFolder.open();
    } catch (MessagingException e) {
        Timber.e(e, "syncFolder: Couldn't load local folder %d", folderId);
        return;
    }
    // We can't sync local folders
    if (localFolder.isLocalOnly()) {
        return;
    }
    final boolean suppressNotifications;
    if (notify) {
        MessageStore messageStore = messageStoreManager.getMessageStore(account);
        Long lastChecked = messageStore.getFolder(folderId, FolderDetailsAccessor::getLastChecked);
        suppressNotifications = lastChecked == null;
    } else {
        suppressNotifications = true;
    }
    String folderServerId = localFolder.getServerId();
    SyncConfig syncConfig = createSyncConfig(account);
    ControllerSyncListener syncListener = new ControllerSyncListener(account, listener, suppressNotifications, notificationState);
    backend.sync(folderServerId, syncConfig, syncListener);
    if (commandException != null && !syncListener.syncFailed) {
        String rootMessage = getRootCauseMessage(commandException);
        Timber.e("Root cause failure in %s:%s was '%s'", account, folderServerId, rootMessage);
        updateFolderStatus(account, folderServerId, rootMessage);
        listener.synchronizeMailboxFailed(account, folderId, rootMessage);
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) MessageStore(com.fsck.k9.mailstore.MessageStore) MessagingException(com.fsck.k9.mail.MessagingException) FolderDetailsAccessor(com.fsck.k9.mailstore.FolderDetailsAccessor) ServerSettings(com.fsck.k9.mail.ServerSettings) LocalStore(com.fsck.k9.mailstore.LocalStore) SyncConfig(com.fsck.k9.backend.api.SyncConfig) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Example 5 with Backend

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

the class MessagingController method searchRemoteMessagesSynchronous.

@VisibleForTesting
void searchRemoteMessagesSynchronous(String acctUuid, long folderId, String query, Set<Flag> requiredFlags, Set<Flag> forbiddenFlags, MessagingListener listener) {
    Account account = preferences.getAccount(acctUuid);
    if (listener != null) {
        listener.remoteSearchStarted(folderId);
    }
    List<String> extraResults = new ArrayList<>();
    try {
        LocalStore localStore = localStoreProvider.getInstance(account);
        LocalFolder localFolder = localStore.getFolder(folderId);
        if (!localFolder.exists()) {
            throw new MessagingException("Folder not found");
        }
        localFolder.open();
        String folderServerId = localFolder.getServerId();
        Backend backend = getBackend(account);
        boolean performFullTextSearch = account.isRemoteSearchFullText();
        List<String> messageServerIds = backend.search(folderServerId, query, requiredFlags, forbiddenFlags, performFullTextSearch);
        Timber.i("Remote search got %d results", messageServerIds.size());
        // There's no need to fetch messages already completely downloaded
        messageServerIds = localFolder.extractNewMessages(messageServerIds);
        if (listener != null) {
            listener.remoteSearchServerQueryComplete(folderId, messageServerIds.size(), account.getRemoteSearchNumResults());
        }
        int resultLimit = account.getRemoteSearchNumResults();
        if (resultLimit > 0 && messageServerIds.size() > resultLimit) {
            extraResults = messageServerIds.subList(resultLimit, messageServerIds.size());
            messageServerIds = messageServerIds.subList(0, resultLimit);
        }
        loadSearchResultsSynchronous(account, messageServerIds, localFolder);
    } catch (Exception e) {
        if (Thread.currentThread().isInterrupted()) {
            Timber.i(e, "Caught exception on aborted remote search; safe to ignore.");
        } else {
            Timber.e(e, "Could not complete remote search");
            if (listener != null) {
                listener.remoteSearchFailed(null, e.getMessage());
            }
            Timber.e(e);
        }
    } finally {
        if (listener != null) {
            listener.remoteSearchFinished(folderId, 0, account.getRemoteSearchNumResults(), extraResults);
        }
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) Backend(com.fsck.k9.backend.api.Backend) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) SuppressLint(android.annotation.SuppressLint) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) VisibleForTesting(androidx.annotation.VisibleForTesting)

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