[Zope] Re: [ZOPE Collector] Zope Question entry: Generating a feedback form

Stephen Pitts smpitts@midsouth.rr.com
Mon, 7 Feb 2000 15:43:42 -0600


--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii

> > Description:  We are test driving zope by constructing our Globopolis intranet with it. One of the intranet's primary functions will be a bulletin board, and I have tried programming a mailto form three different ways using tutorials. It has yet to work. My most recent attempt involved creating a mail host and the feedback/sendfeedback documents. However, upon submission I get an SMTP error saying that the domain must be specified. I have checked with the tech guys here and maybe they're high on smack, but I believe the host and mail addresses are correct. I have just about given up on successfully implementing any forms using zope, please throw me an innertube..

The following patch replaces the stock Mailhost code with a new version
based off of smtplib (a module that comes with Python). I've heard
nothing but positive reports from people using it. It is in the
Collector and <hint, hint, Chris> should be in the next version of Zope.

Apply the patch from inside your Zope directory using the "patch"
command. I've got a Win32 version of "patch" I could mail you privately
if you need it (its about 60k, not that big).
-- 
Stephen Pitts
smpitts@midsouth.rr.com

--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; 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">

--wRRV7LY7NUeQGEoC--