Newbie: trying to twist my head around twisted (and python)

2006-10-11 Thread Jan Bakuwel
Hoi all,

Please see below a small piece of python code that resembles a
smtpserver using the twisted framework. The code is based on the example
smtp server discussed in Twisted Network Programming Essentials.
The unmodified example code can be found on the O'Reilly website:
(http://examples.oreilly.com/twistedadn/, in ch08 subdir).

I've removed all the code I don't (the original example write an email
received with SMTP to a Maildir; I'll do something else with it). For
the sake of the example, the only thing I'll do in eomReceived is print
whether the message had any attachments or not, then return a "failed"
if a message had any attachments and a "success" if not.

According to the book, I need to return a "Deferred result" from the
function eomReceived (see  below).

In eomReceived, I intend to process the email then either return success
 or failure. I've been looking at the twisted way of using twisted :-).
According to the book "its a little confusing for a start" and I have to
agree :-)

Does anyone know how I need to complete the code below so it returns
this mysterious "Deferred result" and runs?

Many thanks in advance,
Jan


#!/usr/bin/python

from twisted.mail import smtp, maildir
from zope.interface import implements
from twisted.internet import protocol, reactor, defer
import os
from email.Header import Header
from email import message_from_string


class MessageHandler(object):
implements(smtp.IMessage)

def __init__(self, userDir):
self.lines = []
#end __init__

def lineReceived(self, line):
self.lines.append(line)
#end lineReceived

def eomReceived(self):
# message is complete, store it
self.lines.append('') # add a trailing newline
messageData = '\n'.join(self.lines)
emailMessage = message_from_string (messageData)

# return a Deferred result so the client knows whether the
# message has been successfully processed
if emailMessage.is_multipart():
print "email has attachments"
return ?? failed ???
else:
print "email has no attachments"
return ?? success ???

#end eomReceived

def connectionLost(self):
print "Connection lost unexpectedly!"
# unexpected loss of connection; don't save
del(self.lines)
del(self.email)
#end connectionLost

#end MessageHandler


class LocalDelivery(object):
implements(smtp.IMessageDelivery)

def __init__(self):
pass
#end __init__

def receivedHeader(self, helo, origin, recipients):
myHostname, clientIP = helo
headerValue = "by %s from %s with ESMTP ; %s" % (myHostname,
clientIP, smtp.rfc822date())
# email.Header.Header used for automatic wrapping of long lines
return "Received: %s" % Header(headerValue)
#end receivedHeader

def validateFrom(self, helo, originAddress):
# accept mail from anywhere. To reject an address, raise
# smtp.SMTPBadSender here.
return originAddress
#end validateFrom

def validateTo(self, user):
print "Accepting mail for %s" % user.dest
return lambda: MessageHandler()
#end validateTo

#end LocalDelivery


class SMTPFactory(protocol.ServerFactory):
def __init__(self):
pass
#end __init__

def buildProtocol(self, addr):
delivery = LocalDelivery()
smtpProtocol = smtp.SMTP(delivery)
smtpProtocol.factory = self
return smtpProtocol
#end buildProtocol

#end SMTPFactory


if __name__ == "__main__":
import sys
reactor.listenTCP(10025, SMTPFactory())
from twisted.internet import ssl
# SSL stuff here... and certificates...
reactor.run()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Newbie: trying to twist my head around twisted (and python)

2006-10-11 Thread Jan Bakuwel
Hoi Jean-Paul,

> The return value of eomReceived is used to determine whether to signal to
> the SMTP client whether the message has been accepted.  Regardless of your
> application logic, if you are taking responsibility for the message, you
> should return a successful result.  If all of your processing is
> synchronous,
> then you simply need to return twisted.internet.defer.succeed(None) at the
> end of the function.  If you have asynchronous processing to do (it does
> not
> appear as though you do), you will need to return a Deferred which only
> fires
> once that processing has been completed.

Many thanks... this helps me a great deal!

kind regards,
Jan
-- 
http://mail.python.org/mailman/listinfo/python-list


Newbie: how to wait for callbacks...

2006-10-13 Thread Jan Bakuwel
Hoi all,

I'm trying to write a little code that waits for a callback routine to
be called, ideally with a timeout...

I guess the code below is not right (using a boolean flag), but since
I'm new to Python, I don't know yet where the semaphores live and/or
whether I'm on the right track...

Any help is much appreciated...

Jan


def processEmail(emailMessage):

sendSent = False

def sendComplete(result):
print "Message sent successfully"
processEmail.sendSent = True
#end sendComplete

def sendFailed(error):
print >> sys.stderr, "Error", error.getErrorMessage()
processEmail.sendSent = True
#end sendFailed

if emailMessage.is_multipart():
print "...multipart"
for pl in emailMessage.walk():
pass
else:
print "...not multipart"
# simulate some processing that will take place here
time.sleep(1)

multiMessage = MIMEMultipart()
multiMessage['From'] = emailMessage['From']
multiMessage['To'] = emailMessage['To']
multiMessage['Subject'] = emailMessage['Subject']
messageData = multiMessage.as_string(unixfrom=False)
sending = smtp.sendmail('smtp', '[EMAIL PROTECTED]', '[EMAIL PROTECTED]', 
messageData)
sending.addCallback(sendComplete).addErrback(sendFailed)

while not processEmail.sendSent:
print "z"
time.sleep(0.1)
#end while

print "...done"
#raise smtp.SMTPDeliveryError(code=550, resp="Unable to deliver
email, please try again later", isFatal=True, retry=False)
print ""
#endif

#end ProcessEmail
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: IDE

2006-10-13 Thread Jan Bakuwel
John Purser wrote:
> On Fri, 2006-10-13 at 15:48 +, giuseppe wrote:
>> What is the better IDE software for python programming?
>>
>> many thanks
>>
>> joe 
> 
> Joe,
> 
> Find the best Python programmer and ask him/her.
> 
> John Purser

I may be the worst Python programmer (since Python is new for me)... but
I have a lot of experience with IDEs and just looked into Python IDEs.

My opinion: Eclipse is free but rather complex; WingIDE is commercial
software but well worth the few $ - at least for someone like myself.

cheers,
Jan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Newbie: trying to twist my head around twisted (and python)

2006-10-13 Thread Jan Bakuwel
Jean-Paul Calderone wrote:

> The return value of eomReceived is used to determine whether to signal to
> the SMTP client whether the message has been accepted.  Regardless of your
> application logic, if you are taking responsibility for the message, you
> should return a successful result.  If all of your processing is
> synchronous,
> then you simply need to return twisted.internet.defer.succeed(None) at the
> end of the function.  If you have asynchronous processing to do (it does
> not
> appear as though you do), you will need to return a Deferred which only
> fires
> once that processing has been completed.

There's still a bit of mystery in here for me...
I'll be taking responsibility for the message in my code... but perhaps
my code encounters a non resolvable error (such as disc full). In that
case I would like to be able to signal a failure instead of success.

Would the following code do the job "properly"?

def eomReceived(self):
# message is complete, store it
self.lines.append('') # add a trailing newline
messageData = '\n'.join(self.lines)
emailMessage = message_from_string(messageData)
try:
processEmail(emailMessage)
return defer.succeed(None)
except:
return defer.fail
#end eomReceived

thanks,
Jan
-- 
http://mail.python.org/mailman/listinfo/python-list