use of com.fsck.k9.mail.MessageRetrievalListener in project k-9 by k9mail.
the class ImapFolder method fetchPart.
@Override
public void fetchPart(Message message, Part part, MessageRetrievalListener<Message> listener) throws MessagingException {
checkOpen();
String partId = part.getServerExtra();
String fetch;
if ("TEXT".equalsIgnoreCase(partId)) {
int maximumAutoDownloadMessageSize = store.getStoreConfig().getMaximumAutoDownloadMessageSize();
fetch = String.format(Locale.US, "BODY.PEEK[TEXT]<0.%d>", maximumAutoDownloadMessageSize);
} else {
fetch = String.format("BODY.PEEK[%s]", partId);
}
try {
String command = String.format("UID FETCH %s (UID %s)", message.getUid(), fetch);
connection.sendCommand(command, false);
ImapResponse response;
int messageNumber = 0;
ImapResponseCallback callback = new FetchPartCallback(part);
do {
response = connection.readResponse(callback);
if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(1), "FETCH")) {
ImapList fetchList = (ImapList) response.getKeyedValue("FETCH");
String uid = fetchList.getKeyedString("UID");
if (!message.getUid().equals(uid)) {
if (K9MailLib.isDebug()) {
Log.d(LOG_TAG, "Did not ask for UID " + uid + " for " + getLogId());
}
handleUntaggedResponse(response);
continue;
}
if (listener != null) {
listener.messageStarted(uid, messageNumber++, 1);
}
ImapMessage imapMessage = (ImapMessage) message;
Object literal = handleFetchResponse(imapMessage, fetchList);
if (literal != null) {
if (literal instanceof Body) {
// Most of the work was done in FetchAttchmentCallback.foundLiteral()
MimeMessageHelper.setBody(part, (Body) literal);
} else if (literal instanceof String) {
String bodyString = (String) literal;
InputStream bodyStream = new ByteArrayInputStream(bodyString.getBytes());
String contentTransferEncoding = part.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0];
String contentType = part.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0];
MimeMessageHelper.setBody(part, MimeUtility.createBody(bodyStream, contentTransferEncoding, contentType));
} else {
// This shouldn't happen
throw new MessagingException("Got FETCH response with bogus parameters");
}
}
if (listener != null) {
listener.messageFinished(message, messageNumber, 1);
}
} else {
handleUntaggedResponse(response);
}
} while (response.getTag() == null);
} catch (IOException ioe) {
throw ioExceptionHandler(connection, ioe);
}
}
use of com.fsck.k9.mail.MessageRetrievalListener in project k-9 by k9mail.
the class MessagingController method searchLocalMessagesSynchronous.
@VisibleForTesting
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
List<Account> searchAccounts = getAccountsFromLocalSearch(search, preferences);
for (final Account account : searchAccounts) {
// 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);
if (listener != null) {
listener.listLocalMessagesAddMessages(account, null, messages);
}
}
}
};
// build and do the query in the localstore
try {
LocalStore localStore = localStoreProvider.getInstance(account);
localStore.searchForMessages(retrievalListener, search);
} catch (Exception e) {
Timber.e(e);
}
}
if (listener != null) {
listener.listLocalMessagesFinished();
}
}
use of com.fsck.k9.mail.MessageRetrievalListener in project k-9 by k9mail.
the class WebDavFolder method fetchMessages.
/**
* Fetches the full messages or up to {@param lines} lines and passes them to the message parser.
*/
private void fetchMessages(List<WebDavMessage> messages, MessageRetrievalListener<WebDavMessage> listener, int lines) throws MessagingException {
WebDavHttpClient httpclient;
httpclient = store.getHttpClient();
/**
* We can't hand off to processRequest() since we need the stream to parse.
*/
for (int i = 0, count = messages.size(); i < count; i++) {
WebDavMessage wdMessage = messages.get(i);
int statusCode = 0;
if (listener != null) {
listener.messageStarted(wdMessage.getUid(), i, count);
}
/**
* If fetch is called outside of the initial list (ie, a locally stored message), it may not have a URL
* associated. Verify and fix that
*/
if (wdMessage.getUrl().equals("")) {
wdMessage.setUrl(getMessageUrls(new String[] { wdMessage.getUid() }).get(wdMessage.getUid()));
Timber.i("Fetching messages with UID = '%s', URL = '%s'", wdMessage.getUid(), wdMessage.getUrl());
if (wdMessage.getUrl().equals("")) {
throw new MessagingException("Unable to get URL for message");
}
}
try {
Timber.i("Fetching message with UID = '%s', URL = '%s'", wdMessage.getUid(), wdMessage.getUrl());
HttpGet httpget = new HttpGet(new URI(wdMessage.getUrl()));
HttpResponse response;
HttpEntity entity;
httpget.setHeader("translate", "f");
if (store.getAuthentication() == WebDavConstants.AUTH_TYPE_BASIC) {
httpget.setHeader("Authorization", store.getAuthString());
}
response = httpclient.executeOverride(httpget, store.getHttpContext());
statusCode = response.getStatusLine().getStatusCode();
entity = response.getEntity();
if (statusCode < 200 || statusCode > 300) {
throw new IOException("Error during with code " + statusCode + " during fetch: " + response.getStatusLine().toString());
}
if (entity != null) {
InputStream istream = null;
StringBuilder buffer = new StringBuilder();
String tempText;
String resultText;
BufferedReader reader = null;
int currentLines = 0;
try {
istream = WebDavHttpClient.getUngzippedContent(entity);
if (lines != -1) {
// Convert the ungzipped input stream into a StringBuilder
// containing the given line count
reader = new BufferedReader(new InputStreamReader(istream), 8192);
while ((tempText = reader.readLine()) != null && (currentLines < lines)) {
buffer.append(tempText).append("\r\n");
currentLines++;
}
IOUtils.closeQuietly(istream);
resultText = buffer.toString();
istream = new ByteArrayInputStream(resultText.getBytes("UTF-8"));
}
// Parse either the entire message stream, or a stream of the given lines
wdMessage.parse(istream);
} catch (IOException ioe) {
Timber.e(ioe, "IOException during message parsing");
throw new MessagingException("I/O Error", ioe);
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(istream);
}
} else {
Timber.v("Empty response");
}
} catch (IllegalArgumentException iae) {
Timber.e(iae, "IllegalArgumentException caught");
throw new MessagingException("IllegalArgumentException caught", iae);
} catch (URISyntaxException use) {
Timber.e(use, "URISyntaxException caught");
throw new MessagingException("URISyntaxException caught", use);
} catch (IOException ioe) {
Timber.e(ioe, "Non-success response code loading message, response code was %d, URL: %s", statusCode, wdMessage.getUrl());
throw new MessagingException("Failure code " + statusCode, ioe);
}
if (listener != null) {
listener.messageFinished(wdMessage, i, count);
}
}
}
use of com.fsck.k9.mail.MessageRetrievalListener in project k-9 by k9mail.
the class Pop3Folder method getMessages.
public List<Pop3Message> getMessages(int start, int end, MessageRetrievalListener<Pop3Message> listener) throws MessagingException {
if (start < 1 || end < 1 || end < start) {
throw new MessagingException(String.format(Locale.US, "Invalid message set %d %d", start, end));
}
try {
indexMsgNums(start, end);
} catch (IOException ioe) {
throw new MessagingException("getMessages", ioe);
}
List<Pop3Message> messages = new ArrayList<>();
int i = 0;
for (int msgNum = start; msgNum <= end; msgNum++) {
Pop3Message message = msgNumToMsgMap.get(msgNum);
if (message == null) {
/*
* There could be gaps in the message numbers or malformed
* responses which lead to "gaps" in msgNumToMsgMap.
*
* See issue 2252
*/
continue;
}
if (listener != null) {
listener.messageStarted(message.getUid(), i++, (end - start) + 1);
}
messages.add(message);
if (listener != null) {
listener.messageFinished(message, i++, (end - start) + 1);
}
}
return messages;
}
use of com.fsck.k9.mail.MessageRetrievalListener in project k-9 by k9mail.
the class ImapFolder method fetch.
@Override
public void fetch(List<ImapMessage> messages, FetchProfile fetchProfile, MessageRetrievalListener<ImapMessage> listener) throws MessagingException {
if (messages == null || messages.isEmpty()) {
return;
}
checkOpen();
List<String> uids = new ArrayList<>(messages.size());
HashMap<String, Message> messageMap = new HashMap<>();
for (Message message : messages) {
String uid = message.getUid();
uids.add(uid);
messageMap.put(uid, message);
}
Set<String> fetchFields = new LinkedHashSet<>();
fetchFields.add("UID");
if (fetchProfile.contains(FetchProfile.Item.FLAGS)) {
fetchFields.add("FLAGS");
}
if (fetchProfile.contains(FetchProfile.Item.ENVELOPE)) {
fetchFields.add("INTERNALDATE");
fetchFields.add("RFC822.SIZE");
fetchFields.add("BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc " + "reply-to message-id references in-reply-to " + K9MailLib.IDENTITY_HEADER + ")]");
}
if (fetchProfile.contains(FetchProfile.Item.STRUCTURE)) {
fetchFields.add("BODYSTRUCTURE");
}
if (fetchProfile.contains(FetchProfile.Item.BODY_SANE)) {
int maximumAutoDownloadMessageSize = store.getStoreConfig().getMaximumAutoDownloadMessageSize();
if (maximumAutoDownloadMessageSize > 0) {
fetchFields.add(String.format(Locale.US, "BODY.PEEK[]<0.%d>", maximumAutoDownloadMessageSize));
} else {
fetchFields.add("BODY.PEEK[]");
}
}
if (fetchProfile.contains(FetchProfile.Item.BODY)) {
fetchFields.add("BODY.PEEK[]");
}
String spaceSeparatedFetchFields = combine(fetchFields.toArray(new String[fetchFields.size()]), ' ');
for (int windowStart = 0; windowStart < messages.size(); windowStart += (FETCH_WINDOW_SIZE)) {
int windowEnd = Math.min(windowStart + FETCH_WINDOW_SIZE, messages.size());
List<String> uidWindow = uids.subList(windowStart, windowEnd);
try {
String commaSeparatedUids = combine(uidWindow.toArray(new String[uidWindow.size()]), ',');
String command = String.format("UID FETCH %s (%s)", commaSeparatedUids, spaceSeparatedFetchFields);
connection.sendCommand(command, false);
ImapResponse response;
int messageNumber = 0;
ImapResponseCallback callback = null;
if (fetchProfile.contains(FetchProfile.Item.BODY) || fetchProfile.contains(FetchProfile.Item.BODY_SANE)) {
callback = new FetchBodyCallback(messageMap);
}
do {
response = connection.readResponse(callback);
if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(1), "FETCH")) {
ImapList fetchList = (ImapList) response.getKeyedValue("FETCH");
String uid = fetchList.getKeyedString("UID");
long msgSeq = response.getLong(0);
if (uid != null) {
try {
msgSeqUidMap.put(msgSeq, uid);
if (K9MailLib.isDebug()) {
Log.v(LOG_TAG, "Stored uid '" + uid + "' for msgSeq " + msgSeq + " into map");
}
} catch (Exception e) {
Log.e(LOG_TAG, "Unable to store uid '" + uid + "' for msgSeq " + msgSeq);
}
}
Message message = messageMap.get(uid);
if (message == null) {
if (K9MailLib.isDebug()) {
Log.d(LOG_TAG, "Do not have message in messageMap for UID " + uid + " for " + getLogId());
}
handleUntaggedResponse(response);
continue;
}
if (listener != null) {
listener.messageStarted(uid, messageNumber++, messageMap.size());
}
ImapMessage imapMessage = (ImapMessage) message;
Object literal = handleFetchResponse(imapMessage, fetchList);
if (literal != null) {
if (literal instanceof String) {
String bodyString = (String) literal;
InputStream bodyStream = new ByteArrayInputStream(bodyString.getBytes());
imapMessage.parse(bodyStream);
} else if (literal instanceof Integer) {
// All the work was done in FetchBodyCallback.foundLiteral()
} else {
// This shouldn't happen
throw new MessagingException("Got FETCH response with bogus parameters");
}
}
if (listener != null) {
listener.messageFinished(imapMessage, messageNumber, messageMap.size());
}
} else {
handleUntaggedResponse(response);
}
} while (response.getTag() == null);
} catch (IOException ioe) {
throw ioExceptionHandler(connection, ioe);
}
}
}
Aggregations