summaryrefslogtreecommitdiff
path: root/04-CustomLibrary/Smtp4Library
diff options
context:
space:
mode:
authordongxiaoyan <[email protected]>2020-04-01 12:42:05 +0800
committerdongxiaoyan <[email protected]>2020-04-01 12:42:05 +0800
commitacc676857bd85512f344a8d06aa1ae8846e7c0db (patch)
treef2a7e19139d7f763e699ae10a997184c168fed76 /04-CustomLibrary/Smtp4Library
first init project codeHEADmaster
Diffstat (limited to '04-CustomLibrary/Smtp4Library')
-rw-r--r--04-CustomLibrary/Smtp4Library/__init__.py417
-rw-r--r--04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-36.pycbin0 -> 11414 bytes
-rw-r--r--04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-37.pycbin0 -> 11425 bytes
-rw-r--r--04-CustomLibrary/Smtp4Library/__pycache__/version.cpython-37.pycbin0 -> 207 bytes
-rw-r--r--04-CustomLibrary/Smtp4Library/version.py11
5 files changed, 428 insertions, 0 deletions
diff --git a/04-CustomLibrary/Smtp4Library/__init__.py b/04-CustomLibrary/Smtp4Library/__init__.py
new file mode 100644
index 0000000..dff36a4
--- /dev/null
+++ b/04-CustomLibrary/Smtp4Library/__init__.py
@@ -0,0 +1,417 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of robotframework-Smtp3Library.
+# https://github.io/lucamaro/robotframework-Smtp3Library
+
+# Licensed under the Apache License 2.0 license:
+# http://www.opensource.org/licenses/Apache-2.0
+# Copyright (c) 2016, Luca Maragnani <[email protected]>
+
+"""
+Library implementation
+"""
+import ast
+import smtplib
+import email
+import random
+import string
+import mimetypes
+import quopri
+from email.message import Message
+from email.mime.audio import MIMEAudio
+from email.mime.base import MIMEBase
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+from email import encoders
+import os.path
+import socket
+from robot.api.deco import keyword
+from robot.api import logger
+
+from Smtp3Library.version import __version__ # NOQA
+
+COMMASPACE = ', '
+
+class Smtp3Library(object):
+ """
+ SMTP Client class
+ """
+
+ def __init__(self):
+ """
+ Constructor
+ """
+ self.message = self._MailMessage()
+ self.host = None
+ self.port = None
+ self.user = None
+ self.password = None
+ self.smtp = None
+
+ def _prepare_connection(self, host, port, user=None, password=None):
+ """
+ Private method to collect connection informations
+ """
+ self.host = host
+ self.port = int(port)
+ self.user = user
+ self.password = password
+ self.client_hostname = socket.gethostname()
+
+
+ def prepare_ssl_connection(self, host, port=465, user=None, password=None):
+ """
+ Collect connection informations for SSL channel
+ """
+ self._prepare_connection(host, port, user, password)
+ self.smtp = smtplib.SMTP_SSL()
+
+ def prepare_connection(self, host, port=25, user=None, password=None):
+ """
+ Collect connection informations for unencrypted channel
+ """
+ self._prepare_connection(host, port, user, password)
+ self.smtp = smtplib.SMTP()
+
+ def add_to_recipient(self, recipient):
+ """
+ Add a recipient to "To:" list
+ """
+ self.message.mail_to.append(recipient)
+
+ def add_cc_recipient(self, recipient):
+ """
+ Add a recipient to "Cc:" list
+ """
+ self.message.mail_cc.append(recipient)
+
+ def add_bcc_recipient(self, recipient):
+ """
+ Add a recipient to "Bcc:" list
+ """
+ self.message.mail_bcc.append(recipient)
+
+ def set_subject(self, subj):
+ """
+ Set email subject
+ """
+ self.message.subject = subj
+
+ def set_from(self, from_recipient):
+ """
+ Set from address of message and envelope
+ """
+ self.message.mail_from = from_recipient
+
+ def set_body(self, body):
+ """
+ Set email body
+ """
+ self.message.body = body
+
+ def set_random_body(self, size):
+ """
+ Set a random body of <size> length
+ """
+ body = ''
+ for i in range(0, size):
+ body += ''.join(random.choice(string.uppercase + string.digits))
+ if i % 80 == 0:
+ body += "\n"
+ self.message.body = body
+
+ def add_attachment(self, attach):
+ """
+ Add attachment to a list of filenames
+ """
+ self.message.attachments.append(attach)
+
+ def add_header(self, name, value):
+ """
+ Add a custom header to headers list
+ """
+ self.message.headers[name] = value
+
+ def connect(self):
+ '''
+ Open connection to server
+ Returns tuple (smtp status code, message)
+ '''
+ return self.smtp.connect(self.host, self.port)
+
+ def present_client_as(self, client_hostname):
+ '''
+ Set helo/ehlo client identity
+ '''
+ self.client_hostname = client_hostname
+
+ def helo(self):
+ '''
+ Send HELO command
+ Returns tuple (smtp status code, message)
+ '''
+ result = self.smtp.helo(self.client_hostname)
+ logger.info(result)
+ return result
+
+ def ehlo(self):
+ '''
+ Send EHLO command
+ Returns tuple (smtp status code, message)
+ '''
+ result = self.smtp.ehlo(self.client_hostname)
+ logger.info(result)
+ return result
+
+ def get_esmtp_features(self):
+ '''
+ Returns hashmap with ESMTP feature received with EHLO
+ '''
+ logger.info(self.smtp.esmtp_features)
+ return self.smtp.esmtp_features
+
+ def logins(self):
+ try:
+ '''
+ Login user
+ Returns tuple (smtp status code, message)
+ '''
+ logger.info("Login with user " + self.user + " and password " + self.password)
+ '''try:
+ subuser=bytes.decode(self.user)
+ subpassword=bytes.decode(self.password)
+ result = self.smtp.login(subuser.encode('ascii'), subpassword.encode('ascii'))
+ logger.info(result)
+ return result
+ except:
+ logger.info("本身就是str类型不需要bytes to str!")
+ subuser=str(self.user).encode('ascii')
+ subpassword=str(self.password).encode('ascii')
+ result = self.smtp.login(subuser, subpassword)
+ logger.info(result)
+ return result'''
+ result = self.smtp.login(self.user, self.password)
+ logger.info(result)
+ return "success"
+ except:
+ return "fail"
+
+
+ def starttls(self, keyfile=None, certfile=None):
+ '''
+ sends STARTTLS
+ optional: keyfile certfile
+ Returns tuple (smtp status code, message)
+ '''
+ logger.info("STARTTLS")
+ if keyfile is None and certfile is None:
+ result = self.smtp.starttls()
+ else:
+ result = self.smtp.starttls(keyfile, certfile)
+ logger.info(result)
+ return result
+
+ def data(self):
+ '''
+ Data command send email body with "MAIL FROM:", "RCPT TO:" and "DATA" commands
+ Returns tuple (smtp status code, message)
+ '''
+ result = self.smtp.mail(self.message.mail_from)
+ result += self.smtp.rcpt(self.message.get_message_recipients())
+
+ result += self.smtp.data(self.message.get_message_as_string())
+ logger.info(result)
+ return result
+
+ def sendmail(self):
+ '''
+ Send email with "MAIL FROM:", "RCPT TO:" and "DATA" commands
+ Returns tuple (smtp status code, message)
+ '''
+ result = self.smtp.sendmail(self.message.mail_from, self.message.get_message_recipients(), self.message.get_message_as_string())
+ logger.info(result)
+ return result
+
+ def quit(self):
+ '''
+ Send QUIT command
+ Returns tuple (smtp status code, message)
+ '''
+ result = self.smtp.quit()
+ logger.info(result)
+ return result
+
+ def close_connection(self):
+ '''
+ Close connection to server
+ '''
+ return self.smtp.close()
+
+ def send_message(self):
+ """
+ Send the message, from connection establishment to quit and close connection.
+ All the connection and email parameters must be already set before invocation.
+ Returns sendmail response (code, message)
+ """
+
+ # Send the message
+ try:
+ self.connect()
+
+ if self.user is not None:
+ self.ehlo()
+ self.logins()
+
+ send_result = self.sendmail()
+
+ self.quit()
+ self.close_connection()
+ # return send_result
+ return "success"
+ except:
+ return "fail"
+
+ @keyword('Send Message With All Parameters')
+ def send_message_full(self, host, user, password, subj,
+ from_recipient, to_recipient, cc_recipient=None, bcc_recipient=None,
+ body=None, attach=None):
+ """
+ Send a message specifing all parameters on the same linecc
+ cc, bcc and attach parameters may be strings or array of strings
+ host, user, password, subj, fromadd, toadd - are mandatory parameters
+ to use the optional paramaters pleas specify the name fo the parameter in the call
+ user and password even if mandatory could be set to None so no authentication will be made
+ Example:
+ sendMail("smtp.mail.com", None, None, "The subject", "[email protected]", "[email protected]", body="Hello World body")
+
+ sendMail("smtp.mail.com", "scott", "tiger", "The subject", "[email protected]", "[email protected]", body="Hello World body", attach=attaches
+ where could be:
+ attaches = ["c:\\desktop\\file1.zip", "c:\\desktop\\file2.zip"] or
+ attaches = "c:\\desktop\\file1.zip"
+ Returns sendmail response (code, message)
+ """
+
+ self.host = host
+ self.user = user
+ self.password = password
+
+ self.set_subject(subj)
+ self.set_from(from_recipient)
+ self.message.mail_to = to_recipient
+ if cc_recipient != None:
+ self.message.mail_cc = cc_recipient
+ if bcc_recipient != None:
+ self.message.mail_bcc = bcc_recipient
+ #Fill the message
+ if body != None:
+ self.set_body(body)
+ # Part two is attachment
+ if attach != None:
+ attachlist = ast.literal_eval(attach)
+ self.message.attachments = attachlist
+ #logger.info("self.message.attachments:"+str(type(self.message.attachments)))
+ #logger.info("attachtype:"+str(type(attachlist)))
+ #logger.info("attachlist:"+str(attachlist))
+
+ return self.send_message()
+
+
+ class _MailMessage:
+ """
+ Simplified email message
+ This class represent email headers and payload content, not envelope data
+ """
+
+ def __init__(self):
+ """
+ init object variables
+ """
+ self.mail_from = None
+ self.mail_to = []
+ self.mail_cc = []
+ self.mail_bcc = []
+ self.subject = ''
+ self.body = ''
+ self.attachments = []
+ self.headers = {}
+
+ def get_message_recipients(self):
+ '''
+ Get all message recipients (to, cc, bcc)
+ '''
+ recipients = []
+ tolist = ast.literal_eval(self.mail_to)
+ cclist = ast.literal_eval(self.mail_cc)
+ bcclist = ast.literal_eval(self.mail_bcc)
+ recipients.extend(tolist)
+ recipients.extend(cclist)
+ recipients.extend(bcclist)
+ #logger.info("recipientslist:"+str(recipients))
+ return recipients
+
+ def get_message_as_string(self):
+ '''
+ Get message as string to be sent with smtplib.sendmail api
+ '''
+ if len(self.attachments) > 0:
+ #logger.info("attachments:"+str(self.attachments))
+ #logger.info("attachmentstype:"+str(type(self.attachments)))
+ #logger.info("attachmentsnum:"+str(len(self.attachments)))
+
+ envelope = MIMEMultipart()
+ envelope.attach(MIMEText(self.body))
+ else:
+ envelope = MIMEText(self.body)
+
+ recipients = self.get_message_recipients()
+
+
+ tolist = ast.literal_eval(self.mail_to)
+ cclist = ast.literal_eval(self.mail_cc)
+ envelope['From'] = self.mail_from
+ envelope['To'] = COMMASPACE.join(tolist)
+ envelope['Cc'] = COMMASPACE.join(cclist)
+ envelope['Subject'] = self.subject
+ #logger.info("envelope111:"+str(self.attachments))
+ for attachment in list(self.attachments):
+ ctype, encoding = mimetypes.guess_type(attachment)
+ #logger.info("attachment:"+attachment+" ctype:"+str(ctype)+" encoding:"+str(encoding))
+ if ctype is None or encoding is not None:
+ # No guess could be made, or the file is encoded (compressed), so
+ # use a generic bag-of-bits type.
+ ctype = 'application/octet-stream'
+ maintype, subtype = ctype.split('/', 1)
+ #logger.info("maintype:"+str(maintype)+" subtype:"+str(subtype))
+
+ msg = None
+ if maintype == 'text':
+ attach_file = open(attachment,'rb')
+ # TODO: we should handle calculating the charset
+ msg = MIMEText(attach_file.read(), _subtype=subtype, _charset='utf-8')
+ attach_file.close()
+ elif maintype == 'image':
+ attach_file = open(attachment, 'rb')
+ msg = MIMEImage(attach_file.read(), _subtype=subtype)
+ attach_file.close()
+ elif maintype == 'audio':
+ attach_file = open(attachment, 'rb')
+ msg = MIMEAudio(attach_file.read(), _subtype=subtype)
+ attach_file.close()
+ else:
+ attach_file = open(attachment, 'rb')
+ msg = MIMEBase(maintype, subtype)
+ msg.set_payload(attach_file.read())
+ attach_file.close()
+ # Encode the payload using Base64
+ encoders.encode_base64(msg)
+
+ # Set the filename parameter
+ msg.add_header('Content-Disposition', 'attachment',
+ filename=os.path.basename(attachment))
+ envelope.attach(msg)
+
+
+ #logger.info("envelope.as_string:"+envelope.as_string())
+ return envelope.as_string()
diff --git a/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-36.pyc b/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000..15fa648
--- /dev/null
+++ b/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-36.pyc
Binary files differ
diff --git a/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-37.pyc b/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000..29c241c
--- /dev/null
+++ b/04-CustomLibrary/Smtp4Library/__pycache__/__init__.cpython-37.pyc
Binary files differ
diff --git a/04-CustomLibrary/Smtp4Library/__pycache__/version.cpython-37.pyc b/04-CustomLibrary/Smtp4Library/__pycache__/version.cpython-37.pyc
new file mode 100644
index 0000000..d83a4bb
--- /dev/null
+++ b/04-CustomLibrary/Smtp4Library/__pycache__/version.cpython-37.pyc
Binary files differ
diff --git a/04-CustomLibrary/Smtp4Library/version.py b/04-CustomLibrary/Smtp4Library/version.py
new file mode 100644
index 0000000..8f9fcb8
--- /dev/null
+++ b/04-CustomLibrary/Smtp4Library/version.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of robotframework-Smtp3Library.
+# https://github.io/lucamaro/robotframework-SmtpLibrary
+
+# Licensed under the Apache License 2.0 license:
+# http://www.opensource.org/licenses/Apache-2.0
+# Copyright (c) 2016, Luca Maragnani <[email protected]>
+
+__version__ = '0.1.3' # NOQA