< prev index next > mailinglist/src/main/java/org/openjdk/skara/mailinglist/Mbox.java
Print this page
package org.openjdk.skara.mailinglist;
import org.openjdk.skara.email.*;
import java.io.*;
- import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.regex.Pattern;
"^(From (?:.(?!^\\R^From ))*)", Pattern.MULTILINE | Pattern.DOTALL);
private final static DateTimeFormatter ctimeFormat = DateTimeFormatter.ofPattern(
"EEE LLL dd HH:mm:ss yyyy", Locale.US);
private final static Pattern fromStringEncodePattern = Pattern.compile("^(>*From )", Pattern.MULTILINE);
private final static Pattern fromStringDecodePattern = Pattern.compile("^>(>*From )", Pattern.MULTILINE);
- private final static Pattern encodeQuotedPrintablePattern = Pattern.compile("([^\\x00-\\x7f]+)");
- private final static Pattern decodedQuotedPrintablePattern = Pattern.compile("=\\?utf-8\\?b\\?(.*?)\\?=");
private static List<Email> splitMbox(String mbox) {
// Initial split
var messages = mboxMessagePattern.matcher(mbox).results()
.map(match -> match.group(1))
- .map(Mbox::decodeQuotedPrintable)
.collect(Collectors.toList());
// Pipermail can occasionally fail to encode 'From ' in message bodies, try to handle this
var messageBuilder = new StringBuilder();
var parsedMails = new ArrayList<Email>();
private static String decodeFromStrings(String body) {
var fromStringMatcher = fromStringDecodePattern.matcher(body);
return fromStringMatcher.replaceAll("$1");
}
- private static String encodeQuotedPrintable(String raw) {
- var quoteMatcher = encodeQuotedPrintablePattern.matcher(raw);
- return quoteMatcher.replaceAll(mo -> "=?utf-8?b?" + Base64.getEncoder().encodeToString(String.valueOf(mo.group(1)).getBytes(StandardCharsets.UTF_8)) + "?=");
- }
-
- private static String decodeQuotedPrintable(String raw) {
- var quotedMatcher = decodedQuotedPrintablePattern.matcher(raw);
- return quotedMatcher.replaceAll(mo -> new String(Base64.getDecoder().decode(mo.group(1)), StandardCharsets.UTF_8));
- }
-
public static List<Conversation> parseMbox(String mbox) {
var emails = splitMbox(mbox);
var idToMail = emails.stream().collect(Collectors.toMap(Email::id, Function.identity(), (a, b) -> a));
var idToConversation = idToMail.values().stream()
.filter(email -> !email.hasHeader("In-Reply-To"))
var mboxString = new StringWriter();
var mboxMail = new PrintWriter(mboxString);
mboxMail.println();
mboxMail.println("From " + mail.sender().address() + " " + mail.date().format(ctimeFormat));
- mboxMail.println("From: " + mail.author().toObfuscatedString());
+ mboxMail.println("From: " + MimeText.encode(mail.author().toObfuscatedString()));
if (!mail.author().equals(mail.sender())) {
- mboxMail.println("Sender: " + mail.sender().toObfuscatedString());
+ mboxMail.println("Sender: " + MimeText.encode(mail.sender().toObfuscatedString()));
}
if (!mail.recipients().isEmpty()) {
mboxMail.println("To: " + mail.recipients().stream()
.map(EmailAddress::toString)
+ .map(MimeText::encode)
.collect(Collectors.joining(", ")));
}
mboxMail.println("Date: " + mail.date().format(DateTimeFormatter.RFC_1123_DATE_TIME));
- mboxMail.println("Subject: " + mail.subject());
+ mboxMail.println("Subject: " + MimeText.encode(mail.subject()));
mboxMail.println("Message-Id: " + mail.id());
- mail.headers().forEach(header -> mboxMail.println(header + ": " + mail.headerValue(header)));
+ mail.headers().forEach(header -> mboxMail.println(header + ": " + MimeText.encode(mail.headerValue(header))));
mboxMail.println();
- mboxMail.println(encodeFromStrings(mail.body()));
+ mboxMail.println(encodeFromStrings(MimeText.encode(mail.body())));
- return encodeQuotedPrintable(mboxString.toString());
+ return mboxString.toString();
}
}
< prev index next >