use of com.fsck.k9.mailstore.LocalFolder 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.LocalFolder 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);
}
}
use of com.fsck.k9.mailstore.LocalFolder 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);
}
}
use of com.fsck.k9.mailstore.LocalFolder in project k-9 by k9mail.
the class LocalFolder method getMessagesByReference.
public List<LocalMessage> getMessagesByReference(@NonNull List<MessageReference> messageReferences) throws MessagingException {
open();
String accountUuid = getAccountUuid();
long folderId = getDatabaseId();
List<LocalMessage> messages = new ArrayList<>();
for (MessageReference messageReference : messageReferences) {
if (!accountUuid.equals(messageReference.getAccountUuid())) {
throw new IllegalArgumentException("all message references must belong to this Account!");
}
if (folderId != messageReference.getFolderId()) {
throw new IllegalArgumentException("all message references must belong to this LocalFolder!");
}
LocalMessage message = getMessage(messageReference.getUid());
if (message != null) {
messages.add(message);
}
}
return messages;
}
use of com.fsck.k9.mailstore.LocalFolder in project k-9 by k9mail.
the class LocalStore method loadLocalMessageByMessageId.
@Nullable
private LocalMessage loadLocalMessageByMessageId(long messageId) throws MessagingException {
Map<Long, List<String>> folderIdsAndUids = getFolderIdsAndUids(Collections.singletonList(messageId), false);
if (folderIdsAndUids.isEmpty()) {
return null;
}
Map.Entry<Long, List<String>> entry = folderIdsAndUids.entrySet().iterator().next();
long folderId = entry.getKey();
String uid = entry.getValue().get(0);
LocalFolder folder = getFolder(folderId);
LocalMessage localMessage = folder.getMessage(uid);
FetchProfile fp = new FetchProfile();
fp.add(Item.BODY);
folder.fetch(Collections.singletonList(localMessage), fp, null);
return localMessage;
}
Aggregations