Doc for send email
This commit is contained in:
parent
7114cafea3
commit
04db977d37
|
@ -0,0 +1,109 @@
|
||||||
|
|
||||||
|
Email
|
||||||
|
=====
|
||||||
|
|
||||||
|
Remember, always import library.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import easymacro as app
|
||||||
|
|
||||||
|
|
||||||
|
**IMPORTANT:** Always save your config the more security way possible.
|
||||||
|
|
||||||
|
|
||||||
|
Send email
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from conf import PASSWORD
|
||||||
|
|
||||||
|
SERVER = dict(
|
||||||
|
server = 'mail.server.net' ,
|
||||||
|
port = 495,
|
||||||
|
ssl = True,
|
||||||
|
user = 'no-responder@noexiste.mx',
|
||||||
|
password = PASSWORD,
|
||||||
|
)
|
||||||
|
|
||||||
|
body = "Hello Ingrid\n\nWho are you?\n\nBest regards"
|
||||||
|
|
||||||
|
message = dict(
|
||||||
|
to = 'ingrid.bergman@love.you',
|
||||||
|
subject = 'I love you',
|
||||||
|
body = body,
|
||||||
|
)
|
||||||
|
|
||||||
|
app.email.send(SERVER, message)
|
||||||
|
|
||||||
|
* We can use fields `cc`, `bcc` too and send to more than one address emails.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
to = 'mail1@correo.com,mail2@correo.com,mail3@correo.com'
|
||||||
|
cc = 'other@correo.com'
|
||||||
|
bcc = 'hidden@correo.com'
|
||||||
|
|
||||||
|
* We can send too more than one message.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
message1 = dict(
|
||||||
|
to = 'ingrid.bergman@email.net',
|
||||||
|
subject = 'I love you',
|
||||||
|
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
|
||||||
|
)
|
||||||
|
message2 = dict(
|
||||||
|
to = 'sophia.loren@email.net',
|
||||||
|
subject = 'I love you',
|
||||||
|
body = "Hello Sophia\n\nWho are you?\n\nBest regards",
|
||||||
|
)
|
||||||
|
messages = (message1, message2)
|
||||||
|
|
||||||
|
app.email.send(SERVER, messages)
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
30/06/2021 13:43:23 - DEBUG - Connect to: mail.gandi.net
|
||||||
|
30/06/2021 13:43:24 - DEBUG - Email sent...
|
||||||
|
30/06/2021 13:43:26 - DEBUG - Email sent...
|
||||||
|
30/06/2021 13:43:26 - DEBUG - Close connection...
|
||||||
|
|
||||||
|
* Send with attachment
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
files = '/home/mau/file.epub'
|
||||||
|
message = dict(
|
||||||
|
to = 'ingrid.bergman@email.net',
|
||||||
|
subject = 'I love you',
|
||||||
|
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
|
||||||
|
files = files,
|
||||||
|
)
|
||||||
|
|
||||||
|
* Send more than one file.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
files = (
|
||||||
|
'/home/mau/file1.epub',
|
||||||
|
'/home/mau/file2.epub',
|
||||||
|
)
|
||||||
|
|
||||||
|
* If your client email used `mbox` format, we can save in any path into your email client configuration.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
path_save = '/home/mau/.thunderbird/7iznrbyw.default/Mail/Local Folders/LibreOffice'
|
||||||
|
message = dict(
|
||||||
|
to = 'ingrid.bergman@email.net',
|
||||||
|
subject = 'I love you',
|
||||||
|
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
|
||||||
|
path = path_save
|
||||||
|
)
|
||||||
|
app.email.send(SERVER, message)
|
||||||
|
|
||||||
|
|
||||||
|
* All emails always send in other thread.
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
Color
|
Color
|
||||||
Config
|
Config
|
||||||
Dates
|
Dates
|
||||||
|
Email
|
||||||
Hash
|
Hash
|
||||||
Json
|
Json
|
||||||
LOServer
|
LOServer
|
||||||
|
|
|
@ -25,6 +25,7 @@ You can used **easymacro** with any extension or directly in your macros.
|
||||||
tools_debug
|
tools_debug
|
||||||
tools
|
tools
|
||||||
paths
|
paths
|
||||||
|
email
|
||||||
api
|
api
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1633,6 +1633,151 @@ class Url(object):
|
||||||
return cls._open(url, data, headers, verify, json, timeout, 'POST')
|
return cls._open(url, data, headers, verify, json, timeout, 'POST')
|
||||||
|
|
||||||
|
|
||||||
|
class Email(object):
|
||||||
|
"""Class for send email
|
||||||
|
"""
|
||||||
|
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'))
|
||||||
|
|
||||||
|
paths = message.get('files', ())
|
||||||
|
if isinstance(paths, str):
|
||||||
|
paths = (paths,)
|
||||||
|
for path in paths:
|
||||||
|
fn = _P(path).file_name
|
||||||
|
print('NAME', fn)
|
||||||
|
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
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _send_email(cls, server, messages):
|
||||||
|
with cls.SmtpServer(server) as server:
|
||||||
|
if server.is_connect:
|
||||||
|
for msg in messages:
|
||||||
|
server.send(msg)
|
||||||
|
else:
|
||||||
|
error(server.error)
|
||||||
|
return server.error
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def send(cls, server: dict, messages: Union[dict, tuple, list]):
|
||||||
|
if isinstance(messages, dict):
|
||||||
|
messages = (messages,)
|
||||||
|
t = threading.Thread(target=cls._send_email, args=(server, messages))
|
||||||
|
t.start()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class Color(object):
|
class Color(object):
|
||||||
"""Class for colors
|
"""Class for colors
|
||||||
|
|
||||||
|
@ -1820,6 +1965,7 @@ def __getattr__(name):
|
||||||
'path': Paths,
|
'path': Paths,
|
||||||
'config': Config,
|
'config': Config,
|
||||||
'url': Url,
|
'url': Url,
|
||||||
|
'email': Email,
|
||||||
'color': Color(),
|
'color': Color(),
|
||||||
}
|
}
|
||||||
if name in classes:
|
if name in classes:
|
||||||
|
|
Loading…
Reference in New Issue