use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method moveOrCopyMessageSynchronous.
private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder, final List<? extends Message> inMessages, final String destFolder, final boolean isCopy) {
try {
LocalStore localStore = account.getLocalStore();
Store remoteStore = account.getRemoteStore();
if (!isCopy && (!remoteStore.isMoveCapable() || !localStore.isMoveCapable())) {
return;
}
if (isCopy && (!remoteStore.isCopyCapable() || !localStore.isCopyCapable())) {
return;
}
LocalFolder localSrcFolder = localStore.getFolder(srcFolder);
Folder localDestFolder = localStore.getFolder(destFolder);
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) {
Map<String, Message> origUidMap = new HashMap<>();
for (Message message : messages) {
origUidMap.put(message.getUid(), message);
}
Timber.i("moveOrCopyMessageSynchronous: source folder = %s, %d messages, destination folder = %s, " + "isCopy = %s", srcFolder, messages.size(), destFolder, isCopy);
Map<String, String> uidMap;
if (isCopy) {
FetchProfile fp = new FetchProfile();
fp.add(Item.ENVELOPE);
fp.add(Item.BODY);
localSrcFolder.fetch(messages, fp, null);
uidMap = localSrcFolder.copyMessages(messages, localDestFolder);
if (unreadCountAffected) {
// If this copy operation changes the unread count in the destination
// folder, notify the listeners.
int unreadMessageCount = localDestFolder.getUnreadMessageCount();
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, destFolder, unreadMessageCount);
}
}
} else {
uidMap = localSrcFolder.moveMessages(messages, localDestFolder);
for (Entry<String, Message> entry : origUidMap.entrySet()) {
String origUid = entry.getKey();
Message message = entry.getValue();
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, srcFolder, origUid, message.getUid());
}
}
unsuppressMessages(account, messages);
if (unreadCountAffected) {
// If this move operation changes the unread count, notify the listeners
// that the unread count changed in both the source and destination folder.
int unreadMessageCountSrc = localSrcFolder.getUnreadMessageCount();
int unreadMessageCountDest = localDestFolder.getUnreadMessageCount();
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, srcFolder, unreadMessageCountSrc);
l.folderStatusChanged(account, destFolder, unreadMessageCountDest);
}
}
}
List<String> origUidKeys = new ArrayList<>(origUidMap.keySet());
queueMoveOrCopy(account, srcFolder, destFolder, isCopy, origUidKeys, uidMap);
}
processPendingCommands(account);
} catch (UnavailableStorageException e) {
Timber.i("Failed to move/copy message because storage is not available - trying again later.");
throw new UnavailableAccountException(e);
} catch (MessagingException me) {
addErrorMessage(account, null, me);
throw new RuntimeException("Error moving message", me);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method setFlagSynchronous.
private void setFlagSynchronous(final Account account, final List<Long> ids, final Flag flag, final boolean newState, final boolean threadedList) {
LocalStore localStore;
try {
localStore = account.getLocalStore();
} catch (MessagingException e) {
Timber.e(e, "Couldn't get LocalStore instance");
return;
}
// can be updated with the new state.
try {
if (threadedList) {
localStore.setFlagForThreads(ids, flag, newState);
removeFlagForThreadsFromCache(account, ids, flag);
} else {
localStore.setFlag(ids, flag, newState);
removeFlagFromCache(account, ids, flag);
}
} catch (MessagingException e) {
Timber.e(e, "Couldn't set flags in local database");
}
// Read folder name and UID of messages from the database
Map<String, List<String>> folderMap;
try {
folderMap = localStore.getFoldersAndUids(ids, threadedList);
} catch (MessagingException e) {
Timber.e(e, "Couldn't get folder name and UID of messages");
return;
}
// Loop over all folders
for (Entry<String, List<String>> entry : folderMap.entrySet()) {
String folderName = entry.getKey();
// Notify listeners of changed folder status
LocalFolder localFolder = localStore.getFolder(folderName);
try {
int unreadMessageCount = localFolder.getUnreadMessageCount();
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderName, unreadMessageCount);
}
} catch (MessagingException e) {
Timber.w(e, "Couldn't get unread count for folder: %s", folderName);
}
// TODO: Skip the remote part for all local-only folders
if (account.getErrorFolderName().equals(folderName)) {
continue;
}
// Send flag change to server
queueSetFlag(account, folderName, newState, flag, entry.getValue());
processPendingCommands(account);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method setFlag.
/**
* Set or remove a flag for a message referenced by message UID.
*
* @param account
* The account the folder containing the message belongs to.
* @param folderName
* The name of the folder.
* @param uid
* The UID of the message to change the flag for.
* @param flag
* The flag to change.
* @param newState
* {@code true}, if the flag should be set. {@code false} if it should be removed.
*/
public void setFlag(Account account, String folderName, String uid, Flag flag, boolean newState) {
Folder localFolder = null;
try {
LocalStore localStore = account.getLocalStore();
localFolder = localStore.getFolder(folderName);
localFolder.open(Folder.OPEN_MODE_RW);
Message message = localFolder.getMessage(uid);
if (message != null) {
setFlag(account, folderName, Collections.singletonList(message), flag, newState);
}
} catch (MessagingException me) {
addErrorMessage(account, null, me);
throw new RuntimeException(me);
} finally {
closeFolder(localFolder);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method collectMessagesInThreads.
private static List<Message> collectMessagesInThreads(Account account, List<? extends Message> messages) throws MessagingException {
LocalStore localStore = account.getLocalStore();
List<Message> messagesInThreads = new ArrayList<>();
for (Message message : messages) {
LocalMessage localMessage = (LocalMessage) message;
long rootId = localMessage.getRootId();
long threadId = (rootId == -1) ? localMessage.getThreadId() : rootId;
List<? extends Message> messagesInThread = localStore.getMessagesInThread(threadId);
messagesInThreads.addAll(messagesInThread);
}
return messagesInThreads;
}
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 + Account.ACCOUNT_DESCRIPTION_KEY, accountName);
if (account.incoming == null) {
// We don't import accounts without incoming server settings
throw new InvalidSettingValueException();
}
// Write incoming server settings (storeUri)
ServerSettings incoming = new ImportedServerSettings(account.incoming);
String storeUri = RemoteStore.createStoreUri(incoming);
putString(editor, accountKeyPrefix + Account.STORE_URI_KEY, Base64.encode(storeUri));
// Mark account as disabled if the AuthType isn't EXTERNAL and the
// settings file didn't contain a password
boolean createAccountDisabled = AuthType.EXTERNAL != incoming.authenticationType && (incoming.password == null || incoming.password.isEmpty());
if (account.outgoing == null && !ServerSettings.Type.WebDAV.name().equals(account.incoming.type)) {
// All account types except WebDAV need to provide outgoing server settings
throw new InvalidSettingValueException();
}
if (account.outgoing != null) {
// Write outgoing server settings (transportUri)
ServerSettings outgoing = new ImportedServerSettings(account.outgoing);
String transportUri = Transport.createTransportUri(outgoing);
putString(editor, accountKeyPrefix + Account.TRANSPORT_URI_KEY, Base64.encode(transportUri));
/*
* 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.
*/
boolean outgoingPasswordNeeded = AuthType.EXTERNAL != outgoing.authenticationType && !(ServerSettings.Type.WebDAV == outgoing.type) && outgoing.username != null && !outgoing.username.isEmpty() && (outgoing.password == null || outgoing.password.isEmpty());
createAccountDisabled = outgoingPasswordNeeded || createAccountDisabled;
}
// Write key to mark account as disabled if necessary
if (createAccountDisabled) {
editor.putBoolean(accountKeyPrefix + "enabled", false);
}
// Validate account settings
Map<String, Object> validatedSettings = AccountSettings.validate(contentVersion, account.settings.settings, !mergeImportedAccount);
// Upgrade account settings to current content version
if (contentVersion != Settings.VERSION) {
AccountSettings.upgrade(contentVersion, validatedSettings);
}
// Convert account settings to the string representation used in preference storage
Map<String, String> stringSettings = AccountSettings.convert(validatedSettings);
// Merge account settings if necessary
Map<String, String> writeSettings;
if (mergeImportedAccount) {
writeSettings = new HashMap<>(AccountSettings.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 = Account.generateAccountNumber(prefs);
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);
}
Aggregations