简体   繁体   中英

Replace body message of an email using python

I created a class in python that will send emails via one of my private servers. It works but I'm wondering if there is a method to replace an existing email body message with a new one?

Emailer Class

class Emailer:

  def __init__(self, subj=None, message=None, toAddr=None, attachment=None, image=None):
    # initialize email inputs

    self.msg = email.MIMEMultipart.MIMEMultipart()

    self.cidNum = 0

    self.message = []
    if message is not None:
        self.addToMessage(message,image)

    # set the subject of the email if there is one specified
    self.subj = []
    if subj is not None:
        self.setSubject(subj)

    # set the body of the email and any attachements specified
    self.attachment = []
    if attachment is not None:
        self.addAtachment(attachment)

    # set the recipient list
    self.toAddr = []
    if toAddr is not None:
        self.addRecipient(toAddr)

  def addAttachment(self,attachment):
    logger.debug("Adding attachement to email")
    # loop through list of attachments and add them to the email
    if attachment is not None:
        if type(attachment) is not list:
            attachment = [attachment]
        for f in attachment:
            part = email.MIMEBase.MIMEBase('application',"octet-stream")
            part.set_payload( open(f,"rb").read() )
            encoders.encode_base64(part)
            part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(f)))
            self.msg.attach(part)

  def addToMessage(self,message,image=None):
    logger.debug("Adding to email message. Content: [%s]" % message)
    # add the plain text message
    self.message.append(message) 
    # add embedded images to message
    if image is not None:
        if type(image) is not list:
            image = [image]
        for i in image:
            msgText = email.MIMEText.MIMEText('<br><img src="cid:image%s"><br>' % self.cidNum, 'html')   
            self.msg.attach(msgText)

            fp = open(i, 'rb')
            img = email.MIMEImage.MIMEImage(fp.read())
            fp.close()
            img.add_header('Content-ID','<image%s>' % self.cidNum)
            self.msg.attach(img)
            self.cidNum += 1

# method to set the subject of the email
  def setSubject(self,subj):
    self.msg['Subject'] = subj

# method to add recipients to the email
  def addRecipient(self, toAddr):
    # loop through recipient list
    for x in toAddr:
        self.msg['To'] = x

# method to configure server settings: the server host/port and the senders login info
  def configure(self,  serverLogin, serverPassword, fromAddr, toAddr, serverHost='myserver', serverPort=465):
    self.server=smtplib.SMTP_SSL(serverHost,serverPort) 
    self.server.set_debuglevel(True)
    # self.server.ehlo()
    # self.server.ehlo()
    self.server.login(serverLogin, serverPassword)  #login to senders email
    self.fromAddr = fromAddr
    self.toAddr = toAddr

# method to send the email
  def send(self):
    logger.debug("Sending email!")
    msgText = email.MIMEText.MIMEText("\n".join(self.message))
    self.msg.attach(msgText) 
    print "Sending email to %s " % self.toAddr
    text = self.msg.as_string() #conver the message contents to string format
    try:
        self.server.sendmail(self.fromAddr, self.toAddr, text)  #send the email
    except Exception as e:
        logger.error(e)

Currently, the addToMessage() method is what adds text to the body of the email. If addToMessage() had already been called but I wanted to replace that body text with new text, is there a way?

If addToMessage() had already been called but I wanted to replace that body text with new text, is there a way?

Yes. If you are always replacing the last entry added to self.message , you can reference this element with self.message[-1] since it is a list. If you want to replace a specific element, you can search for it with the index() method.

Example #1: Replace Last Written Text in Body

def replace_last_written_body_text(new_text):
    if len(self.message) > 0:
        self.message[-1] = new_text

Example #2: Replace Specified Text in Body

def replace_specified_body_text(text_to_replace, new_text):
    index_of_text_to_replace = self.message.index(text_to_replace)
    if index_of_text_to_replace is not None:
        self.message[index_of_text_to_replace] = new_text
    else:
        logger.warning("Cannot replace non-existent body text")

If addToMessage has been called just once, then:

message is a list, and its first element is the body text, so you just need to replace that element with the new text:

def replace_body(self, new_text):
    if len(self.message) > 0:
        self.message[0] = new_text
    else:
        self.message = [new_text]

I haven't tested that, but it should work. Make sure you write some unit tests for this project!

EDIT: if addToMessage has been called multiple times, then the new replace function could replace the entire text, or just part of it. If you want to replace all of it, then just replace message, like the part after else above: self.message = [new_text] . Otherwise, you're going to have to find the element you need to replace, like @BobDylan is doing in his answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM