Mail Box Parsing

lua-users home
wiki

Showing revision 13
Below is a simple library to parse mailbox files, as usually found in Unix systems.

[!] VersionNotice: The below code pertains to an older Lua version, Lua 4. It does not run as is under Lua 5.

Parsing Mail box files

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.",
  },
  n = 1 
}
	

Source Code

local Public = {}
parse = Public

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
	

Credits

This code was created by DiegoNehab, and is used to test the LuaSocket[1] 1.4 SMTP code.


RecentChanges · preferences
edit · history · current revision
Edited January 5, 2007 5:41 am GMT (diff)