Search in sources :

Example 11 with Html

use of com.fsck.k9.mail.internet.Viewable.Html in project k-9 by k9mail.

the class TextPartFinder method findFirstTextPart.

@Nullable
public Part findFirstTextPart(@NonNull Part part) {
    String mimeType = part.getMimeType();
    Body body = part.getBody();
    if (body instanceof Multipart) {
        Multipart multipart = (Multipart) body;
        if (isSameMimeType(mimeType, "multipart/alternative")) {
            return findTextPartInMultipartAlternative(multipart);
        } else {
            return findTextPartInMultipart(multipart);
        }
    } else if (isSameMimeType(mimeType, "text/plain") || isSameMimeType(mimeType, "text/html")) {
        return part;
    }
    return null;
}
Also used : Multipart(com.fsck.k9.mail.Multipart) Body(com.fsck.k9.mail.Body) Nullable(androidx.annotation.Nullable)

Example 12 with Html

use of com.fsck.k9.mail.internet.Viewable.Html in project k-9 by k9mail.

the class BodyTextExtractor method getBodyTextFromMessage.

/**
 * Fetch the body text from a messagePart in the desired messagePart format. This method handles
 * conversions between formats (html to text and vice versa) if necessary.
 */
@NonNull
public static String getBodyTextFromMessage(Part messagePart, SimpleMessageFormat format) {
    Part part;
    if (format == SimpleMessageFormat.HTML) {
        // HTML takes precedence, then text.
        part = MimeUtility.findFirstPartByMimeType(messagePart, "text/html");
        if (part != null) {
            Timber.d("getBodyTextFromMessage: HTML requested, HTML found.");
            return getTextFromPartOrEmpty(part);
        }
        part = MimeUtility.findFirstPartByMimeType(messagePart, "text/plain");
        if (part != null) {
            Timber.d("getBodyTextFromMessage: HTML requested, text found.");
            String text = getTextFromPartOrEmpty(part);
            return HtmlConverter.textToHtml(text);
        }
    } else if (format == SimpleMessageFormat.TEXT) {
        // Text takes precedence, then html.
        part = MimeUtility.findFirstPartByMimeType(messagePart, "text/plain");
        if (part != null) {
            Timber.d("getBodyTextFromMessage: Text requested, text found.");
            return getTextFromPartOrEmpty(part);
        }
        part = MimeUtility.findFirstPartByMimeType(messagePart, "text/html");
        if (part != null) {
            Timber.d("getBodyTextFromMessage: Text requested, HTML found.");
            String text = getTextFromPartOrEmpty(part);
            return HtmlConverter.htmlToText(text);
        }
    }
    // If we had nothing interesting, return an empty string.
    return "";
}
Also used : Part(com.fsck.k9.mail.Part) NonNull(androidx.annotation.NonNull)

Example 13 with Html

use of com.fsck.k9.mail.internet.Viewable.Html in project k-9 by k9mail.

the class MessageCryptoStructureDetectorTest method findPrimaryCryptoPart_withMultipartMixedContainingMultipartAlternativeContainingPgpInline.

@Test
public void findPrimaryCryptoPart_withMultipartMixedContainingMultipartAlternativeContainingPgpInline() throws Exception {
    List<Part> outputExtraParts = new ArrayList<>();
    BodyPart pgpInlinePart = bodypart("text/plain", PGP_INLINE_DATA);
    Message message = messageFromBody(multipart("mixed", multipart("alternative", pgpInlinePart, bodypart("text/html")), bodypart("application/octet-stream")));
    Part cryptoPart = MessageCryptoStructureDetector.findPrimaryEncryptedOrSignedPart(message, outputExtraParts);
    assertSame(pgpInlinePart, cryptoPart);
}
Also used : BodyPart(com.fsck.k9.mail.BodyPart) MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Message(com.fsck.k9.mail.Message) BodyPart(com.fsck.k9.mail.BodyPart) Part(com.fsck.k9.mail.Part) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 14 with Html

use of com.fsck.k9.mail.internet.Viewable.Html in project k-9 by k9mail.

the class QuotedMessagePresenter method processDraftMessage.

public void processDraftMessage(MessageViewInfo messageViewInfo, Map<IdentityField, String> k9identity) {
    quoteStyle = k9identity.get(IdentityField.QUOTE_STYLE) != null ? QuoteStyle.valueOf(k9identity.get(IdentityField.QUOTE_STYLE)) : account.getQuoteStyle();
    int cursorPosition = 0;
    if (k9identity.containsKey(IdentityField.CURSOR_POSITION)) {
        try {
            cursorPosition = Integer.parseInt(k9identity.get(IdentityField.CURSOR_POSITION));
        } catch (Exception e) {
            Timber.e(e, "Could not parse cursor position for MessageCompose; continuing.");
        }
    }
    String showQuotedTextMode;
    if (k9identity.containsKey(IdentityField.QUOTED_TEXT_MODE)) {
        showQuotedTextMode = k9identity.get(IdentityField.QUOTED_TEXT_MODE);
    } else {
        showQuotedTextMode = "NONE";
    }
    int bodyLength = k9identity.get(IdentityField.LENGTH) != null ? Integer.valueOf(k9identity.get(IdentityField.LENGTH)) : UNKNOWN_LENGTH;
    int bodyOffset = k9identity.get(IdentityField.OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.OFFSET)) : UNKNOWN_LENGTH;
    Integer bodyFooterOffset = k9identity.get(IdentityField.FOOTER_OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.FOOTER_OFFSET)) : null;
    Integer bodyPlainLength = k9identity.get(IdentityField.PLAIN_LENGTH) != null ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_LENGTH)) : null;
    Integer bodyPlainOffset = k9identity.get(IdentityField.PLAIN_OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_OFFSET)) : null;
    QuotedTextMode quotedMode;
    try {
        quotedMode = QuotedTextMode.valueOf(showQuotedTextMode);
    } catch (Exception e) {
        quotedMode = QuotedTextMode.NONE;
    }
    // Always respect the user's current composition format preference, even if the
    // draft was saved in a different format.
    // TODO - The current implementation doesn't allow a user in HTML mode to edit a draft that wasn't saved with K9mail.
    String messageFormatString = k9identity.get(IdentityField.MESSAGE_FORMAT);
    MessageFormat messageFormat = null;
    if (messageFormatString != null) {
        try {
            messageFormat = MessageFormat.valueOf(messageFormatString);
        } catch (Exception e) {
        /* do nothing */
        }
    }
    if (messageFormat == null) {
        // This message probably wasn't created by us. The exception is legacy
        // drafts created before the advent of HTML composition. In those cases,
        // we'll display the whole message (including the quoted part) in the
        // composition window. If that's the case, try and convert it to text to
        // match the behavior in text mode.
        view.setMessageContentCharacters(BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, SimpleMessageFormat.TEXT));
        forcePlainText = true;
        showOrHideQuotedText(quotedMode);
        return;
    }
    if (messageFormat == MessageFormat.HTML) {
        // defaults to null
        String bodyText;
        Part part = MimeUtility.findFirstPartByMimeType(messageViewInfo.rootPart, "text/html");
        if (part != null) {
            // Shouldn't happen if we were the one who saved it.
            quotedTextFormat = SimpleMessageFormat.HTML;
            String text = MessageExtractor.getTextFromPart(part);
            if (text == null) {
                Timber.d("Empty message; skipping.");
                bodyText = "";
            } else {
                Timber.d("Loading message with offset %d, length %d. Text length is %d.", bodyOffset, bodyLength, text.length());
                if (bodyOffset + bodyLength > text.length()) {
                    // The draft was edited outside of K-9 Mail?
                    Timber.d("The identity field from the draft contains an invalid LENGTH/OFFSET");
                    bodyOffset = 0;
                    bodyLength = 0;
                }
                // Grab our reply text.
                bodyText = text.substring(bodyOffset, bodyOffset + bodyLength);
            }
            view.setMessageContentCharacters(HtmlConverter.htmlToText(bodyText));
            // Regenerate the quoted html without our user content in it.
            StringBuilder quotedHTML = new StringBuilder();
            // stuff before the reply
            quotedHTML.append(text.substring(0, bodyOffset));
            quotedHTML.append(text.substring(bodyOffset + bodyLength));
            if (quotedHTML.length() > 0) {
                quotedHtmlContent = new InsertableHtmlContent();
                quotedHtmlContent.setQuotedContent(quotedHTML);
                // We don't know if bodyOffset refers to the header or to the footer
                quotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
                if (bodyFooterOffset != null) {
                    quotedHtmlContent.setFooterInsertionPoint(bodyFooterOffset);
                } else {
                    quotedHtmlContent.setFooterInsertionPoint(bodyOffset);
                }
                // TODO replace with MessageViewInfo data
                view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), AttachmentResolver.createFromPart(messageViewInfo.rootPart));
            }
        }
        if (bodyPlainOffset != null && bodyPlainLength != null) {
            processSourceMessageText(messageViewInfo.rootPart, bodyPlainOffset, bodyPlainLength, false);
        }
    } else if (messageFormat == MessageFormat.TEXT) {
        quotedTextFormat = SimpleMessageFormat.TEXT;
        processSourceMessageText(messageViewInfo.rootPart, bodyOffset, bodyLength, true);
    } else {
        Timber.e("Unhandled message format.");
    }
    // Set the cursor position if we have it.
    try {
        view.setMessageContentCursorPosition(cursorPosition);
    } catch (Exception e) {
        Timber.e(e, "Could not set cursor position in MessageCompose; ignoring.");
    }
    showOrHideQuotedText(quotedMode);
}
Also used : SimpleMessageFormat(com.fsck.k9.message.SimpleMessageFormat) MessageFormat(com.fsck.k9.Account.MessageFormat) Part(com.fsck.k9.mail.Part) QuotedTextMode(com.fsck.k9.message.QuotedTextMode) InsertableHtmlContent(com.fsck.k9.message.quote.InsertableHtmlContent) MessagingException(com.fsck.k9.mail.MessagingException)

Example 15 with Html

use of com.fsck.k9.mail.internet.Viewable.Html in project k-9 by k9mail.

the class QuotedMessagePresenter method populateUIWithQuotedMessage.

/**
 * Build and populate the UI with the quoted message.
 *
 * @param showQuotedText
 *         {@code true} if the quoted text should be shown, {@code false} otherwise.
 */
public void populateUIWithQuotedMessage(MessageViewInfo messageViewInfo, boolean showQuotedText, Action action) throws MessagingException {
    MessageFormat origMessageFormat = account.getMessageFormat();
    if (forcePlainText || origMessageFormat == MessageFormat.TEXT) {
        // Use plain text for the quoted message
        quotedTextFormat = SimpleMessageFormat.TEXT;
    } else if (origMessageFormat == MessageFormat.AUTO) {
        // Figure out which message format to use for the quoted text by looking if the source
        // message contains a text/html part. If it does, we use that.
        quotedTextFormat = (MimeUtility.findFirstPartByMimeType(messageViewInfo.rootPart, "text/html") == null) ? SimpleMessageFormat.TEXT : SimpleMessageFormat.HTML;
    } else {
        quotedTextFormat = SimpleMessageFormat.HTML;
    }
    // Handle the original message in the reply
    // If we already have sourceMessageBody, use that.  It's pre-populated if we've got crypto going on.
    String content = BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, quotedTextFormat);
    if (quotedTextFormat == SimpleMessageFormat.HTML) {
        // closing tags such as </div>, </span>, </table>, </pre> will be cut off.
        if (account.isStripSignature() && (action == Action.REPLY || action == Action.REPLY_ALL)) {
            content = HtmlSignatureRemover.stripSignature(content);
        }
        // Add the HTML reply header to the top of the content.
        quotedHtmlContent = HtmlQuoteCreator.quoteOriginalHtmlMessage(messageViewInfo.message, content, quoteStyle);
        // Load the message with the reply header. TODO replace with MessageViewInfo data
        view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), AttachmentResolver.createFromPart(messageViewInfo.rootPart));
        // TODO: Also strip the signature from the text/plain part
        view.setQuotedText(textQuoteCreator.quoteOriginalTextMessage(messageViewInfo.message, BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, SimpleMessageFormat.TEXT), quoteStyle, account.getQuotePrefix()));
    } else if (quotedTextFormat == SimpleMessageFormat.TEXT) {
        if (account.isStripSignature() && (action == Action.REPLY || action == Action.REPLY_ALL)) {
            content = TextSignatureRemover.stripSignature(content);
        }
        view.setQuotedText(textQuoteCreator.quoteOriginalTextMessage(messageViewInfo.message, content, quoteStyle, account.getQuotePrefix()));
    }
    if (showQuotedText) {
        showOrHideQuotedText(QuotedTextMode.SHOW);
    } else {
        showOrHideQuotedText(QuotedTextMode.HIDE);
    }
}
Also used : SimpleMessageFormat(com.fsck.k9.message.SimpleMessageFormat) MessageFormat(com.fsck.k9.Account.MessageFormat)

Aggregations

Part (com.fsck.k9.mail.Part)31 BodyPart (com.fsck.k9.mail.BodyPart)24 Test (org.junit.Test)24 MessageCreationHelper.createTextPart (com.fsck.k9.message.MessageCreationHelper.createTextPart)12 MessageCreationHelper.createEmptyPart (com.fsck.k9.message.MessageCreationHelper.createEmptyPart)11 MessageCreationHelper.createPart (com.fsck.k9.message.MessageCreationHelper.createPart)11 ArrayList (java.util.ArrayList)11 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)9 Body (com.fsck.k9.mail.Body)7 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)7 Message (com.fsck.k9.mail.Message)6 Multipart (com.fsck.k9.mail.Multipart)6 TextBody (com.fsck.k9.mail.internet.TextBody)6 Viewable (com.fsck.k9.mail.internet.Viewable)6 Alternative (com.fsck.k9.mail.internet.Viewable.Alternative)4 Html (com.fsck.k9.mail.internet.Viewable.Html)4 Text (com.fsck.k9.mail.internet.Viewable.Text)4 MessageFormat (com.fsck.k9.Account.MessageFormat)3 K9RobolectricTest (com.fsck.k9.K9RobolectricTest)3 MessagingException (com.fsck.k9.mail.MessagingException)3