Newbie: trying to twist my head around twisted (and python)
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)
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...
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
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)
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