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.
*/
public void setFlag(Account account, long folderId, String uid, Flag flag, boolean newState) {
try {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
LocalMessage message = localFolder.getMessage(uid);
if (message != null) {
setFlag(account, folderId, Collections.singletonList(message), flag, newState);
}
} catch (MessagingException me) {
throw new RuntimeException(me);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method processPendingMoveOrCopy.
@VisibleForTesting
void processPendingMoveOrCopy(Account account, long srcFolderId, long destFolderId, List<String> uids, MoveOrCopyFlavor operation, Map<String, String> newUidMap) throws MessagingException {
checkNotNull(newUidMap);
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localSourceFolder = localStore.getFolder(srcFolderId);
localSourceFolder.open();
String srcFolderServerId = localSourceFolder.getServerId();
LocalFolder localDestFolder = localStore.getFolder(destFolderId);
localDestFolder.open();
String destFolderServerId = localDestFolder.getServerId();
Backend backend = getBackend(account);
Map<String, String> remoteUidMap;
switch(operation) {
case COPY:
remoteUidMap = backend.copyMessages(srcFolderServerId, destFolderServerId, uids);
break;
case MOVE:
remoteUidMap = backend.moveMessages(srcFolderServerId, destFolderServerId, uids);
break;
case MOVE_AND_MARK_AS_READ:
remoteUidMap = backend.moveMessagesAndMarkAsRead(srcFolderServerId, destFolderServerId, uids);
break;
default:
throw new RuntimeException("Unsupported messaging operation");
}
if (operation != MoveOrCopyFlavor.COPY) {
if (backend.getSupportsExpunge() && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) {
Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account, srcFolderServerId);
backend.expungeMessages(srcFolderServerId, uids);
}
destroyPlaceholderMessages(localSourceFolder, uids);
}
// TODO: Change Backend interface to ensure we never receive null for remoteUidMap
if (remoteUidMap == null) {
remoteUidMap = Collections.emptyMap();
}
// Update local messages (that currently have local UIDs) with new server IDs
for (String uid : uids) {
String localUid = newUidMap.get(uid);
String newUid = remoteUidMap.get(uid);
LocalMessage localMessage = localDestFolder.getMessage(localUid);
if (localMessage == null) {
// Local message no longer exists
continue;
}
if (newUid != null) {
// Update local message with new server ID
localMessage.setUid(newUid);
localDestFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, destFolderId, localUid, newUid);
}
} else {
// New server ID wasn't provided. Remove local message.
localMessage.destroy();
}
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method sendMessage.
/**
* Stores the given message in the Outbox and starts a sendPendingMessages command to attempt to send the message.
*/
public void sendMessage(Account account, Message message, String plaintextSubject, MessagingListener listener) {
try {
Long outboxFolderId = account.getOutboxFolderId();
if (outboxFolderId == null) {
if (BuildConfig.DEBUG) {
throw new AssertionError("Outbox does not exist");
}
Timber.w("Outbox does not exist");
outboxFolderId = specialLocalFoldersCreator.createOutbox(account);
}
message.setFlag(Flag.SEEN, true);
MessageStore messageStore = messageStoreManager.getMessageStore(account);
SaveMessageData messageData = saveMessageDataCreator.createSaveMessageData(message, MessageDownloadState.FULL, plaintextSubject);
long messageId = messageStore.saveLocalMessage(outboxFolderId, messageData, null);
LocalStore localStore = localStoreProvider.getInstance(account);
OutboxStateRepository outboxStateRepository = localStore.getOutboxStateRepository();
outboxStateRepository.initializeOutboxState(messageId);
sendPendingMessages(account, listener);
} catch (Exception e) {
Timber.e(e, "Error sending message");
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method deleteMessagesSynchronous.
private void deleteMessagesSynchronous(Account account, long folderId, List<LocalMessage> messages) {
try {
List<LocalMessage> localOnlyMessages = new ArrayList<>();
List<LocalMessage> syncedMessages = new ArrayList<>();
List<String> syncedMessageUids = new ArrayList<>();
for (LocalMessage message : messages) {
notificationController.removeNewMailNotification(account, message.makeMessageReference());
String uid = message.getUid();
if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
localOnlyMessages.add(message);
} else {
syncedMessages.add(message);
syncedMessageUids.add(uid);
}
}
Backend backend = getBackend(account);
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
Map<String, String> uidMap = null;
Long trashFolderId = account.getTrashFolderId();
LocalFolder localTrashFolder = null;
if (!account.hasTrashFolder() || folderId == trashFolderId || (backend.getSupportsTrashFolder() && !backend.isDeleteMoveToTrash())) {
Timber.d("Not moving deleted messages to local Trash folder. Removing local copies.");
if (!localOnlyMessages.isEmpty()) {
localFolder.destroyMessages(localOnlyMessages);
}
if (!syncedMessages.isEmpty()) {
localFolder.setFlags(syncedMessages, Collections.singleton(Flag.DELETED), true);
}
} else {
Timber.d("Deleting messages in normal folder, moving");
localTrashFolder = localStore.getFolder(trashFolderId);
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> moveMessageIdMapping = messageStore.moveMessages(messageIds, trashFolderId);
Map<Long, String> destinationMapping = messageStore.getMessageServerIds(moveMessageIdMapping.values());
uidMap = new HashMap<>();
for (Entry<Long, Long> entry : moveMessageIdMapping.entrySet()) {
long sourceMessageId = entry.getKey();
long destinationMessageId = entry.getValue();
String sourceUid = messageIdToUidMapping.get(sourceMessageId);
String destinationUid = destinationMapping.get(destinationMessageId);
uidMap.put(sourceUid, destinationUid);
}
if (account.isMarkMessageAsReadOnDelete()) {
Collection<Long> destinationMessageIds = moveMessageIdMapping.values();
messageStore.setFlag(destinationMessageIds, Flag.SEEN, true);
}
}
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderId);
if (localTrashFolder != null) {
l.folderStatusChanged(account, trashFolderId);
}
}
Timber.d("Delete policy for account %s is %s", account, account.getDeletePolicy());
Long outboxFolderId = account.getOutboxFolderId();
if (outboxFolderId != null && folderId == outboxFolderId && supportsUpload(account)) {
for (String destinationUid : uidMap.values()) {
// 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(trashFolderId, destinationUid);
queuePendingCommand(account, command);
}
processPendingCommands(account);
} else if (localFolder.isLocalOnly()) {
// Nothing to do on the remote side
} else if (!syncedMessageUids.isEmpty()) {
if (account.getDeletePolicy() == DeletePolicy.ON_DELETE) {
if (!account.hasTrashFolder() || folderId == trashFolderId || !backend.isDeleteMoveToTrash()) {
queueDelete(account, folderId, syncedMessageUids);
} else if (account.isMarkMessageAsReadOnDelete()) {
queueMoveOrCopy(account, folderId, trashFolderId, MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ, uidMap);
} else {
queueMoveOrCopy(account, folderId, trashFolderId, MoveOrCopyFlavor.MOVE, uidMap);
}
processPendingCommands(account);
} else if (account.getDeletePolicy() == DeletePolicy.MARK_AS_READ) {
queueSetFlag(account, localFolder.getDatabaseId(), true, Flag.SEEN, syncedMessageUids);
processPendingCommands(account);
} else {
Timber.d("Delete policy %s prevents delete from server", account.getDeletePolicy());
}
}
unsuppressMessages(account, messages);
} catch (MessagingException me) {
throw new RuntimeException("Error deleting message from local store.", me);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method clearAllPending.
public void clearAllPending(final Account account) {
try {
Timber.w("Clearing pending commands!");
LocalStore localStore = localStoreProvider.getInstance(account);
localStore.removePendingCommands();
} catch (MessagingException me) {
Timber.e(me, "Unable to clear pending command");
}
}
Aggregations