smtplib hack
Dennis Voss
dennis at dennis-voss.de
Sat Jul 28 13:58:26 EDT 2001
Hi,
I patched the smtplib to support sending email via sendmail also.
With this addon, you should be able to do:
import smtplib2
mysendmailexe = "/usr/sbin/sendmail"
fromaddr = "dennis at dennis-voss.de"
toaddr = "dennis.voss at tu-harburg.de"
message = "Just a quick test for the smtplib enhancement\n"
server = smtplib2.SMTP(mysendmailexe)
server.sendmail(fromaddr, toaddr, message)
server.quit()
The code is largely beta and in some parts untested.
However, swapping sendmail and a fully fledged is nice and
hopefully welcomed in cgi.
Here's the diff -u:
--- smtplib.py Mon Jun 18 21:38:06 2001
+++ smtplib2.py Sat Jul 28 19:09:18 2001
@@ -36,6 +36,7 @@
# Eric S. Raymond <esr at thyrsus.com>
# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data)
# by Carey Evans <c.evans at clear.net.nz>, for picky mail servers.
+# Sendmail interface added by Dennis Voss <dennis at dennis-voss.de>
#
# This was modified from the Python 1.5 library HTTP lib.
@@ -111,6 +112,9 @@
class SMTPHeloError(SMTPResponseException):
"""The server refused our HELO reply."""
+class SMTPSendmailError(SMTPResponseException):
+ """sendmail did exit with an error."""
+
def quoteaddr(addr):
"""Quote a subset of the email addresses defined by RFC 821.
@@ -172,21 +176,26 @@
helo_resp = None
ehlo_resp = None
does_esmtp = 0
+ sendmail_path = ''
def __init__(self, host = '', port = 0):
"""Initialize a new instance.
If specified, `host' is the name of the remote host to which to
- connect. If specified, `port' specifies the port to which to
connect.
+ connect OR path to sendmail (or compatible) executeable.
+ If specified, `port' specifies the port to which to connect.
By default, smtplib.SMTP_PORT is used. An SMTPConnectError is
raised
if the specified `host' doesn't respond correctly.
"""
self.esmtp_features = {}
if host:
- (code, msg) = self.connect(host, port)
- if code != 220:
- raise SMTPConnectError(code, msg)
+ if host[0] == '/':
+ self.sendmail_path = host
+ else:
+ (code, msg) = self.connect(host, port)
+ if code != 220:
+ raise SMTPConnectError(code, msg)
def set_debuglevel(self, debuglevel):
"""Set the debug output level.
@@ -464,6 +473,17 @@
empty dictionary.
"""
+ if self.sendmail_path:
+ import os
+ p = os.popen("%s -t" % self.sendmail_path, "w")
+ p.write("From: %s\n" % from_addr)
+ p.write("To: %s\n" % to_addrs)
+ p.write("\n") # blank line separating headers from body
+ p.write("%s\n" % msg)
+ sts = p.close()
+ if sts != 0:
+ raise SMTPSendmailError
+
if self.helo_resp is None and self.ehlo_resp is None:
if not (200 <= self.ehlo()[0] <= 299):
(code,resp) = self.helo()
My diff program did not recognize the two extra lines in the sendmail()
function:
- (code,resp) = self.mail(from_addr, esmtp_opts)
+ if not self.sendmail_path:
+ (code,resp) = self.mail(from_addr, esmtp_opts)
- (code,resp) = self.data(msg)
+ if not self.sendmail_path:
+ (code,resp) = self.data(msg)
And the new quit() function:
def quit(self):
"""Terminate the SMTP session."""
if not self.sendmail_path:
self.docmd("quit")
self.close()
Further encapsulation is needed, but I generally only use these.
Dennis Voss
More information about the Python-list
mailing list