/usr/lib/python2.7/dist-packages/sagenb/notebook/mailsender.py is in python-sagenb 1.0.1+ds1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | # -*- coding: utf-8 -*
"""nodoctest
"""
#############################################################################
# Copyright (C) 2007 William Stein <wstein@gmail.com>
# Distributed under the terms of the GNU General Public License (GPL)
# The full text of the GPL is available at:
# http://www.gnu.org/licenses/
#############################################################################
from twisted.application import service
from twisted.application import internet
from twisted.internet import protocol
from twisted.mail import smtp, relaymanager
from six import StringIO
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email import Encoders
import mimetypes
class MailMessage(MIMEMultipart):
"""
Represents an email's data.
"""
def __init__(self, fromaddr, toaddr, subject, body):
MIMEMultipart.__init__(self)
self['From'] = fromaddr
self['To'] = toaddr
self['Subject'] = subject
text_part = MIMEBase('text', 'plain')
text_part.set_payload(body)
self.attach(text_part)
# Make an instance of this class if you need to send an email
class SMTPInput:
"""
A message to be sent off to an SMTP server.
INPUT:
mail_from -- the SMTP MAIL FROM: ...
rcpt -- the SMTP RCPT TO: ...
data -- the entire message. This should be a StringIO object.
identity -- the SMTP HELO identity. For some SMTP servers, the
Sage email sender's IP must resolve to this address.
secret -- Dunno?
"""
def __init__(self, mail_from, rcpt, data, identity, secret=None):
self._mail_from = mail_from
self._rcpt = rcpt
self._id = identity
self._data = data
self._secret = secret
self._factory = SMTPClientFactory(self)
# the server that we will deliver the mail to
try:
self._rcpt_domain = [(r.split('@'))[1] for r in rcpt]
except ValueError:
raise ValueError("mal-formed recipient email address")
print(self._rcpt_domain)
def exchange_mail(self, exchange):
smtp_client = internet.TCPClient(exchange, 25, self._factory)
smtp_client.setServiceParent(self._app)
def get_mx(self, host):
on_found_record = lambda rec: str(rec.name)
# return a deffered that will call on_found_record when it's done.
# on_found_record's return value gets passed to exchange_mail
return relaymanager.MXCalculator().getMX(host).addCallback(on_found_record)
def run_from(self, app):
self._app = app
self.get_mx(self._rcpt_domain[0]).addCallback(self.exchange_mail)
class MailClient(smtp.ESMTPClient):
def __init__(self, mesg, **kwds):
smtp.ESMTPClient.__init__(self,**kwds)
self._mesg = mesg
# these are all overridden from the super class, and called by Twisted to do
# the real work
getMailFrom = lambda self: self._mesg._mail_from
getMailTo = lambda self: self._mesg._rcpt
def getMailData(self):
return StringIO(self._mesg._data)
def sentMail(self, code, resp, numOk, addresses, log):
print('<< dest SMTP server >> %s: %s' % (code, resp))
print('Sent %s messages.' % numOk)
from twisted.internet import reactor
reactor.stop()
class SMTPClientFactory(protocol.ClientFactory):
def __init__(self, mesg):
self._mesg = mesg
self._protocol = MailClient
def buildProtocol(self, addr):
mesg = self._mesg
return self._protocol(mesg, secret=mesg._secret, identity=mesg._id)
application = service.Application("SAGE SMTP Client")
_from = "moretti@u.math.washington.edu"
_to = ["wstein@gmail.com"]
_id = "sage.math.washington.edu"
subject = "Progress"
body = \
"""
William,
I'm sending this to you from Twisted. I think I'm ready to try to plug this in
from SAGE, as soon as Yi has the login stuff working (which he almost does.)
~Bobby
"""
data = MailMessage(_from, _to[0], subject, body)
m = SMTPInput(_from, _to, data.as_string(unixfrom=False), _id)
m.run_from(application)
|