<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
  <title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Thanks! In order to help others like me who were struggling with this,
here's the working code. Please let me know if I did anything
egregiously stupid here. <br>
<br>
#!/usr/bin/env python<br>
# Simple SMTP server shell<br>
<br>
from twisted.internet import reactor, protocol, defer<br>
from twisted.protocols import smtp<br>
<br>
class MyMessage:<br>
&nbsp;&nbsp;&nbsp; __implements__ = (smtp.IMessage)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; def __init__(self):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; self.msg = []<br>
<br>
&nbsp;&nbsp;&nbsp; def lineReceived(self, line):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; self.msg.append(line)<br>
<br>
&nbsp;&nbsp;&nbsp; def eomReceived(self):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # Handle message here<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for line in self.msg:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; print line<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; self.msg = []<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return defer.succeed('&lt;Whatever&gt;')<br>
&nbsp;&nbsp;&nbsp; <br>
class MyMessageDelivery:<br>
&nbsp;&nbsp;&nbsp; __implements__ = (smtp.IMessageDelivery)<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; def validateFrom(self, helo, origin):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return origin<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; def validateTo(self, user):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return MyMessage<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; def receivedHeader(self, helo, origin, recipients):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return None<br>
<br>
class MySMTPFactory(smtp.SMTPFactory):<br>
&nbsp;&nbsp;&nbsp; def buildProtocol(self, addr):<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p = self.protocol(MyMessageDelivery())<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p.factory = self<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p.portal = self.portal<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; p.host = "somedomain.com"<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return p&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
factory = MySMTPFactory()<br>
factory.protocol = smtp.SMTP<br>
reactor.listenTCP(25, factory)<br>
reactor.run()<br>
<br>
Anders Hammarquist wrote:<br>
<blockquote type="cite"
 cite="mid200310012347.h91NlHW04812@haddock.cd.chalmers.se">
  <pre wrap="">Hi Greg!

In a message of Wed, 01 Oct 2003 17:20:17 EDT, Greg writes:
  </pre>
  <blockquote type="cite">
    <pre wrap="">Working on an SMTP filter (consisting of an SMTP server that receives 
messages, some code that mangles them, then and SMTP client that forwards 
them along). The first step is to get a functioning SMTP server working, and 
I'm having some trouble with SMTPFactory / SMTP. I've overloaded the validate 
methods in an attempt accept emails to and from any domain, but I can't 
figure out how to hook in a class that implements IMessageDelivery:
    </pre>
  </blockquote>
  <pre wrap=""><!---->
There are several problems with your code, but to my eye it looks like
confusion between several methods of using the SMTP class. Until recently,
the IMessageDelivery method didn't exists, and you needed to override
SMTP to implement validateTo and validateFrom. Now, you can instead pass
an IMessageDelivery to SMTP, either directly or using the authenticator
(and if you do, you shouldn't need to subclass SMTP - and if your twisted
is recent enough, you have to use the IMessageDelivery method).

You do need to make your own factory though, since the one that's there
doesn't deal with IMessageDelivery()s yet. Something like

class MySMTPFactory(SMTPFactory):
        def buildProtocol(self, addr):
                p = self.protocol(MyMessageDelivery())
                p.factory = self
                p.portal = self.portal
                p.host = self.domain
                return p

  </pre>
  <blockquote type="cite">
    <pre wrap="">class MySMTPProtocol(SMTP):
    </pre>
  </blockquote>
  <pre wrap=""><!---->[...]
  </pre>
  <blockquote type="cite">
    <pre wrap="">        def validateTo(self, user):
                d = defer.Deferred()
                reactor.callLater(0, self.fakeSucceed())
                return d
    </pre>
  </blockquote>
  <pre wrap=""><!---->
You don't need this code, but I still want to point out that it doesn't
do anything useful, and is overcomplicated. 

First, validateTo may return an IMessage or a deferred returning an
IMessage, so you don't need the deferred, you can just return you
IMessage directly. Secondly the deferred is never called, so it will
never return, and thus your SMTP server stops here.

reactor.callLater() just calls another function asynchrously and discards
the result. If you want to pass back a result from a callLater, you need
to pass along the deferred and call it in the function you callLater()ed.

  </pre>
  <blockquote type="cite">
    <pre wrap="">class MyIMessage:
        __implements__ = (smtp.IMessageDelivery)
    </pre>
  </blockquote>
  <pre wrap=""><!---->
You seem to have mixed up IMessage and IMessageDelivery. You need both.
Your IMessageDelivery.validateTo() should return an IMessage (or a deferred
returning an IMessage).

HTH
/Anders

  </pre>
</blockquote>
</body>
</html>