From 39fec59875d860f77564be1553ddcf5a040abec7 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 15 Jun 2021 15:15:03 +0200 Subject: [PATCH] Pretty print received headers --- .../java/eu/faircode/email/HtmlHelper.java | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/eu/faircode/email/HtmlHelper.java b/app/src/main/java/eu/faircode/email/HtmlHelper.java index 1e7f229e0a..0a563c84fc 100644 --- a/app/src/main/java/eu/faircode/email/HtmlHelper.java +++ b/app/src/main/java/eu/faircode/email/HtmlHelper.java @@ -89,12 +89,15 @@ import org.w3c.dom.css.CSSRuleList; import org.w3c.dom.css.CSSStyleSheet; import org.w3c.dom.stylesheets.MediaList; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; +import java.text.DateFormat; +import java.text.ParsePosition; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -107,6 +110,10 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.mail.internet.InternetHeaders; +import javax.mail.internet.MailDateFormat; +import javax.mail.internet.MimeUtility; + import static androidx.core.text.HtmlCompat.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL; import static org.w3c.css.sac.Condition.SAC_CLASS_CONDITION; @@ -1961,8 +1968,9 @@ public class HtmlHelper { } static Spanned highlightHeaders(Context context, String headers) { - int colorAccent = Helper.resolveColor(context, android.R.attr.textColorLink); SpannableStringBuilder ssb = new SpannableStringBuilder(headers); + int colorAccent = Helper.resolveColor(context, android.R.attr.textColorLink); + int index = 0; for (String line : headers.split("\n")) { if (line.length() > 0 && !Character.isWhitespace(line.charAt(0))) { @@ -1972,6 +1980,54 @@ public class HtmlHelper { } index += line.length() + 1; } + + try { + // https://datatracker.ietf.org/doc/html/rfc2821#section-4.4 + final List words = Collections.unmodifiableList(Arrays.asList( + "from", "by", "via", "with", "id", "for")); + final DateFormat DTF = Helper.getDateTimeInstance(context, DateFormat.SHORT, DateFormat.MEDIUM); + + ByteArrayInputStream bis = new ByteArrayInputStream(headers.getBytes()); + String[] received = new InternetHeaders(bis).getHeader("Received"); + if (received.length > 0) { + ssb.append('\n'); + for (int i = received.length - 1; i >= 0; i--) { + String h = MimeUtility.unfold(received[i]); + + int semi = h.lastIndexOf(';'); + Date date = null; + if (semi > 0) { + MailDateFormat mdf = new MailDateFormat(); + date = mdf.parse(h, new ParsePosition(semi + 1)); + h = h.substring(0, semi); + } + + int s = ssb.length(); + ssb.append('#').append(Integer.toString(received.length - i)); + if (date != null) + ssb.append(' ').append(DTF.format(date)); + ssb.setSpan(new StyleSpan(Typeface.BOLD), s, ssb.length(), 0); + ssb.append('\n'); + + int j = 0; + String[] w = h.split("\\s+"); + while (j < w.length) { + if (j > 0) + ssb.append(' '); + + s = ssb.length(); + ssb.append(w[j]); + if (words.contains(w[j].toLowerCase(Locale.ROOT))) + ssb.setSpan(new ForegroundColorSpan(colorAccent), s, ssb.length(), 0); + j++; + } + ssb.append("\n\n"); + } + } + } catch (Throwable ex) { + Log.w(ex); + } + return ssb; }