Fixed reading all, also nested, message parts
This commit is contained in:
parent
2516328da8
commit
48270e7922
|
@ -1,8 +1,8 @@
|
||||||
package net.codinux.invoicing.mail
|
package net.codinux.invoicing.mail
|
||||||
|
|
||||||
import jakarta.mail.BodyPart
|
|
||||||
import jakarta.mail.Folder
|
import jakarta.mail.Folder
|
||||||
import jakarta.mail.Message
|
import jakarta.mail.Message
|
||||||
|
import jakarta.mail.Multipart
|
||||||
import jakarta.mail.Part
|
import jakarta.mail.Part
|
||||||
import jakarta.mail.Session
|
import jakarta.mail.Session
|
||||||
import jakarta.mail.Store
|
import jakarta.mail.Store
|
||||||
|
@ -92,21 +92,18 @@ class MailReader(
|
||||||
// tried to parallelize reading messages by reading them on multiple thread but that had no effect on process duration (don't know why)
|
// tried to parallelize reading messages by reading them on multiple thread but that had no effect on process duration (don't know why)
|
||||||
private fun listAllMessagesWithEInvoiceInFolder(folder: Folder): List<MailWithInvoice> = folder.messages.mapNotNull { message ->
|
private fun listAllMessagesWithEInvoiceInFolder(folder: Folder): List<MailWithInvoice> = folder.messages.mapNotNull { message ->
|
||||||
try {
|
try {
|
||||||
if (message.isMimeType("multipart/*")) {
|
val parts = getAllMessageParts(message)
|
||||||
val multipart = message.content as MimeMultipart
|
|
||||||
val parts = IntRange(0, multipart.count - 1).map { multipart.getBodyPart(it) }
|
|
||||||
|
|
||||||
val attachmentsWithEInvoice = parts.mapNotNull { part ->
|
val attachmentsWithEInvoice = parts.mapNotNull { part ->
|
||||||
findEInvoice(part)
|
findEInvoice(part)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachmentsWithEInvoice.isNotEmpty()) {
|
if (attachmentsWithEInvoice.isNotEmpty()) {
|
||||||
return@mapNotNull MailWithInvoice(
|
return@mapNotNull MailWithInvoice(
|
||||||
message.from.joinToString(), message.subject,
|
message.from.joinToString(), message.subject,
|
||||||
message.sentDate?.let { map(it) }, map(message.receivedDate), message.messageNumber,
|
message.sentDate?.let { map(it) }, map(message.receivedDate), message.messageNumber,
|
||||||
attachmentsWithEInvoice
|
attachmentsWithEInvoice
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(e) { "Could not read mail $message" }
|
log.error(e) { "Could not read mail $message" }
|
||||||
|
@ -115,7 +112,22 @@ class MailReader(
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findEInvoice(part: BodyPart): MailAttachmentWithEInvoice? {
|
private fun getAllMessageParts(part: Part): List<Part> {
|
||||||
|
contentClasses.add(part.content?.let { it::class })
|
||||||
|
|
||||||
|
return if (part.content is Multipart) {
|
||||||
|
val multipart = part.content as Multipart
|
||||||
|
val parts = IntRange(0, multipart.count - 1).map { multipart.getBodyPart(it) }
|
||||||
|
|
||||||
|
parts.flatMap { subPart ->
|
||||||
|
getAllMessageParts(subPart)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listOf(part)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findEInvoice(part: Part): MailAttachmentWithEInvoice? {
|
||||||
try {
|
try {
|
||||||
if (Part.ATTACHMENT.equals(part.disposition, true)) { // TODO: what about Part.INLINE?
|
if (Part.ATTACHMENT.equals(part.disposition, true)) { // TODO: what about Part.INLINE?
|
||||||
val mediaType = getMediaType(part)?.lowercase()
|
val mediaType = getMediaType(part)?.lowercase()
|
||||||
|
@ -138,7 +150,7 @@ class MailReader(
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToReadEInvoice(part: BodyPart, mediaType: String?): Invoice? = try {
|
private fun tryToReadEInvoice(part: Part, mediaType: String?): Invoice? = try {
|
||||||
val filename = part.fileName.lowercase()
|
val filename = part.fileName.lowercase()
|
||||||
|
|
||||||
if (filename.endsWith(".pdf") || mediaType == "application/pdf" || mediaType == "application/octet-stream") {
|
if (filename.endsWith(".pdf") || mediaType == "application/pdf" || mediaType == "application/octet-stream") {
|
||||||
|
@ -160,7 +172,7 @@ class MailReader(
|
||||||
*
|
*
|
||||||
* -> This method removes parameters and return media type (first part) only
|
* -> This method removes parameters and return media type (first part) only
|
||||||
*/
|
*/
|
||||||
private fun getMediaType(part: BodyPart): String? = part.contentType?.let { contentType ->
|
private fun getMediaType(part: Part): String? = part.contentType?.let { contentType ->
|
||||||
val indexOfSeparator = contentType.indexOf(';')
|
val indexOfSeparator = contentType.indexOf(';')
|
||||||
|
|
||||||
if (indexOfSeparator > -1) {
|
if (indexOfSeparator > -1) {
|
||||||
|
|
Loading…
Reference in New Issue