如何使用python向用户发送电子邮件?

时间:2017-08-30 16:30:37

标签: python

我必须向用户发送电子邮件,并关闭各自的服务器。

代码:

import smtplib
import time
import re
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

#SMTP Credential
user = "username"
password = "pass"
server = smtplib.SMTP('smtp server')

def get_contacts(filename):

   emails = []
   hostname = []
   ip = []
   with open(filename,'r') as contacts_file:
       for a_contact in contacts_file:
          match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', a_contact.split()[0])
          if match == None:
             emails.append('no_email')
             hostname.append(a_contact.split()[0])
             ip.append(a_contact.split()[1])
           else:
              emails.append(a_contact.split()[0])
              hostname.append(a_contact.split()[1])
              ip.append(a_contact.split()[2])
      return emails, hostname, ip


def main():
   emails, hostname, ip = get_contacts('provider.txt') # read contacts


   # Send email to l2@abc.com if provider's support email address is not available:
   for email, hostname, ip in zip(emails, hostname, ip):
      match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email)
      if match == None: #If provider does not have support email send email to l2@abc.com
        l2_email = 'l2@abc.com'
        msg = MIMEText("Hello server with main IP %s is currently down." %ip,'html')
        msg['Subject'] = 'Server down %s: %s' % (hostname,ip)
        msg['From'] = 'username@abc.com'
        msg['To'] = l2_email
        server.starttls()
        server.login(user,password)
        server.sendmail(msg['From'], msg['To'], msg.as_string())


     ##Send email to provider if support email address is found##
      else:
        msg = MIMEText("Hello server with main IP %s is currently down." %ip,'html')
        msg['Subject'] = 'Server down %s: %s' % (hostname,ip)
        msg['From'] = 'username@abc.com'
        msg['To'] = email
        server.starttls()
        server.login(user,password)
        server.sendmail(msg['From'], msg['To'], msg.as_string())
   server.quit()

if __name__ == '__main__':
main()

输入:

    host1 192.168.100.24
    user1@abc.com  host2 192.168.100.45 host7 192.168.100.40 host3 192.168.100.34 host4 192.168.100.20
    user2@xyz.com  host8 192.168.100.48 host6 192.168.100.43 host10 192.168.100.37 
    host5 192.168.100.24 host9 192.168.100.33

我想发送电子邮件至user1@abc.com,邮件如下:

您好以下服务器已关闭:

host2 192.168.100.45

host7 192.168.100.40

host3 192.168.100.34

host4 192.168.100.20

如果该行不包含电子邮件地址,则转到特定的电子邮件地址,如l2@abc.com,其中包含以下消息: 您好以下服务器已关闭:

host1 192.168.100.24

host5 192.168.100.24

host9 192.168.100.33

目前,脚本仅适用于单个主机。任何人都可以帮忙解决这个问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

get_contacts()方法中,您只需为每个处理过的联系信息添加一个hostip

如果我们将您的功能简化为非常基本的功能,您将会看到正在发生的事情:

contact = 'user1@abc.com  host2 192.168.100.45 host7 192.168.100.40 host3 192.168.100.34 host4 192.168.100.20'

# This has an email in it, so we won't bother with the regex check.
print(contact.split()[0])
print(contact.split()[1])
print(contact.split()[2])

如果您运行上面的代码段,您将获得此输出:

user1@abc.com
host2
192.168.100.45

这是因为split()会将整行划分为元素列表,因此您最多只能访问第一个hostip组合。

或者更具体地说,这是我的Python shell中的print(contact.split())

>> print(contact.split())
['user1@abc.com', 'host2', '192.168.100.45', 'host7', '192.168.100.40', 'host3', '192.168.100.34', 'host4', '192.168.100.20']

对于您的问题,您有很多方法可以解决它。一个基本的是:

  • 拆分整个字符串
  • 确定第一个元素是否是电子邮件地址
    • 如果找到了电子邮件地址,请将该电子邮件添加到字典中,然后处理将通过电子邮件发送的host-ip组合列表的其余部分
    • 如果找不到电子邮件地址,请将默认电子邮件添加到字典中,然后处理列表的其余部分以查找将通过电子邮件发送的host-ip组合

以下是您的代码的修改版本,它会生成一个字典,其中所有主机都绑定到应该发送到的任何电子邮件。

from collections import defaultdict

def get_contacts(filename):
    contacts = defaultdict(list)
    with open(filename, 'r') as contacts_file:
        for line in contacts_file:
            split_data = line.split()
            if re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', split_data[0]):
                email = split_data[0]
                # Merge every two elements in the list
                # together to form a host-ip pair
                hosts = [' '.join(i) for i in zip(split_data[1::2], split_data[2::2])]
            else:
                # Some default email here
                email = 'l2@abc.com'
                hosts = [' '.join(i) for i in zip(split_data[0::2], split_data[1::2])]


            contacts[email].extend(hosts)
    return contacts

针对您的数据运行此操作,您的数据将如下所示:

{'l2@abc.com': ['host1 192.168.100.24',
              'host5 192.168.100.24',
              'host9 192.168.100.33'],
 'user1@abc.com': ['host2 192.168.100.45',
              'host7 192.168.100.40',
              'host3 192.168.100.34',
              'host4 192.168.100.20'],
 'user2@xyz.com': ['host8 192.168.100.48',
              'host6 192.168.100.43',
              'host10 192.168.100.37']})

然后你只需迭代结构并根据需要发送电子邮件:

for email, hosts in get_contacts('provider.txt'):
    # ... do what you need to do with the email address
    # and list of hosts

请注意我已完成的一些事情,以及我在您的代码中注意到的一些内容:

  • 每次要在split()方法中进行比较时,您都会在同一行文本上调用get_contacts。这是不必要的 - 如果您要继续使用它,请将其拆分一次并分配给变量。

  • 您不会在发送电子邮件的代码中为您的电子邮件创建正文。

  • 您的电子邮件正则表达式可能过多,因为您实际上无法保证它是真正的电子邮件。您只是想知道您正在解析的内容是类似电子邮件的格式,因此类似[^@]+@[^@]+\.[^@]+的内容可能会同样有效。