<!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>&nbsp;</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>&nbsp;</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>&nbsp;</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 &lt;<A 
href="mailto:tutorial_sender@example.com">tutorial_sender@example.com</A>&gt;<BR>To: 
Tutorial Gal &lt;<A 
href="mailto:tutorial_recipient@example.net">tutorial_recipient@example.net</A>&gt;<BR>Subject: 
Tutorate!</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT face=Arial 
size=2>Dosomething(that-returns-a-deferred).addCallback(Then-do-the-next-thing, 
extra-parameter1, extraparameter2)</FONT></DIV>
<DIV>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</DIV>
<DIV>Thanks for any suggestions and directions!</DIV>
<DIV>&nbsp;</DIV>
<DIV>-Dave</DIV>
<DIV>&nbsp;</DIV>
<DIV></FONT>&nbsp;</DIV></BODY></HTML>