Mail Box Parsing

lua-users home
wiki

Difference (from prior major revision) (no other diffs)

Changed: 2,3c2

[!] VersionNotice: The below code pertains to an older Lua version, Lua 4. It does not run as is under Lua 5.
The code has been tested on Lua 5.0, 5.1 and 5.2(beta).

Added: 6a6,10
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"




Changed: 46,47c50
},
n = 1
}

Changed: 55c58,59
parse = Public
local strfind, strlower, gsub = string.find, string.lower, string.gsub
local strsub, tinsert = string.sub, table.insert

Changed: 83c87
return { headers = %Public.headers(headers_s), body = body }
return { headers = Public.headers(headers_s), body = body }

Changed: 93c97
tinsert(mbox, %Public.message(strsub(mbox_s, i + 1, j - 1)))
tinsert(mbox, Public.message(strsub(mbox_s, i + 1, j - 1)))

Added: 97a102,103

return Public

Added: 99a106,107



Changed: 102c110,111
This code was created by DiegoNehab, and is used to test the LuaSocket[1] 1.4 SMTP code.
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.


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)