From c2193e770b9401fe49e7b703ac83a17491b083b5 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 10 Jan 2014 15:44:47 -0300 Subject: Add script to send a mail batch --- .gitignore | 3 + src/lorem-ipsum-subjects.txt | 50 +++++++++++ src/options.cfg.demo | 11 +++ src/send-mail-batch.py | 209 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 src/lorem-ipsum-subjects.txt create mode 100644 src/options.cfg.demo create mode 100755 src/send-mail-batch.py 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 -- cgit v1.2.3 From ac1d5f8867f4a91b0fe29a9e64556c3e1ab02d86 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 10 Jan 2014 15:45:11 -0300 Subject: Add sample image download helper script. --- src/util/lorempixel-downloader.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 src/util/lorempixel-downloader.sh diff --git a/src/util/lorempixel-downloader.sh b/src/util/lorempixel-downloader.sh new file mode 100755 index 0000000..84b1a9a --- /dev/null +++ b/src/util/lorempixel-downloader.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# small script that allows you to download some random images from lorempixel + +download_images(){ + # args: + # $1: initial number + # $2: final number + # $3: image width + # $4: image height + for n in $(seq -w $1 $2); do wget http://lorempixel.com/$3/$4/ -O $n.jpg; done +} + +# download a set of images from 01..30 + +# 5 images 640x480 +download_images 01 05 640 480 + +# 5 images 1280x720 +download_images 05 10 1280 720 + +# 5 images 1920x1080 +download_images 10 15 1920 1080 -- cgit v1.2.3 From be826760c111a02a668608f835509e3f98712548 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 10 Jan 2014 15:45:24 -0300 Subject: Add some sample attachments. --- src/attachments/01.jpg | Bin 0 -> 30589 bytes src/attachments/02.jpg | Bin 0 -> 56982 bytes src/attachments/03.jpg | Bin 0 -> 42384 bytes src/attachments/04.jpg | Bin 0 -> 26305 bytes src/attachments/05.jpg | Bin 0 -> 115558 bytes src/attachments/06.jpg | Bin 0 -> 140168 bytes src/attachments/07.jpg | Bin 0 -> 169922 bytes src/attachments/08.jpg | Bin 0 -> 122585 bytes src/attachments/09.jpg | Bin 0 -> 99277 bytes src/attachments/10.jpg | Bin 0 -> 132332 bytes src/attachments/11.jpg | Bin 0 -> 322972 bytes src/attachments/12.jpg | Bin 0 -> 242888 bytes src/attachments/13.jpg | Bin 0 -> 224879 bytes src/attachments/14.jpg | Bin 0 -> 67893 bytes src/attachments/15.jpg | Bin 0 -> 224879 bytes src/attachments/Unicode_arrows.pdf | Bin 0 -> 127712 bytes src/attachments/bitmask.png | Bin 0 -> 15903 bytes src/attachments/gpl-3.0.odt | Bin 0 -> 33391 bytes 18 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/attachments/01.jpg create mode 100644 src/attachments/02.jpg create mode 100644 src/attachments/03.jpg create mode 100644 src/attachments/04.jpg create mode 100644 src/attachments/05.jpg create mode 100644 src/attachments/06.jpg create mode 100644 src/attachments/07.jpg create mode 100644 src/attachments/08.jpg create mode 100644 src/attachments/09.jpg create mode 100644 src/attachments/10.jpg create mode 100644 src/attachments/11.jpg create mode 100644 src/attachments/12.jpg create mode 100644 src/attachments/13.jpg create mode 100644 src/attachments/14.jpg create mode 100644 src/attachments/15.jpg create mode 100644 src/attachments/Unicode_arrows.pdf create mode 100644 src/attachments/bitmask.png create mode 100644 src/attachments/gpl-3.0.odt diff --git a/src/attachments/01.jpg b/src/attachments/01.jpg new file mode 100644 index 0000000..2a972e0 Binary files /dev/null and b/src/attachments/01.jpg differ diff --git a/src/attachments/02.jpg b/src/attachments/02.jpg new file mode 100644 index 0000000..5e77b6e Binary files /dev/null and b/src/attachments/02.jpg differ diff --git a/src/attachments/03.jpg b/src/attachments/03.jpg new file mode 100644 index 0000000..9bae1b1 Binary files /dev/null and b/src/attachments/03.jpg differ diff --git a/src/attachments/04.jpg b/src/attachments/04.jpg new file mode 100644 index 0000000..01e6060 Binary files /dev/null and b/src/attachments/04.jpg differ diff --git a/src/attachments/05.jpg b/src/attachments/05.jpg new file mode 100644 index 0000000..3266745 Binary files /dev/null and b/src/attachments/05.jpg differ diff --git a/src/attachments/06.jpg b/src/attachments/06.jpg new file mode 100644 index 0000000..7a8b41e Binary files /dev/null and b/src/attachments/06.jpg differ diff --git a/src/attachments/07.jpg b/src/attachments/07.jpg new file mode 100644 index 0000000..9059b41 Binary files /dev/null and b/src/attachments/07.jpg differ diff --git a/src/attachments/08.jpg b/src/attachments/08.jpg new file mode 100644 index 0000000..ffcf5ac Binary files /dev/null and b/src/attachments/08.jpg differ diff --git a/src/attachments/09.jpg b/src/attachments/09.jpg new file mode 100644 index 0000000..3aec7e1 Binary files /dev/null and b/src/attachments/09.jpg differ diff --git a/src/attachments/10.jpg b/src/attachments/10.jpg new file mode 100644 index 0000000..aad719f Binary files /dev/null and b/src/attachments/10.jpg differ diff --git a/src/attachments/11.jpg b/src/attachments/11.jpg new file mode 100644 index 0000000..dc39c0a Binary files /dev/null and b/src/attachments/11.jpg differ diff --git a/src/attachments/12.jpg b/src/attachments/12.jpg new file mode 100644 index 0000000..33928b9 Binary files /dev/null and b/src/attachments/12.jpg differ diff --git a/src/attachments/13.jpg b/src/attachments/13.jpg new file mode 100644 index 0000000..20ac820 Binary files /dev/null and b/src/attachments/13.jpg differ diff --git a/src/attachments/14.jpg b/src/attachments/14.jpg new file mode 100644 index 0000000..de38c90 Binary files /dev/null and b/src/attachments/14.jpg differ diff --git a/src/attachments/15.jpg b/src/attachments/15.jpg new file mode 100644 index 0000000..20ac820 Binary files /dev/null and b/src/attachments/15.jpg differ diff --git a/src/attachments/Unicode_arrows.pdf b/src/attachments/Unicode_arrows.pdf new file mode 100644 index 0000000..659ca70 Binary files /dev/null and b/src/attachments/Unicode_arrows.pdf differ diff --git a/src/attachments/bitmask.png b/src/attachments/bitmask.png new file mode 100644 index 0000000..6ff2dba Binary files /dev/null and b/src/attachments/bitmask.png differ diff --git a/src/attachments/gpl-3.0.odt b/src/attachments/gpl-3.0.odt new file mode 100644 index 0000000..5a9a6be Binary files /dev/null and b/src/attachments/gpl-3.0.odt differ -- cgit v1.2.3