Commit faedab35 authored by Tres Seaver's avatar Tres Seaver

Collector #1005: Use smtplib

parent df8a3136
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
"""SMTP mail objects""" """SMTP mail objects"""
from Globals import Persistent, HTMLFile, HTML, MessageDialog from Globals import Persistent, HTMLFile, HTML, MessageDialog
from socket import *; from select import select from smtplib import SMTP
from AccessControl.Role import RoleManager from AccessControl.Role import RoleManager
from operator import truth from operator import truth
import Acquisition, sys, string, types, mimetools import Acquisition, sys, string, types, mimetools
...@@ -93,20 +93,18 @@ import OFS.SimpleItem, re, quopri, rfc822 ...@@ -93,20 +93,18 @@ import OFS.SimpleItem, re, quopri, rfc822
import Globals import Globals
from cStringIO import StringIO from cStringIO import StringIO
#$Id: MailHost.py,v 1.46 2000/01/10 23:48:36 amos Exp $ #$Id: MailHost.py,v 1.47 2000/04/21 14:10:20 tseaver Exp $
__version__ = "$Revision: 1.46 $"[11:-2] __version__ = "$Revision: 1.47 $"[11:-2]
smtpError = "SMTP Error" smtpError = "SMTP Error"
MailHostError = "MailHost Error" MailHostError = "MailHost Error"
addForm=HTMLFile('addMailHost_form', globals(), localhost=gethostname()) addForm=HTMLFile('addMailHost_form', globals())
def add(self, id, title='', smtp_host=None, def add(self, id, title='', smtp_host=None, smtp_port=25, REQUEST=None):
localhost='localhost', smtp_port=25, timeout=1.0, REQUEST=None):
' add a MailHost into the system ' ' add a MailHost into the system '
i=MailHost() #create new mail host i=MailHost() #create new mail host
i.id=id #give it id i.id=id #give it id
i.title=title #title i.title=title #title
i._init(localHost=localhost, smtpHost=smtp_host, smtpPort=smtp_port, i._init(smtpHost=smtp_host, smtpPort=smtp_port)
timeout=timeout)
self._setObject(id,i) #register it self._setObject(id,i) #register it
if REQUEST: return self.manage_main(self,REQUEST) if REQUEST: return self.manage_main(self,REQUEST)
...@@ -138,20 +136,15 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -138,20 +136,15 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
'nothing yet' 'nothing yet'
pass pass
def _init(self, localHost, smtpHost, smtpPort, timeout=1): def _init(self, smtpHost, smtpPort):
self.localHost=localHost
self.smtpHost=smtpHost self.smtpHost=smtpHost
self.smtpPort=smtpPort self.smtpPort=smtpPort
self.timeout=timeout
def manage_makeChanges(self,title,localHost,smtpHost,smtpPort, def manage_makeChanges(self,title,smtpHost,smtpPort, REQUEST=None):
timeout, REQUEST=None):
'make the changes' 'make the changes'
self.title=title self.title=title
self.localHost=localHost
self.smtpHost=smtpHost self.smtpHost=smtpHost
self.smtpPort=smtpPort self.smtpPort=smtpPort
self.timeout=timeout
if REQUEST: return MessageDialog( if REQUEST: return MessageDialog(
title ='Changed %s' % self.__name__, title ='Changed %s' % self.__name__,
message='%s has been updated' % self.id, message='%s has been updated' % self.id,
...@@ -165,18 +158,15 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -165,18 +158,15 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
mtemplate = getattr(self, messageTemplate) mtemplate = getattr(self, messageTemplate)
messageText = mtemplate(self, trueself.REQUEST) messageText = mtemplate(self, trueself.REQUEST)
messageText=_encode(messageText, encode) messageText=_encode(messageText, encode)
headers, message = decapitate(messageText) headers = extractheaders(messageText)
if mto: headers['to'] = mto if mto: headers['to'] = mto
if mfrom: headers['from'] = mfrom if mfrom: headers['from'] = mfrom
for requiredHeader in ('to', 'from'): for requiredHeader in ('to', 'from'):
if not headers.has_key(requiredHeader): if not headers.has_key(requiredHeader):
raise MailHostError,"Message missing SMTP Header '%s'"\ raise MailHostError,"Message missing SMTP Header '%s'"\
% requiredHeader % requiredHeader
Send(trueself.smtpHost, trueself.smtpPort, mailserver = SMTP(trueself.smtpHost, trueself.smtpPort)
trueself.localHost, trueself.timeout, mailserver.sendmail(headers['from'], headers['to'], messageText)
headers['from'], headers['to'],
headers['subject'] or 'No Subject', messageText
)
if not statusTemplate: return "SEND OK" if not statusTemplate: return "SEND OK"
...@@ -188,7 +178,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -188,7 +178,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
def send(self, messageText, mto=None, mfrom=None, subject=None, def send(self, messageText, mto=None, mfrom=None, subject=None,
encode=None): encode=None):
headers, message = decapitate(messageText) headers = extractheaders(messageText)
if not headers['subject']: if not headers['subject']:
messageText="subject: %s\n%s" % (subject or '[No Subject]', messageText="subject: %s\n%s" % (subject or '[No Subject]',
...@@ -205,14 +195,12 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -205,14 +195,12 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
raise MailHostError,"Message missing SMTP Header '%s'"\ raise MailHostError,"Message missing SMTP Header '%s'"\
% requiredHeader % requiredHeader
messageText=_encode(messageText, encode) messageText=_encode(messageText, encode)
sm=SendMail(self.smtpHost, self.smtpPort, self.localHost, self.timeout) smtpserver = SMTP(self.smtpHost, self.smtpPort)
sm.send(mfrom=headers['from'], mto=headers['to'], smtpserver.sendmail(headers['from'],headers['to'], messageText)
subj=headers['subject'] or 'No Subject',
body=messageText)
def scheduledSend(self, messageText, mto=None, mfrom=None, subject=None, def scheduledSend(self, messageText, mto=None, mfrom=None, subject=None,
encode=None): encode=None):
headers, message = decapitate(messageText) headers = extractheaders(messageText)
if not headers['subject']: if not headers['subject']:
messageText="subject: %s\n%s" % (subject or '[No Subject]', messageText="subject: %s\n%s" % (subject or '[No Subject]',
...@@ -229,91 +217,17 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -229,91 +217,17 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
raise MailHostError,"Message missing SMTP Header '%s'"\ raise MailHostError,"Message missing SMTP Header '%s'"\
% requiredHeader % requiredHeader
messageText=_encode(messageText, encode) messageText=_encode(messageText, encode)
Send(self.smtpHost, self.smtpPort, self.localHost, self.timeout, smtpserver = SMTP(self.smtpHost, self.smtpPort)
headers['from'], headers['to'], smtpserver.sendmail(headers['from'], headers['to'], messageText)
headers['subject'] or 'No Subject', messageText
)
def simple_send(self, mto, mfrom, subject, body): def simple_send(self, mto, mfrom, subject, body):
body="subject: %s\n\n%s" % (subject, body) body="from: %s\nto: %s\nsubject: %s\n\n%s" % (mfrom, mto, subject, body)
SendMail(self.smtpHost, self.smtpPort, self.localHost, mailserver = SMTP(self.smtphost, self.smtpport)
self.timeout).send( mailserver.sendmail(mfrom, mto, body)
mfrom=mfrom, mto=mto, subj=subject, body=body
)
class MailHost(Persistent, MailBase): class MailHost(Persistent, MailBase):
"persistent version" "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): def _encode(body, encode=None):
if encode is None: if encode is None:
return body return body
...@@ -331,8 +245,8 @@ def _encode(body, encode=None): ...@@ -331,8 +245,8 @@ def _encode(body, encode=None):
return newmfile.getvalue() return newmfile.getvalue()
def decapitate(message): def extractheaders(message):
# split message into headers / body # return headers of message
mfile=StringIO(message) mfile=StringIO(message)
mo=rfc822.Message(mfile) mo=rfc822.Message(mfile)
...@@ -347,5 +261,4 @@ def decapitate(message): ...@@ -347,5 +261,4 @@ def decapitate(message):
hd['from']=mo.getaddr('from')[1] hd['from']=mo.getaddr('from')[1]
hd['subject']=mo.getheader('subject') or "No Subject" hd['subject']=mo.getheader('subject') or "No Subject"
return hd
return hd, mfile.read()
...@@ -37,12 +37,6 @@ when trying to send mail. ...@@ -37,12 +37,6 @@ when trying to send mail.
<INPUT TYPE="TEXT" NAME="title" SIZE="40"> <INPUT TYPE="TEXT" NAME="title" SIZE="40">
</TD> </TD>
</TR> </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"> <TR VALIGN="TOP">
<TH ALIGN="LEFT">SMTP Host</TH> <TH ALIGN="LEFT">SMTP Host</TH>
<TD ALIGN="LEFT"> <TD ALIGN="LEFT">
...@@ -55,12 +49,6 @@ when trying to send mail. ...@@ -55,12 +49,6 @@ when trying to send mail.
<INPUT TYPE="TEXT" NAME="smtp_port:int" SIZE="4" VALUE="25"> <INPUT TYPE="TEXT" NAME="smtp_port:int" SIZE="4" VALUE="25">
</TD> </TD>
</TR> </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"> <TR VALIGN="TOP">
<TD>&nbsp;</TD> <TD>&nbsp;</TD>
<TD><BR><INPUT TYPE="SUBMIT" VALUE=" Add "></TD> <TD><BR><INPUT TYPE="SUBMIT" VALUE=" Add "></TD>
......
...@@ -18,12 +18,6 @@ ...@@ -18,12 +18,6 @@
<INPUT TYPE="TEXT" NAME="title" SIZE="40" VALUE="<dtml-var title html_quote>"> <INPUT TYPE="TEXT" NAME="title" SIZE="40" VALUE="<dtml-var title html_quote>">
</TD> </TD>
</TR> </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"> <TR VALIGN="TOP">
<TH ALIGN="LEFT">SMTP Host</TH> <TH ALIGN="LEFT">SMTP Host</TH>
<TD ALIGN="LEFT"> <TD ALIGN="LEFT">
...@@ -36,12 +30,6 @@ ...@@ -36,12 +30,6 @@
<INPUT TYPE="TEXT" NAME="smtpPort:int" SIZE="4" VALUE="<dtml-var smtpPort html_quote>"> <INPUT TYPE="TEXT" NAME="smtpPort:int" SIZE="4" VALUE="<dtml-var smtpPort html_quote>">
</TD> </TD>
</TR> </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"> <TR VALIGN="TOP">
<TD></TD> <TD></TD>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment