Search in sources :

Example 26 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method setupPushing.

public boolean setupPushing(final Account account) {
    try {
        Pusher previousPusher = pushers.remove(account);
        if (previousPusher != null) {
            previousPusher.stop();
        }
        Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
        Account.FolderMode aPushMode = account.getFolderPushMode();
        List<String> names = new ArrayList<>();
        Store localStore = account.getLocalStore();
        for (final Folder folder : localStore.getPersonalNamespaces(false)) {
            if (folder.getName().equals(account.getErrorFolderName()) || folder.getName().equals(account.getOutboxFolderName())) {
                continue;
            }
            folder.open(Folder.OPEN_MODE_RW);
            Folder.FolderClass fDisplayClass = folder.getDisplayClass();
            Folder.FolderClass fPushClass = folder.getPushClass();
            if (modeMismatch(aDisplayMode, fDisplayClass)) {
                continue;
            }
            if (modeMismatch(aPushMode, fPushClass)) {
                continue;
            }
            Timber.i("Starting pusher for %s:%s", account.getDescription(), folder.getName());
            names.add(folder.getName());
        }
        if (!names.isEmpty()) {
            PushReceiver receiver = new MessagingControllerPushReceiver(context, account, this);
            int maxPushFolders = account.getMaxPushFolders();
            if (names.size() > maxPushFolders) {
                Timber.i("Count of folders to push for account %s is %d, greater than limit of %d, truncating", account.getDescription(), names.size(), maxPushFolders);
                names = names.subList(0, maxPushFolders);
            }
            try {
                Store store = account.getRemoteStore();
                if (!store.isPushCapable()) {
                    Timber.i("Account %s is not push capable, skipping", account.getDescription());
                    return false;
                }
                Pusher pusher = store.getPusher(receiver);
                if (pusher != null) {
                    Pusher oldPusher = pushers.putIfAbsent(account, pusher);
                    if (oldPusher == null) {
                        pusher.start(names);
                    }
                }
            } catch (Exception e) {
                Timber.e(e, "Could not get remote store");
                return false;
            }
            return true;
        } else {
            Timber.i("No folders are configured for pushing in account %s", account.getDescription());
            return false;
        }
    } catch (Exception e) {
        Timber.e(e, "Got exception while setting up pushing");
    }
    return false;
}
Also used : SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) 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) Pusher(com.fsck.k9.mail.Pusher) SuppressLint(android.annotation.SuppressLint) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) PushReceiver(com.fsck.k9.mail.PushReceiver)

Example 27 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method searchRemoteMessagesSynchronous.

@VisibleForTesting
void searchRemoteMessagesSynchronous(final String acctUuid, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) {
    final Account acct = Preferences.getPreferences(context).getAccount(acctUuid);
    if (listener != null) {
        listener.remoteSearchStarted(folderName);
    }
    List<Message> extraResults = new ArrayList<>();
    try {
        Store remoteStore = acct.getRemoteStore();
        LocalStore localStore = acct.getLocalStore();
        if (remoteStore == null || localStore == null) {
            throw new MessagingException("Could not get store");
        }
        Folder remoteFolder = remoteStore.getFolder(folderName);
        LocalFolder localFolder = localStore.getFolder(folderName);
        if (remoteFolder == null || localFolder == null) {
            throw new MessagingException("Folder not found");
        }
        List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags);
        Timber.i("Remote search got %d results", messages.size());
        // There's no need to fetch messages already completely downloaded
        List<Message> remoteMessages = localFolder.extractNewMessages(messages);
        messages.clear();
        if (listener != null) {
            listener.remoteSearchServerQueryComplete(folderName, remoteMessages.size(), acct.getRemoteSearchNumResults());
        }
        Collections.sort(remoteMessages, new UidReverseComparator());
        int resultLimit = acct.getRemoteSearchNumResults();
        if (resultLimit > 0 && remoteMessages.size() > resultLimit) {
            extraResults = remoteMessages.subList(resultLimit, remoteMessages.size());
            remoteMessages = remoteMessages.subList(0, resultLimit);
        }
        loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener);
    } 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());
            }
            addErrorMessage(acct, null, e);
        }
    } finally {
        if (listener != null) {
            listener.remoteSearchFinished(folderName, 0, acct.getRemoteSearchNumResults(), extraResults);
        }
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) 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) LocalStore(com.fsck.k9.mailstore.LocalStore) Folder(com.fsck.k9.mail.Folder) LocalFolder(com.fsck.k9.mailstore.LocalFolder) SuppressLint(android.annotation.SuppressLint) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 28 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class MessagingController method loadMessageRemoteSynchronous.

private boolean loadMessageRemoteSynchronous(final Account account, final String folder, final String uid, final MessagingListener listener, final boolean loadPartialFromSearch) {
    Folder remoteFolder = null;
    LocalFolder localFolder = null;
    try {
        LocalStore localStore = account.getLocalStore();
        localFolder = localStore.getFolder(folder);
        localFolder.open(Folder.OPEN_MODE_RW);
        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);
        }
        /* commented out because this was pulled from another unmerged branch:
            } else if (localFolder.isLocalOnly() && !force) {
                Log.w(K9.LOG_TAG, "Message in local-only folder so cannot download fully.");
                // ASH move toast
                android.widget.Toast.makeText(mApplication,
                        "Message in local-only folder so cannot download fully",
                        android.widget.Toast.LENGTH_LONG).show();
                message.setFlag(Flag.X_DOWNLOADED_FULL, true);
                message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
            }*/
        /*if (!message.isSet(Flag.X_DOWNLOADED_FULL)) */
        {
            /*
                 * At this point the message is not available, so we need to download it
                 * fully if possible.
                 */
            Store remoteStore = account.getRemoteStore();
            remoteFolder = remoteStore.getFolder(folder);
            remoteFolder.open(Folder.OPEN_MODE_RW);
            // Get the remote message and fully download it
            Message remoteMessage = remoteFolder.getMessage(uid);
            if (loadPartialFromSearch) {
                downloadMessages(account, remoteFolder, localFolder, Collections.singletonList(remoteMessage), false, false);
            } else {
                FetchProfile fp = new FetchProfile();
                fp.add(FetchProfile.Item.BODY);
                remoteFolder.fetch(Collections.singletonList(remoteMessage), fp, null);
                localFolder.appendMessages(Collections.singletonList(remoteMessage));
            }
            message = localFolder.getMessage(uid);
            if (!loadPartialFromSearch) {
                message.setFlag(Flag.X_DOWNLOADED_FULL, true);
            }
        }
        // Mark that this message is now fully synched
        if (account.isMarkMessageAsReadOnView()) {
            message.setFlag(Flag.SEEN, true);
        }
        // now that we have the full message, refresh the headers
        for (MessagingListener l : getListeners(listener)) {
            l.loadMessageRemoteFinished(account, folder, uid);
        }
        return true;
    } catch (Exception e) {
        for (MessagingListener l : getListeners(listener)) {
            l.loadMessageRemoteFailed(account, folder, uid, e);
        }
        notifyUserIfCertificateProblem(account, e, true);
        addErrorMessage(account, null, e);
        return false;
    } 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) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Example 29 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class LocalFolder method saveMessage.

protected void saveMessage(SQLiteDatabase db, Message message, boolean copy, Map<String, String> uidMap) throws MessagingException {
    if (!(message instanceof MimeMessage)) {
        throw new Error("LocalStore can only store Messages that extend MimeMessage");
    }
    long oldMessageId = -1;
    String uid = message.getUid();
    boolean shouldCreateNewMessage = uid == null || copy;
    if (shouldCreateNewMessage) {
        String randomLocalUid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
        if (copy) {
            // Save mapping: source UID -> target UID
            uidMap.put(uid, randomLocalUid);
        } else {
            // Modify the Message instance to reference the new UID
            message.setUid(randomLocalUid);
        }
        // The message will be saved with the newly generated UID
        uid = randomLocalUid;
    } else {
        LocalMessage oldMessage = getMessage(uid);
        if (oldMessage != null) {
            oldMessageId = oldMessage.getId();
            long oldRootMessagePartId = oldMessage.getMessagePartId();
            deleteMessagePartsAndDataFromDisk(oldRootMessagePartId);
        }
    }
    long rootId = -1;
    long parentId = -1;
    long msgId;
    if (oldMessageId == -1) {
        // This is a new message. Do the message threading.
        ThreadInfo threadInfo = doMessageThreading(db, message);
        oldMessageId = threadInfo.msgId;
        rootId = threadInfo.rootId;
        parentId = threadInfo.parentId;
    }
    try {
        MessagePreviewCreator previewCreator = localStore.getMessagePreviewCreator();
        PreviewResult previewResult = previewCreator.createPreview(message);
        PreviewType previewType = previewResult.getPreviewType();
        DatabasePreviewType databasePreviewType = DatabasePreviewType.fromPreviewType(previewType);
        MessageFulltextCreator fulltextCreator = localStore.getMessageFulltextCreator();
        String fulltext = fulltextCreator.createFulltext(message);
        AttachmentCounter attachmentCounter = localStore.getAttachmentCounter();
        int attachmentCount = attachmentCounter.getAttachmentCount(message);
        long rootMessagePartId = saveMessageParts(db, message);
        ContentValues cv = new ContentValues();
        cv.put("message_part_id", rootMessagePartId);
        cv.put("uid", uid);
        cv.put("subject", message.getSubject());
        cv.put("sender_list", Address.pack(message.getFrom()));
        cv.put("date", message.getSentDate() == null ? System.currentTimeMillis() : message.getSentDate().getTime());
        cv.put("flags", this.localStore.serializeFlags(message.getFlags()));
        cv.put("deleted", message.isSet(Flag.DELETED) ? 1 : 0);
        cv.put("read", message.isSet(Flag.SEEN) ? 1 : 0);
        cv.put("flagged", message.isSet(Flag.FLAGGED) ? 1 : 0);
        cv.put("answered", message.isSet(Flag.ANSWERED) ? 1 : 0);
        cv.put("forwarded", message.isSet(Flag.FORWARDED) ? 1 : 0);
        cv.put("folder_id", mFolderId);
        cv.put("to_list", Address.pack(message.getRecipients(RecipientType.TO)));
        cv.put("cc_list", Address.pack(message.getRecipients(RecipientType.CC)));
        cv.put("bcc_list", Address.pack(message.getRecipients(RecipientType.BCC)));
        cv.put("reply_to_list", Address.pack(message.getReplyTo()));
        cv.put("attachment_count", attachmentCount);
        cv.put("internal_date", message.getInternalDate() == null ? System.currentTimeMillis() : message.getInternalDate().getTime());
        cv.put("mime_type", message.getMimeType());
        cv.put("empty", 0);
        cv.put("preview_type", databasePreviewType.getDatabaseValue());
        if (previewResult.isPreviewTextAvailable()) {
            cv.put("preview", previewResult.getPreviewText());
        } else {
            cv.putNull("preview");
        }
        String messageId = message.getMessageId();
        if (messageId != null) {
            cv.put("message_id", messageId);
        }
        if (oldMessageId == -1) {
            msgId = db.insert("messages", "uid", cv);
            // Create entry in 'threads' table
            cv.clear();
            cv.put("message_id", msgId);
            if (rootId != -1) {
                cv.put("root", rootId);
            }
            if (parentId != -1) {
                cv.put("parent", parentId);
            }
            db.insert("threads", null, cv);
        } else {
            msgId = oldMessageId;
            db.update("messages", cv, "id = ?", new String[] { Long.toString(oldMessageId) });
        }
        if (fulltext != null) {
            cv.clear();
            cv.put("docid", msgId);
            cv.put("fulltext", fulltext);
            db.replace("messages_fulltext", null, cv);
        }
    } catch (Exception e) {
        throw new MessagingException("Error appending message: " + message.getSubject(), e);
    }
}
Also used : ContentValues(android.content.ContentValues) MessageFulltextCreator(com.fsck.k9.message.extractors.MessageFulltextCreator) MessagingException(com.fsck.k9.mail.MessagingException) AttachmentCounter(com.fsck.k9.message.extractors.AttachmentCounter) PreviewResult(com.fsck.k9.message.extractors.PreviewResult) MessagePreviewCreator(com.fsck.k9.message.extractors.MessagePreviewCreator) WrappedException(com.fsck.k9.mailstore.LockableDatabase.WrappedException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) PreviewType(com.fsck.k9.message.extractors.PreviewResult.PreviewType) MimeMessage(com.fsck.k9.mail.internet.MimeMessage)

Example 30 with Store

use of com.fsck.k9.mail.Store in project k-9 by k9mail.

the class LockableDatabase method switchProvider.

/**
     * @param newProviderId
     *            Never <code>null</code>.
     * @throws MessagingException
     */
public void switchProvider(final String newProviderId) throws MessagingException {
    if (newProviderId.equals(mStorageProviderId)) {
        Timber.v("LockableDatabase: Ignoring provider switch request as they are equal: %s", newProviderId);
        return;
    }
    final String oldProviderId = mStorageProviderId;
    lockWrite(oldProviderId);
    try {
        lockWrite(newProviderId);
        try {
            try {
                mDb.close();
            } catch (Exception e) {
                Timber.i(e, "Unable to close DB on local store migration");
            }
            final StorageManager storageManager = getStorageManager();
            File oldDatabase = storageManager.getDatabase(uUid, oldProviderId);
            // create new path
            prepareStorage(newProviderId);
            // move all database files
            FileHelper.moveRecursive(oldDatabase, storageManager.getDatabase(uUid, newProviderId));
            // move all attachment files
            FileHelper.moveRecursive(storageManager.getAttachmentDirectory(uUid, oldProviderId), storageManager.getAttachmentDirectory(uUid, newProviderId));
            // remove any remaining old journal files
            deleteDatabase(oldDatabase);
            mStorageProviderId = newProviderId;
            // re-initialize this class with the new Uri
            openOrCreateDataspace();
        } finally {
            unlockWrite(newProviderId);
        }
    } finally {
        unlockWrite(oldProviderId);
    }
}
Also used : File(java.io.File) SQLiteException(android.database.sqlite.SQLiteException) MessagingException(com.fsck.k9.mail.MessagingException)

Aggregations

Store (com.fsck.k9.mail.Store)24 MessagingException (com.fsck.k9.mail.MessagingException)23 LocalStore (com.fsck.k9.mailstore.LocalStore)21 Pop3Store (com.fsck.k9.mail.store.pop3.Pop3Store)20 LocalFolder (com.fsck.k9.mailstore.LocalFolder)19 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)17 Folder (com.fsck.k9.mail.Folder)16 Message (com.fsck.k9.mail.Message)16 LocalMessage (com.fsck.k9.mailstore.LocalMessage)16 ArrayList (java.util.ArrayList)10 SuppressLint (android.annotation.SuppressLint)7 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)7 IOException (java.io.IOException)6 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)5 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)5 FetchProfile (com.fsck.k9.mail.FetchProfile)5 Date (java.util.Date)5 Account (com.fsck.k9.Account)4 VisibleForTesting (android.support.annotation.VisibleForTesting)3 SearchAccount (com.fsck.k9.search.SearchAccount)3