Implemented saving message UID so that on next app run fetchAllEmails() can continue on last downloaded message

This commit is contained in:
dankito 2024-11-26 21:42:24 +01:00
parent 9257205a43
commit 1e372cf592
4 changed files with 23 additions and 13 deletions

View File

@ -6,6 +6,7 @@ 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
import jakarta.mail.UIDFolder
import jakarta.mail.event.MessageCountAdapter import jakarta.mail.event.MessageCountAdapter
import jakarta.mail.event.MessageCountEvent import jakarta.mail.event.MessageCountEvent
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -116,19 +117,23 @@ open class EmailsFetcher(
return@runBlocking emptyList() return@runBlocking emptyList()
} }
IntRange(1, messageCount).mapNotNull { messageNumber -> // message numbers start at 1 async(coroutineDispatcher) {
async(coroutineDispatcher) { val startUid = max(status.options.lastRetrievedMessageId?.let { it + 1 } ?: 0, 1) // message numbers start at 1
try {
getEmail(folder.getMessage(messageNumber), status) folder.getMessagesByUID(startUid, UIDFolder.MAXUID).mapNotNull { message ->
} catch (e: Throwable) { async(coroutineDispatcher) {
log.error(e) { "Could not get email with messageNumber $messageNumber" } try {
status.addError(FetchEmailsErrorType.GetEmail, messageNumber, e) getEmail(message, status)
null } catch (e: Throwable) {
log.error(e) { "Could not get email $message" }
status.addError(FetchEmailsErrorType.GetEmail, message, e)
null
}
} }
} }
} .awaitAll()
.awaitAll() .filterNotNull()
.filterNotNull() }.await()
} }
protected open fun getEmail(message: Message, status: FetchEmailsStatus): Email? { protected open fun getEmail(message: Message, status: FetchEmailsStatus): Email? {

View File

@ -4,6 +4,11 @@ import net.codinux.invoicing.email.model.Email
import java.io.File import java.io.File
open class FetchEmailsOptions( open class FetchEmailsOptions(
/**
* The ID of the last retrieved message. If set, only messages newer than this ID will be fetched.
*/
val lastRetrievedMessageId: Long? = null,
val downloadMessageBody: Boolean = false, val downloadMessageBody: Boolean = false,
/** /**
* Set the extension (without the dot) of files that should be downloaded. * Set the extension (without the dot) of files that should be downloaded.

View File

@ -16,4 +16,4 @@ open class ListenForNewMailsOptions(
onError: ((FetchEmailsError) -> Unit)? = null, onError: ((FetchEmailsError) -> Unit)? = null,
onEmailReceived: (Email) -> Unit onEmailReceived: (Email) -> Unit
) : FetchEmailsOptions(downloadMessageBody, downloadAttachmentsWithExtensions, attachmentsDownloadDirectory, emailFolderName, connectTimeoutSeconds, onError, onEmailReceived) ) : FetchEmailsOptions(null, downloadMessageBody, downloadAttachmentsWithExtensions, attachmentsDownloadDirectory, emailFolderName, connectTimeoutSeconds, onError, onEmailReceived)

View File

@ -27,7 +27,7 @@ class EmailsFetcherTest {
@Test @Test
fun fetchAllEmails() { fun fetchAllEmails() {
val result = underTest.fetchAllEmails(emailAccount, FetchEmailsOptions(true)) val result = underTest.fetchAllEmails(emailAccount, FetchEmailsOptions(downloadMessageBody = true))
assertThat(result.overallError).isNull() assertThat(result.overallError).isNull()
assertThat(result.emails).isNotEmpty() assertThat(result.emails).isNotEmpty()