-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathemail_sender.py
153 lines (132 loc) · 5.12 KB
/
email_sender.py
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import re
from time import sleep
from smtplib import SMTP, SMTP_SSL
from Queue import Queue
from email.mime.text import MIMEText
REG_TXT = re.compile('\d{10}@.+')
class EmailSender:
def __init__(self, host, port, from_addr, logger, user, password, max_retry=5, queue_time=5, send_opt=1):
self.host = host
self.port = port
self.from_addr = from_addr
self.logger = logger
self.server = None
self.user = user
self.password = password
self.msg_queue = Queue() # used to queue messages
self.max_retry = max_retry # max retry count for sending email
self.queue_time = queue_time # queue wait time in seconds
self.send_opt = send_opt
def connect(self):
# user SSL SMTP if user and password are present
if self.user and self.password:
self.server = SMTP_SSL(self.host, self.port)
self.server.login(self.user, self.password)
else:
self.server = SMTP(self.host, self.port, timeout=3)
def send(self, to_addr, subj, body):
if not to_addr:
return
msg = MIMEText(body)
msg['Subject'] = subj
msg['From'] = self.from_addr
# If there're more than 1 address, we will send it bcc style, otherwise
# it will be addressed normally.
msg['To'] = self.from_addr if len(to_addr) > 1 else to_addr[0]
retry_sec = 0
while True:
try:
if not self.test_conn_open():
self.connect()
self.server.sendmail(self.from_addr, to_addr, msg.as_string())
msg = "Emailed to: %s" % ','.join(to_addr)
if self.logger:
self.logger.info(msg)
else:
print(msg)
break
except Exception as e:
retry_sec += 1
if self.logger:
self.logger.error(e)
else:
print(str(e))
if retry_sec >= self.max_retry:
msg = "Max retry reached. Fails to send email!"
if self.logger:
self.logger.error(msg)
else:
print(msg)
break
msg = "retrying ..."
if self.logger:
self.logger.error(msg)
else:
print(msg)
sleep(retry_sec * 2)
def daemon_sender(self, email_list):
"""Wait for message in the queue, and sends message every 5 seconds
"""
subj = 'SigBridge Alert'
slept_time = 0
while True:
if not self.msg_queue.empty():
# Only start sleep timer when there's message in queue
slept_time += 1
if slept_time >= self.queue_time:
# send queued emails since queuing time has exceeded
msg = ''
while not self.msg_queue.empty():
msg += self.msg_queue.get() + '\n'
if self.send_opt == 1:
# Sending every email in bcc style
self.send(email_list, subj, msg)
elif self.send_opt == 2:
# send regular email in bcc style, but txt msg email
# is sent one at a time.
self.batch_sorter(email_list, subj, msg)
else:
# default: send all emails one at a time.
for email in email_list:
self.send([email], subj, msg)
# reset timer
slept_time = 0
sleep(1)
def batch_sorter(self, email_list, subj, msg):
"""Sort email into two batches: regular and txt msg email.
Regular email are sent all at once bcc style. Txt msg email
is sent one by one.
"""
txt_emails = []
reg_emails = []
for email in email_list:
if REG_TXT.match(email):
txt_emails.append(email)
else:
reg_emails.append(email)
# send regular email
self.send(reg_emails, subj, msg)
# send txt msg email
for txt in txt_emails:
self.send([txt], subj, msg)
def queue_trade(self, trade_str):
self.msg_queue.put(trade_str)
def test_conn_open(self):
try:
status = self.server.noop()[0]
except: # smtplib.SMTPServerDisconnected
status = -1
return True if status == 250 else False
def quit(self):
self.server.quit()
if __name__ == '__main__':
# smtp_server = 'mail.twc.com'
# sender = '' # needs to be a roadrunner email.
smtp_server = 'smtp.sendgrid.net'
smtp_port = 465
sender = '' # needs to be an authorized email address
addrs = ['[email protected]', '[email protected]']
body = 'Just testing sandgrid mails 3.'
es = EmailSender(smtp_server, smtp_port, sender, None, 'apikey', 'sendgrid_api_key')
# es.batch_sorter(addrs, body)
es.send(addrs, 'Testing Sendgrid Alert 3', body)