2021-07-23 11:54:40 +02:00

267 lines
9.4 KiB
VB.net

Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Imports Limilabs.Mail
Imports Limilabs.Client.IMAP
Imports Limilabs.Mail.MIME
Imports System.IO
Imports Limilabs.Mail.MSG
Public Class Email2
Private ReadOnly Logger As Logger
Private ReadOnly LogConfig As LogConfig
Private ReadOnly FileEx As Filesystem.File
Private ReadOnly MailBuilder As New MailBuilder()
Public Sub New(pLogConfig As LogConfig)
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger()
FileEx = New Filesystem.File(pLogConfig)
End Sub
Public Enum EmailSecurity
SSLTLS
STARTTLS
End Enum
Private Function Get_PortForSecurityOption(pSecurity As EmailSecurity) As Integer
If pSecurity = EmailSecurity.STARTTLS Then
Return 143
Else ' EmailSecurity.SSL
Return 993
End If
End Function
Private Function New_Connection(pIMAP As Imap, pServer As String, pUsername As String, pPassword As String, pPort As Integer, pSecurity As EmailSecurity) As Boolean
Try
Logger.Debug("Connecting to IMAP server [{0}]", pServer)
Dim oPort As Integer = pPort
If oPort = 0 Then
oPort = Get_PortForSecurityOption(pSecurity)
End If
Logger.Debug("Using Port [{0}] for connection", oPort)
If pSecurity = EmailSecurity.STARTTLS Then
Logger.Debug("Using STARTTLS as Security Option")
pIMAP.Connect(pServer, oPort)
pIMAP.StartTLS()
Else
Logger.Debug("Using SSL/TLS as Security Option")
pIMAP.ConnectSSL(pServer, oPort)
End If
Logger.Debug("Connection to IMAP Server [{0}] established!", pServer)
Logger.Debug("Logging in with user [{0}]", pUsername)
pIMAP.UseBestLogin(pUsername, pPassword)
Return True
Catch ex As Exception
Logger.Warn("Could not connect to server [{0}] with user [{1}]", pServer, pUsername)
Logger.Error(ex)
Return False
End Try
End Function
Public Function Test_Login(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As Boolean
Logger.Debug("Testing Login to Server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
Try
Using oClient As New Imap()
If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
Logger.Debug("Fetching Inbox")
Dim oStatus As FolderStatus = oClient.SelectInbox()
Logger.Debug("Test finished!")
oClient.Close()
End If
End Using
Return True
Catch ex As Exception
Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
Logger.Error(ex)
Return False
End Try
End Function
Public Function Get_Messages(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As List(Of IMail)
Logger.Debug("Fetching Messages from Server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
Dim oMails As New List(Of IMail)
Try
Using oClient As New Imap()
If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
Logger.Debug("Fetching Folder [{0}]", pFolder)
Dim oStatus As FolderStatus = oClient.Select(pFolder)
Logger.Debug("Fetching Unseen UUIDs")
Dim oUUIDs As List(Of Long) = oClient.Search(Flag.Unseen)
Dim oMailBuilder As New MailBuilder()
Logger.Debug("Fetching Unseen Mails")
For Each oUUID As Long In oUUIDs
Dim oEmlFile As Byte() = oClient.GetMessageByUID(oUUID)
Dim oEmail As IMail = oMailBuilder.CreateFromEml(oEmlFile)
oMails.Add(oEmail)
Next
Logger.Debug("Emails fetched!")
oClient.Close()
End If
End Using
Return oMails
Catch ex As Exception
Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
Logger.Error(ex)
Return New List(Of IMail)
End Try
End Function
Public Function Get_Message(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, pMessageId As String, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As IMail
Logger.Debug("Fetching Message [{0}] from Server [{1}:{2}] with user [{3}]", pMessageId, pServer, pPort, pUsername)
Dim oMail As IMail = Nothing
Try
Using oClient As New Imap()
If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
Logger.Debug("Fetching Folder [{0}]", pFolder)
Dim oStatus As FolderStatus = oClient.Select(pFolder)
Logger.Debug("Fetching UUIDs")
Dim oUUIDs As List(Of Long) = oClient.Search(Flag.All)
Logger.Debug("Fetching Mails")
Dim oInfos As List(Of MessageInfo) = oClient.GetMessageInfoByUID(oUUIDs)
Dim oMailInfo = oInfos.Where(Function(i) i.Envelope.MessageID = pMessageId).FirstOrDefault()
If oMailInfo IsNot Nothing Then
Dim oMailData As Byte() = oClient.GetMessageByUID(oMailInfo.UID)
oMail = MailBuilder.CreateFromEml(oMailData)
End If
Logger.Debug("Emails fetched!")
oClient.Close()
End If
End Using
Return oMail
Catch ex As Exception
Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
Logger.Error(ex)
Return Nothing
End Try
End Function
Public Function Remove_AttachmentsFromEmail(pFileName As String, Optional pSuffix As String = "") As String
Try
Dim oTempFileName As String = Path.Combine(Path.GetTempPath(), AddFilenameSuffix(pFileName, pSuffix))
Dim oMail = MailBuilder.CreateFromEmlFile(pFileName)
oMail.RemoveAttachments()
oMail.Save(oTempFileName)
Return oTempFileName
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Public Function Save_AttachmentsToDisk(pFileName As String) As List(Of String)
Try
Dim oAttachmentPaths As New List(Of String)
Dim oMail = MailBuilder.CreateFromEmlFile(pFileName)
Dim oTempPath As String = IO.Path.GetTempPath()
If oMail.Attachments.Count = 0 Then
Return New List(Of String)
End If
For Each oAttachment As MimeData In oMail.Attachments
Dim oPath As String = IO.Path.Combine(oTempPath, oAttachment.SafeFileName)
Dim oVersionedPath As String = FileEx.GetVersionedFilename(oPath)
oAttachment.Save(oVersionedPath)
oAttachmentPaths.Add(oVersionedPath)
Next
Return oAttachmentPaths
Catch ex As Exception
Logger.Error(ex)
Return New List(Of String)
End Try
End Function
Public Function ConvertMsgToEml(pEmailFileName As String) As String
Dim oInfo As New FileInfo(pEmailFileName)
If oInfo.Extension.ToUpper = ".EML" Then
Return pEmailFileName
ElseIf oInfo.Extension.ToUpper = ".MSG" Then
Return DoConvertMsgToEmlFile(pEmailFileName)
Else
Return Nothing
End If
End Function
Private Function DoConvertMsgToEmlFile(pMsgFile As String) As String
Try
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pMsgFile)
Dim oEmlPath As String = $"{oFileNameWithoutExtension}.eml"
Using oConverter As New MsgConverter(pMsgFile)
Dim oEmail As IMail = oConverter.CreateMessage()
Dim oData As Byte() = oEmail.Render()
oEmail.Save(oEmlPath)
End Using
Return oEmlPath
Catch ex As Exception
Return Nothing
End Try
End Function
Private Function GetTempFileNameWithExtension(pExtension As String) As String
Dim oTempFileName As String = IO.Path.GetTempFileName()
Dim oInfo As New IO.FileInfo(oTempFileName)
Dim oExtension As String = IIf(pExtension.StartsWith("."), pExtension, $".{pExtension}")
Dim oNewFileName = IO.Path.Combine(oInfo.DirectoryName, oInfo.Name.Replace(oInfo.Extension, oExtension))
Return oNewFileName
End Function
Private Function AddFilenameSuffix(pFilename As String, pSuffix As String)
Dim oFileInfo As New FileInfo(pFilename)
Dim oExtension As String = oFileInfo.Extension
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pFilename)
Return $"{oFileNameWithoutExtension}{pSuffix}{oExtension}"
End Function
End Class