<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1106" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>I love the idea of twisted but I think I must have
a twisted learning disability, as I have gotten nowhere in what ought to be a
simple matter. </FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>I need to send out emails to small groups from my
apache server running a python cgi using mod_python, but my hosting service
doesn't have a MTA. Instead of learning how to install and configure exim I
thought I would use twisted to make a simple mail client. I started with the
tutorial example that appears at:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><A
href="http://twistedmatrix.com/projects/mail/documentation/tutorial/smtpclient/smtpclient.html">http://twistedmatrix.com/projects/mail/documentation/tutorial/smtpclient/smtpclient.html</A></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>(.... is indenting)<BR>============ tutorial code
================<BR>import StringIO<BR>from twisted.application import
service<BR>application = service.Application("SMTP Client Tutorial")<BR>from
twisted.application import internet<BR>from twisted.internet import
protocol<BR>from twisted.internet import defer<BR>from twisted.mail import smtp,
relaymanager<BR>class SMTPTutorialClient(smtp.ESMTPClient):<BR>....mailFrom =
"<A
href="mailto:tutorial_sender@example.com">tutorial_sender@example.com</A>"<BR>....mailTo
= "<A
href="mailto:tutorial_recipient@example.net">tutorial_recipient@example.net</A>"<BR>....mailData
= '''\<BR>Date: Fri, 6 Feb 2004 10:14:39 -0800<BR>From: Tutorial Guy <<A
href="mailto:tutorial_sender@example.com">tutorial_sender@example.com</A>><BR>To:
Tutorial Gal <<A
href="mailto:tutorial_recipient@example.net">tutorial_recipient@example.net</A>><BR>Subject:
Tutorate!</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Hello, how are you, goodbye.<BR>'''<BR>....def
getMailFrom(self):<BR>........result = self.mailFrom<BR>........self.mailFrom =
None<BR>........return result<BR>....def getMailTo(self):<BR>........return
[self.mailTo]<BR>....def getMailData(self):<BR>........return
StringIO.StringIO(self.mailData)<BR>....def sentMail(self, code, resp, numOk,
addresses, log):<BR>........print 'Sent', numOk, 'messages'<BR>........from
twisted.internet import reactor<BR>........reactor.stop()<BR>class
SMTPClientFactory(protocol.ClientFactory):<BR>....protocol =
SMTPTutorialClient<BR>....def buildProtocol(self, addr):<BR>........return
self.protocol(secret=None, identity='example.com')<BR>def
getMailExchange(host):<BR>....def cbMX(mxRecord):<BR>........return
str(mxRecord.exchange)<BR>....return
relaymanager.MXCalculator().getMX(host).addCallback(cbMX)<BR>def
cbMailExchange(exchange):<BR>....smtpClientFactory =
SMTPClientFactory()<BR>....smtpClientService = internet.TCPClient(exchange, 25,
smtpClientFactory)<BR>....smtpClientService.setServiceParent(application)<BR>getMailExchange('example.net').addCallback(cbMailExchange)<BR>============
end tutorial code ============</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>This nicely looks up the right MX record and sends
out an email, just what I need. Now I want to expand it to allow me to give it a
list of email addresses to send the message to (not just call this same routine
multple times, which seems wasteful and slow and doesn't use twisted's power to
process the multiple emails in multiple threads), but I'm having terrible
trouble figuring out how to do that, which tells me I'm missing a paradigm
somewhere, there's something I'm not getting.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Trouble 1 is figuring out the right way to pass
additional parameters to callbacks. Is this right:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial
size=2>Dosomething(that-returns-a-deferred).addCallback(Then-do-the-next-thing,
extra-parameter1, extraparameter2)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>The function Then-do-the-next-thing() will receive
the deferred returned results from Dosomething() as its first argument, and
extra-parameter1 and extraparameter2 as the next two. That is as if
calling:<BR>Then-do-the-next-thing(Result-returned-by-Dosomething(),extra-parameter1,
extraparameter2). Have I got this correct?</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>So, if this is right, then where do I want to put
the additional argument that contains the next email address to send, if I
iterate through the list and hand each one to the email sending process like
this:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial
size=2>elist=['addr1@domain.com','addr2@nextdomain.com'...]<BR>for e in
elist:<BR>.... e2={'mxhost':'','toaddr':e}<BR>....
getMailExchange(e2).addCallback(cbMailExchange)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>In the tutorial, getMailExchange() is passed just
the domain of the addressee, and the sending out of the email happens when the
callback returns the MX exchange. I changed that to split the email address, so
now it returns both the full address and the mx:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>def getMailExchange(addr):<BR>....
host=addr.split(<A href="mailto:'@')[1">'@')[1</A>]<BR>.... def
cbMX(mxRecord):<BR>.... .... return [addr,str(mxRecord.name)]<BR>.... return
relaymanager.MXCalculator().getMX(host).addCallback(cbMX)</FONT></DIV>
<DIV> </DIV><FONT face=Arial size=2>
<DIV><BR>At this point I can't figure out how to get the email address passed to
wherever it needs to go. And I don't know really where it needs to go...
yikes.</DIV>
<DIV> </DIV>
<DIV>In the tutorial the actual email address is hard coded into the class
SMTPTutorialClient(smtp.ESMTPClient) as a class attribute, mailTo. I need to
change that to be variable.</DIV>
<DIV> </DIV>
<DIV>How do I get this value (of mailTo) changed for each of the instances
created by smtpClientFactory = SMTPClientFactory()? I think I must be confused
about the roles of Factories and Protocols.</DIV>
<DIV> </DIV>
<DIV>I can't seem to figure out a way that works to get the email address passed
into the system as a variable. Rather than waste people's time by describing my
various failures, I thought I'd just ask for suggestions about the right twisted
way to do it. </DIV>
<DIV> </DIV>
<DIV>Thanks for any suggestions and directions!</DIV>
<DIV> </DIV>
<DIV>-Dave</DIV>
<DIV> </DIV>
<DIV></FONT> </DIV></BODY></HTML>