use of com.fsck.k9.mail.Store in project k-9 by k9mail.
the class MessagingController method setupPushing.
public boolean setupPushing(final Account account) {
try {
Pusher previousPusher = pushers.remove(account);
if (previousPusher != null) {
previousPusher.stop();
}
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
Account.FolderMode aPushMode = account.getFolderPushMode();
List<String> names = new ArrayList<>();
Store localStore = account.getLocalStore();
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
if (folder.getName().equals(account.getErrorFolderName()) || folder.getName().equals(account.getOutboxFolderName())) {
continue;
}
folder.open(Folder.OPEN_MODE_RW);
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
Folder.FolderClass fPushClass = folder.getPushClass();
if (modeMismatch(aDisplayMode, fDisplayClass)) {
continue;
}
if (modeMismatch(aPushMode, fPushClass)) {
continue;
}
Timber.i("Starting pusher for %s:%s", account.getDescription(), folder.getName());
names.add(folder.getName());
}
if (!names.isEmpty()) {
PushReceiver receiver = new MessagingControllerPushReceiver(context, account, this);
int maxPushFolders = account.getMaxPushFolders();
if (names.size() > maxPushFolders) {
Timber.i("Count of folders to push for account %s is %d, greater than limit of %d, truncating", account.getDescription(), names.size(), maxPushFolders);
names = names.subList(0, maxPushFolders);
}
try {
Store store = account.getRemoteStore();
if (!store.isPushCapable()) {
Timber.i("Account %s is not push capable, skipping", account.getDescription());
return false;
}
Pusher pusher = store.getPusher(receiver);
if (pusher != null) {
Pusher oldPusher = pushers.putIfAbsent(account, pusher);
if (oldPusher == null) {
pusher.start(names);
}
}
} catch (Exception e) {
Timber.e(e, "Could not get remote store");
return false;
}
return true;
} else {
Timber.i("No folders are configured for pushing in account %s", account.getDescription());
return false;
}
} catch (Exception e) {
Timber.e(e, "Got exception while setting up pushing");
}
return false;
}
use of com.fsck.k9.mail.Store 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.mail.Store 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.mail.Store 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.mail.Store in project k-9 by k9mail.
the class LockableDatabase method switchProvider.
/**
* @param newProviderId
* Never <code>null</code>.
* @throws MessagingException
*/
public void switchProvider(final String newProviderId) throws MessagingException {
if (newProviderId.equals(mStorageProviderId)) {
Timber.v("LockableDatabase: Ignoring provider switch request as they are equal: %s", newProviderId);
return;
}
final String oldProviderId = mStorageProviderId;
lockWrite(oldProviderId);
try {
lockWrite(newProviderId);
try {
try {
mDb.close();
} catch (Exception e) {
Timber.i(e, "Unable to close DB on local store migration");
}
final StorageManager storageManager = getStorageManager();
File oldDatabase = storageManager.getDatabase(uUid, oldProviderId);
// create new path
prepareStorage(newProviderId);
// move all database files
FileHelper.moveRecursive(oldDatabase, storageManager.getDatabase(uUid, newProviderId));
// move all attachment files
FileHelper.moveRecursive(storageManager.getAttachmentDirectory(uUid, oldProviderId), storageManager.getAttachmentDirectory(uUid, newProviderId));
// remove any remaining old journal files
deleteDatabase(oldDatabase);
mStorageProviderId = newProviderId;
// re-initialize this class with the new Uri
openOrCreateDataspace();
} finally {
unlockWrite(newProviderId);
}
} finally {
unlockWrite(oldProviderId);
}
}
Aggregations