Commit 035d39fa authored by 's avatar

Added Martijn Pieters patches to 1.11.0

parent b339fd13
...@@ -88,15 +88,15 @@ from Globals import Persistent, HTMLFile, HTML, MessageDialog ...@@ -88,15 +88,15 @@ from Globals import Persistent, HTMLFile, HTML, MessageDialog
from socket import *; from select import select from socket import *; from select import select
from AccessControl.Role import RoleManager from AccessControl.Role import RoleManager
from operator import truth from operator import truth
import Acquisition, sys, ts_regex, string, types, rfc822 import Acquisition, sys, ts_regex, string, types, mimetools
import OFS.SimpleItem, re, quopri import OFS.SimpleItem, re, quopri, rfc822
import Globals import Globals
from Scheduler.OneTimeEvent import OneTimeEvent from Scheduler.OneTimeEvent import OneTimeEvent
from ImageFile import ImageFile from ImageFile import ImageFile
from cStringIO import StringIO from cStringIO import StringIO
#$Id: MailHost.py,v 1.39 1999/03/10 00:15:24 klm Exp $ #$Id: MailHost.py,v 1.40 1999/03/22 20:39:53 brian Exp $
__version__ = "$Revision: 1.39 $"[11:-2] __version__ = "$Revision: 1.40 $"[11:-2]
smtpError = "SMTP Error" smtpError = "SMTP Error"
MailHostError = "MailHost Error" MailHostError = "MailHost Error"
...@@ -162,11 +162,12 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -162,11 +162,12 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
target ='manage_main') target ='manage_main')
def sendTemplate(trueself, self, messageTemplate, def sendTemplate(trueself, self, messageTemplate,
statusTemplate=None, mto=None, mfrom=None, REQUEST=None): statusTemplate=None, mto=None, mfrom=None,
encode=None, REQUEST=None):
'render a mail template, then send it...' 'render a mail template, then send it...'
mtemplate = getattr(self, messageTemplate) mtemplate = getattr(self, messageTemplate)
messageText = mtemplate(self, trueself.REQUEST) messageText = mtemplate(self, trueself.REQUEST)
messageText=_encode(messageText, encode)
headers, message = decapitate(messageText) headers, message = decapitate(messageText)
if mto: headers['to'] = mto if mto: headers['to'] = mto
if mfrom: headers['from'] = mfrom if mfrom: headers['from'] = mfrom
...@@ -174,7 +175,6 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -174,7 +175,6 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
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
Globals.Scheduler.schedule(OneTimeEvent( Globals.Scheduler.schedule(OneTimeEvent(
Send, Send,
(trueself.smtpHost, trueself.smtpPort, (trueself.smtpHost, trueself.smtpPort,
...@@ -193,7 +193,8 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -193,7 +193,8 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
except: except:
return "SEND OK" return "SEND OK"
def send(self, messageText, mto=None, mfrom=None, subject=None): def send(self, messageText, mto=None, mfrom=None, subject=None,
encode=None):
headers, message = decapitate(messageText) headers, message = decapitate(messageText)
if not headers['subject']: if not headers['subject']:
...@@ -210,13 +211,14 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -210,13 +211,14 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
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
messageText=_encode(messageText, encode)
sm=SendMail(self.smtpHost, self.smtpPort, self.localHost, self.timeout) sm=SendMail(self.smtpHost, self.smtpPort, self.localHost, self.timeout)
sm.send(mfrom=headers['from'], mto=headers['to'], sm.send(mfrom=headers['from'], mto=headers['to'],
subj=headers['subject'] or 'No Subject', subj=headers['subject'] or 'No Subject',
body=messageText) body=messageText)
def scheduledSend(self, messageText, mto=None, mfrom=None, subject=None): def scheduledSend(self, messageText, mto=None, mfrom=None, subject=None,
encode=None):
headers, message = decapitate(messageText) headers, message = decapitate(messageText)
if not headers['subject']: if not headers['subject']:
...@@ -233,7 +235,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager): ...@@ -233,7 +235,7 @@ class MailBase(Acquisition.Implicit, OFS.SimpleItem.Item, RoleManager):
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
messageText=_encode(messageText, encode)
Globals.Scheduler.schedule(OneTimeEvent( Globals.Scheduler.schedule(OneTimeEvent(
Send, Send,
(self.smtpHost, self.smtpPort, self.localHost, self.timeout, (self.smtpHost, self.smtpPort, self.localHost, self.timeout,
...@@ -309,26 +311,9 @@ class SendMail: ...@@ -309,26 +311,9 @@ class SendMail:
self._check() self._check()
self.conn.send("data\015\012") self.conn.send("data\015\012")
self._check() self._check()
bfile = StringIO(body)
mo=rfc822.Message(bfile)
for k, v in mo.items():
self.conn.send('%s: %s\015\012' % (string.capitalize(k), v))
# Add some Mime headers if not present
if not mo.has_key('Mime-Version'):
self.conn.send('Mime-Version: 1.0\015\012')
if not mo.has_key('Content-Type'):
self.conn.send(
'Content-Type: text/plain; charset="iso-8859-1"\015\012')
if not mo.has_key('Content-Transfer-Encoding'):
self.conn.send(
'Content-Transfer-Encoding: quoted-printable\015\012')
self.conn.send('\015\012')
body=bfile.read()
body=self.singledots.sub('..', body) body=self.singledots.sub('..', body)
body=string.replace(body, '\r\n', '\n') body=string.replace(body, '\r\n', '\n')
body=string.replace(body, '\r', '\n') body=string.replace(body, '\r', '\n')
body=encode(body, 0)
body=string.replace(body, '\n', '\015\012') body=string.replace(body, '\n', '\015\012')
self.conn.send(body) self.conn.send(body)
self.conn.send("\015\012.\015\012") self.conn.send("\015\012.\015\012")
...@@ -340,43 +325,21 @@ class SendMail: ...@@ -340,43 +325,21 @@ class SendMail:
def _encode(body, encode=None):
if encode is None:
ESCAPE = '=' return body
MAXLINESIZE = 76 mfile=StringIO(body)
HEX = '0123456789ABCDEF' mo=mimetools.Message(mfile)
if mo.getencoding() != '7bit':
def needsquoting(c, quotetabs): raise MailHostError, 'Message already encoded'
if c == '\t': newmfile=StringIO()
return not quotetabs newmfile.write(string.joinfields(mo.headers, ''))
return c == ESCAPE or not(' ' <= c <= '~') newmfile.write('Content-Transfer-Encoding: %s\n' % encode)
if not mo.has_key('Mime-Version'):
def quote(c): newmfile.write('Mime-Version: 1.0\n')
if c == ESCAPE: newmfile.write('\n')
return ESCAPE * 2 mimetools.encode(mfile, newmfile, encode)
else: return newmfile.getvalue()
i = ord(c)
return ESCAPE + HEX[i/16] + HEX[i%16]
def encode(input, quotetabs):
"""Encode a string to Quoted-Printable"""
output = ''
for line in string.split(input, '\n'):
new = ''
prev = ''
for c in line:
if needsquoting(c, quotetabs):
c = quote(c)
if len(new) + len(c) >= MAXLINESIZE:
output = output + new + ESCAPE + '\n'
new = ''
new = new + c
prev = c
if prev in (' ', '\t'):
output = output + new + ESCAPE + '\n\n'
else:
output = output + new + '\n'
return output
def decapitate(message): def decapitate(message):
......
...@@ -4,3 +4,5 @@ MailHost ...@@ -4,3 +4,5 @@ MailHost
The MailHost product provides support for sending email from The MailHost product provides support for sending email from
within the Zope environment using MailHost objects. within the Zope environment using MailHost objects.
Email can optionally be encoded using Base64, Quoted-Printable
or UUEncode encoding.
...@@ -82,8 +82,8 @@ ...@@ -82,8 +82,8 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__rcs_id__='$Id: SendMailTag.py,v 1.5 1999/03/10 00:15:24 klm Exp $' __rcs_id__='$Id: SendMailTag.py,v 1.6 1999/03/22 20:39:53 brian Exp $'
__version__='$Revision: 1.5 $'[11:-2] __version__='$Revision: 1.6 $'[11:-2]
from MailHost import MailBase from MailHost import MailBase
from DocumentTemplate.DT_Util import * from DocumentTemplate.DT_Util import *
...@@ -121,15 +121,21 @@ class SendMailTag: ...@@ -121,15 +121,21 @@ class SendMailTag:
* subject -- optional subject. If not specified, there **must** be a * subject -- optional subject. If not specified, there **must** be a
subject: header in the message. subject: header in the message.
* encode -- optional encoding. Possible values are: 'base64',
'quoted-printable' and 'uuencode'.
''' '''
name='sendmail' name='sendmail'
blockContinuations=() blockContinuations=()
encode=None
def __init__(self, blocks): def __init__(self, blocks):
tname, args, section=blocks[0] tname, args, section=blocks[0]
args=parse_params(args, mailhost=None, mailto=None, mailfrom=None, args=parse_params(args, mailhost=None, mailto=None, mailfrom=None,
subject=None, smtphost=None, port='25') subject=None, smtphost=None, port='25',
encode=None)
for key in ('mailto', 'mailfrom', 'subject', 'smtphost', 'port'): for key in ('mailto', 'mailfrom', 'subject', 'smtphost', 'port'):
if not args.has_key(key):args[key]='' if not args.has_key(key):args[key]=''
...@@ -141,6 +147,12 @@ class SendMailTag: ...@@ -141,6 +147,12 @@ class SendMailTag:
elif has_key(''): mailhost=args['mailhost']=args[''] elif has_key(''): mailhost=args['mailhost']=args['']
else: raise MailHostError, 'No mailhost was specified in tag' else: raise MailHostError, 'No mailhost was specified in tag'
if has_key('encode') and args['encode'] not in \
('base64', 'quoted-printable', 'uuencode', 'x-uuencode',
'uue', 'x-uue'):
raise MailHostError, (
'An unsupported encoding was specified in tag')
if not smtphost: if not smtphost:
self.__name__=self.mailhost=mailhost self.__name__=self.mailhost=mailhost
self.smtphost=None self.smtphost=None
...@@ -158,7 +170,10 @@ class SendMailTag: ...@@ -158,7 +170,10 @@ class SendMailTag:
self.port=args['port']=25 self.port=args['port']=25
else: else:
self.port=args['port'] self.port=args['port']
if has_key('encode'):
self.encode=args['encode']
else: self.encode=None
def render(self, md): def render(self, md):
args=self.args args=self.args
has_key=args.has_key has_key=args.has_key
...@@ -171,7 +186,7 @@ class SendMailTag: ...@@ -171,7 +186,7 @@ class SendMailTag:
smtpPort=self.port) smtpPort=self.port)
mhost.send(self.section(md.this, md), self.mailto, self.mailfrom, mhost.send(self.section(md.this, md), self.mailto, self.mailfrom,
self.subject) self.subject, self.encode)
return ' ' return ' '
......
...@@ -83,8 +83,8 @@ ...@@ -83,8 +83,8 @@
# #
############################################################################## ##############################################################################
__doc__='''MailHost Product Initialization __doc__='''MailHost Product Initialization
$Id: __init__.py,v 1.10 1999/03/10 00:15:24 klm Exp $''' $Id: __init__.py,v 1.11 1999/03/22 20:39:53 brian Exp $'''
__version__='$Revision: 1.10 $'[11:-2] __version__='$Revision: 1.11 $'[11:-2]
import MailHost, SendMailTag import MailHost, SendMailTag
from ImageFile import ImageFile from ImageFile import ImageFile
...@@ -103,3 +103,9 @@ methods={ ...@@ -103,3 +103,9 @@ methods={
misc_={ misc_={
'MHIcon': ImageFile("www/MailHost_icon.gif", globals()) 'MHIcon': ImageFile("www/MailHost_icon.gif", globals())
} }
__ac_permissions__=(
('Add MailHost objects', ('manage_addMailHost_form', 'manage_addMailHost')),
('Change configuration', ()),
('Use mailhost services',()),
)
MailHost 1.0.1 Release Notes
Features Added
- MailHost objects now have an adjustable 'timeout' parameter that
sets how long to wait to connect to the SMTP server before
timing out.
MailHost 1.0.1 Release Notes MailHost 1.0.1 Release Notes
Features Added Features Added
......
MailHost 1.1.0 Release Notes
Features Added
- Sendmail tag now has optional encode attribute, which results
in the body of the email message being encoded using the
designated encoding, and the proper headers being added.
Choices are: base64, quoted-printable and uuencode.
Bugs Fixed
- MailHost object permissions now show op in the security list of
Folder objects.
MailHost 1.0.1 Release Notes
Features Added
- MailHost objects now have an adjustable 'timeout' parameter that
sets how long to wait to connect to the SMTP server before
timing out.
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