Search in sources :

Example 76 with LocalStore

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

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

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

the class SettingsImporter method importAccount.

private static AccountDescriptionPair importAccount(Context context, StorageEditor editor, int contentVersion, ImportedAccount account, boolean overwrite) throws InvalidSettingValueException {
    AccountDescription original = new AccountDescription(account.name, account.uuid);
    Preferences prefs = Preferences.getPreferences(context);
    List<Account> accounts = prefs.getAccounts();
    String uuid = account.uuid;
    Account existingAccount = prefs.getAccount(uuid);
    boolean mergeImportedAccount = (overwrite && existingAccount != null);
    if (!overwrite && existingAccount != null) {
        // An account with this UUID already exists, but we're not allowed to overwrite it.
        // So generate a new UUID.
        uuid = UUID.randomUUID().toString();
    }
    // Make sure the account name is unique
    String accountName = account.name;
    if (isAccountNameUsed(accountName, accounts)) {
        // number >= 1 that results in an unused account name.
        for (int i = 1; i <= accounts.size(); i++) {
            accountName = account.name + " (" + i + ")";
            if (!isAccountNameUsed(accountName, accounts)) {
                break;
            }
        }
    }
    // Write account name
    String accountKeyPrefix = uuid + ".";
    putString(editor, accountKeyPrefix + AccountPreferenceSerializer.ACCOUNT_DESCRIPTION_KEY, accountName);
    if (account.incoming == null) {
        // We don't import accounts without incoming server settings
        throw new InvalidSettingValueException();
    }
    // Write incoming server settings
    ServerSettings incoming = createServerSettings(account.incoming);
    ServerSettingsSerializer serverSettingsSerializer = DI.get(ServerSettingsSerializer.class);
    String incomingServer = serverSettingsSerializer.serialize(incoming);
    putString(editor, accountKeyPrefix + AccountPreferenceSerializer.INCOMING_SERVER_SETTINGS_KEY, incomingServer);
    String incomingServerName = incoming.host;
    boolean incomingPasswordNeeded = AuthType.EXTERNAL != incoming.authenticationType && (incoming.password == null || incoming.password.isEmpty());
    String incomingServerType = ServerTypeConverter.toServerSettingsType(account.incoming.type);
    if (account.outgoing == null && !incomingServerType.equals(Protocols.WEBDAV)) {
        // All account types except WebDAV need to provide outgoing server settings
        throw new InvalidSettingValueException();
    }
    String outgoingServerName = null;
    boolean outgoingPasswordNeeded = false;
    if (account.outgoing != null) {
        // Write outgoing server settings
        ServerSettings outgoing = createServerSettings(account.outgoing);
        String outgoingServer = serverSettingsSerializer.serialize(outgoing);
        putString(editor, accountKeyPrefix + AccountPreferenceSerializer.OUTGOING_SERVER_SETTINGS_KEY, outgoingServer);
        /*
             * Mark account as disabled if the settings file contained a username but no password. However, no password
             * is required for the outgoing server for WebDAV accounts, because incoming and outgoing servers are 
             * identical for this account type. Nor is a password required if the AuthType is EXTERNAL.
             */
        String outgoingServerType = ServerTypeConverter.toServerSettingsType(outgoing.type);
        outgoingPasswordNeeded = AuthType.EXTERNAL != outgoing.authenticationType && !outgoingServerType.equals(Protocols.WEBDAV) && outgoing.username != null && !outgoing.username.isEmpty() && (outgoing.password == null || outgoing.password.isEmpty());
        outgoingServerName = outgoing.host;
    }
    boolean createAccountDisabled = incomingPasswordNeeded || outgoingPasswordNeeded;
    if (createAccountDisabled) {
        editor.putBoolean(accountKeyPrefix + "enabled", false);
    }
    // Validate account settings
    Map<String, Object> validatedSettings = AccountSettingsDescriptions.validate(contentVersion, account.settings.settings, !mergeImportedAccount);
    // Upgrade account settings to current content version
    if (contentVersion != Settings.VERSION) {
        AccountSettingsDescriptions.upgrade(contentVersion, validatedSettings);
    }
    // Convert account settings to the string representation used in preference storage
    Map<String, String> stringSettings = AccountSettingsDescriptions.convert(validatedSettings);
    // Merge account settings if necessary
    Map<String, String> writeSettings;
    if (mergeImportedAccount) {
        writeSettings = new HashMap<>(AccountSettingsDescriptions.getAccountSettings(prefs.getStorage(), uuid));
        writeSettings.putAll(stringSettings);
    } else {
        writeSettings = stringSettings;
    }
    // Write account settings
    for (Map.Entry<String, String> setting : writeSettings.entrySet()) {
        String key = accountKeyPrefix + setting.getKey();
        String value = setting.getValue();
        putString(editor, key, value);
    }
    // If it's a new account generate and write a new "accountNumber"
    if (!mergeImportedAccount) {
        int newAccountNumber = prefs.generateAccountNumber();
        putString(editor, accountKeyPrefix + "accountNumber", Integer.toString(newAccountNumber));
    }
    // Write identities
    if (account.identities != null) {
        importIdentities(editor, contentVersion, uuid, account, overwrite, existingAccount, prefs);
    } else if (!mergeImportedAccount) {
        // Require accounts to at least have one identity
        throw new InvalidSettingValueException();
    }
    // Write folder settings
    if (account.folders != null) {
        for (ImportedFolder folder : account.folders) {
            importFolder(editor, contentVersion, uuid, folder, mergeImportedAccount, prefs);
        }
    }
    // TODO: sync folder settings with localstore?
    AccountDescription imported = new AccountDescription(accountName, uuid);
    return new AccountDescriptionPair(original, imported, mergeImportedAccount, incomingPasswordNeeded, outgoingPasswordNeeded, incomingServerName, outgoingServerName);
}
Also used : Account(com.fsck.k9.Account) ServerSettingsSerializer(com.fsck.k9.ServerSettingsSerializer) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) ServerSettings(com.fsck.k9.mail.ServerSettings) SharedPreferences(android.content.SharedPreferences) Preferences(com.fsck.k9.Preferences) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Collections.emptyMap(java.util.Collections.emptyMap) Collections.unmodifiableMap(java.util.Collections.unmodifiableMap)

Example 79 with LocalStore

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

the class AttachmentProvider method getType.

private String getType(String accountUuid, String id, String mimeType) {
    String type;
    final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
    try {
        final LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
        AttachmentInfo attachmentInfo = localStore.getAttachmentInfo(id);
        if (mimeType != null) {
            type = mimeType;
        } else {
            type = attachmentInfo.type;
        }
    } catch (MessagingException e) {
        Timber.e(e, "Unable to retrieve LocalStore for %s", account);
        type = MimeUtility.DEFAULT_ATTACHMENT_MIME_TYPE;
    }
    return type;
}
Also used : Account(com.fsck.k9.Account) MessagingException(com.fsck.k9.mail.MessagingException) AttachmentInfo(com.fsck.k9.mailstore.LocalStore.AttachmentInfo) LocalStore(com.fsck.k9.mailstore.LocalStore) LocalStoreProvider(com.fsck.k9.mailstore.LocalStoreProvider)

Example 80 with LocalStore

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

the class StoreSchemaDefinitionTest method createStoreSchemaDefinition.

private StoreSchemaDefinition createStoreSchemaDefinition() throws MessagingException {
    final Account account = createAccount();
    final LockableDatabase lockableDatabase = createLockableDatabase();
    final LocalStore localStore = mock(LocalStore.class);
    when(localStore.getDatabase()).thenReturn(lockableDatabase);
    MigrationsHelper migrationsHelper = new MigrationsHelper() {

        @Override
        public Account getAccount() {
            return account;
        }

        @Override
        public void saveAccount() {
        // Do nothing
        }
    };
    return new StoreSchemaDefinition(migrationsHelper);
}
Also used : Account(com.fsck.k9.Account) LockableDatabase(com.fsck.k9.mailstore.LockableDatabase) LocalStore(com.fsck.k9.mailstore.LocalStore) MigrationsHelper(com.fsck.k9.mailstore.MigrationsHelper)

Aggregations

LocalStore (com.fsck.k9.mailstore.LocalStore)63 LocalFolder (com.fsck.k9.mailstore.LocalFolder)53 MessagingException (com.fsck.k9.mail.MessagingException)46 LocalMessage (com.fsck.k9.mailstore.LocalMessage)27 FetchProfile (com.fsck.k9.mail.FetchProfile)17 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)16 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)16 Store (com.fsck.k9.mail.Store)16 Folder (com.fsck.k9.mail.Folder)15 Pop3Store (com.fsck.k9.mail.store.pop3.Pop3Store)15 Account (com.fsck.k9.Account)13 Message (com.fsck.k9.mail.Message)13 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)13 ArrayList (java.util.ArrayList)13 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)10 Test (org.junit.Test)10 Backend (com.fsck.k9.backend.api.Backend)9 IOException (java.io.IOException)9 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)8 SuppressLint (android.annotation.SuppressLint)7