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
|
||||
Config
|
||||
Dates
|
||||
Email
|
||||
Hash
|
||||
Json
|
||||
LOServer
|
||||
|
|
|
@ -25,6 +25,7 @@ You can used **easymacro** with any extension or directly in your macros.
|
|||
tools_debug
|
||||
tools
|
||||
paths
|
||||
email
|
||||
api
|
||||
|
||||
|
||||
|
|
|
@ -1633,6 +1633,151 @@ class Url(object):
|
|||
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 for colors
|
||||
|
||||
|
@ -1820,6 +1965,7 @@ def __getattr__(name):
|
|||
'path': Paths,
|
||||
'config': Config,
|
||||
'url': Url,
|
||||
'email': Email,
|
||||
'color': Color(),
|
||||
}
|
||||
if name in classes:
|
||||
|
|
Loading…
Reference in New Issue