Search in sources :

Example 1 with Storage

use of com.fsck.k9.preferences.Storage in project k-9 by k9mail.

the class MigrationTo42 method from41MoveFolderPreferences.

public static void from41MoveFolderPreferences(MigrationsHelper migrationsHelper) {
    try {
        LocalStore localStore = migrationsHelper.getLocalStore();
        Storage storage = migrationsHelper.getStorage();
        long startTime = System.currentTimeMillis();
        StorageEditor editor = storage.edit();
        List<? extends Folder> folders = localStore.getPersonalNamespaces(true);
        for (Folder folder : folders) {
            if (folder instanceof LocalFolder) {
                LocalFolder lFolder = (LocalFolder) folder;
                lFolder.save(editor);
            }
        }
        editor.commit();
        long endTime = System.currentTimeMillis();
        Timber.i("Putting folder preferences for %d folders back into Preferences took %d ms", folders.size(), endTime - startTime);
    } catch (Exception e) {
        Timber.e(e, "Could not replace Preferences in upgrade from DB_VERSION 41");
    }
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) Storage(com.fsck.k9.preferences.Storage) LocalStore(com.fsck.k9.mailstore.LocalStore) Folder(com.fsck.k9.mail.Folder) LocalFolder(com.fsck.k9.mailstore.LocalFolder) StorageEditor(com.fsck.k9.preferences.StorageEditor)

Example 2 with Storage

use of com.fsck.k9.preferences.Storage in project k-9 by k9mail.

the class MessagingController method downloadMessages.

/**
     * Fetches the messages described by inputMessages from the remote store and writes them to
     * local storage.
     *
     * @param account
     *         The account the remote store belongs to.
     * @param remoteFolder
     *         The remote folder to download messages from.
     * @param localFolder
     *         The {@link LocalFolder} instance corresponding to the remote folder.
     * @param inputMessages
     *         A list of messages objects that store the UIDs of which messages to download.
     * @param flagSyncOnly
     *         Only flags will be fetched from the remote store if this is {@code true}.
     * @param purgeToVisibleLimit
     *         If true, local messages will be purged down to the limit of visible messages.
     *
     * @return The number of downloaded messages that are not flagged as {@link Flag#SEEN}.
     *
     * @throws MessagingException
     */
private int downloadMessages(final Account account, final Folder remoteFolder, final LocalFolder localFolder, List<Message> inputMessages, boolean flagSyncOnly, boolean purgeToVisibleLimit) throws MessagingException {
    final Date earliestDate = account.getEarliestPollDate();
    // now
    Date downloadStarted = new Date();
    if (earliestDate != null) {
        Timber.d("Only syncing messages after %s", earliestDate);
    }
    final String folder = remoteFolder.getName();
    int unreadBeforeStart = 0;
    try {
        AccountStats stats = account.getStats(context);
        unreadBeforeStart = stats.unreadMessageCount;
    } catch (MessagingException e) {
        Timber.e(e, "Unable to getUnreadMessageCount for account: %s", account);
    }
    List<Message> syncFlagMessages = new ArrayList<>();
    List<Message> unsyncedMessages = new ArrayList<>();
    final AtomicInteger newMessages = new AtomicInteger(0);
    List<Message> messages = new ArrayList<>(inputMessages);
    for (Message message : messages) {
        evaluateMessageForDownload(message, folder, localFolder, remoteFolder, account, unsyncedMessages, syncFlagMessages, flagSyncOnly);
    }
    final AtomicInteger progress = new AtomicInteger(0);
    final int todo = unsyncedMessages.size() + syncFlagMessages.size();
    for (MessagingListener l : getListeners()) {
        l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
    }
    Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
    messages.clear();
    final List<Message> largeMessages = new ArrayList<>();
    final List<Message> smallMessages = new ArrayList<>();
    if (!unsyncedMessages.isEmpty()) {
        /*
             * Reverse the order of the messages. Depending on the server this may get us
             * fetch results for newest to oldest. If not, no harm done.
             */
        Collections.sort(unsyncedMessages, new UidReverseComparator());
        int visibleLimit = localFolder.getVisibleLimit();
        int listSize = unsyncedMessages.size();
        if ((visibleLimit > 0) && (listSize > visibleLimit)) {
            unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
        }
        FetchProfile fp = new FetchProfile();
        if (remoteFolder.supportsFetchingFlags()) {
            fp.add(FetchProfile.Item.FLAGS);
        }
        fp.add(FetchProfile.Item.ENVELOPE);
        Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
        fetchUnsyncedMessages(account, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp);
        String updatedPushState = localFolder.getPushState();
        for (Message message : unsyncedMessages) {
            String newPushState = remoteFolder.getNewPushState(updatedPushState, message);
            if (newPushState != null) {
                updatedPushState = newPushState;
            }
        }
        localFolder.setPushState(updatedPushState);
        Timber.d("SYNC: Synced unsynced messages for folder %s", folder);
    }
    Timber.d("SYNC: Have %d large messages and %d small messages out of %d unsynced messages", largeMessages.size(), smallMessages.size(), unsyncedMessages.size());
    unsyncedMessages.clear();
    /*
         * Grab the content of the small messages first. This is going to
         * be very fast and at very worst will be a single up of a few bytes and a single
         * download of 625k.
         */
    FetchProfile fp = new FetchProfile();
    //TODO: Only fetch small and large messages if we have some
    fp.add(FetchProfile.Item.BODY);
    //        fp.add(FetchProfile.Item.FLAGS);
    //        fp.add(FetchProfile.Item.ENVELOPE);
    downloadSmallMessages(account, remoteFolder, localFolder, smallMessages, progress, unreadBeforeStart, newMessages, todo, fp);
    smallMessages.clear();
    /*
         * Now do the large messages that require more round trips.
         */
    fp = new FetchProfile();
    fp.add(FetchProfile.Item.STRUCTURE);
    downloadLargeMessages(account, remoteFolder, localFolder, largeMessages, progress, unreadBeforeStart, newMessages, todo, fp);
    largeMessages.clear();
    /*
         * Refresh the flags for any messages in the local store that we didn't just
         * download.
         */
    refreshLocalMessageFlags(account, remoteFolder, localFolder, syncFlagMessages, progress, todo);
    Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
    if (purgeToVisibleLimit) {
        localFolder.purgeToVisibleLimit(new MessageRemovalListener() {

            @Override
            public void messageRemoved(Message message) {
                for (MessagingListener l : getListeners()) {
                    l.synchronizeMailboxRemovedMessage(account, folder, message);
                }
            }
        });
    }
    // If the oldest message seen on this sync is newer than
    // the oldest message seen on the previous sync, then
    // we want to move our high-water mark forward
    // this is all here just for pop which only syncs inbox
    // this would be a little wrong for IMAP (we'd want a folder-level pref, not an account level pref.)
    // fortunately, we just don't care.
    Long oldestMessageTime = localFolder.getOldestMessageDate();
    if (oldestMessageTime != null) {
        Date oldestExtantMessage = new Date(oldestMessageTime);
        if (oldestExtantMessage.before(downloadStarted) && oldestExtantMessage.after(new Date(account.getLatestOldMessageSeenTime()))) {
            account.setLatestOldMessageSeenTime(oldestExtantMessage.getTime());
            account.save(Preferences.getPreferences(context));
        }
    }
    return newMessages.get();
}
Also used : 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) MessagingException(com.fsck.k9.mail.MessagingException) ArrayList(java.util.ArrayList) Date(java.util.Date) SuppressLint(android.annotation.SuppressLint) MessageRemovalListener(com.fsck.k9.mailstore.MessageRemovalListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AccountStats(com.fsck.k9.AccountStats)

Example 3 with Storage

use of com.fsck.k9.preferences.Storage in project k-9 by k9mail.

the class MessagingController method clearFolderSynchronous.

@VisibleForTesting
protected void clearFolderSynchronous(Account account, String folderName, MessagingListener listener) {
    LocalFolder localFolder = null;
    try {
        localFolder = account.getLocalStore().getFolder(folderName);
        localFolder.open(Folder.OPEN_MODE_RW);
        localFolder.clearAllMessages();
    } catch (UnavailableStorageException e) {
        Timber.i("Failed to clear folder because storage is not available - trying again later.");
        throw new UnavailableAccountException(e);
    } catch (Exception e) {
        Timber.e(e, "clearFolder failed");
        addErrorMessage(account, null, e);
    } finally {
        closeFolder(localFolder);
    }
    listFoldersSynchronous(account, false, listener);
}
Also used : LocalFolder(com.fsck.k9.mailstore.LocalFolder) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) 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 4 with Storage

use of com.fsck.k9.preferences.Storage in project k-9 by k9mail.

the class MessagingController method deleteMessagesSynchronous.

private void deleteMessagesSynchronous(final Account account, final String folder, final List<? extends Message> messages, MessagingListener listener) {
    Folder localFolder = null;
    Folder localTrashFolder = null;
    List<String> uids = getUidsFromMessages(messages);
    try {
        //as messages get a new UID after being moved
        for (Message message : messages) {
            for (MessagingListener l : getListeners(listener)) {
                l.messageDeleted(account, folder, message);
            }
        }
        Store localStore = account.getLocalStore();
        localFolder = localStore.getFolder(folder);
        Map<String, String> uidMap = null;
        if (folder.equals(account.getTrashFolderName()) || !account.hasTrashFolder()) {
            Timber.d("Deleting messages in trash folder or trash set to -None-, not copying");
            localFolder.setFlags(messages, Collections.singleton(Flag.DELETED), true);
        } else {
            localTrashFolder = localStore.getFolder(account.getTrashFolderName());
            if (!localTrashFolder.exists()) {
                localTrashFolder.create(Folder.FolderType.HOLDS_MESSAGES);
            }
            if (localTrashFolder.exists()) {
                Timber.d("Deleting messages in normal folder, moving");
                uidMap = localFolder.moveMessages(messages, localTrashFolder);
            }
        }
        for (MessagingListener l : getListeners()) {
            l.folderStatusChanged(account, folder, localFolder.getUnreadMessageCount());
            if (localTrashFolder != null) {
                l.folderStatusChanged(account, account.getTrashFolderName(), localTrashFolder.getUnreadMessageCount());
            }
        }
        Timber.d("Delete policy for account %s is %s", account.getDescription(), account.getDeletePolicy());
        if (folder.equals(account.getOutboxFolderName())) {
            for (Message message : messages) {
                // 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(account.getTrashFolderName(), message.getUid());
                queuePendingCommand(account, command);
            }
            processPendingCommands(account);
        } else if (account.getDeletePolicy() == DeletePolicy.ON_DELETE) {
            if (folder.equals(account.getTrashFolderName())) {
                queueSetFlag(account, folder, true, Flag.DELETED, uids);
            } else {
                queueMoveOrCopy(account, folder, account.getTrashFolderName(), false, uids, uidMap);
            }
            processPendingCommands(account);
        } else if (account.getDeletePolicy() == DeletePolicy.MARK_AS_READ) {
            queueSetFlag(account, folder, true, Flag.SEEN, uids);
            processPendingCommands(account);
        } else {
            Timber.d("Delete policy %s prevents delete from server", account.getDeletePolicy());
        }
        unsuppressMessages(account, messages);
    } catch (UnavailableStorageException e) {
        Timber.i("Failed to delete message because storage is not available - trying again later.");
        throw new UnavailableAccountException(e);
    } catch (MessagingException me) {
        addErrorMessage(account, null, me);
        throw new RuntimeException("Error deleting message from local store.", me);
    } finally {
        closeFolder(localFolder);
        closeFolder(localTrashFolder);
    }
}
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) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) 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) PendingCommand(com.fsck.k9.controller.MessagingControllerCommands.PendingCommand)

Example 5 with Storage

use of com.fsck.k9.preferences.Storage in project k-9 by k9mail.

the class Prefs method saveSettings.

private void saveSettings() {
    Storage storage = Preferences.getPreferences(this).getStorage();
    K9.setK9Theme(themeNameToId(mTheme.getValue()));
    K9.setUseFixedMessageViewTheme(mFixedMessageTheme.isChecked());
    K9.setK9MessageViewThemeSetting(themeNameToId(mMessageTheme.getValue()));
    K9.setK9ComposerThemeSetting(themeNameToId(mComposerTheme.getValue()));
    K9.setAnimations(mAnimations.isChecked());
    K9.setGesturesEnabled(mGestures.isChecked());
    K9.setUseVolumeKeysForNavigation(mVolumeNavigation.getCheckedItems()[0]);
    K9.setUseVolumeKeysForListNavigation(mVolumeNavigation.getCheckedItems()[1]);
    K9.setStartIntegratedInbox(!mHideSpecialAccounts.isChecked() && mStartIntegratedInbox.isChecked());
    K9.setNotificationHideSubject(NotificationHideSubject.valueOf(mNotificationHideSubject.getValue()));
    int index = 0;
    K9.setConfirmDelete(mConfirmActions.getCheckedItems()[index++]);
    K9.setConfirmDeleteStarred(mConfirmActions.getCheckedItems()[index++]);
    if (NotificationController.platformSupportsExtendedNotifications()) {
        K9.setConfirmDeleteFromNotification(mConfirmActions.getCheckedItems()[index++]);
    }
    K9.setConfirmSpam(mConfirmActions.getCheckedItems()[index++]);
    K9.setConfirmDiscardMessage(mConfirmActions.getCheckedItems()[index++]);
    K9.setConfirmMarkAllRead(mConfirmActions.getCheckedItems()[index++]);
    K9.setMeasureAccounts(mMeasureAccounts.isChecked());
    K9.setCountSearchMessages(mCountSearch.isChecked());
    K9.setHideSpecialAccounts(mHideSpecialAccounts.isChecked());
    K9.setMessageListPreviewLines(Integer.parseInt(mPreviewLines.getValue()));
    K9.setMessageListCheckboxes(mCheckboxes.isChecked());
    K9.setMessageListStars(mStars.isChecked());
    K9.setShowCorrespondentNames(mShowCorrespondentNames.isChecked());
    K9.setMessageListSenderAboveSubject(mSenderAboveSubject.isChecked());
    K9.setShowContactName(mShowContactName.isChecked());
    K9.setShowContactPicture(mShowContactPicture.isChecked());
    K9.setColorizeMissingContactPictures(mColorizeMissingContactPictures.isChecked());
    K9.setUseBackgroundAsUnreadIndicator(mBackgroundAsUnreadIndicator.isChecked());
    K9.setThreadedViewEnabled(mThreadedView.isChecked());
    K9.setChangeContactNameColor(mChangeContactNameColor.isChecked());
    K9.setMessageViewFixedWidthFont(mFixedWidth.isChecked());
    K9.setMessageViewReturnToList(mReturnToList.isChecked());
    K9.setMessageViewShowNext(mShowNext.isChecked());
    K9.setAutofitWidth(mAutofitWidth.isChecked());
    K9.setQuietTimeEnabled(mQuietTimeEnabled.isChecked());
    boolean[] enabledRefileActions = mVisibleRefileActions.getCheckedItems();
    K9.setMessageViewDeleteActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_DELETE]);
    K9.setMessageViewArchiveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_ARCHIVE]);
    K9.setMessageViewMoveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_MOVE]);
    K9.setMessageViewCopyActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_COPY]);
    K9.setMessageViewSpamActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_SPAM]);
    K9.setNotificationDuringQuietTimeEnabled(!mDisableNotificationDuringQuietTime.isChecked());
    K9.setQuietTimeStarts(mQuietTimeStarts.getTime());
    K9.setQuietTimeEnds(mQuietTimeEnds.getTime());
    K9.setWrapFolderNames(mWrapFolderNames.isChecked());
    if (mNotificationQuickDelete != null) {
        K9.setNotificationQuickDeleteBehaviour(NotificationQuickDelete.valueOf(mNotificationQuickDelete.getValue()));
    }
    if (mLockScreenNotificationVisibility != null) {
        K9.setLockScreenNotificationVisibility(K9.LockScreenNotificationVisibility.valueOf(mLockScreenNotificationVisibility.getValue()));
    }
    K9.setSplitViewMode(SplitViewMode.valueOf(mSplitViewMode.getValue()));
    K9.setAttachmentDefaultPath(mAttachmentPathPreference.getSummary().toString());
    boolean needsRefresh = K9.setBackgroundOps(mBackgroundOps.getValue());
    if (!K9.isDebug() && mDebugLogging.isChecked()) {
        Toast.makeText(this, R.string.debug_logging_enabled, Toast.LENGTH_LONG).show();
    }
    K9.setDebug(mDebugLogging.isChecked());
    K9.DEBUG_SENSITIVE = mSensitiveLogging.isChecked();
    K9.setHideUserAgent(mHideUserAgent.isChecked());
    K9.setHideTimeZone(mHideTimeZone.isChecked());
    K9.setOpenPgpProvider(mOpenPgpProvider.getValue());
    K9.setOpenPgpSupportSignOnly(mOpenPgpSupportSignOnly.isChecked());
    StorageEditor editor = storage.edit();
    K9.save(editor);
    editor.commit();
    if (needsRefresh) {
        MailService.actionReset(this, null);
    }
}
Also used : Storage(com.fsck.k9.preferences.Storage) StorageEditor(com.fsck.k9.preferences.StorageEditor)

Aggregations

Storage (com.fsck.k9.preferences.Storage)10 MessagingException (com.fsck.k9.mail.MessagingException)9 Account (com.fsck.k9.Account)7 InvalidSettingValueException (com.fsck.k9.preferences.Settings.InvalidSettingValueException)7 Preferences (com.fsck.k9.Preferences)6 StorageEditor (com.fsck.k9.preferences.StorageEditor)6 IOException (java.io.IOException)6 Map (java.util.Map)5 TreeMap (java.util.TreeMap)5 Intent (android.content.Intent)4 Folder (com.fsck.k9.mail.Folder)4 LocalFolder (com.fsck.k9.mailstore.LocalFolder)4 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)4 SettingsDescription (com.fsck.k9.preferences.Settings.SettingsDescription)4 ArrayList (java.util.ArrayList)4 Message (com.fsck.k9.mail.Message)3 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)3 LocalMessage (com.fsck.k9.mailstore.LocalMessage)3 LocalStore (com.fsck.k9.mailstore.LocalStore)3 SuppressLint (android.annotation.SuppressLint)2