summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Alejandro <ivanalejandro0@gmail.com>2014-01-10 15:44:47 -0300
committerIvan Alejandro <ivanalejandro0@gmail.com>2014-01-13 16:18:11 -0300
commitc2193e770b9401fe49e7b703ac83a17491b083b5 (patch)
treec4889f2ee35e92a548bbb62c9f1a46d7a0fafe68
parent4b7784a53b3aeb30a6cd3c9bc573afbe47504081 (diff)
Add script to send a mail batch
-rw-r--r--.gitignore3
-rw-r--r--src/lorem-ipsum-subjects.txt50
-rw-r--r--src/options.cfg.demo11
-rwxr-xr-xsrc/send-mail-batch.py209
4 files changed, 273 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index ded6067..fc5764f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,6 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject
+
+# Ignore file containing sensitive data
+options.cfg
diff --git a/src/lorem-ipsum-subjects.txt b/src/lorem-ipsum-subjects.txt
new file mode 100644
index 0000000..5d98233
--- /dev/null
+++ b/src/lorem-ipsum-subjects.txt
@@ -0,0 +1,50 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit
+Ullamcorper Maecenas orci duis malesuada
+Condimentum imperdiet quam nascetur vestibulum
+Venenatis elit fusce platea facilisi
+Et Cubilia phasellus pharetra dictum
+Vivamus ultricies viverra habitasse faucibus
+Eleifend eros Et ac urna
+Dui mauris senectus lorem malesuada
+Metus sed Lorem fames nullam
+Parturient conubia tempor suscipit netus
+Inceptos cum lorem risus congue
+Dui tempor ultrices nisl lectus
+Justo ullamcorper risus gravida sit
+Velit primis Quis est sagittis
+Eros dignissim litora id suscipit
+Senectus Eros aptent mollis cubilia
+Vitae ultricies Habitasse purus praesent
+Magnis mauris vitae facilisi dictum
+Condimentum velit gravida a nullam
+Non at magna consectetur congue
+Dolor id ipsum duis vehicula
+Taciti cum augue dictumst morbi
+Habitant magnis vitae amet porta
+Libero turpis fusce eros ut
+Non eu lorem commodo duis
+Parturient proin Mattis placerat congue
+Magnis elementum iaculis litora cras
+Scelerisque felis nostra pellentesque nisi
+Parturient conubia himenaeos varius ultrices
+Rutrum cursus Nostra dictumst aliquam
+Quam blandit pharetra cras purus
+Arcu viverra Amet magna pharetra
+Felis aenean lobortis ridiculus molestie
+Venenatis scelerisque accumsan varius vehicula
+Inceptos dui proin gravida diam
+Per euismod in facilisis id
+Turpis feugiat lacus viverra aliquam
+Metus rutrum Lobortis interdum sem
+Dolor dui primis interdum suscipit
+Adipiscing lacinia mollis phasellus fames
+Habitant laoreet faucibus suspendisse hendrerit
+Parturient lacus phasellus suscipit mus
+Justo iaculis Bibendum ridiculus mattis
+Hac justo Habitant nec diam
+Eu enim conubia proin leo
+Metus scelerisque nec magna pulvinar
+Dolor felis porta cubilia mus
+Felis vitae vulputate adipiscing tincidunt
+Dis odio vivamus erat torquent
+Habitant arcu vivamus vehicula sit
diff --git a/src/options.cfg.demo b/src/options.cfg.demo
new file mode 100644
index 0000000..8f2c5ba
--- /dev/null
+++ b/src/options.cfg.demo
@@ -0,0 +1,11 @@
+# You need to copy this file to 'options.cfg' and update it
+# using your preferences.
+# 'options.cfg' is ignored by git.
+
+[Credentials]
+account = your.test.account@gmail.com
+password = password placeholder
+
+[Configs]
+mails_amount = 10
+to = test_account@bitmask.net
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