Skip to content

Instantly share code, notes, and snippets.

@rezazarchi
Last active October 7, 2023 09:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rezazarchi/8923ef38433677b77943195624cb6f71 to your computer and use it in GitHub Desktop.
Save rezazarchi/8923ef38433677b77943195624cb6f71 to your computer and use it in GitHub Desktop.
Mapping K9 MimeMessage objects to Javax Mail MimeMessage objects together
package com.fsck.k9.message
import android.content.Context
import com.fsck.k9.mail.internet.MimeHeader
import com.fsck.k9.mail.internet.MimeMessageHelper
import com.fsck.k9.mail.internet.MimeMultipart
import com.fsck.k9.mail.internet.TextBody
import com.fsck.k9.mailstore.TempFileBody
import java.io.File
import java.io.FileOutputStream
import javax.mail.Address
import javax.mail.Session
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMessage
import org.apache.commons.io.IOUtils
object MessageConverter {
@JvmStatic
fun mapToJavaXMimeMultipart(
currentMsgBody: MimeMultipart,
context: Context,
contentType: String
): javax.mail.internet.MimeMultipart {
val mp =
javax.mail.internet.MimeMultipart(contentType.substring(10, contentType.indexOf(";")), currentMsgBody.boundary)
currentMsgBody.bodyParts.forEach { part ->
when (part.body) {
is MimeMultipart -> {
mp.addBodyPart(MimeBodyPart().apply {
setContent(mapMimeMultipart(part.body as MimeMultipart, context, part.contentType))
})
}
is TextBody -> {
mp.addBodyPart(MimeBodyPart().apply {
setText((part.body as TextBody).rawText, "utf-8", part.mimeType.substring(5))
setHeader(
MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING,
part.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING).firstOrNull()
)
})
}
is TempFileBody -> {
val fileName = part.contentType.split(" name=".toRegex()).toTypedArray().getOrNull(1)
val file = File(context.cacheDir, fileName.toString())
IOUtils.copy(part.body.inputStream, FileOutputStream(file))
mp.addBodyPart(MimeBodyPart().apply {
attachFile(file, part.contentType, "base64")
setHeader(
MimeHeader.HEADER_CONTENT_TYPE,
part.getHeader(MimeHeader.HEADER_CONTENT_TYPE).firstOrNull()
)
setHeader(
MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING,
part.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING).firstOrNull()
)
setHeader(
MimeHeader.HEADER_CONTENT_DISPOSITION,
part.getHeader(MimeHeader.HEADER_CONTENT_DISPOSITION).firstOrNull()
)
})
}
is BinaryMemoryBody -> {
//TODO we have some problems for attachments and s/mime signature. created hash is invalid
mp.addBodyPart(MimeBodyPart().apply {
val contentDisposition =
part.getHeader(MimeHeader.HEADER_CONTENT_DISPOSITION)
.firstOrNull()?.split(";")
if (contentDisposition?.firstOrNull() == "attachment") {
val fileName = part.contentType.split(" name=".toRegex()).toTypedArray().getOrNull(1)
val file = File(context.cacheDir, fileName)
IOUtils.copy(part.body.inputStream, FileOutputStream(file))
attachFile(file, part.contentType, "base64")
} else {
setContent(IOUtils.toString(part.body.inputStream), part.contentType)
}
})
}
}
}
return mp
}
@JvmStatic
fun mapToK9Message(
currentProcessedMimeMessage: com.fsck.k9.mail.internet.MimeMessage,
signedContent: javax.mail.internet.MimeMultipart
): com.fsck.k9.mail.internet.MimeMessage {
val props = System.getProperties()
val session = Session.getInstance(props)
val fromUser: Address = InternetAddress(
currentProcessedMimeMessage.from.first().address,
currentProcessedMimeMessage.from.first().personal
)
val body = MimeMessage(session)
body.setFrom(fromUser)
body.subject = currentProcessedMimeMessage.subject
body.setContent(signedContent, signedContent.contentType)
body.saveChanges()
val boundary = body.contentType.substring(body.contentType.indexOf("----"), body.contentType.length - 1)
val multipartSigned = MimeMultipart(boundary)
val parseMimeMessage = com.fsck.k9.mail.internet.MimeMessage.parseMimeMessage(body.inputStream, true)
multipartSigned.addBodyPart(parseMimeMessage.toBodyPart());
MimeMessageHelper.setBody(currentProcessedMimeMessage, multipartSigned)
currentProcessedMimeMessage.setHeader(MimeHeader.HEADER_CONTENT_TYPE, body.contentType)
currentProcessedMimeMessage.removeHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)
(currentProcessedMimeMessage.body as MimeMultipart).bodyParts.first().setHeader(
MimeHeader.HEADER_CONTENT_TYPE,
((body.content) as javax.mail.internet.MimeMultipart).getBodyPart(0)
.getHeader(MimeHeader.HEADER_CONTENT_TYPE).firstOrNull()
)
(currentProcessedMimeMessage.body as MimeMultipart).bodyParts.first()
.removeHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)
return currentProcessedMimeMessage
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment