Search in sources :

Example 81 with LocalFolder

use of com.fsck.k9.mailstore.LocalFolder 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 82 with LocalFolder

use of com.fsck.k9.mailstore.LocalFolder 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 83 with LocalFolder

use of com.fsck.k9.mailstore.LocalFolder in project k-9 by k9mail.

the class MessagingController method moveOrCopyMessageSynchronous.

private void moveOrCopyMessageSynchronous(Account account, long srcFolderId, List<LocalMessage> inMessages, long destFolderId, MoveOrCopyFlavor operation) {
    if (operation == MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ) {
        throw new UnsupportedOperationException("MOVE_AND_MARK_AS_READ unsupported");
    }
    try {
        LocalStore localStore = localStoreProvider.getInstance(account);
        if (operation == MoveOrCopyFlavor.MOVE && !isMoveCapable(account)) {
            return;
        }
        if (operation == MoveOrCopyFlavor.COPY && !isCopyCapable(account)) {
            return;
        }
        LocalFolder localSrcFolder = localStore.getFolder(srcFolderId);
        localSrcFolder.open();
        LocalFolder localDestFolder = localStore.getFolder(destFolderId);
        localDestFolder.open();
        boolean unreadCountAffected = false;
        List<String> uids = new LinkedList<>();
        for (Message message : inMessages) {
            String uid = message.getUid();
            if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
                uids.add(uid);
            }
            if (!unreadCountAffected && !message.isSet(Flag.SEEN)) {
                unreadCountAffected = true;
            }
        }
        List<LocalMessage> messages = localSrcFolder.getMessagesByUids(uids);
        if (messages.size() > 0) {
            Timber.i("moveOrCopyMessageSynchronous: source folder = %s, %d messages, destination folder = %s, " + "operation = %s", srcFolderId, messages.size(), destFolderId, operation.name());
            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> resultIdMapping;
            if (operation == MoveOrCopyFlavor.COPY) {
                resultIdMapping = messageStore.copyMessages(messageIds, destFolderId);
                if (unreadCountAffected) {
                    // folder, notify the listeners.
                    for (MessagingListener l : getListeners()) {
                        l.folderStatusChanged(account, destFolderId);
                    }
                }
            } else {
                resultIdMapping = messageStore.moveMessages(messageIds, destFolderId);
                unsuppressMessages(account, messages);
                if (unreadCountAffected) {
                    // that the unread count changed in both the source and destination folder.
                    for (MessagingListener l : getListeners()) {
                        l.folderStatusChanged(account, srcFolderId);
                        l.folderStatusChanged(account, destFolderId);
                    }
                }
            }
            Map<Long, String> destinationMapping = messageStore.getMessageServerIds(resultIdMapping.values());
            Map<String, String> uidMap = new HashMap<>();
            for (Entry<Long, Long> entry : resultIdMapping.entrySet()) {
                long sourceMessageId = entry.getKey();
                long destinationMessageId = entry.getValue();
                String sourceUid = messageIdToUidMapping.get(sourceMessageId);
                String destinationUid = destinationMapping.get(destinationMessageId);
                uidMap.put(sourceUid, destinationUid);
            }
            queueMoveOrCopy(account, localSrcFolder.getDatabaseId(), localDestFolder.getDatabaseId(), operation, uidMap);
        }
        processPendingCommands(account);
    } catch (MessagingException me) {
        throw new RuntimeException("Error moving message", me);
    }
}
Also used : MessageStore(com.fsck.k9.mailstore.MessageStore) LocalMessage(com.fsck.k9.mailstore.LocalMessage) LocalMessage(com.fsck.k9.mailstore.LocalMessage) ExceptionHelper.getRootCauseMessage(com.fsck.k9.helper.ExceptionHelper.getRootCauseMessage) Message(com.fsck.k9.mail.Message) HashMap(java.util.HashMap) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) LinkedList(java.util.LinkedList) LocalFolder(com.fsck.k9.mailstore.LocalFolder)

Example 84 with LocalFolder

use of com.fsck.k9.mailstore.LocalFolder in project k-9 by k9mail.

the class LocalFolder method getMessagesByReference.

public List<LocalMessage> getMessagesByReference(@NonNull List<MessageReference> messageReferences) throws MessagingException {
    open();
    String accountUuid = getAccountUuid();
    long folderId = getDatabaseId();
    List<LocalMessage> messages = new ArrayList<>();
    for (MessageReference messageReference : messageReferences) {
        if (!accountUuid.equals(messageReference.getAccountUuid())) {
            throw new IllegalArgumentException("all message references must belong to this Account!");
        }
        if (folderId != messageReference.getFolderId()) {
            throw new IllegalArgumentException("all message references must belong to this LocalFolder!");
        }
        LocalMessage message = getMessage(messageReference.getUid());
        if (message != null) {
            messages.add(message);
        }
    }
    return messages;
}
Also used : ArrayList(java.util.ArrayList) MessageReference(com.fsck.k9.controller.MessageReference)

Example 85 with LocalFolder

use of com.fsck.k9.mailstore.LocalFolder in project k-9 by k9mail.

the class LocalStore method loadLocalMessageByMessageId.

@Nullable
private LocalMessage loadLocalMessageByMessageId(long messageId) throws MessagingException {
    Map<Long, List<String>> folderIdsAndUids = getFolderIdsAndUids(Collections.singletonList(messageId), false);
    if (folderIdsAndUids.isEmpty()) {
        return null;
    }
    Map.Entry<Long, List<String>> entry = folderIdsAndUids.entrySet().iterator().next();
    long folderId = entry.getKey();
    String uid = entry.getValue().get(0);
    LocalFolder folder = getFolder(folderId);
    LocalMessage localMessage = folder.getMessage(uid);
    FetchProfile fp = new FetchProfile();
    fp.add(Item.BODY);
    folder.fetch(Collections.singletonList(localMessage), fp, null);
    return localMessage;
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Map(java.util.Map) HashMap(java.util.HashMap) Nullable(androidx.annotation.Nullable)

Aggregations

LocalFolder (com.fsck.k9.mailstore.LocalFolder)62 LocalStore (com.fsck.k9.mailstore.LocalStore)47 MessagingException (com.fsck.k9.mail.MessagingException)44 LocalMessage (com.fsck.k9.mailstore.LocalMessage)40 Message (com.fsck.k9.mail.Message)20 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)20 Folder (com.fsck.k9.mail.Folder)17 FetchProfile (com.fsck.k9.mail.FetchProfile)15 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)13 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)13 ArrayList (java.util.ArrayList)13 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)11 SuppressLint (android.annotation.SuppressLint)10 Backend (com.fsck.k9.backend.api.Backend)10 Store (com.fsck.k9.mail.Store)10 Pop3Store (com.fsck.k9.mail.store.pop3.Pop3Store)10 IOException (java.io.IOException)9 Date (java.util.Date)9 Test (org.junit.Test)9 Account (com.fsck.k9.Account)7