This package requires use of cl-qprint, cl-base64 and cl-ppcre.
Repository: https://github.com/40ants/cl-mime
Author: Robert Marlow
License: LLGPL
Usage example
Small example to parse Thunderbird messages in mbox format:
(defun thunderbird-mbox-msg-to-text (email)
(with-open-file (msg email :direction :input)
(with-open-file (out (concatenate 'string (pathname-name x) ".txt") :direction :output :if-exists :supersede)
(let ((mime (parse-mime msg)))
(case (type-of mime)
(text-mime (print (content mime) out))
(multipart-mime
(dolist (part (content mime))
(if (and (string-equal (content-type part) "text")
(string-equal (content-subtype part) "plain"))
(print-mime out part nil nil))))
(mime (print "mime")) ;?
(t (print "other"))))))) ;?
The MIME class is the mixin which TEXT-MIME and MULTIPART-MIME inherit from. Most plain text messages will be of type TEXT-MIME and you can read the body with the CONTENT function. MULTIPART-MIME messages have multiple parts, you will have to iterate over them inspecting the type and subtype of each and choose what to do with them. In the example above, I was extracting the plain text version of html emails. See the wikipedia page on MIME and help yourself.
Quick assessment (2023-04-05)
Tested with MKCL:
> (with-open-file (stream "M:/downloads/new.eml")
(cl-mime:parse-mime stream))
#<a CL-MIME:MULTIPART-MIME 166614816>
> (cl-mime:get-mime-headers *)
((:MIME-VERSION . "1.0")
(:CONTENT-TYPE
. "multipart/alternative; boundary=\"9f9ed95156ef51dd4088a1e5dc2b74a836bd9e70f09380894bde1b1a0fa9\"")
(:CONTENT-TRANSFER-ENCODING . :7BIT))
> (cl-mime:header-parms (second *))
((:BOUNDARY "9f9ed95156ef51dd4088a1e5dc2b74a836bd9e70f09380894bde1b1a0fa9"))
> (cl-mime:print-headers *standard-output* ** t)
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="9f9ed95156ef51dd4088a1e5dc2b74a836bd9e70f09380894bde1b1a0fa9"
Content-Transfer-Encoding: 7bit
NIL