Mail Box Parsing

lua-users home
wiki

Below is a simple library to parse mailbox files, as usually found in Unix systems. The code has been tested on Lua 5.0, 5.1 and 5.2(beta).

Parsing Mail box files

Say you save the source code in the current directory (or elsewhere in your PackagePath) as mboxparser.lua. In your code, put:

parse = require "mboxparser" 

The main function, parse.mbox, receives the mailbox file contents as a string and returns a table with one entry per message. Each entry has the following structure:

message = {

    headers = {

        [["name_1"]] = "value_1",

        [["name_2"]] = "value_2",

        ...           ...

        [["name_n"]] = "value_n",

    },

    body = "message body"

}

	

Therefore, if a mailbox has the following contents:


From  whoever@tecgraf.puc-rio.br  Thu Nov 22 13:59:05 2001

Date: Thu, 22 Nov 2001 13:59:04 -0200 (EDT)

From: Whoever Smith <whoever@tecgraf.puc-rio.br>

To: Other Smith <other@tecgraf.puc-rio.br>

Subject: This is a test message

Content-Type: TEXT/PLAIN; charset=US-ASCII



Hi, This is the message body.  Regards, Diego.

	

Calling parse.mbox on it would return the following table:

messages = {

  { 

    headers = {

      from = "Whoever Smith <whoever@tecgraf.puc-rio.br>", 

      subject = "This is a test message", 

      to = "Other Smith <other@tecgraf.puc-rio.br>", 

      date = "Thu, 22 Nov 2001 13:59:04 -0200 (EDT)", 

      ["content-type"] = "TEXT/PLAIN; charset=US-ASCII", 

    }, 

    body = "Hi, This is the message body.  Regards, Diego.",

  }

}

	

Source Code

local Public = {}

local strfind, strlower, gsub = string.find, string.lower, string.gsub

local strsub, tinsert = string.sub, table.insert



function Public.headers(headers_s)

    local headers = {}

    headers_s = "\n" .. headers_s .. "$$$:\n"

    local i, j = 1, 1

    local name, value, _

    while 1 do

        j = strfind(headers_s, "\n%S-:", i+1)

        if not j then break end

        _, _, name, value = strfind(strsub(headers_s, i+1, j-1), "(%S-):(.*)")

        value = gsub(value or "", "\r\n", "\n")

        value = gsub(value, "\n%s*", " ")

        name = strlower(name)

        if headers[name] then headers[name] = headers[name] .. ", " ..  value

        else headers[name] = value end

        i, j = j, i

    end

    headers["$$$"] = nil

    return headers

end



function Public.message(message_s)

    message_s = gsub(message_s, "^.-\n", "")

    local _, headers_s, body

    _, _, headers_s, body = strfind(message_s, "^(.-\n)\n(.*)")

    headers_s = headers_s or ""

    body = body or ""

    return { headers = Public.headers(headers_s), body = body }

end



function Public.mbox(mbox_s)

    local mbox = {}

    mbox_s = "\n" .. mbox_s .. "\nFrom "

    local i, j = 1, 1

    while 1 do

        j = strfind(mbox_s, "\nFrom ", i + 1)

        if not j then break end

        tinsert(mbox, Public.message(strsub(mbox_s, i + 1, j - 1)))

        i, j = j, i

    end

    return mbox

end



return Public

	

Credits

The original Lua 4 code was created by DiegoNehab, and is used to test the LuaSocket[1] 1.4 SMTP code. The Lua 5 version was made by DirkLaurie.


RecentChanges · preferences
edit · history
Last edited August 5, 2011 10:01 am GMT (diff)