Mail Box Parsing


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: 2001年11月22日 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 5:01 am GMT (diff)

AltStyle によって変換されたページ (->オリジナル) /