Send mails
This commit is contained in:
parent
3c9f0cc0f9
commit
1f712dfc8a
145
source/diff.py
145
source/diff.py
|
@ -4167,149 +4167,4 @@ def format(template, data):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class SmtpServer(object):
|
|
||||||
|
|
||||||
def __init__(self, config):
|
|
||||||
self._server = None
|
|
||||||
self._error = ''
|
|
||||||
self._sender = ''
|
|
||||||
self._is_connect = self._login(config)
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_connect(self):
|
|
||||||
return self._is_connect
|
|
||||||
|
|
||||||
@property
|
|
||||||
def error(self):
|
|
||||||
return self._error
|
|
||||||
|
|
||||||
def _login(self, config):
|
|
||||||
name = config['server']
|
|
||||||
port = config['port']
|
|
||||||
is_ssl = config['ssl']
|
|
||||||
self._sender = config['user']
|
|
||||||
hosts = ('gmail' in name or 'outlook' in name)
|
|
||||||
try:
|
|
||||||
if is_ssl and hosts:
|
|
||||||
self._server = smtplib.SMTP(name, port, timeout=TIMEOUT)
|
|
||||||
self._server.ehlo()
|
|
||||||
self._server.starttls()
|
|
||||||
self._server.ehlo()
|
|
||||||
elif is_ssl:
|
|
||||||
self._server = smtplib.SMTP_SSL(name, port, timeout=TIMEOUT)
|
|
||||||
self._server.ehlo()
|
|
||||||
else:
|
|
||||||
self._server = smtplib.SMTP(name, port, timeout=TIMEOUT)
|
|
||||||
|
|
||||||
self._server.login(self._sender, config['pass'])
|
|
||||||
msg = 'Connect to: {}'.format(name)
|
|
||||||
debug(msg)
|
|
||||||
return True
|
|
||||||
except smtplib.SMTPAuthenticationError as e:
|
|
||||||
if '535' in str(e):
|
|
||||||
self._error = _('Incorrect user or password')
|
|
||||||
return False
|
|
||||||
if '534' in str(e) and 'gmail' in name:
|
|
||||||
self._error = _('Allow less secure apps in GMail')
|
|
||||||
return False
|
|
||||||
except smtplib.SMTPException as e:
|
|
||||||
self._error = str(e)
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
self._error = str(e)
|
|
||||||
return False
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _body(self, msg):
|
|
||||||
body = msg.replace('\\n', '<BR>')
|
|
||||||
return body
|
|
||||||
|
|
||||||
def send(self, message):
|
|
||||||
file_name = 'attachment; filename={}'
|
|
||||||
email = MIMEMultipart()
|
|
||||||
email['From'] = self._sender
|
|
||||||
email['To'] = message['to']
|
|
||||||
email['Cc'] = message.get('cc', '')
|
|
||||||
email['Subject'] = message['subject']
|
|
||||||
email['Date'] = formatdate(localtime=True)
|
|
||||||
if message.get('confirm', False):
|
|
||||||
email['Disposition-Notification-To'] = email['From']
|
|
||||||
email.attach(MIMEText(self._body(message['body']), 'html'))
|
|
||||||
|
|
||||||
for path in message.get('files', ()):
|
|
||||||
_, fn, _, _ = get_info_path(path)
|
|
||||||
part = MIMEBase('application', 'octet-stream')
|
|
||||||
part.set_payload(read_file(path, 'rb'))
|
|
||||||
encoders.encode_base64(part)
|
|
||||||
part.add_header('Content-Disposition', file_name.format(fn))
|
|
||||||
email.attach(part)
|
|
||||||
|
|
||||||
receivers = (
|
|
||||||
email['To'].split(',') +
|
|
||||||
email['CC'].split(',') +
|
|
||||||
message.get('bcc', '').split(','))
|
|
||||||
try:
|
|
||||||
self._server.sendmail(self._sender, receivers, email.as_string())
|
|
||||||
msg = 'Email sent...'
|
|
||||||
debug(msg)
|
|
||||||
if message.get('path', ''):
|
|
||||||
self.save_message(email, message['path'])
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
self._error = str(e)
|
|
||||||
return False
|
|
||||||
return False
|
|
||||||
|
|
||||||
def save_message(self, email, path):
|
|
||||||
mbox = mailbox.mbox(path, create=True)
|
|
||||||
mbox.lock()
|
|
||||||
try:
|
|
||||||
msg = mailbox.mboxMessage(email)
|
|
||||||
mbox.add(msg)
|
|
||||||
mbox.flush()
|
|
||||||
finally:
|
|
||||||
mbox.unlock()
|
|
||||||
return
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
try:
|
|
||||||
self._server.quit()
|
|
||||||
msg = 'Close connection...'
|
|
||||||
debug(msg)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def _send_email(server, messages):
|
|
||||||
with SmtpServer(server) as server:
|
|
||||||
if server.is_connect:
|
|
||||||
for msg in messages:
|
|
||||||
server.send(msg)
|
|
||||||
else:
|
|
||||||
error(server.error)
|
|
||||||
return server.error
|
|
||||||
|
|
||||||
|
|
||||||
def send_email(server, message):
|
|
||||||
messages = message
|
|
||||||
if isinstance(message, dict):
|
|
||||||
messages = (message,)
|
|
||||||
t = threading.Thread(target=_send_email, args=(server, messages))
|
|
||||||
t.start()
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def server_smtp_test(config):
|
|
||||||
with SmtpServer(config) as server:
|
|
||||||
if server.error:
|
|
||||||
error(server.error)
|
|
||||||
return server.error
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -680,6 +680,145 @@ def decrypt(token, password):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class SmtpServer(object):
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self._server = None
|
||||||
|
self._error = ''
|
||||||
|
self._sender = ''
|
||||||
|
self._is_connect = self._login(config)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_connect(self):
|
||||||
|
return self._is_connect
|
||||||
|
|
||||||
|
@property
|
||||||
|
def error(self):
|
||||||
|
return self._error
|
||||||
|
|
||||||
|
def _login(self, config):
|
||||||
|
name = config['server']
|
||||||
|
port = config['port']
|
||||||
|
is_ssl = config['ssl']
|
||||||
|
self._sender = config['user']
|
||||||
|
hosts = ('gmail' in name or 'outlook' in name)
|
||||||
|
try:
|
||||||
|
if is_ssl and hosts:
|
||||||
|
self._server = smtplib.SMTP(name, port, timeout=TIMEOUT)
|
||||||
|
self._server.ehlo()
|
||||||
|
self._server.starttls()
|
||||||
|
self._server.ehlo()
|
||||||
|
elif is_ssl:
|
||||||
|
self._server = smtplib.SMTP_SSL(name, port, timeout=TIMEOUT)
|
||||||
|
self._server.ehlo()
|
||||||
|
else:
|
||||||
|
self._server = smtplib.SMTP(name, port, timeout=TIMEOUT)
|
||||||
|
|
||||||
|
self._server.login(self._sender, config['password'])
|
||||||
|
msg = 'Connect to: {}'.format(name)
|
||||||
|
debug(msg)
|
||||||
|
return True
|
||||||
|
except smtplib.SMTPAuthenticationError as e:
|
||||||
|
if '535' in str(e):
|
||||||
|
self._error = _('Incorrect user or password')
|
||||||
|
return False
|
||||||
|
if '534' in str(e) and 'gmail' in name:
|
||||||
|
self._error = _('Allow less secure apps in GMail')
|
||||||
|
return False
|
||||||
|
except smtplib.SMTPException as e:
|
||||||
|
self._error = str(e)
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
self._error = str(e)
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _body(self, msg):
|
||||||
|
body = msg.replace('\\n', '<BR>')
|
||||||
|
return body
|
||||||
|
|
||||||
|
def send(self, message):
|
||||||
|
file_name = 'attachment; filename={}'
|
||||||
|
email = MIMEMultipart()
|
||||||
|
email['From'] = self._sender
|
||||||
|
email['To'] = message['to']
|
||||||
|
email['Cc'] = message.get('cc', '')
|
||||||
|
email['Subject'] = message['subject']
|
||||||
|
email['Date'] = formatdate(localtime=True)
|
||||||
|
if message.get('confirm', False):
|
||||||
|
email['Disposition-Notification-To'] = email['From']
|
||||||
|
email.attach(MIMEText(self._body(message['body']), 'html'))
|
||||||
|
|
||||||
|
for path in message.get('files', ()):
|
||||||
|
fn = _P(path).file_name
|
||||||
|
part = MIMEBase('application', 'octet-stream')
|
||||||
|
part.set_payload(_P.read_bin(path))
|
||||||
|
encoders.encode_base64(part)
|
||||||
|
part.add_header('Content-Disposition', f'attachment; filename={fn}')
|
||||||
|
email.attach(part)
|
||||||
|
|
||||||
|
receivers = (
|
||||||
|
email['To'].split(',') +
|
||||||
|
email['CC'].split(',') +
|
||||||
|
message.get('bcc', '').split(','))
|
||||||
|
try:
|
||||||
|
self._server.sendmail(self._sender, receivers, email.as_string())
|
||||||
|
msg = 'Email sent...'
|
||||||
|
debug(msg)
|
||||||
|
if message.get('path', ''):
|
||||||
|
self.save_message(email, message['path'])
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self._error = str(e)
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def save_message(self, email, path):
|
||||||
|
mbox = mailbox.mbox(path, create=True)
|
||||||
|
mbox.lock()
|
||||||
|
try:
|
||||||
|
msg = mailbox.mboxMessage(email)
|
||||||
|
mbox.add(msg)
|
||||||
|
mbox.flush()
|
||||||
|
finally:
|
||||||
|
mbox.unlock()
|
||||||
|
return
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
try:
|
||||||
|
self._server.quit()
|
||||||
|
msg = 'Close connection...'
|
||||||
|
debug(msg)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _send_email(server, messages):
|
||||||
|
with SmtpServer(server) as server:
|
||||||
|
if server.is_connect:
|
||||||
|
for msg in messages:
|
||||||
|
server.send(msg)
|
||||||
|
else:
|
||||||
|
error(server.error)
|
||||||
|
return server.error
|
||||||
|
|
||||||
|
|
||||||
|
def send_email(server, message):
|
||||||
|
messages = message
|
||||||
|
if isinstance(message, dict):
|
||||||
|
messages = (message,)
|
||||||
|
t = threading.Thread(target=_send_email, args=(server, messages))
|
||||||
|
t.start()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
# ~ Classes
|
# ~ Classes
|
||||||
|
|
||||||
class LOBaseObject(object):
|
class LOBaseObject(object):
|
||||||
|
|
Loading…
Reference in New Issue