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 {
|
open fun listenForNewEmails(account: EmailAccount, options: ListenForNewMailsOptions) = runBlocking {
|
||||||
try {
|
try {
|
||||||
connect(account, options) { store ->
|
val status = connect(account, options)
|
||||||
val folder = store.getFolder(options.emailFolderName) as IMAPFolder
|
|
||||||
folder.open(Folder.READ_ONLY)
|
|
||||||
|
|
||||||
val status = FetchEmailsStatus(account, folder, options)
|
status.folder.addMessageCountListener(object : MessageCountAdapter() {
|
||||||
|
override fun messagesAdded(event: MessageCountEvent) {
|
||||||
folder.addMessageCountListener(object : MessageCountAdapter() {
|
event.messages.forEach { message ->
|
||||||
override fun messagesAdded(event: MessageCountEvent) {
|
getEmail(message, status)
|
||||||
event.messages.forEach { message ->
|
|
||||||
getEmail(message, status)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
launch(coroutineDispatcher) {
|
|
||||||
keepConnectionOpen(status, folder, options)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
launch(coroutineDispatcher) {
|
||||||
|
keepConnectionOpen(status, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(status)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(e) { "Listening to new emails of '${account.username}' failed" }
|
log.error(e) { "Listening to new emails of '${account.username}' failed" }
|
||||||
options.onError?.invoke(FetchEmailError(FetchEmailErrorType.ListenForNewEmails, null, e))
|
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 account = status.account
|
||||||
|
val folder = status.folder
|
||||||
log.info { "Listening to new emails of $account" }
|
log.info { "Listening to new emails of $account" }
|
||||||
|
|
||||||
// Use IMAP IDLE to keep the connection alive
|
// Use IMAP IDLE to keep the connection alive
|
||||||
|
@ -88,18 +86,13 @@ open class EmailsFetcher(
|
||||||
|
|
||||||
open fun fetchAllEmails(account: EmailAccount, options: FetchEmailsOptions = FetchEmailsOptions()): FetchEmailsResult {
|
open fun fetchAllEmails(account: EmailAccount, options: FetchEmailsOptions = FetchEmailsOptions()): FetchEmailsResult {
|
||||||
try {
|
try {
|
||||||
return connect(account, options) { store ->
|
val status = connect(account, options)
|
||||||
val folder = store.getFolder(options.emailFolderName) as IMAPFolder
|
|
||||||
folder.open(Folder.READ_ONLY)
|
|
||||||
|
|
||||||
val status = FetchEmailsStatus(account, folder, options)
|
val emails = fetchAllEmailsInFolder(status)
|
||||||
|
|
||||||
val emails = fetchAllEmailsInFolder(status).also {
|
close(status)
|
||||||
folder.close(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
FetchEmailsResult(emails, null, status.messageSpecificErrors)
|
return FetchEmailsResult(emails, null, status.messageSpecificErrors)
|
||||||
}
|
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(e) { "Could not fetch emails of account $account" }
|
log.error(e) { "Could not fetch emails of account $account" }
|
||||||
|
|
||||||
|
@ -326,15 +319,17 @@ open class EmailsFetcher(
|
||||||
date.toInstant()
|
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 properties = mapAccountToJavaMailProperties(account, options)
|
||||||
|
|
||||||
val session = Session.getInstance(properties)
|
val session = Session.getInstance(properties)
|
||||||
session.getStore("imap").use { store ->
|
val store = session.getStore("imap")
|
||||||
store.connect(account.serverAddress, account.username, account.password)
|
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 {
|
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.
|
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.BodyPart
|
||||||
import jakarta.mail.Message
|
import jakarta.mail.Message
|
||||||
import jakarta.mail.Part
|
import jakarta.mail.Part
|
||||||
|
import jakarta.mail.Store
|
||||||
import net.codinux.invoicing.email.model.EmailAccount
|
import net.codinux.invoicing.email.model.EmailAccount
|
||||||
import net.codinux.invoicing.filesystem.FileUtil
|
import net.codinux.invoicing.filesystem.FileUtil
|
||||||
import org.eclipse.angus.mail.imap.IMAPFolder
|
import org.eclipse.angus.mail.imap.IMAPFolder
|
||||||
|
@ -10,6 +11,7 @@ import java.io.File
|
||||||
|
|
||||||
data class FetchEmailsStatus(
|
data class FetchEmailsStatus(
|
||||||
val account: EmailAccount,
|
val account: EmailAccount,
|
||||||
|
val store: Store,
|
||||||
val folder: IMAPFolder,
|
val folder: IMAPFolder,
|
||||||
val options: FetchEmailsOptions,
|
val options: FetchEmailsOptions,
|
||||||
val messageSpecificErrors: MutableList<FetchEmailError> = mutableListOf()
|
val messageSpecificErrors: MutableList<FetchEmailError> = mutableListOf()
|
||||||
|
|
Loading…
Reference in New Issue