User Tools

Site Tools


Sidebar

Network and communication

k24:k24.5:k24.5.3:start

24.5.3 POP3 parser

For the POP3 client in chapter 24.5.4, the component gb.net.pop3client by Sebastian Kulesz is used. In my opinion, the advantage of the component is that all POP3 commands are encapsulated in methods according to RFC 1939. Since the Pop3Client class includes, among other things, the Exec(…) method, you can also execute all POP3 commands directly. As an extension of the component, the authentication procedure APOP was implemented by the book author Hans Lehmann. The procedure ensures that the POP3 password is transmitted in encrypted form from the POP3 client to the POP3 server. A description of the APOP authentication procedure can be found in → Chapter 24.5.3. The implementation was done in such a way that the system automatically switches to the APOP procedure if the POP3 client detects that the POP3 server also offers APOP as an authentication procedure. If you switch the 'Debug' property to True in the POP3 client trial, you can follow the complete communication between POP3 client and POP3 server:

gb.net.pop3: Connecting to mx.freenet.de
gb.net.pop3: Connecting to Port 995
gb.net.pop3: Encryption: Net.SSL
gb.net.pop3: Change to APOP
gb.net.pop3: Authenticating...
gb.net.pop3: Sending: APOP wer@ist.da 1eeddd29088529659e3bc76e84c4d44c
gb.net.pop3: +OK 2 messages (66766 octets).
gb.net.pop3: APOP Authentification OK
gb.net.pop3: Refreshing inbox cache
gb.net.pop3: Sending: STAT
gb.net.pop3: +OK 2 66766
gb.net.pop3: Sending: UIDL
gb.net.pop3: +OK...
gb.net.pop3: Sending: UIDL
gb.net.pop3: +OK...
gb.net.pop3: Creating new message instance for 0
gb.net.pop3: Sending: RETR 1
gb.net.pop3: +OK 1879 octets...
gb.net.pop3: Creating new message instance for 1
gb.net.pop3: Sending: RETR 2
gb.net.pop3: +OK 64887 octets...
gb.net.pop3: Sending: QUIT
gb.net.pop3: +OK
gb.net.pop3: Disconnecting...

For the settings of the created POP3 client object, the POP3 client uses the specifications that have been stored in a configuration file via the manager for e-mail accounts → Chapter 24.3.4 'Manager for e-mail accounts'. If there is no configuration file when the programme is started for the first time, the manager starts automatically. These six settings must be assigned suitable values for POP3:

  • POP3 server
  • POP3 port (110, 995)
  • Connection security: POP3Encryption: Net.SSL, Net.TLS or Net.NONE
  • Authentication method : POP3Authentication: Basic (password normal) or APOP (password encrypted).
  • POP3 User
  • POP3-Password

and are required in the following procedures:

Public Sub GeneratePOP3Client(_Debug As Boolean)
 
  If hPOP3Client <> Null Then
     If hPOP3Client.Status = Net.Connected Then
        If hPOP3Client.Close() = False Then
           hPOP3Client = Null
        Endif
     Else
        hPOP3Client = Null
     Endif
  Endif
 
  hPOP3Client = New Pop3Client
  hPOP3Client.Host = acSettings[sCurAccount & "/POP3Server"]
  hPOP3Client.Port = CInt(acSettings[sCurAccount & "/POP3Port"])
 
  If Upper(acSettings[sCurAccount & "/POP3Encryption"]) = "NET.SSL" Then hPOP3Client.Encrypt = 1
  If Upper(acSettings[sCurAccount & "/POP3Encryption"]) = "NET.NONE" Then hPOP3Client.Encrypt = 0
 
  If acSettings[sCurAccount &/ "POP3Authentication"] = ("Password normal") Then \
                            hPOP3Client.Authent = Net.AuthBasic ' 0
  If acSettings[sCurAccount &/ "POP3Authentication"] = ("Password encrypted (APOP)") Then \
                            hPOP3Client.Authent = Net.AuthAPOP ' 3
 
  hPOP3Client.User = acSettings[sCurAccount & "/POP3UserName"]
  hPOP3Client.Password = M3.E4(acSettings[sCurAccount & "/POP3UserPassword"]) ' Decrypted password
 
  hPOP3Client.Debug = _Debug
 
End ' GeneratePOP3Client(...)
 
Public Function ConnectToPOP3Server() As String
 
  Try hPOP3Client.Open()
  If Not Error Then Return "NoError"
 
End ' ConnectToServer()

If there is a connection from the POP3 client to the POP3 server:

  • whether there are emails in the mailbox in your account and how many there are in total. Either read the Pop3Client.Count property or use the Stat method to get the number of emails with Stat[0] and the total size of all emails in the mailbox with Stat[1],
  • via the size of each individual email in a list (method List()),
  • via the number and unique ID of each email in a list (method ListUniqueID()).

You can also delete individual e-mails in the mailbox on the POP3 server by marking the e-mail as the e-mail to be deleted via the number of the e-mail. You can undo this marking for all affected e-mails by using the Reset() method. The marked e-mails are only actually deleted when you terminate the TCP-IP connection.

With this information, you are able to either selectively download a specific e-mail from the mailbox on the POP3 server to a local mailbox on your home PC for a specific e-mail account or to do this for all e-mails. The POP3 client always triggers the download for all e-mails in the mailbox - but only if an e-mail is not yet in the local mailbox. In the account settings, you can also specify that all e-mails should be deleted from the POP3 server after they have been downloaded to the mailbox.

The following paragraph describes how the download of all emails present in the selected mailbox on the POP3 server has been implemented. Saving an email in the local mailbox to a specific email account is done by saving the email source text in a file. The file name for the source text is generated from the unique ID of each email.

The complete source text for the procedure is given, which is then commented on.

Source text for downloading and storing emails:

[1] Public Sub RetrieveEMails()
[2]
[3]   Dim i, iCount, iIndex As Integer
[4]   Dim sFileName, sBaseName, sMessage, sMailBoxDir, sMimeMessageText, sSavePath, sUniqueIDText, sHash As String
[5]   Dim dMMDate As Date
[6]   Dim iUID As Integer
[7]   Dim aValue, aElement As New Variant[]
[8]   Dim aDownloadList As New Variant[][]
[9]   Dim aBaseNameList As New String[]
[10]   Dim hMimeMessageHeaders As MimeMessage
[11]
[12]   If Not MMMP.SystemOnline() Then Return
[13]
[14]   sMailBoxDir = sBaseDir &/ sCurAccount
[15]
[16] '----------------------------------------------------------------------------
[17]   GeneratePOP3Client(True) ' True for debugging for tests
[18] '----------------------------------------------------------------------------
[19]
[20]   If ConnectToPOP3Server() = "NoError" Then
[21]      sMessage = ("Connected to ") & acSettings[sCurAccount & "/POP3Server"]
[22]      lblStatus.Text = sMessage
[23]   Else
[24]      sMessage = ("Error connecting to the POP3 server!")
[25]      lblStatus.Text = sMessage
[26]      Return
[27]   Endif
[28]   Wait 0.2
[29]
[30]   If hPOP3Client.Count > 0 Then
[31]      For Each sFileName In Dir(sMailBoxDir, "*.*", gb.File) ' Lokales Postfach
[32]        aBaseNameList.Add(Scan(sFileName, "*.*.*")[1])
[33]      Next
[34]
[35]      For i = 0 To hPOP3Client.Count - 1
[36]      ' Muster ListUniqueID: 4 000008394ef05e55
[37]        sUniqueIDText = Scan(hPOP3Client.ListUniqueID()[i], "* *")[1]
[38]        sHash = Split(Base64(Digest["MD5"].Hash(sUniqueIDText)), "=")[0]
[39]        sHash = Replace(sHash, "+", "A")
[40]        sHash = Replace(sHash, "/", "B")
[41]
[42]        sBaseName = sHash
[43]
[44]      ' Wenn eine EMail auf dem POP3-Server noch NICHT lokal gespeichert wurde, dann wird ihre
[45]      ' EMail-Nummer (UID-Zahl) auf dem Server und ihr konvertierter UID-Text als sBaseName = sHash
[46]      ' als Basis-Dateiname in die Download-Liste eingetragen.
[47]        If Not aBaseNameList.Exist(sBaseName) Then
[48]           aValue = New Variant[]
[49]           iUID = CInt(Scan(hPOP3Client.ListUniqueID()[i], "* *")[0])
[50]           aValue.Add(iUID) ' EMail-Nummer
[51]           aValue.Add(sBaseName & ".txt") ' Dateiname als konvertierter UID-Text
[52]           aDownloadList.Add(aValue)
[53]        Endif
[54]      Next
[55]   Endif
[56]
[57]   If aDownloadList.Count = 0
[58]      lblStatus.Text = ("You have no new messages!")
[59]      Wait 0.5
[60]      lblStatus.Text = ""
[61]      If Connected() Then DisconnectFromPOP3Server()
[62]      Return
[63]   Else
[64]      lblStatus.Text = Subst$(("You have &1 new &2."), aDownloadList.Count, \
[65]                             IIf(aDownloadList.Count = 1, ("message"), ("messages")))
[66]      Wait 0.3
[67]   Endif
[68]
[69]   lblStatus.Text = ""
[70]   iCount = 0
[71]   wevBody.Url = Application.Path &/ "download.html"
[72]
[73]   For Each aElement In aDownloadList
[74]     Inc iCount
[75]     lblStatus.Text = ("Download ") & Str$(iCount) & (" of ") & Str$(aDownloadList.Count)
[76]     iIndex = aElement[0]
[77]
[78]   ' -------------------------------------------------------------------------------------
[79]   ' Download einer EMail (EMail-Quelltext vom Typ MimeMessageText)
[80]     sMimeMessageText = hPOP3Client[iIndex - 1].Text
[81]     Wait
[82]   ' -------------------------------------------------------------------------------------
[83]
[84]     hMimeMessageHeaders = New MimeMessage(MMMP.GetMMHeaderText(sMimeMessageText))
[85]
[86]     dMMDate = MMMP.ReadDate(hMimeMessageHeaders.Headers["Received"])
[87]     sSavePath = sMailBoxDir &/ Format(dMMDate, "yyyy-mm-dd-hh-nn-ss") & "." & aElement[1]
[88]     File.Save(sSavePath, sMimeMessageText)
[89]     Wait
[90]   ' -------------------------------------------------------------------------------------------------
[91]   ' Löschen der EMail *auf dem Server* nach dem Download, wenn das Löschen der EMails vorgesehen ist!
[92]     If bDeleteMailAllowed = True Then hPOP3Client.Remove(iIndex - 1)
[93]
[94]     UpdateListHeaders(sBaseDir &/ sCurAccount)
[95]   ' Anzeige einer Übersicht der lokal gespeicherten EMails
[96]   ' (Anhang-Symbol(optional), Betreff, Absender, Datum und Größe)
[97]     ShowMailHeaders(aListHeaders)
[98]
[99]   Next ' EMail
[100]
[101]   If aListHeaders.Count > 0 Then
[102]      If Dir(sBaseDir &/ sCurAccount, "*.txt", gb.File).Count > 0 Then
[103]         ShowMailData() ' Anzeige der EMail im internen Browser (WebView)
[104]      Endif
[105]   Endif
[106]
[107]   lblStatus.Text = ("Download completed!")
[108]   Wait 0.3
[109]
[110] '------------------------------------------------
[111]   If Connected() Then DisconnectFromPOP3Server()
[112]   DestroyPOP3Client()
[113] '------------------------------------------------
[114]
[115] End ' RetrieveEMails()

Comment:

  • In line 12, a check is made at the start of the programme whether an active connection to the Internet exists.
  • The selection of the current mailbox on the server is made in line 14.
  • A POP3 client object is created in line 17. The properties are read from a configuration file. For testing purposes, it is essential to switch on debugging.
  • In lines 31 to 33, a list (aBaseNameList) is created in which the second part of the file name is entered from all files in the current local mailbox that have the pattern *.*.* in the file name such as 2016-03-07-09-17-35.XanBcUYCsp6RltyFsocqiA.txt. The Scan() function offers - not only at this point - very good functionality!
  • In lines 37 to 42, a hash value is generated from the text part of the unique ID via several conversions (MD5, Base64 with substitutions), which serves as the base file name.
  • In order for an email to be saved to the local mailbox on the POP3 server, it must be ensured that this email has not yet been saved. To do this, line 47 checks whether there is not yet a file in the local mailbox with the converted UID text as the base file name. In this case, the UID number → line 50 and the base file name → line 51 are saved in another list (aValue), which is then used and processed as a download list.
  • In line 80, the source text of the email of type MimeMessageText is assigned to the variable sMimeMessageText - this is the actual download.
  • This text is saved in a file in line 88. The file name has the following format: “Converted Date ('Received')”. DOT base file name DOT “txt”.
  • If deletion of the email after download from the POP3 server was specified in the configuration, then the email → line 92 is marked for deletion.
  • In lines 94 onwards, the email overview is redisplayed and the first email in the browser.
  • Finally, the existing connection of POP3 client and POP3 server is disconnected and the POP3 client is destroyed.

After the successful download, the e-mails are in the local mailbox. Whenever e-mails are mentioned in the following paragraphs, the e-mail source text of the type MimeMessage is always meant, for the processing of which the classes of the component gb.mime are used → Chapter 24.3.0 Component gb.mime.

The algorithms necessary for displaying the emails are based on the knowledge and understanding of how emails are structured internally. For this reason, a parser was first developed that determines the structure for a given email source text of the type MimeMessage and saves it as an HTML file and falls back on the parser in → Chapter 24.3.2 Class MimePart. It is noticeable that this structure has a (recursive) nested character, which is also reflected in the project source code (recursive loop) of the structure parser for emails:

':::::  MIMEMESSAGE-STRUKTUR GENERIEREN UND ALS HTML-DATEI SPEICHERN  :::::::::::::::::::::::::::::::::::
 
' Funktion:        Structure(...)
' Parameter:       MimeMessageText Typ: String
' Funktionswert:   Datei-Pfad zur Struktur-Datei Typ: String
Public Function Structure(MimeMessageText As String) As String
 
  Dim sHTMLData As String
 
  $sMM = New MimeMessage(MimeMessageText)
 
  sHTMLData = "<!DOCTYPE html>" & gb.NewLine
  sHTMLData &= "<html lang=\"de\">" & gb.NewLine
  sHTMLData &= " <head>" & gb.NewLine
  sHTMLData &= "  <meta charset=\"utf-8\">" & gb.NewLine
  sHTMLData &= "  <style>" & gb.NewLine
  sHTMLData &= "    body{font-family:Arial,Verdana;color:darkgreen;font-size:16px;}" & gb.NewLine
  sHTMLData &= "  </style>" & gb.NewLine
  sHTMLData &= " </head>" & gb.NewLine
  sHTMLData &= " <body>" & gb.NewLine
  sHTMLData &= Replace(GetMimeMessageStructure($sMM.Part), gb.NewLine, "<br>\n")
  sHTMLData &= " </body>" & gb.NewLine
  sHTMLData &= "</html>"
 
' Struktur-Datei temporär speichern
  File.Save($sBasePath &/ _STRUCTURFILENAME, sHTMLData)
  If $bDebug Then _PrintDebug(("Show EMail-Structure"))
 
  Return $sBasePath &/ _STRUCTURFILENAME
 
End ' Structure(...)
 
' Funktion:        GetMimeMessageStructure(...)
' Parameter:       Part Typ: MimePart
' Funktionswert:   Text der Struktur-Datei Typ: String
Private Function GetMimeMessageStructure(Part As MimePart) As String
 
  Dim sBodyType As String
 
  If $bDebug Then _PrintDebug(("Create EMail-Structure"))
  If Not Part Then Error.Raise("MimePart not set")
 
  sBodyType = Scan(Part.Headers["Content-Type"], "*;*")[0]
 
  $sStructure = ""
 
  $sStructureH = ("STRUCTURE MIME-MESSAGE")
  $sStructureH &= gb.NewLine
  $sStructureH &= String$(String.Len($sStructureH), "-") & gb.NewLine
  $sStructureH &= gb.NewLine
  $sStructureH &= "+ " & sBodyType & gb.NewLine
 
  $sStructureB = ""
  ParseStructureBody($sMM.Body)   ' Parse Structure: Body
 
  $sStructureA = ""
  $iAttachmentCount = 0
  $iFlag = 0
  ParseStructureAttachments(Part) ' Parse Structure: Attachments
 
  $sStructure = $sStructureH & $sStructureB & $sStructureA
 
  Return $sStructure
 
End ' GetMimeMessageStructure(...)
 
' Prozedur:       ParseStructureBody(...)
' Parameter:      Part Typ: MimePart
' Aktion:         Parsen der Struktur des MimeMessage-Bodys.
'                 Das Ergebnis wird in der Variablen $sStructureB gespeichert
Private Sub ParseStructureBody(Part As MimePart)
 
  Dim hChild As MimePart
  Dim sLine As String
 
  sLine &= String$($iLevel, "| ") & "| " & gb.NewLine
  sLine &= String$($iLevel, "| ") & "+-" & If(Part.Count, "+ ", "- ")
  sLine &= Part.ContentType & " " & IIf(Part.FileName, Part.FileName & " ", "") & Part.Count & gb.NewLine
  $sStructureB &= sLine
 
  Inc $iLevel
    For Each hChild In Part
        ParseStructureBody(hChild) ' Recursive loop
    Next
  Dec $iLevel
 
End ' ParseStructureBody(...)
 
' Prozedur:       ParseStructureAttachments(Part As MimePart)
' Parameter:      Part Typ: MimePart
' Aktion:         Parsen der Struktur des MM-Anhangs.
'                 Das Ergebnis wird in der (globalen) Variablen $sStructureA gespeichert
Private Sub ParseStructureAttachments(Part As MimePart)
 
  Dim hChild As MimePart
  Dim sLine As String
 
  If Part.Disposition = "attachment" And Str(Part.Count) = 0 Then
     If $iFlag = 0 Then
        sLine &= "|" & gb.NewLine
        Inc $iFlag
     Endif
     sLine &= ("+ Attachment ") & Str($iAttachmentCount + 1) & ": " & " " & Part.ContentType
     sLine &= " " & Part.FileName & gb.NewLine
     Inc $iAttachmentCount
     $sStructureA &= sLine
  Endif
 
  Inc $iLevel
    For Each hChild In Part
        ParseStructureAttachments(hChild) ' Recursive loop
    Next
  Dec $iLevel
 
End ' ParseStructureAttachments(..)
 
':::::  ENDE MIMEMESSAGE-STRUKTUR GENERIEREN UND ALS HTML-DATEI  SPEICHERN ::::::::::::::::::::::::::::::

As a result, you receive the following display of the structure of an email in the browser from the parser for the email source text passed as an argument:

STRUKTUR MIME-MESSAGE
----------------------

+ multipart/mixed
|
+-+ multipart/alternative 2
| |
| +-- text/plain 0
| |
| +-+ multipart/related 3
| | |
| | +-- text/html 0
| | |
| | +-- image/png bild1.png 0
| | |
| | +-- image/png bild2.png 0
|
+ Anhang 1: text/plain body.txt
+ Anhang 2: image/png chart.png

Interpretation:

  • The EMail consists of several, different parts (multipart/mixed) - the message part (body) and an attachment part (attachment). The message and the attachment have different formats.
  • The message part consists of two parts (multipart/alternative), each containing the same message text in plain text (format text/plain) and alternatively as HTML source text (format text/html).
  • The HTML source code consists of three parts (multipart/related), because in addition to the text part, the HTML part also contains two images, which are stored in two image files.
  • The attachment consists of 2 different parts - a text file (text/plain) and a png image file.

The next step is to use the methods of the class 'MimeMessageParser' to isolate the individual parts of an email for display according to their recursive structure, decode them and store them temporarily in a suitable way. The parts are isolated separately for body and attachment. If one uses the classes of the component gb.mime, then one does not need to worry about the decoding of an image, for example, which is base64-encoded in the email source text. The decoding takes over the data property for each part automatically, so that you only have to turn to the storage of the decoded parts. The text parts of a message are stored in an HTML file. Multimedia objects such as pictures or videos are saved in individual files and the file path is inserted as a link in the HTML file. The path to the HTML file is then saved in a variable and passed to the URL property of a WebView as a value. The attachments (optional) are decoded and temporarily stored under their original file name in a special directory. For each attachment, a button is generated whose tag property contains the path to the attachment. You can view the content of an attachment (if it is of a suitable type) or save the attachment in the dialogue.

This is how the display of an e-mail (format text/plain) with 2 attachments appears in the browser after the e-mail source text has been parsed:

B1
Figure 24.5.3.1: GUI POP3 client

The source code for the most important procedures of the MimeMessageParser is only complicated at first glance. In my opinion, this is mainly due to the sections in which recursions determine the programme flow (→ recursive loop):

':::::  BEGINN BODY PARSEN  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
' Funktion:        MessageBody(...)
' Parameter:       MimeMessageText Typ: String
' Funktionswert:   Datei-Pfad zum Text-Teil - Typ: String
Public Function MessageBody(MimeMessageText As String) As String
 
  $cInlineCID.Clear
  $bIsText = False
  $bIsHTML = False
 
  MMMP.DeleteTempFiles($sBasePath &/ $sInlineDir)
  MMMP.DeleteTempFiles($sBasePath)
 
  $sMM = New MimeMessage(MimeMessageText)
  ParseBody($sMM.Body)
 
  If $cInlineCID.Count > 0 Then
     ReplaceCID()
  Endif
  If $bIsHtml Or ($bIsHtml And $bIsText) Then
     Return $sBasePath &/ _HTMLFILENAME
  Endif
  If $bIsText Then
     Return $sBasePath &/ _TEXTFILENAME
  Endif
 
 End
 
' Prozedur:	ReplaceCID() - CID steht für Content-ID
' Parameter:	-
' Aktion:	In der HTML-Datei wird jede CID durch den Pfad zur Inline-Datei ersetzt
Private Sub ReplaceCID()
 
  Dim sHTMLText As String
  Dim vElement As Variant
 
  sHTMLText = File.Load($sBasePath &/ _HTMLFILENAME)
  For Each vElement In $cInlineCID
    sHTMLText = Replace(sHTMLText, "cid:" & $cInlineCID.Key, $cInlineCID[$cInlineCID.Key])
  Next
 
' Speichern der geänderten HTML-Datei
  File.Save($sBasePath &/ _HTMLFILENAME, sHTMLText)
 
End
 
' Prozedur:        ParseBody()
' Parameter:       Part Typ: MimePart
' Parsen des MimeMessage-Bodys (Inline-Dateien, Nachricht)
' Die in einer HTML-Nachricht liegenden multimedialen Objekte (image, audio, video, application)
' werden in der Variablen '$cInlineCID' (Typ: Collection) mit dem originalen Datei-Namen gespeichert.
' Die Pfade zu den Objekten werden in der Variablen $cInlineCID (Typ: Collection) gespeichert.
' Eine Nachricht kann eine Text-Nachricht oder eine HTML-Nachricht oder beides sein.
' Jede Nachricht wird in einer Datei mit den Datei-Namen "html.part.html" oder "text.part.html"
' im Basis-Verzeichnis temporär gespeichert
Private Sub ParseBody(Part As MimePart)
 
  Dim hChild As MimePart
  Dim sTextData As String
 
  If Part.Data Then
     If Part.Disposition = "inline" And
        (Part.ContentType Like "image/*" Or
        Part.ContentType Like "audio/*" Or
        Part.ContentType Like "application/*" Or
        Part.ContentType Like "video/*") Then
           File.Save($sBasePath &/ $sInlineDir &/ Part.FileName, Part.Data)
           $cInlineCID[Part.ContentId] = $sBasePath &/ $sInlineDir &/ Part.FileName
     Endif
 
     If Part.ContentType = "text/html" Then
        $bIsHtml = True
        File.Save($sBasePath &/ _HTMLFILENAME, Part.Data)
     Endif
 
     If Part.ContentType = "text/plain" Then
        sTextData = "<!DOCTYPE html>" & gb.NewLine
        sTEXTData &= "<html lang=\"de\">" & gb.NewLine
        sTextData &= " <head>" & gb.NewLine
        sTextData &= "  <meta charset=\"utf-8\">" & gb.NewLine
        sTextData &= "  <style>" & gb.NewLine
        sTextData &= "    body{font-family:Verdana,sans-serif;color:darkred;font-size:16px;}" & gb.NewLine
        sTextData &= "  </style>" & gb.NewLine
        sTextData &= " </head>" & gb.NewLine
        sTextData &= " <body>" & gb.NewLine
        sTextData &= Replace(Part.Data, gb.NewLine, "<br>\n")
        sTextData &= " </body>" & gb.NewLine
        sTextData &= "</html>"
        $bIsText = True
        File.Save($sBasePath &/ _TEXTFILENAME, sTextData)
     Endif
  Endif ' Part.Data ?
 
  For Each hChild In Part
    ParseBody(hChild) ' Recursive loop
  Next
 
End
 
':::::  ENDE BODY PARSEN  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
':::::  ANHÄNGE TEMPORÄR SPEICHERN (DATEI)  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
' Funktion:        Attachments(...)
' Parameter:       MimeMessageText Typ: String
' Funktionswert:   Array mit den Datei-Pfaden zu den Anhängen - Typ: String-Array
Public Function Attachments(MimeMessageText As String) As String[]
 
  $aAttachmentPaths.Clear
 
  $sMM = New MimeMessage(MimeMessageText)
  ParseA($sMM.Part)
 
' Funktionswert: String-Array mit den Pfaden zu den Anhängen
  Return $aAttachmentPaths
 
End ' ParseAttachments(..)
 
' Prozedur:       ParseA(...)
' Parameter:      Part Typ: MimePart
' Aktion:         Parsen des MM-Anhangs.
'                 Jeder Anhang wird in einer Datei mit dem originalen Datei-Namen des Anhangs gespeichert
'                 Das Array $aAttachmentPaths wird mit den Datei-Pfaden zu den Anhängen gefüllt
Private Sub ParseA(Part As MimePart)
 
  Dim hChild As MimePart
 
  If Part.Disposition = "attachment" And Part.Count = 0 Then
   ' Anhang (temporär) in einer Datei mit dem Namen der Original-Datei speichern
     File.Save($sBasePath &/ $sAttachmentsDir &/ Part.FileName, Part.Data)
   ' Aktuellen Datei-Pfad zum String-Array hinzufügen
     $aAttachmentPaths.Add($sBasePath &/ $sAttachmentsDir &/ Part.FileName)
  Endif
  For Each hChild In Part
    ParseA(hChild) ' Recursive loop
  Next
End ' ParseA(..)
 
':::::  ENDE ANHÄNGE TEMPORÄR  SPEICHERN ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Attention: Replacing the CID (content id) in the procedure ReplaceCID() only works safely if multimedia objects have been included via a CID.

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k24/k24.5/k24.5.3/start.txt · Last modified: 16.08.2022 (external edit)

Page Tools