Search in sources :

Example 16 with Backend

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

the class MessagingController method deleteMessagesSynchronous.

private void deleteMessagesSynchronous(Account account, long folderId, List<LocalMessage> messages) {
    try {
        List<LocalMessage> localOnlyMessages = new ArrayList<>();
        List<LocalMessage> syncedMessages = new ArrayList<>();
        List<String> syncedMessageUids = new ArrayList<>();
        for (LocalMessage message : messages) {
            notificationController.removeNewMailNotification(account, message.makeMessageReference());
            String uid = message.getUid();
            if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
                localOnlyMessages.add(message);
            } else {
                syncedMessages.add(message);
                syncedMessageUids.add(uid);
            }
        }
        Backend backend = getBackend(account);
        LocalStore localStore = localStoreProvider.getInstance(account);
        LocalFolder localFolder = localStore.getFolder(folderId);
        localFolder.open();
        Map<String, String> uidMap = null;
        Long trashFolderId = account.getTrashFolderId();
        LocalFolder localTrashFolder = null;
        if (!account.hasTrashFolder() || folderId == trashFolderId || (backend.getSupportsTrashFolder() && !backend.isDeleteMoveToTrash())) {
            Timber.d("Not moving deleted messages to local Trash folder. Removing local copies.");
            if (!localOnlyMessages.isEmpty()) {
                localFolder.destroyMessages(localOnlyMessages);
            }
            if (!syncedMessages.isEmpty()) {
                localFolder.setFlags(syncedMessages, Collections.singleton(Flag.DELETED), true);
            }
        } else {
            Timber.d("Deleting messages in normal folder, moving");
            localTrashFolder = localStore.getFolder(trashFolderId);
            MessageStore messageStore = messageStoreManager.getMessageStore(account);
            List<Long> messageIds = new ArrayList<>();
            Map<Long, String> messageIdToUidMapping = new HashMap<>();
            for (LocalMessage message : messages) {
                long messageId = message.getDatabaseId();
                messageIds.add(messageId);
                messageIdToUidMapping.put(messageId, message.getUid());
            }
            Map<Long, Long> moveMessageIdMapping = messageStore.moveMessages(messageIds, trashFolderId);
            Map<Long, String> destinationMapping = messageStore.getMessageServerIds(moveMessageIdMapping.values());
            uidMap = new HashMap<>();
            for (Entry<Long, Long> entry : moveMessageIdMapping.entrySet()) {
                long sourceMessageId = entry.getKey();
                long destinationMessageId = entry.getValue();
                String sourceUid = messageIdToUidMapping.get(sourceMessageId);
                String destinationUid = destinationMapping.get(destinationMessageId);
                uidMap.put(sourceUid, destinationUid);
            }
            if (account.isMarkMessageAsReadOnDelete()) {
                Collection<Long> destinationMessageIds = moveMessageIdMapping.values();
                messageStore.setFlag(destinationMessageIds, Flag.SEEN, true);
            }
        }
        for (MessagingListener l : getListeners()) {
            l.folderStatusChanged(account, folderId);
            if (localTrashFolder != null) {
                l.folderStatusChanged(account, trashFolderId);
            }
        }
        Timber.d("Delete policy for account %s is %s", account, account.getDeletePolicy());
        Long outboxFolderId = account.getOutboxFolderId();
        if (outboxFolderId != null && folderId == outboxFolderId && supportsUpload(account)) {
            for (String destinationUid : uidMap.values()) {
                // If the message was in the Outbox, then it has been copied to local Trash, and has
                // to be copied to remote trash
                PendingCommand command = PendingAppend.create(trashFolderId, destinationUid);
                queuePendingCommand(account, command);
            }
            processPendingCommands(account);
        } else if (localFolder.isLocalOnly()) {
        // Nothing to do on the remote side
        } else if (!syncedMessageUids.isEmpty()) {
            if (account.getDeletePolicy() == DeletePolicy.ON_DELETE) {
                if (!account.hasTrashFolder() || folderId == trashFolderId || !backend.isDeleteMoveToTrash()) {
                    queueDelete(account, folderId, syncedMessageUids);
                } else if (account.isMarkMessageAsReadOnDelete()) {
                    queueMoveOrCopy(account, folderId, trashFolderId, MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ, uidMap);
                } else {
                    queueMoveOrCopy(account, folderId, trashFolderId, MoveOrCopyFlavor.MOVE, uidMap);
                }
                processPendingCommands(account);
            } else if (account.getDeletePolicy() == DeletePolicy.MARK_AS_READ) {
                queueSetFlag(account, localFolder.getDatabaseId(), true, Flag.SEEN, syncedMessageUids);
                processPendingCommands(account);
            } else {
                Timber.d("Delete policy %s prevents delete from server", account.getDeletePolicy());
            }
        }
        unsuppressMessages(account, messages);
    } catch (MessagingException me) {
        throw new RuntimeException("Error deleting message from local store.", me);
    }
}
Also used : MessageStore(com.fsck.k9.mailstore.MessageStore) LocalMessage(com.fsck.k9.mailstore.LocalMessage) HashMap(java.util.HashMap) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) LocalFolder(com.fsck.k9.mailstore.LocalFolder) Backend(com.fsck.k9.backend.api.Backend) PendingCommand(com.fsck.k9.controller.MessagingControllerCommands.PendingCommand)

Example 17 with Backend

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

the class MessagingController method processPendingMarkAllAsRead.

void processPendingMarkAllAsRead(PendingMarkAllAsRead command, Account account) throws MessagingException {
    long folderId = command.folderId;
    LocalStore localStore = localStoreProvider.getInstance(account);
    LocalFolder localFolder = localStore.getFolder(folderId);
    localFolder.open();
    String folderServerId = localFolder.getServerId();
    Timber.i("Marking all messages in %s:%s as read", account, folderServerId);
    // TODO: Make this one database UPDATE operation
    List<LocalMessage> messages = localFolder.getMessages(null, false);
    for (Message message : messages) {
        if (!message.isSet(Flag.SEEN)) {
            message.setFlag(Flag.SEEN, true);
        }
    }
    for (MessagingListener l : getListeners()) {
        l.folderStatusChanged(account, folderId);
    }
    Backend backend = getBackend(account);
    if (backend.getSupportsFlags()) {
        backend.markAllAsRead(folderServerId);
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) Backend(com.fsck.k9.backend.api.Backend) LocalMessage(com.fsck.k9.mailstore.LocalMessage) ExceptionHelper.getRootCauseMessage(com.fsck.k9.helper.ExceptionHelper.getRootCauseMessage) Message(com.fsck.k9.mail.Message) LocalStore(com.fsck.k9.mailstore.LocalStore)

Example 18 with Backend

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

the class MessagingControllerTest method sendPendingMessagesSynchronous_withCertificateFailure_shouldNotify.

@Test
public void sendPendingMessagesSynchronous_withCertificateFailure_shouldNotify() throws MessagingException {
    setupAccountWithMessageToSend();
    doThrow(new CertificateValidationException("Test")).when(backend).sendMessage(localMessageToSend1);
    controller.sendPendingMessagesSynchronous(account);
    verify(notificationController).showCertificateErrorNotification(account, false);
}
Also used : CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) K9RobolectricTest(com.fsck.k9.K9RobolectricTest) Test(org.junit.Test)

Example 19 with Backend

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

the class MessagingControllerTest method sendPendingMessagesSynchronous_withAuthenticationFailure_shouldNotify.

@Test
public void sendPendingMessagesSynchronous_withAuthenticationFailure_shouldNotify() throws MessagingException {
    setupAccountWithMessageToSend();
    doThrow(new AuthenticationFailedException("Test")).when(backend).sendMessage(localMessageToSend1);
    controller.sendPendingMessagesSynchronous(account);
    verify(notificationController).showAuthenticationErrorNotification(account, false);
}
Also used : AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) K9RobolectricTest(com.fsck.k9.K9RobolectricTest) Test(org.junit.Test)

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