use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method searchRemoteMessagesSynchronous.
@VisibleForTesting
void searchRemoteMessagesSynchronous(final String acctUuid, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) {
final Account acct = Preferences.getPreferences(context).getAccount(acctUuid);
if (listener != null) {
listener.remoteSearchStarted(folderName);
}
List<Message> extraResults = new ArrayList<>();
try {
Store remoteStore = acct.getRemoteStore();
LocalStore localStore = acct.getLocalStore();
if (remoteStore == null || localStore == null) {
throw new MessagingException("Could not get store");
}
Folder remoteFolder = remoteStore.getFolder(folderName);
LocalFolder localFolder = localStore.getFolder(folderName);
if (remoteFolder == null || localFolder == null) {
throw new MessagingException("Folder not found");
}
List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags);
Timber.i("Remote search got %d results", messages.size());
// There's no need to fetch messages already completely downloaded
List<Message> remoteMessages = localFolder.extractNewMessages(messages);
messages.clear();
if (listener != null) {
listener.remoteSearchServerQueryComplete(folderName, remoteMessages.size(), acct.getRemoteSearchNumResults());
}
Collections.sort(remoteMessages, new UidReverseComparator());
int resultLimit = acct.getRemoteSearchNumResults();
if (resultLimit > 0 && remoteMessages.size() > resultLimit) {
extraResults = remoteMessages.subList(resultLimit, remoteMessages.size());
remoteMessages = remoteMessages.subList(0, resultLimit);
}
loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener);
} 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());
}
addErrorMessage(acct, null, e);
}
} finally {
if (listener != null) {
listener.remoteSearchFinished(folderName, 0, acct.getRemoteSearchNumResults(), extraResults);
}
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method loadMessageRemoteSynchronous.
private boolean loadMessageRemoteSynchronous(final Account account, final String folder, final String uid, final MessagingListener listener, final boolean loadPartialFromSearch) {
Folder remoteFolder = null;
LocalFolder localFolder = null;
try {
LocalStore localStore = account.getLocalStore();
localFolder = localStore.getFolder(folder);
localFolder.open(Folder.OPEN_MODE_RW);
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);
}
/* commented out because this was pulled from another unmerged branch:
} else if (localFolder.isLocalOnly() && !force) {
Log.w(K9.LOG_TAG, "Message in local-only folder so cannot download fully.");
// ASH move toast
android.widget.Toast.makeText(mApplication,
"Message in local-only folder so cannot download fully",
android.widget.Toast.LENGTH_LONG).show();
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
}*/
/*if (!message.isSet(Flag.X_DOWNLOADED_FULL)) */
{
/*
* At this point the message is not available, so we need to download it
* fully if possible.
*/
Store remoteStore = account.getRemoteStore();
remoteFolder = remoteStore.getFolder(folder);
remoteFolder.open(Folder.OPEN_MODE_RW);
// Get the remote message and fully download it
Message remoteMessage = remoteFolder.getMessage(uid);
if (loadPartialFromSearch) {
downloadMessages(account, remoteFolder, localFolder, Collections.singletonList(remoteMessage), false, false);
} else {
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.BODY);
remoteFolder.fetch(Collections.singletonList(remoteMessage), fp, null);
localFolder.appendMessages(Collections.singletonList(remoteMessage));
}
message = localFolder.getMessage(uid);
if (!loadPartialFromSearch) {
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
}
}
// Mark that this message is now fully synched
if (account.isMarkMessageAsReadOnView()) {
message.setFlag(Flag.SEEN, true);
}
// now that we have the full message, refresh the headers
for (MessagingListener l : getListeners(listener)) {
l.loadMessageRemoteFinished(account, folder, uid);
}
return true;
} catch (Exception e) {
for (MessagingListener l : getListeners(listener)) {
l.loadMessageRemoteFailed(account, folder, uid, e);
}
notifyUserIfCertificateProblem(account, e, true);
addErrorMessage(account, null, e);
return false;
} finally {
closeFolder(remoteFolder);
closeFolder(localFolder);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MessagingController method clearAllPending.
public void clearAllPending(final Account account) {
try {
Timber.w("Clearing pending commands!");
LocalStore localStore = account.getLocalStore();
localStore.removePendingCommands();
} catch (MessagingException me) {
Timber.e(me, "Unable to clear pending command");
addErrorMessage(account, null, me);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class LocalFolder method saveMessage.
protected void saveMessage(SQLiteDatabase db, Message message, boolean copy, Map<String, String> uidMap) throws MessagingException {
if (!(message instanceof MimeMessage)) {
throw new Error("LocalStore can only store Messages that extend MimeMessage");
}
long oldMessageId = -1;
String uid = message.getUid();
boolean shouldCreateNewMessage = uid == null || copy;
if (shouldCreateNewMessage) {
String randomLocalUid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
if (copy) {
// Save mapping: source UID -> target UID
uidMap.put(uid, randomLocalUid);
} else {
// Modify the Message instance to reference the new UID
message.setUid(randomLocalUid);
}
// The message will be saved with the newly generated UID
uid = randomLocalUid;
} else {
LocalMessage oldMessage = getMessage(uid);
if (oldMessage != null) {
oldMessageId = oldMessage.getId();
long oldRootMessagePartId = oldMessage.getMessagePartId();
deleteMessagePartsAndDataFromDisk(oldRootMessagePartId);
}
}
long rootId = -1;
long parentId = -1;
long msgId;
if (oldMessageId == -1) {
// This is a new message. Do the message threading.
ThreadInfo threadInfo = doMessageThreading(db, message);
oldMessageId = threadInfo.msgId;
rootId = threadInfo.rootId;
parentId = threadInfo.parentId;
}
try {
MessagePreviewCreator previewCreator = localStore.getMessagePreviewCreator();
PreviewResult previewResult = previewCreator.createPreview(message);
PreviewType previewType = previewResult.getPreviewType();
DatabasePreviewType databasePreviewType = DatabasePreviewType.fromPreviewType(previewType);
MessageFulltextCreator fulltextCreator = localStore.getMessageFulltextCreator();
String fulltext = fulltextCreator.createFulltext(message);
AttachmentCounter attachmentCounter = localStore.getAttachmentCounter();
int attachmentCount = attachmentCounter.getAttachmentCount(message);
long rootMessagePartId = saveMessageParts(db, message);
ContentValues cv = new ContentValues();
cv.put("message_part_id", rootMessagePartId);
cv.put("uid", uid);
cv.put("subject", message.getSubject());
cv.put("sender_list", Address.pack(message.getFrom()));
cv.put("date", message.getSentDate() == null ? System.currentTimeMillis() : message.getSentDate().getTime());
cv.put("flags", this.localStore.serializeFlags(message.getFlags()));
cv.put("deleted", message.isSet(Flag.DELETED) ? 1 : 0);
cv.put("read", message.isSet(Flag.SEEN) ? 1 : 0);
cv.put("flagged", message.isSet(Flag.FLAGGED) ? 1 : 0);
cv.put("answered", message.isSet(Flag.ANSWERED) ? 1 : 0);
cv.put("forwarded", message.isSet(Flag.FORWARDED) ? 1 : 0);
cv.put("folder_id", mFolderId);
cv.put("to_list", Address.pack(message.getRecipients(RecipientType.TO)));
cv.put("cc_list", Address.pack(message.getRecipients(RecipientType.CC)));
cv.put("bcc_list", Address.pack(message.getRecipients(RecipientType.BCC)));
cv.put("reply_to_list", Address.pack(message.getReplyTo()));
cv.put("attachment_count", attachmentCount);
cv.put("internal_date", message.getInternalDate() == null ? System.currentTimeMillis() : message.getInternalDate().getTime());
cv.put("mime_type", message.getMimeType());
cv.put("empty", 0);
cv.put("preview_type", databasePreviewType.getDatabaseValue());
if (previewResult.isPreviewTextAvailable()) {
cv.put("preview", previewResult.getPreviewText());
} else {
cv.putNull("preview");
}
String messageId = message.getMessageId();
if (messageId != null) {
cv.put("message_id", messageId);
}
if (oldMessageId == -1) {
msgId = db.insert("messages", "uid", cv);
// Create entry in 'threads' table
cv.clear();
cv.put("message_id", msgId);
if (rootId != -1) {
cv.put("root", rootId);
}
if (parentId != -1) {
cv.put("parent", parentId);
}
db.insert("threads", null, cv);
} else {
msgId = oldMessageId;
db.update("messages", cv, "id = ?", new String[] { Long.toString(oldMessageId) });
}
if (fulltext != null) {
cv.clear();
cv.put("docid", msgId);
cv.put("fulltext", fulltext);
db.replace("messages_fulltext", null, cv);
}
} catch (Exception e) {
throw new MessagingException("Error appending message: " + message.getSubject(), e);
}
}
use of com.fsck.k9.mailstore.LocalStore in project k-9 by k9mail.
the class MigrationTest method migrateTextPlain.
@Test
public void migrateTextPlain() throws Exception {
SQLiteDatabase db = createV50Database();
insertSimplePlaintextMessage(db);
db.close();
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
LocalMessage msg = localStore.getFolder("dev").getMessage("3");
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.BODY);
localStore.getFolder("dev").fetch(Collections.singletonList(msg), fp, null);
Assert.assertEquals("text/plain", msg.getMimeType());
Assert.assertEquals(2, msg.getId());
Assert.assertEquals(13, msg.getHeaderNames().size());
Assert.assertEquals(0, msg.getAttachmentCount());
Assert.assertEquals(1, msg.getHeader("User-Agent").length);
Assert.assertEquals("Mutt/1.5.24 (2015-08-30)", msg.getHeader("User-Agent")[0]);
Assert.assertEquals(1, msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE).length);
Assert.assertEquals("text/plain", MimeUtility.getHeaderParameter(msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0], null));
Assert.assertEquals("utf-8", MimeUtility.getHeaderParameter(msg.getHeader(MimeHeader.HEADER_CONTENT_TYPE)[0], "charset"));
Assert.assertTrue(msg.getBody() instanceof BinaryMemoryBody);
String msgTextContent = MessageExtractor.getTextFromPart(msg);
Assert.assertEquals("nothing special here.\r\n", msgTextContent);
}
Aggregations