use of com.fsck.k9.mailstore.OutboxStateRepository in project k-9 by k9mail.
the class MessagingController method sendPendingMessagesSynchronous.
/**
* Attempt to send any messages that are sitting in the Outbox.
*/
@VisibleForTesting
protected void sendPendingMessagesSynchronous(final Account account) {
Exception lastFailure = null;
boolean wasPermanentFailure = false;
try {
ServerSettings serverSettings = account.getOutgoingServerSettings();
if (serverSettings.isMissingCredentials()) {
handleAuthenticationFailure(account, false);
return;
}
LocalStore localStore = localStoreProvider.getInstance(account);
OutboxStateRepository outboxStateRepository = localStore.getOutboxStateRepository();
LocalFolder localFolder = localStore.getFolder(account.getOutboxFolderId());
if (!localFolder.exists()) {
Timber.w("Outbox does not exist");
return;
}
localFolder.open();
long outboxFolderId = localFolder.getDatabaseId();
List<LocalMessage> localMessages = localFolder.getMessages(null);
int progress = 0;
int todo = localMessages.size();
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxProgress(account, outboxFolderId, progress, todo);
}
/*
* The profile we will use to pull all of the content
* for a given local message into memory for sending.
*/
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.BODY);
Timber.i("Scanning Outbox folder for messages to send");
Backend backend = getBackend(account);
for (LocalMessage message : localMessages) {
if (message.isSet(Flag.DELETED)) {
// FIXME: When uploading a message to the remote Sent folder the move code creates a placeholder
// message in the Outbox. This code gets rid of these messages. It'd be preferable if the
// placeholder message was never created, though.
message.destroy();
continue;
}
try {
long messageId = message.getDatabaseId();
OutboxState outboxState = outboxStateRepository.getOutboxState(messageId);
if (outboxState.getSendState() != SendState.READY) {
Timber.v("Skipping sending message %s", message.getUid());
notificationController.showSendFailedNotification(account, new MessagingException(message.getSubject()));
continue;
}
Timber.i("Send count for message %s is %d", message.getUid(), outboxState.getNumberOfSendAttempts());
localFolder.fetch(Collections.singletonList(message), fp, null);
try {
if (message.getHeader(K9.IDENTITY_HEADER).length > 0 || message.isSet(Flag.DRAFT)) {
Timber.v("The user has set the Outbox and Drafts folder to the same thing. " + "This message appears to be a draft, so K-9 will not send it");
continue;
}
outboxStateRepository.incrementSendAttempts(messageId);
message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
Timber.i("Sending message with UID %s", message.getUid());
backend.sendMessage(message);
message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
message.setFlag(Flag.SEEN, true);
progress++;
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxProgress(account, outboxFolderId, progress, todo);
}
moveOrDeleteSentMessage(account, localStore, message);
outboxStateRepository.removeOutboxState(messageId);
} catch (AuthenticationFailedException e) {
outboxStateRepository.decrementSendAttempts(messageId);
lastFailure = e;
wasPermanentFailure = false;
handleAuthenticationFailure(account, false);
handleSendFailure(account, localFolder, message, e);
} catch (CertificateValidationException e) {
outboxStateRepository.decrementSendAttempts(messageId);
lastFailure = e;
wasPermanentFailure = false;
notifyUserIfCertificateProblem(account, e, false);
handleSendFailure(account, localFolder, message, e);
} catch (MessagingException e) {
lastFailure = e;
wasPermanentFailure = e.isPermanentFailure();
if (wasPermanentFailure) {
String errorMessage = e.getMessage();
outboxStateRepository.setSendAttemptError(messageId, errorMessage);
} else if (outboxState.getNumberOfSendAttempts() + 1 >= MAX_SEND_ATTEMPTS) {
outboxStateRepository.setSendAttemptsExceeded(messageId);
}
handleSendFailure(account, localFolder, message, e);
} catch (Exception e) {
lastFailure = e;
wasPermanentFailure = true;
handleSendFailure(account, localFolder, message, e);
}
} catch (Exception e) {
lastFailure = e;
wasPermanentFailure = false;
Timber.e(e, "Failed to fetch message for sending");
notifySynchronizeMailboxFailed(account, localFolder, e);
}
}
if (lastFailure != null) {
if (wasPermanentFailure) {
notificationController.showSendFailedNotification(account, lastFailure);
} else {
notificationController.showSendFailedNotification(account, lastFailure);
}
}
} catch (Exception e) {
Timber.v(e, "Failed to send pending messages");
} finally {
if (lastFailure == null) {
notificationController.clearSendFailedNotification(account);
}
}
}
use of com.fsck.k9.mailstore.OutboxStateRepository in project k-9 by k9mail.
the class MessagingControllerTest method setupAccountWithMessageToSend.
private void setupAccountWithMessageToSend() throws MessagingException {
account.setOutboxFolderId(FOLDER_ID);
account.setSentFolderId(SENT_FOLDER_ID);
when(localStore.getFolder(SENT_FOLDER_ID)).thenReturn(sentFolder);
when(sentFolder.getDatabaseId()).thenReturn(SENT_FOLDER_ID);
when(localFolder.exists()).thenReturn(true);
when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localMessageToSend1));
when(localMessageToSend1.getUid()).thenReturn("localMessageToSend1");
when(localMessageToSend1.getDatabaseId()).thenReturn(42L);
when(localMessageToSend1.getHeader(K9.IDENTITY_HEADER)).thenReturn(new String[] {});
OutboxState outboxState = new OutboxState(SendState.READY, 0, null, 0);
OutboxStateRepository outboxStateRepository = mock(OutboxStateRepository.class);
when(outboxStateRepository.getOutboxState(42L)).thenReturn(outboxState);
when(localStore.getOutboxStateRepository()).thenReturn(outboxStateRepository);
controller.addListener(listener);
}
use of com.fsck.k9.mailstore.OutboxStateRepository 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");
}
}
Aggregations