summaryrefslogtreecommitdiff
path: root/src/send-mail-batch.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/send-mail-batch.py')
-rwxr-xr-xsrc/send-mail-batch.py209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/send-mail-batch.py b/src/send-mail-batch.py
new file mode 100755
index 0000000..fceea74
--- /dev/null
+++ b/src/send-mail-batch.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# import getpass
+import mimetypes
+import os
+import sys
+import random
+import smtplib
+import time
+
+from ConfigParser import SafeConfigParser
+
+from email import encoders
+from email.mime.base import MIMEBase
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+
+class GMail(object):
+ """Email sender using the gmail service."""
+ SMTPSERVER = 'smtp.gmail.com:587'
+
+ def __init__(self, account, password):
+ """
+ Initializes the class.
+ You should provide credentials in order to login into gmail.
+
+ :param account: the username@gmail.com account to use for sending.
+ :type account: str
+ :param password: the password for the account.
+ :type password: str
+ """
+ self._from = account
+ login = account.split('@')[0]
+ self._server = smtplib.SMTP(self.SMTPSERVER)
+ self._server.starttls()
+ self._server.login(login, password)
+
+ def __del__(self):
+ """
+ Quits the server.
+ """
+ self._server.quit()
+
+ def _get_attachment(self, file_path):
+ """
+ Creates the MIMEBase attachment for the file 'file_path'.
+
+ Might raise:
+ IOError
+
+ :param file_path: the file from to generate the attachment from.
+ :type file_path: str
+
+ :return: the MIMEBase attachment.
+ :rtype: MIMEBase
+ """
+ ctype, encoding = mimetypes.guess_type(file_path)
+ 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)
+
+ # Read the file, this may rise IOError
+ with open(file_path, 'rb') as fp:
+ the_file = MIMEBase(maintype, subtype)
+ the_file.set_payload(fp.read())
+
+ # Encode the payload using Base64
+ encoders.encode_base64(the_file)
+
+ # Set the filename parameter
+ the_file.add_header('Content-Disposition', 'attachment',
+ filename=os.path.basename(file_path))
+
+ return the_file
+
+ def send_email(self, to_addr_list, cc_addr_list, subject,
+ message, attachments=None):
+ """
+ Sends an email.
+
+ :param to_addr_list: a list of addresses to send the email.
+ :type to_addr_list: list of str
+ :param cc_addr_list: a list of addresses to send (as CC) the email.
+ :type cc_addr_list: list of str
+ :param subject: the subject of the email
+ :type subject: str
+ :param message: the message to send
+ :type message: str
+ :param attachments: a list of paths for the files to attach.
+ :type attachments: list of str
+
+ :return: an empty dict if everything went ok or
+ the problems result of sending the email(s).
+ :rtype: dict
+ """
+ # Create the container (outer) email message.
+ msg = MIMEMultipart()
+ msg['Subject'] = subject
+ msg['From'] = self._from
+ msg['To'] = ', '.join(to_addr_list)
+
+ if cc_addr_list:
+ msg['Cc'] = ', '.join(cc_addr_list)
+
+ # Add the message's text
+ msg.attach(MIMEText(message))
+
+ problems = ''
+ if attachments is not None:
+ # Attach every file in the attachment parameter
+ for file_path in attachments:
+ try:
+ the_file = self._get_attachment(file_path)
+ msg.attach(the_file)
+ except IOError:
+ problems += "Could not attach {0!r}\n".format(file_path)
+
+ message = msg.as_string()
+ try:
+ result = self._server.sendmail(self._from, to_addr_list, message)
+ except Exception as e:
+ result['Exception'] = repr(e)
+
+ if problems:
+ result['Attachments'] = problems
+
+ return result
+
+
+def send_test_mail(subject):
+ # make a list of attachments, add all the files in 'directory'
+ directory = './attachments/'
+ file_list = []
+
+ # randomize the use of attachments
+ if random.choice([True, False]):
+ for filename in os.listdir(directory):
+ path = os.path.join(directory, filename)
+ if os.path.isfile(path):
+ file_list.append(path)
+
+ # randomize attachments
+ ammount = random.randint(0, len(file_list)-1)
+ random.shuffle(file_list)
+ file_list = file_list[0:ammount]
+
+ msg = ('Howdy from python!\n'
+ 'The subject: {0}\n'
+ "Current date & time: {1}\n"
+ "Trying to attach: {2!r}"
+ ).format(subject, time.strftime("%c"), file_list)
+
+ return gmail.send_email(
+ to_addr_list=TO, cc_addr_list=[],
+ subject=subject, message=msg, attachments=file_list)
+
+# Read subjects from file
+lorem_subjects = []
+lorem_file = './lorem-ipsum-subjects.txt'
+with open(lorem_file) as lorem:
+ lorem_subjects = [line.strip() for line in lorem]
+
+
+# Mail account to send from:
+# use this if you want to enter manually your password:
+# FROM = 'your.username@gmail.com'
+# SECRET = getpass.getpass("Password for {0}: ".format(FROM))
+
+# MAX_MAILS = 10
+# TO = ['test_account@dev.bitmask.net']
+
+# Read credentials from options file
+parser = SafeConfigParser()
+parser.read('options.cfg')
+try:
+ FROM = parser.get('Credentials', 'account')
+ SECRET = parser.get('Credentials', 'password')
+ TO = [parser.get('Configs', 'to')]
+ MAX_MAILS = parser.getint('Configs', 'mails_amount')
+except Exception as e:
+ print "Problem reading options.cfg"
+ print "Exception: {0!r}".format(e)
+ sys.exit()
+
+
+# create the GMail global object
+gmail = GMail(FROM, SECRET)
+
+print "Sending {0} mails batch...".format(MAX_MAILS)
+
+count = 1
+while count <= MAX_MAILS:
+ idx = (count % len(lorem_subjects))
+ subject = "[TEST] {0:03} - {1}".format(count, lorem_subjects[idx])
+ print "Sending '{0}' ... ".format(subject),
+ try:
+ problems = send_test_mail(subject)
+ except Exception as e:
+ problems = repr(e)
+
+ if problems:
+ print "Problems: {0!r}".format(problems)
+ else:
+ print 'ok.'
+
+ count += 1