[Zope-dev] where can I get the patch to use smtplib with the sendmail tag?

Sam Gendler sgendler@impossible.com
Wed, 22 Mar 2000 14:45:28 -0800


This is a multi-part message in MIME format.
--------------A3899287FACE23E625926742
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Heer is the patcha again, as I had a terrible time tracking it down
through the archives.  I have tested it fairly heavily, including
running a large scale performance test against it last night, with no
problems.  However, you should definitely get more than just my word, as
I haven't run a lot of real world traffic against it, especially traffic
causing mail to be sent to aol and MS exchange, both of which seem to
have problems with the old code.  In fact, they are the reason I am
using the patch, and I have done preliminary testing that implied
everything worked, but nothing on a large scale.


--sam

Michel Pelletier wrote:
> 
> Ava wrote:
> >
> > Hello,
> >
> > where can I get the patch to use smtplib with the sendmail tag. I also have
> > problems here to use sendmail with the Exchange Server.
> >
> > please answer directly to me, because I'm not on the zope-dev list
> >
> 
> Further, when someone answers this question they can answer mine, how
> tested is this patch?  If several people thing it's bullet proof then
> i'm checkin it in.
> 
> -Michel
> 
> _______________________________________________
> Zope-Dev maillist  -  Zope-Dev@zope.org
> http://lists.zope.org/mailman/listinfo/zope-dev
> **  No cross posts or HTML encoding!  **
> (Related lists -
>  http://lists.zope.org/mailman/listinfo/zope-announce
>  http://lists.zope.org/mailman/listinfo/zope )

-- 
--------------------------
Sam Gendler
CTO, Impossible, Inc.
1222 State St. Suite 250
Santa Barbara, CA. 93101
p: 805-560-0508
f: 805-560-0608
c: 805-689-1191
e: sgendler@impossible.com
--------------A3899287FACE23E625926742
Content-Type: text/plain; charset=us-ascii;
 name="mailhost.smtplib.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="mailhost.smtplib.patch"

Only in lib/python/Products/MailHost/: .MailHost.py.swp
diff -ru ../Zope-2.1.2-src/lib/python/Products/MailHost/MailHost.py lib/python/Products/MailHost/MailHost.py
--- ../Zope-2.1.2-src/lib/python/Products/MailHost/MailHost.py	Wed Nov  3 08:42:15 1999
+++ lib/python/Products/MailHost/MailHost.py	Sun Jan 23 18:14:56 2000
@@ -85,7 +85,7 @@
 """SMTP mail objects"""
 
 from Globals import Persistent, HTMLFile, HTML, MessageDialog
-from socket import *; from select import select
+from smtplib import SMTP
 from AccessControl.Role import RoleManager
 from operator import truth
 import Acquisition, sys, string, types, mimetools
@@ -98,15 +98,13 @@
 smtpError = "SMTP Error"
 MailHostError = "MailHost Error"
 
-addForm=HTMLFile('addMailHost_form', globals(), localhost=gethostname())
-def add(self, id, title='', smtp_host=None, 
-        localhost='localhost', smtp_port=25, timeout=1.0, REQUEST=None):
+addForm=HTMLFile('addMailHost_form', globals())
+def add(self, id, title='', smtp_host=None, smtp_port=25, REQUEST=None):
     ' add a MailHost into the system '
     i=MailHost()            #create new mail host
     i.id=id                 #give it id
     i.title=title           #title
-    i._init(localHost=localhost, smtpHost=smtp_host, smtpPort=smtp_port,
-            timeout=timeout)
+    i._init(smtpHost=smtp_host, smtpPort=smtp_port)
     self._setObject(id,i)   #register it
     if REQUEST: return self.manage_main(self,REQUEST)
 
@@ -136,20 +134,15 @@
         'nothing yet'
         pass
 
-    def _init(self, localHost, smtpHost, smtpPort, timeout=1):
-        self.localHost=localHost
+    def _init(self, smtpHost, smtpPort):
         self.smtpHost=smtpHost
         self.smtpPort=smtpPort
-        self.timeout=timeout
 
-    def manage_makeChanges(self,title,localHost,smtpHost,smtpPort,
-                           timeout, REQUEST=None):
+    def manage_makeChanges(self,title,smtpHost,smtpPort, REQUEST=None):
         'make the changes'
         self.title=title
-        self.localHost=localHost
         self.smtpHost=smtpHost
         self.smtpPort=smtpPort
-        self.timeout=timeout
         if REQUEST: return MessageDialog(
             title  ='Changed %s' % self.__name__,
             message='%s has been updated' % self.id,
@@ -163,18 +156,15 @@
         mtemplate = getattr(self, messageTemplate)
         messageText = mtemplate(self, trueself.REQUEST)
         messageText=_encode(messageText, encode)
-        headers, message = decapitate(messageText)
+        headers = extractheaders(messageText)
         if mto: headers['to'] = mto
         if mfrom: headers['from'] = mfrom
         for requiredHeader in ('to', 'from'):
             if not headers.has_key(requiredHeader):
                 raise MailHostError,"Message missing SMTP Header '%s'"\
                       % requiredHeader
-        Send(trueself.smtpHost, trueself.smtpPort, 
-             trueself.localHost, trueself.timeout, 
-             headers['from'], headers['to'],
-             headers['subject'] or 'No Subject', messageText
-             )
+		mailserver = SMTP(trueself.smtpHost, trueself.smtpPort)
+		mailserver.sendmail(headers['from'], headers['to'], messageText)
 
         if not statusTemplate: return "SEND OK"
 
@@ -186,7 +176,7 @@
 
     def send(self, messageText, mto=None, mfrom=None, subject=None,
              encode=None):
-        headers, message = decapitate(messageText)
+        headers = extractheaders(messageText)
         
         if not headers['subject']:
             messageText="subject: %s\n%s" % (subject or '[No Subject]',
@@ -203,14 +193,12 @@
                 raise MailHostError,"Message missing SMTP Header '%s'"\
                 % requiredHeader
         messageText=_encode(messageText, encode)
-        sm=SendMail(self.smtpHost, self.smtpPort, self.localHost, self.timeout)
-        sm.send(mfrom=headers['from'], mto=headers['to'],
-                subj=headers['subject'] or 'No Subject',
-                body=messageText)
+        smtpserver = SMTP(self.smtpHost, self.smtpPort)
+        smtpserver.sendmail(headers['from'],headers['to'], messageText)
 
     def scheduledSend(self, messageText, mto=None, mfrom=None, subject=None,
                       encode=None):
-        headers, message = decapitate(messageText)
+        headers = extractheaders(messageText)
 
         if not headers['subject']:
             messageText="subject: %s\n%s" % (subject or '[No Subject]',
@@ -227,91 +215,17 @@
                 raise MailHostError,"Message missing SMTP Header '%s'"\
                 % requiredHeader
         messageText=_encode(messageText, encode)
-        Send(self.smtpHost, self.smtpPort, self.localHost, self.timeout,
-             headers['from'], headers['to'],
-             headers['subject'] or 'No Subject', messageText
-             )
+        smtpserver = SMTP(self.smtpHost, self.smtpPort)
+        smtpserver.sendmail(headers['from'], headers['to'], messageText)
 
     def simple_send(self, mto, mfrom, subject, body):
-        body="subject: %s\n\n%s" % (subject, body)
-        SendMail(self.smtpHost, self.smtpPort, self.localHost,
-                 self.timeout).send( 
-                     mfrom=mfrom, mto=mto, subj=subject, body=body
-                     )
+        body="from: %s\nto: %s\nsubject: %s\n\n%s" % (mfrom, mto, subject, body)
+        mailserver = SMTP(self.smtphost, self.smtpport)
+        mailserver.sendmail(mfrom, mto, body)
 
 class MailHost(Persistent, MailBase):
     "persistent version"
 
-def Send(host, port, localhost, timeout, from_, to, subject, body):
-    SendMail(host, port, localhost, timeout).send(from_, to, subject, body)
-        
-class SendMail:
-    singledots=re.compile('^\.$', re.M)
-    
-    def __init__(self, smtpHost, smtpPort, localHost="localhost", timeout=1):
-        self.conn = socket(AF_INET, SOCK_STREAM)
-        self.conn.connect(smtpHost, smtpPort)
-        self.timeout=timeout
-        self.fd=self.conn.fileno()
-        self.conn.send("helo "+localHost+"\015\012")
-        while 1:
-            if not self._check(): break
-
-    def __del__(self):
-        self._close()
-
-    def getLine(self):
-        line=''
-        tm=self.timeout
-        while 1:
-            if not select([self.fd],[],[],tm)[0]:       #check the socket
-                break
-            data=self.conn.recv(1)
-            if (not data) or (data == '\n'):
-                break
-            line=line+data
-        return line
-
-    def _check(self, lev='250'):
-        line = self.getLine()
-        if not line: return 0
-        try:
-            code=string.atoi(line[:3])
-        except:
-            raise smtpError, \
-                  "Cannot convert line from SMTP: %s" % line
-        if code > 400:
-            raise smtpError, \
-                  "Recieved error code %s from SMTP: %s"\
-                  % (code, line)
-        return 1
-
-    def send(self, mfrom, mto, subj='No Subject', body='Blank Message'):
-        self.conn.send("mail from:<%s>\015\012" % mfrom)
-        self._check()
-        if type(mto) in [types.ListType, types.TupleType]:
-            for person in mto:
-                self.conn.send("rcpt to:<%s>\015\012" % person)
-                self._check()
-        else:
-            self.conn.send("rcpt to:<%s>\015\012" % mto)
-            self._check()
-        self.conn.send("data\015\012")
-        self._check()
-        body=self.singledots.sub('..', body)
-        body=string.replace(body, '\r\n', '\n')
-        body=string.replace(body, '\r', '\n')
-        body=string.replace(body, '\n', '\015\012')
-        self.conn.send(body)
-        self.conn.send("\015\012.\015\012")
-        self._check('354')
-
-    def _close(self):
-        self.conn.send("quit\015\012")
-        self.conn.close()
-
-
-
 def _encode(body, encode=None):
     if encode is None:
         return body
@@ -329,8 +243,8 @@
     return newmfile.getvalue()
 
 
-def decapitate(message):
-    # split message into headers / body
+def extractheaders(message):
+    # return headers of message
     mfile=StringIO(message)
     mo=rfc822.Message(mfile)
 
@@ -345,5 +259,4 @@
     
     hd['from']=mo.getaddr('from')[1]
     hd['subject']=mo.getheader('subject') or "No Subject"
-
-    return hd, mfile.read()
+    return hd
Only in lib/python/Products/MailHost/: MailHost.pyc
Only in lib/python/Products/MailHost/: SendMailTag.pyc
Only in lib/python/Products/MailHost/: __init__.pyc
diff -ru ../Zope-2.1.2-src/lib/python/Products/MailHost/addMailHost_form.dtml lib/python/Products/MailHost/addMailHost_form.dtml
--- ../Zope-2.1.2-src/lib/python/Products/MailHost/addMailHost_form.dtml	Wed Nov  3 12:56:32 1999
+++ lib/python/Products/MailHost/addMailHost_form.dtml	Sun Jan 23 18:11:55 2000
@@ -36,12 +36,6 @@
   </TD>
 </TR>
 <TR VALIGN="TOP">
-  <TH ALIGN="LEFT">Local Host</TH>
-  <TD ALIGN="LEFT">
-    <INPUT TYPE="TEXT" NAME="localhost" SIZE="40" VALUE="<dtml-var localhost html_quote>">
-  </TD>
-</TR>
-<TR VALIGN="TOP">
   <TH ALIGN="LEFT">SMTP Host</TH>
   <TD ALIGN="LEFT">
     <INPUT TYPE="TEXT" NAME="smtp_host" SIZE="40">
@@ -51,12 +45,6 @@
   <TH ALIGN="LEFT">SMTP Port</TH>
   <TD ALIGN="LEFT">
     <INPUT TYPE="TEXT" NAME="smtp_port:int" SIZE="4" VALUE="25">
-  </TD>
-</TR>
-<TR VALIGN="TOP">
-  <TH ALIGN="LEFT">Max. Timeout</TH>
-  <TD ALIGN="LEFT">
-    <INPUT TYPE="TEXT" NAME="timeout:float" SIZE="4" VALUE="1">
   </TD>
 </TR>
 <TR VALIGN="TOP">
diff -ru ../Zope-2.1.2-src/lib/python/Products/MailHost/manageMailHost.dtml lib/python/Products/MailHost/manageMailHost.dtml
--- ../Zope-2.1.2-src/lib/python/Products/MailHost/manageMailHost.dtml	Wed Nov  3 12:56:32 1999
+++ lib/python/Products/MailHost/manageMailHost.dtml	Sun Jan 23 18:14:29 2000
@@ -19,12 +19,6 @@
   </TD>
 </TR>
 <TR VALIGN="TOP">
-  <TH ALIGN="LEFT">Local Host</TH>
-  <TD ALIGN="LEFT">
-    <INPUT TYPE="TEXT" NAME="localHost" SIZE="40" VALUE="<dtml-var localHost html_quote>">
-  </TD>
-</TR>
-<TR VALIGN="TOP">
   <TH ALIGN="LEFT">SMTP Host</TH>
   <TD ALIGN="LEFT">
     <INPUT TYPE="TEXT" NAME="smtpHost" SIZE="40" VALUE="<dtml-var smtpHost html_quote>">
@@ -35,12 +29,6 @@
   <TD ALIGN="LEFT">
     <INPUT TYPE="TEXT" NAME="smtpPort:int" SIZE="4" VALUE="<dtml-var smtpPort html_quote>">
   </TD>
-</TR>
-<TR VALIGN="TOP">
- <TH ALIGN="LEFT">Max. Timeout</TH>
- <TD ALIGN="LEFT">
-   <INPUT TYPE="TEXT" NAME="timeout:float" SIZE="4" VALUE="<dtml-var timeout html_quote>">
- </TD>
 </TR>
 
 <TR VALIGN="TOP">

--------------A3899287FACE23E625926742--