Search in sources :

Example 16 with LocalMessage

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

the class EmailProviderCache method unhideMessages.

public void unhideMessages(List<? extends Message> messages) {
    synchronized (mHiddenMessageCache) {
        for (Message message : messages) {
            LocalMessage localMessage = (LocalMessage) message;
            long messageId = localMessage.getId();
            long folderId = ((LocalFolder) localMessage.getFolder()).getId();
            Long hiddenInFolder = mHiddenMessageCache.get(messageId);
            if (hiddenInFolder != null && hiddenInFolder.longValue() == folderId) {
                mHiddenMessageCache.remove(messageId);
            }
        }
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) LocalMessage(com.fsck.k9.mailstore.LocalMessage) Message(com.fsck.k9.mail.Message)

Example 17 with LocalMessage

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

the class MessagingController method refreshLocalMessageFlags.

private void refreshLocalMessageFlags(final Account account, final Folder remoteFolder, final LocalFolder localFolder, List<Message> syncFlagMessages, final AtomicInteger progress, final int todo) throws MessagingException {
    final String folder = remoteFolder.getName();
    if (remoteFolder.supportsFetchingFlags()) {
        Timber.d("SYNC: About to sync flags for %d remote messages for folder %s", syncFlagMessages.size(), folder);
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.FLAGS);
        List<Message> undeletedMessages = new LinkedList<>();
        for (Message message : syncFlagMessages) {
            if (!message.isSet(Flag.DELETED)) {
                undeletedMessages.add(message);
            }
        }
        remoteFolder.fetch(undeletedMessages, fp, null);
        for (Message remoteMessage : syncFlagMessages) {
            LocalMessage localMessage = localFolder.getMessage(remoteMessage.getUid());
            boolean messageChanged = syncFlags(localMessage, remoteMessage);
            if (messageChanged) {
                boolean shouldBeNotifiedOf = false;
                if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(localMessage)) {
                    for (MessagingListener l : getListeners()) {
                        l.synchronizeMailboxRemovedMessage(account, folder, localMessage);
                    }
                } else {
                    if (shouldNotifyForMessage(account, localFolder, localMessage)) {
                        shouldBeNotifiedOf = true;
                    }
                }
                // we're only interested in messages that need removing
                if (!shouldBeNotifiedOf) {
                    MessageReference messageReference = localMessage.makeMessageReference();
                    notificationController.removeNewMailNotification(account, messageReference);
                }
            }
            progress.incrementAndGet();
            for (MessagingListener l : getListeners()) {
                l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
            }
        }
    }
}
Also used : LocalMessage(com.fsck.k9.mailstore.LocalMessage) 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) MessageReference(com.fsck.k9.activity.MessageReference) LinkedList(java.util.LinkedList)

Example 18 with LocalMessage

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

the class MessagingController method processPendingMoveOrCopy.

void processPendingMoveOrCopy(PendingMoveOrCopy command, Account account) throws MessagingException {
    Folder remoteSrcFolder = null;
    Folder remoteDestFolder = null;
    LocalFolder localDestFolder;
    try {
        String srcFolder = command.srcFolder;
        if (account.getErrorFolderName().equals(srcFolder)) {
            return;
        }
        String destFolder = command.destFolder;
        boolean isCopy = command.isCopy;
        Store remoteStore = account.getRemoteStore();
        remoteSrcFolder = remoteStore.getFolder(srcFolder);
        Store localStore = account.getLocalStore();
        localDestFolder = (LocalFolder) localStore.getFolder(destFolder);
        List<Message> messages = new ArrayList<>();
        Collection<String> uids = command.newUidMap != null ? command.newUidMap.keySet() : command.uids;
        for (String uid : uids) {
            if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
                messages.add(remoteSrcFolder.getMessage(uid));
            }
        }
        if (!remoteSrcFolder.exists()) {
            throw new MessagingException("processingPendingMoveOrCopy: remoteFolder " + srcFolder + " does not exist", true);
        }
        remoteSrcFolder.open(Folder.OPEN_MODE_RW);
        if (remoteSrcFolder.getMode() != Folder.OPEN_MODE_RW) {
            throw new MessagingException("processingPendingMoveOrCopy: could not open remoteSrcFolder " + srcFolder + " read/write", true);
        }
        Timber.d("processingPendingMoveOrCopy: source folder = %s, %d messages, destination folder = %s, " + "isCopy = %s", srcFolder, messages.size(), destFolder, isCopy);
        Map<String, String> remoteUidMap = null;
        if (!isCopy && destFolder.equals(account.getTrashFolderName())) {
            Timber.d("processingPendingMoveOrCopy doing special case for deleting message");
            String destFolderName = destFolder;
            if (K9.FOLDER_NONE.equals(destFolderName)) {
                destFolderName = null;
            }
            remoteSrcFolder.delete(messages, destFolderName);
        } else {
            remoteDestFolder = remoteStore.getFolder(destFolder);
            if (isCopy) {
                remoteUidMap = remoteSrcFolder.copyMessages(messages, remoteDestFolder);
            } else {
                remoteUidMap = remoteSrcFolder.moveMessages(messages, remoteDestFolder);
            }
        }
        if (!isCopy && Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
            Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder);
            remoteSrcFolder.expunge();
        }
        /*
             * This next part is used to bring the local UIDs of the local destination folder
             * upto speed with the remote UIDs of remote destination folder.
             */
        if (command.newUidMap != null && remoteUidMap != null && !remoteUidMap.isEmpty()) {
            for (Map.Entry<String, String> entry : remoteUidMap.entrySet()) {
                String remoteSrcUid = entry.getKey();
                String newUid = entry.getValue();
                String localDestUid = command.newUidMap.get(remoteSrcUid);
                if (localDestUid == null) {
                    continue;
                }
                Message localDestMessage = localDestFolder.getMessage(localDestUid);
                if (localDestMessage != null) {
                    localDestMessage.setUid(newUid);
                    localDestFolder.changeUid((LocalMessage) localDestMessage);
                    for (MessagingListener l : getListeners()) {
                        l.messageUidChanged(account, destFolder, localDestUid, newUid);
                    }
                }
            }
        }
    } finally {
        closeFolder(remoteSrcFolder);
        closeFolder(remoteDestFolder);
    }
}
Also used : 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) 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) LocalFolder(com.fsck.k9.mailstore.LocalFolder) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 19 with LocalMessage

use of com.fsck.k9.mailstore.LocalMessage 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.
     * TODO update the local message UID instead of deleting it
     */
void processPendingAppend(PendingAppend command, Account account) throws MessagingException {
    Folder remoteFolder = null;
    LocalFolder localFolder = null;
    try {
        String folder = command.folder;
        String uid = command.uid;
        if (account.getErrorFolderName().equals(folder)) {
            return;
        }
        LocalStore localStore = account.getLocalStore();
        localFolder = localStore.getFolder(folder);
        LocalMessage localMessage = localFolder.getMessage(uid);
        if (localMessage == null) {
            return;
        }
        Store remoteStore = account.getRemoteStore();
        remoteFolder = remoteStore.getFolder(folder);
        if (!remoteFolder.exists()) {
            if (!remoteFolder.create(FolderType.HOLDS_MESSAGES)) {
                return;
            }
        }
        remoteFolder.open(Folder.OPEN_MODE_RW);
        if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
            return;
        }
        Message remoteMessage = null;
        if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
            remoteMessage = remoteFolder.getMessage(localMessage.getUid());
        }
        if (remoteMessage == null) {
            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 rUid = remoteFolder.getUidFromMessageId(localMessage);
                if (rUid != 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, rUid);
                    String oldUid = localMessage.getUid();
                    localMessage.setUid(rUid);
                    localFolder.changeUid(localMessage);
                    for (MessagingListener l : getListeners()) {
                        l.messageUidChanged(account, folder, 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);
            remoteFolder.appendMessages(Collections.singletonList(localMessage));
            localFolder.changeUid(localMessage);
            for (MessagingListener l : getListeners()) {
                l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
            }
        } else {
            /*
                 * If the remote message exists we need to determine which copy to keep.
                 */
            /*
                 * See if the remote message is newer than ours.
                 */
            FetchProfile fp = new FetchProfile();
            fp.add(FetchProfile.Item.ENVELOPE);
            remoteFolder.fetch(Collections.singletonList(remoteMessage), fp, null);
            Date localDate = localMessage.getInternalDate();
            Date remoteDate = remoteMessage.getInternalDate();
            if (remoteDate != null && remoteDate.compareTo(localDate) > 0) {
                /*
                     * If the remote message is newer than ours we'll just
                     * delete ours and move on. A sync will get the server message
                     * if we need to be able to see it.
                     */
                localMessage.destroy();
            } else {
                /*
                     * Otherwise we'll upload our message and then delete the remote message.
                     */
                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);
                remoteFolder.appendMessages(Collections.singletonList(localMessage));
                localFolder.changeUid(localMessage);
                for (MessagingListener l : getListeners()) {
                    l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
                }
                if (remoteDate != null) {
                    remoteMessage.setFlag(Flag.DELETED, true);
                    if (Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
                        remoteFolder.expunge();
                    }
                }
            }
        }
    } finally {
        closeFolder(remoteFolder);
        closeFolder(localFolder);
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) LocalMessage(com.fsck.k9.mailstore.LocalMessage) 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) LocalStore(com.fsck.k9.mailstore.LocalStore) Store(com.fsck.k9.mail.Store) Pop3Store(com.fsck.k9.mail.store.pop3.Pop3Store) LocalStore(com.fsck.k9.mailstore.LocalStore) Folder(com.fsck.k9.mail.Folder) LocalFolder(com.fsck.k9.mailstore.LocalFolder) Date(java.util.Date)

Example 20 with LocalMessage

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

the class MessagingController method saveDraft.

/**
     * Save a draft message.
     *
     * @param account
     *         Account we are saving for.
     * @param message
     *         Message to save.
     *
     * @return Message representing the entry in the local store.
     */
public Message saveDraft(final Account account, final Message message, long existingDraftId, boolean saveRemotely) {
    Message localMessage = null;
    try {
        LocalStore localStore = account.getLocalStore();
        LocalFolder localFolder = localStore.getFolder(account.getDraftsFolderName());
        localFolder.open(Folder.OPEN_MODE_RW);
        if (existingDraftId != INVALID_MESSAGE_ID) {
            String uid = localFolder.getMessageUidById(existingDraftId);
            message.setUid(uid);
        }
        // Save the message to the store.
        localFolder.appendMessages(Collections.singletonList(message));
        // Fetch the message back from the store.  This is the Message that's returned to the caller.
        localMessage = localFolder.getMessage(message.getUid());
        localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
        if (saveRemotely) {
            PendingCommand command = PendingAppend.create(localFolder.getName(), localMessage.getUid());
            queuePendingCommand(account, command);
            processPendingCommands(account);
        }
    } catch (MessagingException e) {
        Timber.e(e, "Unable to save message as draft.");
        addErrorMessage(account, null, e);
    }
    return localMessage;
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) 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) LocalStore(com.fsck.k9.mailstore.LocalStore) PendingCommand(com.fsck.k9.controller.MessagingControllerCommands.PendingCommand)

Aggregations

LocalMessage (com.fsck.k9.mailstore.LocalMessage)42 Test (org.junit.Test)23 FetchProfile (com.fsck.k9.mail.FetchProfile)19 Message (com.fsck.k9.mail.Message)19 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)19 MessagingException (com.fsck.k9.mail.MessagingException)15 LocalFolder (com.fsck.k9.mailstore.LocalFolder)13 LocalStore (com.fsck.k9.mailstore.LocalStore)12 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)10 ArrayList (java.util.ArrayList)9 Notification (android.app.Notification)8 Part (com.fsck.k9.mail.Part)8 MessageReference (com.fsck.k9.activity.MessageReference)7 Multipart (com.fsck.k9.mail.Multipart)7 Date (java.util.Date)7 HashMap (java.util.HashMap)7 SuppressLint (android.annotation.SuppressLint)6 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)6 IOException (java.io.IOException)6 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)5