python 循环文件类型并将其附加到电子邮件中

lyr7nygr  于 2023-02-21  发布在  Python
关注(0)|答案(1)|浏览(94)

我有一个由两个不同函数生成的文本文件和html文件的列表,每个文件都标记为signal1.txt、signal2等和signal1.html、signal2.html等。我需要发送一封包含每个文件对(signal1.txt和signal1.html、signal2.txt和signal.2.html等)的电子邮件。
我试过几种不同的方法,但是我总是一次又一次地只得到一个文件对(不管它是最后一个文件号)。我发送一个文件类型没有问题,但是当我尝试两个不同的文件时,它会变得混乱。我想给予你尽可能多的信息,也许足够的可复制代码,如果你愿意的话,让你在你的一端尝试它,所以我为这个长问题道歉。
从服务器收集数据。使用计数器模块对最终结果进行排序:

data = Counter({('A user account was locked out ', 47, 'medium', 25): 1, ('An attempt was made to reset an accounts password ', 73, 'high', 2): 1, ('PowerShell Keylogging Script', 73, 'high', 37): 1, ('PowerShell Suspicious Script with Audio Capture Capabilities', 47, 'medium', 36): 1})

我需要在电子邮件主题中使用规则名称,所以其他的都是垃圾。例如,在('A user account was locked out ', 47, 'medium', 25): 1中,我只需要A user account was locked out。所以下面的函数负责所有这些:

def create_txt_files():
    global regex
    global count
    count = 0

    #Convert dict into string and remove unwanted chars
    for signal in dict(event_dict).keys():
        indiv_signal = (str(signal).replace(",",'').replace('(','').replace(')','')\
                        .replace("'",'').replace('[','').replace(']',''))
        #Further removal of debris using regex
        pattern = '^(\D*)'
        regex = ''.join(re.findall(pattern,indiv_signal,re.MULTILINE))
        count +=1
        with open(f"signal{count}.txt", "w") as fh:
            fh.write(str(regex))
create_txt_files()

我还需要创建html文件,将在电子邮件的正文作为一个数据框。在这种情况下,我需要几乎所有的字段在数据文件。数据框应该看起来像这样:

Alert Score Risk Severity Total
0  A user account was locked out          47   medium    26

下面的函数可以解决这个问题:

#Create Individual HTML files
def create_indiv_html_files():
    global html_file
    global count
    count = 0

    #Turn rows into columns
    for items in list(event_dict):
        df = pd.DataFrame(items)
        new_df = df.transpose()
        new_df.columns = ['Alert','Score Risk','Severity','Total']
        html_file = new_df.to_html()
        print(new_df)
        count +=1
        with open(f'signal{count}.html','w') as wf:
            wf.write(html_file)
create_indiv_html_files()

所以,到目前为止,一切都很好,尽管代码没有我想要的那么漂亮。但是它能工作,这就是我现在所担心的。问题是当我发送电子邮件时,我只得到一个规则(最后一个)一遍又一遍地发送。它没有迭代txt和html文件,也没有像它应该的那样附加它们。

这是我正在使用的电子邮件功能。尽管我尝试了几种不同的方法,但我仍然无法找出问题所在。感谢您抽出时间来帮助我。

from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
import smtplib, ssl
import os

dirname = r'C:\Path\To\Files'
ext = ('.txt','html')

for files in os.scandir(dirname):
    if files.path.endswith(ext):

        def sendmail():
            html_body = '''
            <html>
                <body>
                    <p style="font-size: 12;"> <strong>Alert</strong><br>{html_file}</p>
                </body>
            </html>
            '''.format(html_file=html_file)

            subject = f'Alert: {regex} '
            senders_email = 'mail@mail.comt'
            receiver_email = 'mail@mail.comt'

            # Create a multipart message and set headers
            message = MIMEMultipart('alternative')
            message['From'] = senders_email
            message['To'] = receiver_email
            message['Subject'] = subject

            #Attach email body
            message.attach(MIMEText(html_body, 'html'))

            # Name of the file to be attached
            filename = f'signal{count}.html'

            # Open file in binary mode
            with open(filename, 'rb') as attachment:
                # Add file as application/octet-stream
                part = MIMEBase('application', 'octet-stream')
                part.set_payload(attachment.read())

            # Encodes file in ASCII characters to send via email
            encoders.encode_base64(part)

            # Add header as key/value pair to attachment part
            part.add_header(
                'Content-Disposition',
                f"attachment; filename= {filename}",

            )

            # Add attachment to message and convert message to string
            message.attach(part)
            text = message.as_string()

            # Log into server using secure connection
            context = ssl.create_default_context()
            with smtplib.SMTP("smtp.mail.com", 25) as server:
                # server.starttls(context=context)
                # server.login(senders_email, 'password')
                server.sendmail(senders_email, receiver_email, text)
            print("Email sent!")
        sendmail()
qxgroojn

qxgroojn1#

我重写了代码,并删除了全局变量。下面的代码应该工作,让我知道,如果你得到任何错误。

import pathlib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
import smtplib, ssl
import os

def create_txt_files(event_dict):
    regex = []
    count = 0

    #Convert dict into string and remove unwanted chars
    for signal in dict(event_dict).keys():
        indiv_signal = (str(signal).replace(",",'').replace('(','').replace(')','')\
                        .replace("'",'').replace('[','').replace(']',''))
        #Further removal of debris using regex
        pattern = '^(\D*)'
        regex.append(''.join(re.findall(pattern,indiv_signal,re.MULTILINE)))
        count +=1
        with open(f"signal{count}.txt", "w") as fh:
            fh.write(str(regex[0]))

    return regex

def create_indiv_html_files(event_dict):
    html_file = []
    count = 0

    #Turn rows into columns
    for items in list(event_dict):
        df = pd.DataFrame(items)
        new_df = df.transpose()
        new_df.columns = ['Alert','Score Risk','Severity','Total']
        html_file.append(new_df.to_html())
        print(new_df)
        count +=1
        with open(f'signal{count}.html','w') as wf:
            wf.write(html_file[0])

    return html_file

def sendmail(html_file, regex, path_html):
    html_body = '''
    <html>
        <body>
            <p style="font-size: 12;"> <strong>Alert</strong><br>{html_file}</p>
        </body>
    </html>
    '''.format(html_file=html_file)

    subject = f'Alert: {regex} '
    senders_email = 'mail@mail.comt'
    receiver_email = 'mail@mail.comt'

    # Create a multipart message and set headers
    message = MIMEMultipart('alternative')
    message['From'] = senders_email
    message['To'] = receiver_email
    message['Subject'] = subject

    #Attach email body
    message.attach(MIMEText(html_body, 'html'))

    # Name of the file to be attached
    # filename = f'signal{count}.html'

    # Open file in binary mode
    with open(path_html, 'rb') as attachment:
        # Add file as application/octet-stream
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(attachment.read())

    # Encodes file in ASCII characters to send via email
    encoders.encode_base64(part)

    # Add header as key/value pair to attachment part
    part.add_header(
        'Content-Disposition',
        f"attachment; filename= {path_html.name}",

    )

    # Add attachment to message and convert message to string
    message.attach(part)
    text = message.as_string()

    # Log into server using secure connection
    context = ssl.create_default_context()
    with smtplib.SMTP("smtp.mail.com", 25) as server:
        # server.starttls(context=context)
        # server.login(senders_email, 'password')
        server.sendmail(senders_email, receiver_email, text)
    print("Email sent!")

data = Counter({('A user account was locked out ', 47, 'medium', 25): 1, ('An attempt was made to reset an accounts password ', 73, 'high', 2): 1, ('PowerShell Keylogging Script', 73, 'high', 37): 1, ('PowerShell Suspicious Script with Audio Capture Capabilities', 47, 'medium', 36): 1})
regex = create_txt_files(data)
html_file = create_indiv_html_files(data)

signalfiles = sorted(list(pathlib.Path('C:\Path\To\Files').glob('*.txt')))
htmlfiles = sorted(list(pathlib.Path('C:\Path\To\Files').glob('*.html')))

for i, path_html_file in enumerate(htmlfiles):
    sendmail(html_file[i], regex[i], path_html_file)

create_txt_files和create_indiv_html_files接受计数器字典的输入。Sendmail函数将接受正则表达式、html_file字符串和html_file路径。

相关问题