connect() now opens folder and returns FetchEmailsStatus, added close()

This commit is contained in:
dankito 2024-11-30 20:54:32 +01:00
parent 52bf9daa7d
commit 1746346ceb
2 changed files with 36 additions and 29 deletions

View File

@ -42,32 +42,30 @@ open class EmailsFetcher(
open fun listenForNewEmails(account: EmailAccount, options: ListenForNewMailsOptions) = runBlocking {
try {
connect(account, options) { store ->
val folder = store.getFolder(options.emailFolderName) as IMAPFolder
folder.open(Folder.READ_ONLY)
val status = connect(account, options)
val status = FetchEmailsStatus(account, folder, options)
folder.addMessageCountListener(object : MessageCountAdapter() {
override fun messagesAdded(event: MessageCountEvent) {
event.messages.forEach { message ->
getEmail(message, status)
}
status.folder.addMessageCountListener(object : MessageCountAdapter() {
override fun messagesAdded(event: MessageCountEvent) {
event.messages.forEach { message ->
getEmail(message, status)
}
})
launch(coroutineDispatcher) {
keepConnectionOpen(status, folder, options)
}
})
launch(coroutineDispatcher) {
keepConnectionOpen(status, options)
}
close(status)
} catch (e: Throwable) {
log.error(e) { "Listening to new emails of '${account.username}' failed" }
options.onError?.invoke(FetchEmailError(FetchEmailErrorType.ListenForNewEmails, null, e))
}
}
protected open suspend fun keepConnectionOpen(status: FetchEmailsStatus, folder: IMAPFolder, options: ListenForNewMailsOptions) {
protected open suspend fun keepConnectionOpen(status: FetchEmailsStatus, options: ListenForNewMailsOptions) {
val account = status.account
val folder = status.folder
log.info { "Listening to new emails of $account" }
// Use IMAP IDLE to keep the connection alive
@ -88,18 +86,13 @@ open class EmailsFetcher(
open fun fetchAllEmails(account: EmailAccount, options: FetchEmailsOptions = FetchEmailsOptions()): FetchEmailsResult {
try {
return connect(account, options) { store ->
val folder = store.getFolder(options.emailFolderName) as IMAPFolder
folder.open(Folder.READ_ONLY)
val status = connect(account, options)
val status = FetchEmailsStatus(account, folder, options)
val emails = fetchAllEmailsInFolder(status)
val emails = fetchAllEmailsInFolder(status).also {
folder.close(false)
}
close(status)
FetchEmailsResult(emails, null, status.messageSpecificErrors)
}
return FetchEmailsResult(emails, null, status.messageSpecificErrors)
} catch (e: Throwable) {
log.error(e) { "Could not fetch emails of account $account" }
@ -326,15 +319,17 @@ open class EmailsFetcher(
date.toInstant()
protected open fun <T> connect(account: EmailAccount, options: FetchEmailsOptions, connected: (Store) -> T): T {
protected open fun connect(account: EmailAccount, options: FetchEmailsOptions): FetchEmailsStatus {
val properties = mapAccountToJavaMailProperties(account, options)
val session = Session.getInstance(properties)
session.getStore("imap").use { store ->
store.connect(account.serverAddress, account.username, account.password)
val store = session.getStore("imap")
store.connect(account.serverAddress, account.username, account.password)
return connected(store)
}
val folder = store.getFolder(options.emailFolderName) as IMAPFolder
folder.open(Folder.READ_ONLY)
return FetchEmailsStatus(account, store, folder, options)
}
protected open fun mapAccountToJavaMailProperties(account: EmailAccount, options: FetchEmailsOptions) = Properties().apply {
@ -354,4 +349,14 @@ open class EmailsFetcher(
put("mail.imap.partialfetch", "false") // Controls whether the IMAP partial-fetch capability should be used. Defaults to true.
}
protected open fun close(status: FetchEmailsStatus) {
try {
status.folder.close(false)
status.store.close()
} catch (e: Exception) {
log.error(e) { "Could not close folder or store" }
}
}
}

View File

@ -3,6 +3,7 @@ package net.codinux.invoicing.email
import jakarta.mail.BodyPart
import jakarta.mail.Message
import jakarta.mail.Part
import jakarta.mail.Store
import net.codinux.invoicing.email.model.EmailAccount
import net.codinux.invoicing.filesystem.FileUtil
import org.eclipse.angus.mail.imap.IMAPFolder
@ -10,6 +11,7 @@ import java.io.File
data class FetchEmailsStatus(
val account: EmailAccount,
val store: Store,
val folder: IMAPFolder,
val options: FetchEmailsOptions,
val messageSpecificErrors: MutableList<FetchEmailError> = mutableListOf()