PDA

View Full Version : Simple POP3 Object



Marquis
July 8th, 2007, 09:32 AM
Hi folks,

I have written a simple POP3-object in lua for my personal needs. I would like to share this with you and hope you like it.

For the source-code see the attachment. Here is a short example on how to use. In a Girder scripting action write:

dofile([[YOURPATH\mp.pop3watch.lua]])
myMail=pop3:new({server='YOURSERVERNAME'},'myMail' )
myMail:get('USERNAME','PASSWORD')

-- here goes your code to parse the messages and to decide what to do
for c=1,myMail.msg.count do
for k,v in pairs(myMail.msg[c]) do
print(k,v)
end
end

The first line can be somewhere else in your .gml, but must be executed before you try to use the object.

OK, what will you get? First of all it's a very simple interface. The new() constructor creates a new object for you. With this you can easily create many mailboxes to watch at the same time. It takes a table with some basic information: server=your servername, port=portnumber or standard-port (110) and also timeout=responsetimeout for the server. Also you can give a name to your object. The name is used in the logger to seperate the messages there for each mailbox.

The get() function retreives all messages available for you and stores it in a table. Get() expects your username and password to login and optional a boolean for deleting messages. If you do not set this parameter to true your messages will not be deleted from the server.

After you run get() you find two values in the table myMail.msg.

count=number of mails
size=size of mails

The messages themselves go in an indexed table named objname.msg[index], where index is the number of the message retreived. All lines are stored themselves in an indexed subtable, so you can easily parse the message line-by-line and run any kind of search-filter (or whatever) on it by using the "in pairs(table)" function on it.

You can also easily access a single line of the message by using
print(myMail.msg[msgindex][lineindex])

If you have a slow server, you MUST increase the timeout. The mechanism is NOT to interpret the response from the server, so my code is not checking if the transfer is complete. It assumes that the server will send the whole response without a gap of more than the timeout. So if you retrieve a long message and the transfer got stuck longer than the timeout value my code believes the transfer is complete and the rest of the message will be lost. To adjust the timeout use

myMail:settimeout(seconds)

On the otherside you can easily send *any* command to the server by using the object.io() function and interpret the response by yourself. So the get() method is doing the basic work for you. But if you want to do more, take a look at the object.io() method.

it expects a string what to send and delivers a table with the response. The table has an index for each line that has been retreived. For example to get the size of all available mails before downloading you could write:

myMail:open()
myMail:login('USERNAME','PASSWORD')
local res=myMail:io('LIST')
for k,v in pairs(res) do
local t=string.Split(v,' ')
if t[1]~='.' then print('mail number '..t[1]..' has a size of '..t[2]) end
end

However, you'll find also a myMail.log table. This holds the logging of the session (but not username and password to have a small piece of safety-feeling).

If you have any questions, comments or bugreports, let me know. Again, I would like to mention that I am not a professional programmer and this is written for my needs only. It has not been tested very deeply, but it's working stable on my system, and also the error handling is not perfect.

You can use this as a starting point and you are allowed to do full modification, but I am asking you to post your changes in this thread to keep all of us up to date.

BR/Marc