It might be interesting to send the current working directory contents as a compressed ZIP archive. You can use this recipe to quickly share your files with your friends.
If you don't have any mail server installed on your machine, you need to install a local mail server such as postfix
. On a Debian/Ubuntu system, this can be installed with default settings using apt-get
, as shown in the following command:
$ sudo apt-get install postfix
Let us first compress the current directory and then create an e-mail message. We can send the e-mail message via an external SMTP host, or we can use a local e-mail server to do this. Like other recipes, let us get the sender and recipient information from parsing the command-line inputs.
Listing 5.3 shows how to convert an e-mail folder into a compressed ZIP file as follows:
#!/usr/bin/env python # Python Network Programming Cookbook -- Chapter - 5 # This program is optimized for Python 2.7. # It may run on any other version with/without modifications. import os import argparse import smtplib import zipfile import tempfile from email import encoders from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart def email_dir_zipped(sender, recipient): zf = tempfile.TemporaryFile(prefix='mail', suffix='.zip') zip = zipfile.ZipFile(zf, 'w') print "Zipping current dir: %s" %os.getcwd() for file_name in os.listdir(os.getcwd()): zip.write(file_name) zip.close() zf.seek(0) # Create the message print "Creating email message..." email_msg = MIMEMultipart() email_msg['Subject'] = 'File from path %s' %os.getcwd() email_msg['To'] = ', '.join(recipient) email_msg['From'] = sender email_msg.preamble = 'Testing email from Python. ' msg = MIMEBase('application', 'zip') msg.set_payload(zf.read()) encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.getcwd()[-1] + '.zip') email_msg.attach(msg) email_msg = email_msg.as_string() # send the message print "Sending email message..." smtp = None try: smtp = smtplib.SMTP('localhost') smtp.set_debuglevel(1) smtp.sendmail(sender, recipient, email_msg) except Exception, e: print "Error: %s" %str(e) finally: if smtp: smtp.close() if __name__ == '__main__': parser = argparse.ArgumentParser(description='Email Example') parser.add_argument('--sender', action="store", dest="sender", default='[email protected]') parser.add_argument('--recipient', action="store", dest="recipient") given_args = parser.parse_args() email_dir_zipped(given_args.sender, given_args.recipient)
Running this recipe shows the following output. The extra output is shown because we enabled the e-mail debug level.
$ python 5_3_email_current_dir_zipped.py --recipient=faruq@localhost Zipping current dir: /home/faruq/Dropbox/PacktPub/pynet-cookbook/pynetcookbook_code/chapter5 Creating email message... Sending email message... send: 'ehlo [127.0.0.1] ' reply: '250-debian6.debian2013.com ' reply: '250-PIPELINING ' reply: '250-SIZE 10240000 ' reply: '250-VRFY ' reply: '250-ETRN ' reply: '250-STARTTLS ' reply: '250-ENHANCEDSTATUSCODES ' reply: '250-8BITMIME ' reply: '250 DSN ' reply: retcode (250); Msg: debian6.debian2013.com PIPELINING SIZE 10240000 VRFY ETRN STARTTLS ENHANCEDSTATUSCODES 8BITMIME DSN send: 'mail FROM:<[email protected]> size=9141 ' reply: '250 2.1.0 Ok ' reply: retcode (250); Msg: 2.1.0 Ok send: 'rcpt TO:<faruq@localhost> ' reply: '250 2.1.5 Ok ' reply: retcode (250); Msg: 2.1.5 Ok send: 'data ' reply: '354 End data with <CR><LF>.<CR><LF> ' reply: retcode (354); Msg: End data with <CR><LF>.<CR><LF> data: (354, 'End data with <CR><LF>.<CR><LF>') send: 'Content-Type: multipart/mixed; boundary="===============0388489101==...[TRUNCATED] reply: '250 2.0.0 Ok: queued as 42D2F34A996 ' reply: retcode (250); Msg: 2.0.0 Ok: queued as 42D2F34A996 data: (250, '2.0.0 Ok: queued as 42D2F34A996')
We have used Python's zipfile
, smtplib
and an email
module to achieve our objective of e-mailing a folder as a zipped archive. This is done using the email_dir_zipped()
method. This method takes two arguments: the sender and recipient's e-mail addresses to create the e-mail message.
In order to create a ZIP archive, we create a temporary file with the tempfile
module's TemporaryFile()
class. We supply a filename prefix, mail
, and suffix, .zip
. Then, we initialize the ZIP archive object with the ZipFile()
class by passing the temporary file as its argument. Later, we add files of the current directory with the ZIP object's write()
method call.
To send an e-mail, we create a multipart MIME message with the MIMEmultipart()
class from the email.mime.multipart
module. Like our usual e-mail message, the subject, recipient, and sender information is added in the e-mail header.
We create the e-mail attachment with the MIMEBase()
method. Here, we first specify the application/ZIP header and call set_payload()
on this message object. Then, in order to encode the message correctly, the encode_base64()
method from encoder's module is used. It is also helpful to use the add_header()
method to construct the attachment header. Now, our attachment is ready to be included in the main e-mail message with an attach()
method call.
Sending an e-mail requires you to call the SMTP()
class instance of smtplib
. There is a sendmail()
method that will utilize the routine provided by the OS to actually send the e-mail message correctly. Its details are hidden under the hood. However, you can see a detailed interaction by enabling the debug option as shown in this recipe.
18.218.3.204