Search in sources :

Example 36 with K9

use of com.fsck.k9.K9 in project k-9 by k9mail.

the class MigrationTo51 method db51MigrateMessageFormat.

/**
     * This method converts from the old message table structure to the new one.
     *
     * This is a complex migration, and ultimately we do not have enough
     * information to recreate the mime structure of the original mails.
     * What we have:
     *  - general mail info
     *  - html_content and text_content data, which is the squashed readable content of the mail
     *  - a table with message headers
     *  - attachments
     *
     * What we need to do:
     *  - migrate general mail info as-is
     *  - flag mails as migrated for re-download
     *  - for each message, recreate a mime structure from its message content and attachments:
     *    + insert one or both of textContent and htmlContent, depending on mimeType
     *    + if mimeType is text/plain, text/html or multipart/alternative and no
     *      attachments are present, just insert that.
     *    + otherwise, use multipart/mixed, adding attachments after textual content
     *    + revert content:// URIs in htmlContent to original cid: URIs.
     */
public static void db51MigrateMessageFormat(SQLiteDatabase db, MigrationsHelper migrationsHelper) {
    renameOldMessagesTableAndCreateNew(db);
    copyMessageMetadataToNewTable(db);
    File attachmentDirNew, attachmentDirOld;
    Account account = migrationsHelper.getAccount();
    attachmentDirNew = StorageManager.getInstance(K9.app).getAttachmentDirectory(account.getUuid(), account.getLocalStorageProviderId());
    attachmentDirOld = renameOldAttachmentDirAndCreateNew(account, attachmentDirNew);
    Cursor msgCursor = db.query("messages_old", new String[] { "id", "flags", "html_content", "text_content", "mime_type", "attachment_count" }, null, null, null, null, null);
    try {
        Timber.d("migrating %d messages", msgCursor.getCount());
        ContentValues cv = new ContentValues();
        while (msgCursor.moveToNext()) {
            long messageId = msgCursor.getLong(0);
            String messageFlags = msgCursor.getString(1);
            String htmlContent = msgCursor.getString(2);
            String textContent = msgCursor.getString(3);
            String mimeType = msgCursor.getString(4);
            int attachmentCount = msgCursor.getInt(5);
            try {
                updateFlagsForMessage(db, messageId, messageFlags, migrationsHelper);
                MimeHeader mimeHeader = loadHeaderFromHeadersTable(db, messageId);
                MimeStructureState structureState = MimeStructureState.getNewRootState();
                boolean messageHadSpecialFormat = false;
                // we do not rely on the protocol parameter here but guess by the multipart structure
                boolean isMaybePgpMimeEncrypted = attachmentCount == 2 && MimeUtil.isSameMimeType(mimeType, "multipart/encrypted");
                if (isMaybePgpMimeEncrypted) {
                    MimeStructureState maybeStructureState = migratePgpMimeEncryptedContent(db, messageId, attachmentDirOld, attachmentDirNew, mimeHeader, structureState);
                    if (maybeStructureState != null) {
                        structureState = maybeStructureState;
                        messageHadSpecialFormat = true;
                    }
                }
                if (!messageHadSpecialFormat) {
                    boolean isSimpleStructured = attachmentCount == 0 && Utility.isAnyMimeType(mimeType, "text/plain", "text/html", "multipart/alternative");
                    if (isSimpleStructured) {
                        structureState = migrateSimpleMailContent(db, htmlContent, textContent, mimeType, mimeHeader, structureState);
                    } else {
                        mimeType = "multipart/mixed";
                        structureState = migrateComplexMailContent(db, attachmentDirOld, attachmentDirNew, messageId, htmlContent, textContent, mimeHeader, structureState);
                    }
                }
                cv.clear();
                cv.put("mime_type", mimeType);
                cv.put("message_part_id", structureState.rootPartId);
                cv.put("attachment_count", attachmentCount);
                db.update("messages", cv, "id = ?", new String[] { Long.toString(messageId) });
            } catch (IOException e) {
                Timber.e(e, "error inserting into database");
            }
        }
    } finally {
        msgCursor.close();
    }
    cleanUpOldAttachmentDirectory(attachmentDirOld);
    dropOldMessagesTable(db);
}
Also used : ContentValues(android.content.ContentValues) Account(com.fsck.k9.Account) MimeHeader(com.fsck.k9.mail.internet.MimeHeader) IOException(java.io.IOException) Cursor(android.database.Cursor) File(java.io.File)

Example 37 with K9

use of com.fsck.k9.K9 in project k-9 by k9mail.

the class MessageBuilder method buildBody.

private void buildBody(MimeMessage message) throws MessagingException {
    // Build the body.
    // TODO FIXME - body can be either an HTML or Text part, depending on whether we're in
    // HTML mode or not.  Should probably fix this so we don't mix up html and text parts.
    TextBody body = buildText(isDraft);
    // text/plain part when messageFormat == MessageFormat.HTML
    TextBody bodyPlain = null;
    final boolean hasAttachments = !attachments.isEmpty();
    if (messageFormat == SimpleMessageFormat.HTML) {
        // HTML message (with alternative text part)
        // This is the compiled MIME part for an HTML message.
        MimeMultipart composedMimeMessage = createMimeMultipart();
        composedMimeMessage.setSubType("alternative");
        // Let the receiver select either the text or the HTML part.
        bodyPlain = buildText(isDraft, SimpleMessageFormat.TEXT);
        composedMimeMessage.addBodyPart(new MimeBodyPart(bodyPlain, "text/plain"));
        composedMimeMessage.addBodyPart(new MimeBodyPart(body, "text/html"));
        if (hasAttachments) {
            // If we're HTML and have attachments, we have a MimeMultipart container to hold the
            // whole message (mp here), of which one part is a MimeMultipart container
            // (composedMimeMessage) with the user's composed messages, and subsequent parts for
            // the attachments.
            MimeMultipart mp = createMimeMultipart();
            mp.addBodyPart(new MimeBodyPart(composedMimeMessage));
            addAttachmentsToMessage(mp);
            MimeMessageHelper.setBody(message, mp);
        } else {
            // If no attachments, our multipart/alternative part is the only one we need.
            MimeMessageHelper.setBody(message, composedMimeMessage);
        }
    } else if (messageFormat == SimpleMessageFormat.TEXT) {
        // Text-only message.
        if (hasAttachments) {
            MimeMultipart mp = createMimeMultipart();
            mp.addBodyPart(new MimeBodyPart(body, "text/plain"));
            addAttachmentsToMessage(mp);
            MimeMessageHelper.setBody(message, mp);
        } else {
            // No attachments to include, just stick the text body in the message and call it good.
            MimeMessageHelper.setBody(message, body);
        }
    }
    // If this is a draft, add metadata for thawing.
    if (isDraft) {
        // Add the identity to the message.
        message.addHeader(K9.IDENTITY_HEADER, buildIdentityHeader(body, bodyPlain));
    }
}
Also used : TextBody(com.fsck.k9.mail.internet.TextBody) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart)

Example 38 with K9

use of com.fsck.k9.K9 in project k-9 by k9mail.

the class MessageBuilder method buildHeader.

private void buildHeader(MimeMessage message) throws MessagingException {
    message.addSentDate(sentDate, hideTimeZone);
    Address from = new Address(identity.getEmail(), identity.getName());
    message.setFrom(from);
    message.setRecipients(RecipientType.TO, to);
    message.setRecipients(RecipientType.CC, cc);
    message.setRecipients(RecipientType.BCC, bcc);
    message.setSubject(subject);
    if (requestReadReceipt) {
        message.setHeader("Disposition-Notification-To", from.toEncodedString());
        message.setHeader("X-Confirm-Reading-To", from.toEncodedString());
        message.setHeader("Return-Receipt-To", from.toEncodedString());
    }
    if (!K9.hideUserAgent()) {
        message.setHeader("User-Agent", context.getString(R.string.message_header_mua));
    }
    final String replyTo = identity.getReplyTo();
    if (replyTo != null) {
        message.setReplyTo(new Address[] { new Address(replyTo) });
    }
    if (inReplyTo != null) {
        message.setInReplyTo(inReplyTo);
    }
    if (references != null) {
        message.setReferences(references);
    }
    String messageId = messageIdGenerator.generateMessageId(message);
    message.setMessageId(messageId);
    if (isDraft && isPgpInlineEnabled) {
        message.setFlag(Flag.X_DRAFT_OPENPGP_INLINE, true);
    }
}
Also used : Address(com.fsck.k9.mail.Address)

Example 39 with K9

use of com.fsck.k9.K9 in project k-9 by k9mail.

the class NotificationActionService method archiveMessages.

private void archiveMessages(Intent intent, Account account, MessagingController controller) {
    Timber.i("NotificationActionService archiving messages");
    String archiveFolderName = account.getArchiveFolderName();
    if (archiveFolderName == null || (archiveFolderName.equals(account.getSpamFolderName()) && K9.confirmSpam()) || !isMovePossible(controller, account, archiveFolderName)) {
        Timber.w("Can not archive messages");
        return;
    }
    List<String> messageReferenceStrings = intent.getStringArrayListExtra(EXTRA_MESSAGE_REFERENCES);
    List<MessageReference> messageReferences = toMessageReferenceList(messageReferenceStrings);
    for (MessageReference messageReference : messageReferences) {
        if (controller.isMoveCapable(messageReference)) {
            String sourceFolderName = messageReference.getFolderName();
            controller.moveMessage(account, sourceFolderName, messageReference, archiveFolderName);
        }
    }
}
Also used : MessageReference(com.fsck.k9.activity.MessageReference)

Example 40 with K9

use of com.fsck.k9.K9 in project k-9 by k9mail.

the class MessageTopView method showMessage.

public void showMessage(Account account, MessageViewInfo messageViewInfo) {
    resetAndPrepareMessageView(messageViewInfo);
    ShowPictures showPicturesSetting = account.getShowPictures();
    boolean automaticallyLoadPictures = shouldAutomaticallyLoadPictures(showPicturesSetting, messageViewInfo.message);
    MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, containerView, false);
    containerView.addView(view);
    boolean hideUnsignedTextDivider = !K9.getOpenPgpSupportSignOnly();
    view.displayMessageViewContainer(messageViewInfo, new OnRenderingFinishedListener() {

        @Override
        public void onLoadFinished() {
            displayViewOnLoadFinished(true);
        }
    }, automaticallyLoadPictures, hideUnsignedTextDivider, attachmentCallback);
    if (view.hasHiddenExternalImages()) {
        showShowPicturesButton();
    }
}
Also used : OnRenderingFinishedListener(com.fsck.k9.ui.messageview.MessageContainerView.OnRenderingFinishedListener) ShowPictures(com.fsck.k9.Account.ShowPictures)

Aggregations

Account (com.fsck.k9.Account)20 MessagingException (com.fsck.k9.mail.MessagingException)13 IOException (java.io.IOException)11 ArrayList (java.util.ArrayList)11 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)10 LocalStore (com.fsck.k9.mailstore.LocalStore)10 Message (com.fsck.k9.mail.Message)9 Store (com.fsck.k9.mail.Store)9 LocalFolder (com.fsck.k9.mailstore.LocalFolder)9 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)9 Intent (android.content.Intent)8 Pop3Store (com.fsck.k9.mail.store.pop3.Pop3Store)8 LocalMessage (com.fsck.k9.mailstore.LocalMessage)8 SuppressLint (android.annotation.SuppressLint)7 BaseAccount (com.fsck.k9.BaseAccount)7 Preferences (com.fsck.k9.Preferences)7 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)7 CertificateValidationException (com.fsck.k9.mail.CertificateValidationException)7 Folder (com.fsck.k9.mail.Folder)7 SearchAccount (com.fsck.k9.search.SearchAccount)7