connect() now opens folder and returns FetchEmailsStatus, added close()
This commit is contained in:
parent
52bf9daa7d
commit
1746346ceb
|
@ -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" }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue