use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.
the class MessagingController method loadMessageRemoteSynchronous.
private void loadMessageRemoteSynchronous(Account account, long folderId, String uid, MessagingListener listener, boolean loadPartialFromSearch) {
try {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
String folderServerId = localFolder.getServerId();
LocalMessage message = localFolder.getMessage(uid);
if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
Timber.w("Message has local UID so cannot download fully.");
// ASH move toast
android.widget.Toast.makeText(context, "Message has local UID so cannot download fully", android.widget.Toast.LENGTH_LONG).show();
// TODO: Using X_DOWNLOADED_FULL is wrong because it's only a partial message. But
// one we can't download completely. Maybe add a new flag; X_PARTIAL_MESSAGE ?
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
} else {
Backend backend = getBackend(account);
if (loadPartialFromSearch) {
SyncConfig syncConfig = createSyncConfig(account);
backend.downloadMessage(syncConfig, folderServerId, uid);
} else {
backend.downloadCompleteMessage(folderServerId, uid);
}
message = localFolder.getMessage(uid);
if (!loadPartialFromSearch) {
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
}
}
// now that we have the full message, refresh the headers
for (MessagingListener l : getListeners(listener)) {
l.loadMessageRemoteFinished(account, folderId, uid);
}
} catch (Exception e) {
for (MessagingListener l : getListeners(listener)) {
l.loadMessageRemoteFailed(account, folderId, uid, e);
}
notifyUserIfCertificateProblem(account, e, true);
Timber.e(e, "Error while loading remote message");
}
}
use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.
the class MessagingController method processPendingAppend.
/**
* Process a pending append message command. This command uploads a local message to the
* server, first checking to be sure that the server message is not newer than
* the local message. Once the local message is successfully processed it is deleted so
* that the server message will be synchronized down without an additional copy being
* created.
*/
void processPendingAppend(PendingAppend command, Account account) throws MessagingException {
LocalStore localStore = localStoreProvider.getInstance(account);
long folderId = command.folderId;
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
String folderServerId = localFolder.getServerId();
String uid = command.uid;
LocalMessage localMessage = localFolder.getMessage(uid);
if (localMessage == null) {
return;
}
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
// FIXME: This should never happen. Throw in debug builds.
return;
}
Backend backend = getBackend(account);
if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED)) {
Timber.w("Local message with uid %s has flag %s already set, checking for remote message with " + "same message id", localMessage.getUid(), X_REMOTE_COPY_STARTED);
String messageServerId = backend.findByMessageId(folderServerId, localMessage.getMessageId());
if (messageServerId != null) {
Timber.w("Local message has flag %s already set, and there is a remote message with uid %s, " + "assuming message was already copied and aborting this copy", X_REMOTE_COPY_STARTED, messageServerId);
String oldUid = localMessage.getUid();
localMessage.setUid(messageServerId);
localFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
}
return;
} else {
Timber.w("No remote message with message-id found, proceeding with append");
}
}
/*
* If the message does not exist remotely we just upload it and then
* update our local copy with the new uid.
*/
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.BODY);
localFolder.fetch(Collections.singletonList(localMessage), fp, null);
String oldUid = localMessage.getUid();
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
String messageServerId = backend.uploadMessage(folderServerId, localMessage);
if (messageServerId == null) {
// We didn't get the server UID of the uploaded message. Remove the local message now. The uploaded
// version will be downloaded during the next sync.
localFolder.destroyMessages(Collections.singletonList(localMessage));
} else {
localMessage.setUid(messageServerId);
localFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
}
}
}
use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.
the class MessagingController method processPendingExpunge.
void processPendingExpunge(PendingExpunge command, Account account) throws MessagingException {
Backend backend = getBackend(account);
String folderServerId = getFolderServerId(account, command.folderId);
backend.expunge(folderServerId);
}
use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.
the class MessagingController method syncFolder.
private void syncFolder(Account account, long folderId, boolean notify, MessagingListener listener, Backend backend, NotificationState notificationState) {
ServerSettings serverSettings = account.getIncomingServerSettings();
if (serverSettings.isMissingCredentials()) {
handleAuthenticationFailure(account, true);
return;
}
Exception commandException = null;
try {
processPendingCommandsSynchronous(account);
} catch (Exception e) {
Timber.e(e, "Failure processing command, but allow message sync attempt");
commandException = e;
}
LocalFolder localFolder;
try {
LocalStore localStore = localStoreProvider.getInstance(account);
localFolder = localStore.getFolder(folderId);
localFolder.open();
} catch (MessagingException e) {
Timber.e(e, "syncFolder: Couldn't load local folder %d", folderId);
return;
}
// We can't sync local folders
if (localFolder.isLocalOnly()) {
return;
}
final boolean suppressNotifications;
if (notify) {
MessageStore messageStore = messageStoreManager.getMessageStore(account);
Long lastChecked = messageStore.getFolder(folderId, FolderDetailsAccessor::getLastChecked);
suppressNotifications = lastChecked == null;
} else {
suppressNotifications = true;
}
String folderServerId = localFolder.getServerId();
SyncConfig syncConfig = createSyncConfig(account);
ControllerSyncListener syncListener = new ControllerSyncListener(account, listener, suppressNotifications, notificationState);
backend.sync(folderServerId, syncConfig, syncListener);
if (commandException != null && !syncListener.syncFailed) {
String rootMessage = getRootCauseMessage(commandException);
Timber.e("Root cause failure in %s:%s was '%s'", account, folderServerId, rootMessage);
updateFolderStatus(account, folderServerId, rootMessage);
listener.synchronizeMailboxFailed(account, folderId, rootMessage);
}
}
use of com.fsck.k9.backend.api.Backend in project k-9 by k9mail.
the class MessagingController method searchRemoteMessagesSynchronous.
@VisibleForTesting
void searchRemoteMessagesSynchronous(String acctUuid, long folderId, String query, Set<Flag> requiredFlags, Set<Flag> forbiddenFlags, MessagingListener listener) {
Account account = preferences.getAccount(acctUuid);
if (listener != null) {
listener.remoteSearchStarted(folderId);
}
List<String> extraResults = new ArrayList<>();
try {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
if (!localFolder.exists()) {
throw new MessagingException("Folder not found");
}
localFolder.open();
String folderServerId = localFolder.getServerId();
Backend backend = getBackend(account);
boolean performFullTextSearch = account.isRemoteSearchFullText();
List<String> messageServerIds = backend.search(folderServerId, query, requiredFlags, forbiddenFlags, performFullTextSearch);
Timber.i("Remote search got %d results", messageServerIds.size());
// There's no need to fetch messages already completely downloaded
messageServerIds = localFolder.extractNewMessages(messageServerIds);
if (listener != null) {
listener.remoteSearchServerQueryComplete(folderId, messageServerIds.size(), account.getRemoteSearchNumResults());
}
int resultLimit = account.getRemoteSearchNumResults();
if (resultLimit > 0 && messageServerIds.size() > resultLimit) {
extraResults = messageServerIds.subList(resultLimit, messageServerIds.size());
messageServerIds = messageServerIds.subList(0, resultLimit);
}
loadSearchResultsSynchronous(account, messageServerIds, localFolder);
} catch (Exception e) {
if (Thread.currentThread().isInterrupted()) {
Timber.i(e, "Caught exception on aborted remote search; safe to ignore.");
} else {
Timber.e(e, "Could not complete remote search");
if (listener != null) {
listener.remoteSearchFailed(null, e.getMessage());
}
Timber.e(e);
}
} finally {
if (listener != null) {
listener.remoteSearchFinished(folderId, 0, account.getRemoteSearchNumResults(), extraResults);
}
}
}
Aggregations