Проблема с циклическим просмотром индекса и отправкой электронной почты - PullRequest
0 голосов
/ 07 октября 2019

У меня есть код Python, который отправляет электронное письмо на основе значения столбца. Он выполняет итерацию по каждой строке во фрейме данных и проверяет, равно ли значение столбца 1. Здесь столбец - временной флаг. Проблема в том, что я не могу запретить многократную отправку, то есть сказать, что после отправки электронного письма и если цикл while запускается во второй раз, выполняется цикл for и снова отправляется электронное письмо, чего я не делаю. не хочу

Вместо этого я хочу отправить электронное письмо только один раз для строки, для которой установлен флаг времени 1. Следующее письмо должно быть отправлено через час для этой строки. Я думал о сохранении индекса в списке для строк, где флаг времени равен 1, но после этого продолжить невозможно.

def send_email(previousindex,index):

        print('entering if loop')
        fromaddr = "**********"
        toaddr = "*********"
        msg = MIMEMultipart()
        msg['From'] = fromaddr
        msg['To'] = toaddr
        a = str(df.loc[df.index[index], 'Station ID'])
        b = str(df.loc[df.index[index], 'Time Difference'])
        print(a)
        msg['Subject'] = "Timestamp Alarm for Station"+ " " + a + " "+"(No data since" +" "+b+")"
        df1 = df.iloc[index,:]

        #Adding styles to the html table
        with open('cssfile.txt', 'r') as myfile:
            style = myfile.read()
        #Mail body
        body = """<html><head></head>{1}<div>{0}</div></html>""".format(pd.DataFrame(df1).T.to_html(index=False),style)
        part = MIMEText(body,'html')
        msg.attach(part)
        server = smtplib.SMTP("smtp.office365.com",587)
        server.ehlo()
        server.starttls()
        server.login('*********', '**********')
        server.sendmail(fromaddr,toaddr,msg.as_string())
        server.quit()
    else:
        print('entering else loop')
        time.sleep(3600)


while True:
    previousindex = []
    cnxn = pyodbc.connect(
        'DRIVER=' + driver + ';SERVER=' + server + ';PORT=1433;DATABASE=' + database + ';UID=' + username + ';PWD=' + password)
    df = pd.read_sql('SELECT * FROM source_reads', cnxn)
    df['current_time'] = datetime.datetime.now() - pd.DateOffset(hours=8)
    df['current_time'] = pd.to_datetime(df['current_time'], infer_datetime_format=True)
    df['last_reported_at'] = pd.to_datetime(df['last_reported_at'], infer_datetime_format=True)
    df['Current UTC Time'] = df['current_time'].dt.strftime('%d-%m-%Y %H:%M %p')
    df['local time'] = datetime.datetime.now()
    df['local time'] = df['local time'].dt.strftime('%d-%m-%Y %H:%M %p')
    df['TD'] = df['current_time'] - pd.to_datetime(df['last_reported_at'])
    TimeD = pd.DatetimeIndex(df['TD'])
    df['TimeD'] = TimeD.hour * 60 + TimeD.minute
    df['Time Difference'] = df['TimeD'].map(str) + " " "min(s)"
    df['timeflag'] = df['TimeD'].apply(lambda x: '1' if x >= 15 else '0')
    df['timeflag'] = df['timeflag'].astype(str).astype(int)

    df = df.drop(
        columns=['created_at', 'updated_at', 'source_read_id', 'current_time', 'TimeD', 'TD', 'Current UTC Time'])

    condlist = [df['reporting_station_id'] == 1,
                df['reporting_station_id'] == 2,
                df['reporting_station_id'] == 3,
                df['reporting_station_id'] == 4,
                df['reporting_station_id'] == 5,
                df['reporting_station_id'] == 6,
                df['reporting_station_id'] == 7,
                df['reporting_station_id'] == 8,
                df['reporting_station_id'] == 9,
                df['reporting_station_id'] == 10,
                df['reporting_station_id'] == 11,
                df['reporting_station_id'] == 12,
                df['reporting_station_id'] == 13,
                df['reporting_station_id'] == 14,
                df['reporting_station_id'] == 15,
                df['reporting_station_id'] == 16,
                ]
    choicelist = [712,713,714,715,716,717,718,719,720,721,722,723,725,728,729]
    df['Station_id'] = np.select(condlist, choicelist)

    df.columns = ['id', 'Last Reported (UTC)', 'Reporting Station Id',
                  'Local Time', 'Time Difference', 'Time flag', 'Station ID', ]

    for index in df.index:  # row in df.iterrows():

        if df.loc[index, 'Time flag'] == 0:
            print('fail')
            print(previousindex)
            send_email(previousindex,index)
            l = previousindex.append(index)

        else:
            time.sleep(10)
            continue

    time.sleep(10)

РЕДАКТИРОВАТЬ: Получение ошибки, когда я вычитаю сейчас и последнее отправленное электронное письмо

    Traceback (most recent call last):
  File "C:/Users/KrishnamurthyKA/Desktop/Project/SQL.py", line 106, in <module>
    elif df.loc[index, 'Time flag'] == 1 and (now - df.loc[df.index[index],'emailsent_time'] > hour):
TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int'

1 Ответ

0 голосов
/ 07 октября 2019

Вы можете добавить столбец к фрейму данных с отметкой времени, которая указывает, когда было отправлено последнее письмо. Затем, когда вы выполняете итерацию по нему, вы можете проверить, прошло ли больше часа с момента последней отправки электронного письма, и если да, то можете ли вы отправить другое электронное письмо и сохранить новую временную метку.

Пример псевдокода:

import time
# initialize all 'email_sent_at' = 0

# time.time() returns seconds since epoch, and one hour is 60*60 seconds.
hour = 60*60

for row in dataframe:
    now = time.time()
    if row['time_flag'] == 1 and (now - row['email_sent_at'] > hour):
        send_email()
        # reset the timestamp, so that another 60*60 seconds need to pass
        # before another email is sent.
        row['email_sent_at'] = now
    else:
        # either the 'time_flag' is not set, or it is set and it's less
        # than an hour since the last sent email.
        pass
...