E-mail Automation using Python (Part - 1)

No comments
In this post I'll be covering sending and scheduling email sending using Python script:


Checking and replying to emails is a huge time sink. We cannot simply write a program to handle all our email cause obviously each message requires its own response.

For example you  have a list of people that you want to send say a standard birthday invitation to (with of course different name on each mail) depending on various parameters like their age, location etc. Typing and sending to each one of them would take a lot of time and patience. Fortunately we can automate this task by writing a simple python script.

Much like HTTP is the protocol used by computers to send web pages across the internet, Simple Mail Transfer Protocol (SMTP) is the protocol used for sending email. SMTP dictates how email messages should be formatted, encrypted, and relayed between mail servers, and all the other details that your computer handles after you click send. All these technical details are simplified into a few functions by Python’s smtplib module.

# coding: utf-8

import time,datetime

print "\nEnter time you want to send mail:\n\t1. Now\n\t2. Morning (8:00 AM)\n\t3. Afternoon (1:00 PM)\n\t4. Evening (6:00 PM)\n\t5. Night (9:00 PM)\n\t6. Customise\n"
choice = raw_input(":")

present_time = datetime.datetime.now()
send_time = datetime.datetime.now()

def now():
 global present_time
 print "Time now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')
 send_time = present_time

def morning():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 8, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 8, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def afternoon():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 13, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 13, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def evening():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 18, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 18, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def night():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 21, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 21, 0,0)
 print "Time at which mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def custom():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')
 
 print "\nCustomise Time(24hr format): "
 hr = int(raw_input("Enter hour: "))
 mn = int(raw_input("Enter minutes: "))
 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, hr, mn,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, hr, mn,0)
 print "\nMail will be sent at: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

options = {
 '1':now,
 '2':morning,
 '3':afternoon,
 '4':evening,
 '5':night,
 '6':custom,
  }
    
options[choice]()

print "\nEnter mail details: ...(loading)"

import smtplib, time, getpass
smtpobj = smtplib.SMTP('smtp.gmail.com', 587)

if type(smtpobj.ehlo()[0]) == int:
 print "\nConnection established to Gmail"
#else:
# break
  
if type(smtpobj.starttls()[0]) == int:
 print "Encryption enabled"
#else:
# break

time.sleep(1)
mailid = raw_input("\nEnter your mail id: ")
pswd = getpass.getpass("Enter your password: ")

if smtpobj.login(mailid, pswd)[0] == int:
 print id + ' authenticated successfully.'

receiver_addr = raw_input("\nEnter receiver's address: ")
sub_of_mail = raw_input("Enter subject: ")
body_of_mail = raw_input("Enter body: ")

print "\nMail will be sent on ",
print send_time.strftime('%I:%M:%S %p') + ' on',
print send_time.strftime(' %A %d %b %Y')

#........Time to sleep..........#
for i in range(int(round((send_time - present_time).total_seconds()))):
 time.sleep(1)

#........Sleep over.............#
smtpobj.sendmail(mailid, receiver_addr, 'Subject:' + sub_of_mail + '\n' + body_of_mail)
print "Sending"

for i in range(5):
 print '.',
 time.sleep(1)
time.sleep(1)
print "Sent!"
smtpobj.quit()

Email providers and their SMTP servers
Gmail                            smtp.gmail.com
Outlook.com/Hotmail.com       smtp-mail.outlook.com
Yahoo mail                       smtp.mail.yahoo.com
AT&T                             smpt.mail.att.net  (port 465)
Comcast                          smtp.comcast.net
Verizon                          smtp.verizon.net   (port 465)

In the 3rd and 105th line, all necessary libraries are imported. 5th line is the menu that will ask the user when he/she wants to send mail. For convenience "morning", "afternoon", "evening" and "night" options are given. From line 11 to 90 all the menus are defined. The datetime library is used along with necessary parameters to format and displayed time and date. Line 1 to 101 is the scheduling mail part which is followed by sending mail using SMTP.

On line 106 SMTP object is created and gmail SMTP server is passed with out port 587. Out port is 587 for all except for AT&T and Verizon which is 465 as mentioned. On line 120 .ehlo() is like sending a "hello" message to gmail and if reply is positive (i.e an interger) then we may proceed. On line 113 .starttls() is used to start encryption for safety issues.

On line 120 getpass is a very nice function. It is used to accept passwords in script in hidden mode i.e your password will not be visible when you are typing it in while running the script. Line 124 - 126 asks you the details about the mail: mail id of receiver, subject of mail and body of mail.

On line 133, we calculate time difference between the: time that user decided to send the mail and present time. This is done so that we can make the script sleep for that time and send it after that. On line 145 SMTP sever is quit by passing the .quit() function.

Web Scraping In Python

No comments

Web scraping (web harvesting or web data extraction) is a computer software technique of extracting information from websites.
There are several modules that make it easy to scrape web pages in Python.
  • Webbrowser: It comes with Python and opens a browser to a specific page.
  • Requests: Downloads files and web pages from the Internet.
  • Beautiful Soup: To parses HTML, the format that web pages are written in.
  • Selenium: It can launch and control a web browser. It is able to fill in forms and simulate mouse clicks in browser and other interesting stuff. 
This is Beautiful Soup official website and this is  Selenium python docs.

I wrote a small script for a friend of mine last month. His team is into making small planes. They collect their data(like battery type, motor manufacturer, propeller type etc.) for their models from this german website. 
So on the site there are about 60 battery types, 172 controller types, 22 propeller types, many different motor manufacturers and each manufacturer has different motor types. All this data appears in form of drop down menu. His objective is to get maximum thrust for input power <= 1000W. 
Now it is not humanly possible to try every possible combination to get the desired result. Here comes the role of web scraping: extracting and manipulating content of a website to obtain desired result.
My web scraping code repository on git.

Extension Modules in Python

No comments

Python is on the order of between 10 and 100 times slower than C, C++, FORTRAN when doing any serious number crunching.

There are many reasons for this:

  • Python is interpreted
  • Python has no primitives, everything including the builtin types are objects
  • Python list can hold objects of different type, so each entry has to store additional data about its type.

But these are no reason to ignore Python though. A lot of software doesn't require much time or memory even with the 100 time slowness factor. Development cost is where Python wins with the simple and concise style. This improvement on development cost often outweighs the cost of additional cpu and memory resources.

It is quite easy to add new built-in modules to Python, if you know how to program in C. Such extension modules can do two things that cant be done directly in python:

  • They can implement new built-in object types
  • They can call C library functions and system calls
  • This improves python's computational speed many folds.
My extension modules code repository on git.

Linux

No comments