use of com.fsck.k9.K9 in project k-9 by k9mail.
the class MessagingController method processPendingMoveOrCopy.
void processPendingMoveOrCopy(PendingMoveOrCopy command, Account account) throws MessagingException {
Folder remoteSrcFolder = null;
Folder remoteDestFolder = null;
LocalFolder localDestFolder;
try {
String srcFolder = command.srcFolder;
if (account.getErrorFolderName().equals(srcFolder)) {
return;
}
String destFolder = command.destFolder;
boolean isCopy = command.isCopy;
Store remoteStore = account.getRemoteStore();
remoteSrcFolder = remoteStore.getFolder(srcFolder);
Store localStore = account.getLocalStore();
localDestFolder = (LocalFolder) localStore.getFolder(destFolder);
List<Message> messages = new ArrayList<>();
Collection<String> uids = command.newUidMap != null ? command.newUidMap.keySet() : command.uids;
for (String uid : uids) {
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
messages.add(remoteSrcFolder.getMessage(uid));
}
}
if (!remoteSrcFolder.exists()) {
throw new MessagingException("processingPendingMoveOrCopy: remoteFolder " + srcFolder + " does not exist", true);
}
remoteSrcFolder.open(Folder.OPEN_MODE_RW);
if (remoteSrcFolder.getMode() != Folder.OPEN_MODE_RW) {
throw new MessagingException("processingPendingMoveOrCopy: could not open remoteSrcFolder " + srcFolder + " read/write", true);
}
Timber.d("processingPendingMoveOrCopy: source folder = %s, %d messages, destination folder = %s, " + "isCopy = %s", srcFolder, messages.size(), destFolder, isCopy);
Map<String, String> remoteUidMap = null;
if (!isCopy && destFolder.equals(account.getTrashFolderName())) {
Timber.d("processingPendingMoveOrCopy doing special case for deleting message");
String destFolderName = destFolder;
if (K9.FOLDER_NONE.equals(destFolderName)) {
destFolderName = null;
}
remoteSrcFolder.delete(messages, destFolderName);
} else {
remoteDestFolder = remoteStore.getFolder(destFolder);
if (isCopy) {
remoteUidMap = remoteSrcFolder.copyMessages(messages, remoteDestFolder);
} else {
remoteUidMap = remoteSrcFolder.moveMessages(messages, remoteDestFolder);
}
}
if (!isCopy && Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder);
remoteSrcFolder.expunge();
}
/*
* This next part is used to bring the local UIDs of the local destination folder
* upto speed with the remote UIDs of remote destination folder.
*/
if (command.newUidMap != null && remoteUidMap != null && !remoteUidMap.isEmpty()) {
for (Map.Entry<String, String> entry : remoteUidMap.entrySet()) {
String remoteSrcUid = entry.getKey();
String newUid = entry.getValue();
String localDestUid = command.newUidMap.get(remoteSrcUid);
if (localDestUid == null) {
continue;
}
Message localDestMessage = localDestFolder.getMessage(localDestUid);
if (localDestMessage != null) {
localDestMessage.setUid(newUid);
localDestFolder.changeUid((LocalMessage) localDestMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, destFolder, localDestUid, newUid);
}
}
}
}
} finally {
closeFolder(remoteSrcFolder);
closeFolder(remoteDestFolder);
}
}
use of com.fsck.k9.K9 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.
* TODO update the local message UID instead of deleting it
*/
void processPendingAppend(PendingAppend command, Account account) throws MessagingException {
Folder remoteFolder = null;
LocalFolder localFolder = null;
try {
String folder = command.folder;
String uid = command.uid;
if (account.getErrorFolderName().equals(folder)) {
return;
}
LocalStore localStore = account.getLocalStore();
localFolder = localStore.getFolder(folder);
LocalMessage localMessage = localFolder.getMessage(uid);
if (localMessage == null) {
return;
}
Store remoteStore = account.getRemoteStore();
remoteFolder = remoteStore.getFolder(folder);
if (!remoteFolder.exists()) {
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES)) {
return;
}
}
remoteFolder.open(Folder.OPEN_MODE_RW);
if (remoteFolder.getMode() != Folder.OPEN_MODE_RW) {
return;
}
Message remoteMessage = null;
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
remoteMessage = remoteFolder.getMessage(localMessage.getUid());
}
if (remoteMessage == null) {
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 rUid = remoteFolder.getUidFromMessageId(localMessage);
if (rUid != 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, rUid);
String oldUid = localMessage.getUid();
localMessage.setUid(rUid);
localFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folder, 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);
remoteFolder.appendMessages(Collections.singletonList(localMessage));
localFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
}
} else {
/*
* If the remote message exists we need to determine which copy to keep.
*/
/*
* See if the remote message is newer than ours.
*/
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
remoteFolder.fetch(Collections.singletonList(remoteMessage), fp, null);
Date localDate = localMessage.getInternalDate();
Date remoteDate = remoteMessage.getInternalDate();
if (remoteDate != null && remoteDate.compareTo(localDate) > 0) {
/*
* If the remote message is newer than ours we'll just
* delete ours and move on. A sync will get the server message
* if we need to be able to see it.
*/
localMessage.destroy();
} else {
/*
* Otherwise we'll upload our message and then delete the remote message.
*/
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);
remoteFolder.appendMessages(Collections.singletonList(localMessage));
localFolder.changeUid(localMessage);
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
}
if (remoteDate != null) {
remoteMessage.setFlag(Flag.DELETED, true);
if (Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
remoteFolder.expunge();
}
}
}
}
} finally {
closeFolder(remoteFolder);
closeFolder(localFolder);
}
}
use of com.fsck.k9.K9 in project k-9 by k9mail.
the class MessagingController method refreshRemoteSynchronous.
@VisibleForTesting
void refreshRemoteSynchronous(final Account account, final MessagingListener listener) {
List<LocalFolder> localFolders = null;
try {
Store store = account.getRemoteStore();
List<? extends Folder> remoteFolders = store.getPersonalNamespaces(false);
LocalStore localStore = account.getLocalStore();
Set<String> remoteFolderNames = new HashSet<>();
List<LocalFolder> foldersToCreate = new LinkedList<>();
localFolders = localStore.getPersonalNamespaces(false);
Set<String> localFolderNames = new HashSet<>();
for (Folder localFolder : localFolders) {
localFolderNames.add(localFolder.getName());
}
for (Folder remoteFolder : remoteFolders) {
if (!localFolderNames.contains(remoteFolder.getName())) {
LocalFolder localFolder = localStore.getFolder(remoteFolder.getName());
foldersToCreate.add(localFolder);
}
remoteFolderNames.add(remoteFolder.getName());
}
localStore.createFolders(foldersToCreate, account.getDisplayCount());
localFolders = localStore.getPersonalNamespaces(false);
/*
* Clear out any folders that are no longer on the remote store.
*/
for (Folder localFolder : localFolders) {
String localFolderName = localFolder.getName();
// special placeholder folder "-NONE-".
if (K9.FOLDER_NONE.equals(localFolderName)) {
localFolder.delete(false);
}
if (!account.isSpecialFolder(localFolderName) && !remoteFolderNames.contains(localFolderName)) {
localFolder.delete(false);
}
}
localFolders = localStore.getPersonalNamespaces(false);
for (MessagingListener l : getListeners(listener)) {
l.listFolders(account, localFolders);
}
for (MessagingListener l : getListeners(listener)) {
l.listFoldersFinished(account);
}
} catch (Exception e) {
for (MessagingListener l : getListeners(listener)) {
l.listFoldersFailed(account, "");
}
addErrorMessage(account, null, e);
} finally {
if (localFolders != null) {
for (Folder localFolder : localFolders) {
closeFolder(localFolder);
}
}
}
}
use of com.fsck.k9.K9 in project k-9 by k9mail.
the class Prefs method saveSettings.
private void saveSettings() {
Storage storage = Preferences.getPreferences(this).getStorage();
K9.setK9Theme(themeNameToId(mTheme.getValue()));
K9.setUseFixedMessageViewTheme(mFixedMessageTheme.isChecked());
K9.setK9MessageViewThemeSetting(themeNameToId(mMessageTheme.getValue()));
K9.setK9ComposerThemeSetting(themeNameToId(mComposerTheme.getValue()));
K9.setAnimations(mAnimations.isChecked());
K9.setGesturesEnabled(mGestures.isChecked());
K9.setUseVolumeKeysForNavigation(mVolumeNavigation.getCheckedItems()[0]);
K9.setUseVolumeKeysForListNavigation(mVolumeNavigation.getCheckedItems()[1]);
K9.setStartIntegratedInbox(!mHideSpecialAccounts.isChecked() && mStartIntegratedInbox.isChecked());
K9.setNotificationHideSubject(NotificationHideSubject.valueOf(mNotificationHideSubject.getValue()));
int index = 0;
K9.setConfirmDelete(mConfirmActions.getCheckedItems()[index++]);
K9.setConfirmDeleteStarred(mConfirmActions.getCheckedItems()[index++]);
if (NotificationController.platformSupportsExtendedNotifications()) {
K9.setConfirmDeleteFromNotification(mConfirmActions.getCheckedItems()[index++]);
}
K9.setConfirmSpam(mConfirmActions.getCheckedItems()[index++]);
K9.setConfirmDiscardMessage(mConfirmActions.getCheckedItems()[index++]);
K9.setConfirmMarkAllRead(mConfirmActions.getCheckedItems()[index++]);
K9.setMeasureAccounts(mMeasureAccounts.isChecked());
K9.setCountSearchMessages(mCountSearch.isChecked());
K9.setHideSpecialAccounts(mHideSpecialAccounts.isChecked());
K9.setMessageListPreviewLines(Integer.parseInt(mPreviewLines.getValue()));
K9.setMessageListCheckboxes(mCheckboxes.isChecked());
K9.setMessageListStars(mStars.isChecked());
K9.setShowCorrespondentNames(mShowCorrespondentNames.isChecked());
K9.setMessageListSenderAboveSubject(mSenderAboveSubject.isChecked());
K9.setShowContactName(mShowContactName.isChecked());
K9.setShowContactPicture(mShowContactPicture.isChecked());
K9.setColorizeMissingContactPictures(mColorizeMissingContactPictures.isChecked());
K9.setUseBackgroundAsUnreadIndicator(mBackgroundAsUnreadIndicator.isChecked());
K9.setThreadedViewEnabled(mThreadedView.isChecked());
K9.setChangeContactNameColor(mChangeContactNameColor.isChecked());
K9.setMessageViewFixedWidthFont(mFixedWidth.isChecked());
K9.setMessageViewReturnToList(mReturnToList.isChecked());
K9.setMessageViewShowNext(mShowNext.isChecked());
K9.setAutofitWidth(mAutofitWidth.isChecked());
K9.setQuietTimeEnabled(mQuietTimeEnabled.isChecked());
boolean[] enabledRefileActions = mVisibleRefileActions.getCheckedItems();
K9.setMessageViewDeleteActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_DELETE]);
K9.setMessageViewArchiveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_ARCHIVE]);
K9.setMessageViewMoveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_MOVE]);
K9.setMessageViewCopyActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_COPY]);
K9.setMessageViewSpamActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_SPAM]);
K9.setNotificationDuringQuietTimeEnabled(!mDisableNotificationDuringQuietTime.isChecked());
K9.setQuietTimeStarts(mQuietTimeStarts.getTime());
K9.setQuietTimeEnds(mQuietTimeEnds.getTime());
K9.setWrapFolderNames(mWrapFolderNames.isChecked());
if (mNotificationQuickDelete != null) {
K9.setNotificationQuickDeleteBehaviour(NotificationQuickDelete.valueOf(mNotificationQuickDelete.getValue()));
}
if (mLockScreenNotificationVisibility != null) {
K9.setLockScreenNotificationVisibility(K9.LockScreenNotificationVisibility.valueOf(mLockScreenNotificationVisibility.getValue()));
}
K9.setSplitViewMode(SplitViewMode.valueOf(mSplitViewMode.getValue()));
K9.setAttachmentDefaultPath(mAttachmentPathPreference.getSummary().toString());
boolean needsRefresh = K9.setBackgroundOps(mBackgroundOps.getValue());
if (!K9.isDebug() && mDebugLogging.isChecked()) {
Toast.makeText(this, R.string.debug_logging_enabled, Toast.LENGTH_LONG).show();
}
K9.setDebug(mDebugLogging.isChecked());
K9.DEBUG_SENSITIVE = mSensitiveLogging.isChecked();
K9.setHideUserAgent(mHideUserAgent.isChecked());
K9.setHideTimeZone(mHideTimeZone.isChecked());
K9.setOpenPgpProvider(mOpenPgpProvider.getValue());
K9.setOpenPgpSupportSignOnly(mOpenPgpSupportSignOnly.isChecked());
StorageEditor editor = storage.edit();
K9.save(editor);
editor.commit();
if (needsRefresh) {
MailService.actionReset(this, null);
}
}
use of com.fsck.k9.K9 in project k-9 by k9mail.
the class SettingsImporter method importSettings.
/**
* Reads an import {@link InputStream} and imports the global settings and/or account
* configurations specified by the arguments.
*
* @param context
* A {@link Context} instance.
* @param inputStream
* The {@code InputStream} to read the settings from.
* @param globalSettings
* {@code true} if global settings should be imported from the file.
* @param accountUuids
* A list of UUIDs of the accounts that should be imported.
* @param overwrite
* {@code true} if existing accounts should be overwritten when an account with the
* same UUID is found in the settings file.<br>
* <strong>Note:</strong> This can have side-effects we currently don't handle, e.g.
* changing the account type from IMAP to POP3. So don't use this for now!
*
* @return An {@link ImportResults} instance containing information about errors and
* successfully imported accounts.
*
* @throws SettingsImportExportException
* In case of an error.
*/
public static ImportResults importSettings(Context context, InputStream inputStream, boolean globalSettings, List<String> accountUuids, boolean overwrite) throws SettingsImportExportException {
try {
boolean globalSettingsImported = false;
List<AccountDescriptionPair> importedAccounts = new ArrayList<>();
List<AccountDescription> erroneousAccounts = new ArrayList<>();
Imported imported = parseSettings(inputStream, globalSettings, accountUuids, false);
Preferences preferences = Preferences.getPreferences(context);
Storage storage = preferences.getStorage();
if (globalSettings) {
try {
StorageEditor editor = storage.edit();
if (imported.globalSettings != null) {
importGlobalSettings(storage, editor, imported.contentVersion, imported.globalSettings);
} else {
Timber.w("Was asked to import global settings but none found.");
}
if (editor.commit()) {
Timber.v("Committed global settings to the preference storage.");
globalSettingsImported = true;
} else {
Timber.v("Failed to commit global settings to the preference storage");
}
} catch (Exception e) {
Timber.e(e, "Exception while importing global settings");
}
}
if (accountUuids != null && accountUuids.size() > 0) {
if (imported.accounts != null) {
for (String accountUuid : accountUuids) {
if (imported.accounts.containsKey(accountUuid)) {
ImportedAccount account = imported.accounts.get(accountUuid);
try {
StorageEditor editor = storage.edit();
AccountDescriptionPair importResult = importAccount(context, editor, imported.contentVersion, account, overwrite);
if (editor.commit()) {
Timber.v("Committed settings for account \"%s\" to the settings database.", importResult.imported.name);
// account UUIDs
if (!importResult.overwritten) {
editor = storage.edit();
String newUuid = importResult.imported.uuid;
String oldAccountUuids = storage.getString("accountUuids", "");
String newAccountUuids = (oldAccountUuids.length() > 0) ? oldAccountUuids + "," + newUuid : newUuid;
putString(editor, "accountUuids", newAccountUuids);
if (!editor.commit()) {
throw new SettingsImportExportException("Failed to set account UUID list");
}
}
// Reload accounts
preferences.loadAccounts();
importedAccounts.add(importResult);
} else {
Timber.w("Error while committing settings for account \"%s\" to the settings " + "database.", importResult.original.name);
erroneousAccounts.add(importResult.original);
}
} catch (InvalidSettingValueException e) {
Timber.e(e, "Encountered invalid setting while importing account \"%s\"", account.name);
erroneousAccounts.add(new AccountDescription(account.name, account.uuid));
} catch (Exception e) {
Timber.e(e, "Exception while importing account \"%s\"", account.name);
erroneousAccounts.add(new AccountDescription(account.name, account.uuid));
}
} else {
Timber.w("Was asked to import account with UUID %s. But this account wasn't found.", accountUuid);
}
}
StorageEditor editor = storage.edit();
String defaultAccountUuid = storage.getString("defaultAccountUuid", null);
if (defaultAccountUuid == null) {
putString(editor, "defaultAccountUuid", accountUuids.get(0));
}
if (!editor.commit()) {
throw new SettingsImportExportException("Failed to set default account");
}
} else {
Timber.w("Was asked to import at least one account but none found.");
}
}
preferences.loadAccounts();
K9.loadPrefs(preferences);
K9.setServicesEnabled(context);
return new ImportResults(globalSettingsImported, importedAccounts, erroneousAccounts);
} catch (SettingsImportExportException e) {
throw e;
} catch (Exception e) {
throw new SettingsImportExportException(e);
}
}
Aggregations