use of com.fsck.k9.Account in project k-9 by k9mail.
the class MessagingController method searchLocalMessagesSynchronous.
@VisibleForTesting
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
final AccountStats stats = new AccountStats();
final Set<String> uuidSet = new HashSet<>(Arrays.asList(search.getAccountUuids()));
List<Account> accounts = Preferences.getPreferences(context).getAccounts();
boolean allAccounts = uuidSet.contains(SearchSpecification.ALL_ACCOUNTS);
// for every account we want to search do the query in the localstore
for (final Account account : accounts) {
if (!allAccounts && !uuidSet.contains(account.getUuid())) {
continue;
}
// Collecting statistics of the search result
MessageRetrievalListener<LocalMessage> retrievalListener = new MessageRetrievalListener<LocalMessage>() {
@Override
public void messageStarted(String message, int number, int ofTotal) {
}
@Override
public void messagesFinished(int number) {
}
@Override
public void messageFinished(LocalMessage message, int number, int ofTotal) {
if (!isMessageSuppressed(message)) {
List<LocalMessage> messages = new ArrayList<>();
messages.add(message);
stats.unreadMessageCount += (!message.isSet(Flag.SEEN)) ? 1 : 0;
stats.flaggedMessageCount += (message.isSet(Flag.FLAGGED)) ? 1 : 0;
if (listener != null) {
listener.listLocalMessagesAddMessages(account, null, messages);
}
}
}
};
// build and do the query in the localstore
try {
LocalStore localStore = account.getLocalStore();
localStore.searchForMessages(retrievalListener, search);
} catch (Exception e) {
addErrorMessage(account, null, e);
}
}
// publish the total search statistics
if (listener != null) {
listener.searchStats(stats);
}
}
use of com.fsck.k9.Account in project k-9 by k9mail.
the class MessagingController method moveMessageToDraftsFolder.
private void moveMessageToDraftsFolder(Account account, Folder localFolder, Store localStore, Message message) throws MessagingException {
LocalFolder draftsFolder = (LocalFolder) localStore.getFolder(account.getDraftsFolderName());
localFolder.moveMessages(Collections.singletonList(message), draftsFolder);
}
use of com.fsck.k9.Account in project k-9 by k9mail.
the class MessagingController method downloadMessages.
/**
* Fetches the messages described by inputMessages from the remote store and writes them to
* local storage.
*
* @param account
* The account the remote store belongs to.
* @param remoteFolder
* The remote folder to download messages from.
* @param localFolder
* The {@link LocalFolder} instance corresponding to the remote folder.
* @param inputMessages
* A list of messages objects that store the UIDs of which messages to download.
* @param flagSyncOnly
* Only flags will be fetched from the remote store if this is {@code true}.
* @param purgeToVisibleLimit
* If true, local messages will be purged down to the limit of visible messages.
*
* @return The number of downloaded messages that are not flagged as {@link Flag#SEEN}.
*
* @throws MessagingException
*/
private int downloadMessages(final Account account, final Folder remoteFolder, final LocalFolder localFolder, List<Message> inputMessages, boolean flagSyncOnly, boolean purgeToVisibleLimit) throws MessagingException {
final Date earliestDate = account.getEarliestPollDate();
// now
Date downloadStarted = new Date();
if (earliestDate != null) {
Timber.d("Only syncing messages after %s", earliestDate);
}
final String folder = remoteFolder.getName();
int unreadBeforeStart = 0;
try {
AccountStats stats = account.getStats(context);
unreadBeforeStart = stats.unreadMessageCount;
} catch (MessagingException e) {
Timber.e(e, "Unable to getUnreadMessageCount for account: %s", account);
}
List<Message> syncFlagMessages = new ArrayList<>();
List<Message> unsyncedMessages = new ArrayList<>();
final AtomicInteger newMessages = new AtomicInteger(0);
List<Message> messages = new ArrayList<>(inputMessages);
for (Message message : messages) {
evaluateMessageForDownload(message, folder, localFolder, remoteFolder, account, unsyncedMessages, syncFlagMessages, flagSyncOnly);
}
final AtomicInteger progress = new AtomicInteger(0);
final int todo = unsyncedMessages.size() + syncFlagMessages.size();
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
}
Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
messages.clear();
final List<Message> largeMessages = new ArrayList<>();
final List<Message> smallMessages = new ArrayList<>();
if (!unsyncedMessages.isEmpty()) {
/*
* Reverse the order of the messages. Depending on the server this may get us
* fetch results for newest to oldest. If not, no harm done.
*/
Collections.sort(unsyncedMessages, new UidReverseComparator());
int visibleLimit = localFolder.getVisibleLimit();
int listSize = unsyncedMessages.size();
if ((visibleLimit > 0) && (listSize > visibleLimit)) {
unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
}
FetchProfile fp = new FetchProfile();
if (remoteFolder.supportsFetchingFlags()) {
fp.add(FetchProfile.Item.FLAGS);
}
fp.add(FetchProfile.Item.ENVELOPE);
Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
fetchUnsyncedMessages(account, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp);
String updatedPushState = localFolder.getPushState();
for (Message message : unsyncedMessages) {
String newPushState = remoteFolder.getNewPushState(updatedPushState, message);
if (newPushState != null) {
updatedPushState = newPushState;
}
}
localFolder.setPushState(updatedPushState);
Timber.d("SYNC: Synced unsynced messages for folder %s", folder);
}
Timber.d("SYNC: Have %d large messages and %d small messages out of %d unsynced messages", largeMessages.size(), smallMessages.size(), unsyncedMessages.size());
unsyncedMessages.clear();
/*
* Grab the content of the small messages first. This is going to
* be very fast and at very worst will be a single up of a few bytes and a single
* download of 625k.
*/
FetchProfile fp = new FetchProfile();
//TODO: Only fetch small and large messages if we have some
fp.add(FetchProfile.Item.BODY);
// fp.add(FetchProfile.Item.FLAGS);
// fp.add(FetchProfile.Item.ENVELOPE);
downloadSmallMessages(account, remoteFolder, localFolder, smallMessages, progress, unreadBeforeStart, newMessages, todo, fp);
smallMessages.clear();
/*
* Now do the large messages that require more round trips.
*/
fp = new FetchProfile();
fp.add(FetchProfile.Item.STRUCTURE);
downloadLargeMessages(account, remoteFolder, localFolder, largeMessages, progress, unreadBeforeStart, newMessages, todo, fp);
largeMessages.clear();
/*
* Refresh the flags for any messages in the local store that we didn't just
* download.
*/
refreshLocalMessageFlags(account, remoteFolder, localFolder, syncFlagMessages, progress, todo);
Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
if (purgeToVisibleLimit) {
localFolder.purgeToVisibleLimit(new MessageRemovalListener() {
@Override
public void messageRemoved(Message message) {
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxRemovedMessage(account, folder, message);
}
}
});
}
// If the oldest message seen on this sync is newer than
// the oldest message seen on the previous sync, then
// we want to move our high-water mark forward
// this is all here just for pop which only syncs inbox
// this would be a little wrong for IMAP (we'd want a folder-level pref, not an account level pref.)
// fortunately, we just don't care.
Long oldestMessageTime = localFolder.getOldestMessageDate();
if (oldestMessageTime != null) {
Date oldestExtantMessage = new Date(oldestMessageTime);
if (oldestExtantMessage.before(downloadStarted) && oldestExtantMessage.after(new Date(account.getLatestOldMessageSeenTime()))) {
account.setLatestOldMessageSeenTime(oldestExtantMessage.getTime());
account.save(Preferences.getPreferences(context));
}
}
return newMessages.get();
}
use of com.fsck.k9.Account 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(final Account account, final Message message, MessagingListener listener) {
try {
LocalStore localStore = account.getLocalStore();
LocalFolder localFolder = localStore.getFolder(account.getOutboxFolderName());
localFolder.open(Folder.OPEN_MODE_RW);
localFolder.appendMessages(Collections.singletonList(message));
Message localMessage = localFolder.getMessage(message.getUid());
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
localFolder.close();
sendPendingMessages(account, listener);
} catch (Exception e) {
/*
for (MessagingListener l : getListeners())
{
// TODO general failed
}
*/
addErrorMessage(account, null, e);
}
}
use of com.fsck.k9.Account in project k-9 by k9mail.
the class MessagingController method actOnMessageGroup.
private void actOnMessageGroup(Account account, String folderName, List<MessageReference> messageReferences, MessageActor actor) {
try {
LocalFolder messageFolder = account.getLocalStore().getFolder(folderName);
List<LocalMessage> localMessages = messageFolder.getMessagesByReference(messageReferences);
actor.act(account, messageFolder, localMessages);
} catch (MessagingException e) {
Timber.e(e, "Error loading account?!");
}
}
Aggregations