mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| """Send the contents of a directory as a MIME message."""
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import smtplib
 | |
| # For guessing MIME type based on file name extension
 | |
| import mimetypes
 | |
| 
 | |
| from optparse import OptionParser
 | |
| 
 | |
| from email import encoders
 | |
| from email.message import Message
 | |
| from email.mime.audio import MIMEAudio
 | |
| from email.mime.base import MIMEBase
 | |
| from email.mime.image import MIMEImage
 | |
| from email.mime.multipart import MIMEMultipart
 | |
| from email.mime.text import MIMEText
 | |
| 
 | |
| COMMASPACE = ', '
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     parser = OptionParser(usage="""\
 | |
| Send the contents of a directory as a MIME message.
 | |
| 
 | |
| Usage: %prog [options]
 | |
| 
 | |
| Unless the -o option is given, the email is sent by forwarding to your local
 | |
| SMTP server, which then does the normal delivery process.  Your local machine
 | |
| must be running an SMTP server.
 | |
| """)
 | |
|     parser.add_option('-d', '--directory',
 | |
|                       type='string', action='store',
 | |
|                       help="""Mail the contents of the specified directory,
 | |
|                       otherwise use the current directory.  Only the regular
 | |
|                       files in the directory are sent, and we don't recurse to
 | |
|                       subdirectories.""")
 | |
|     parser.add_option('-o', '--output',
 | |
|                       type='string', action='store', metavar='FILE',
 | |
|                       help="""Print the composed message to FILE instead of
 | |
|                       sending the message to the SMTP server.""")
 | |
|     parser.add_option('-s', '--sender',
 | |
|                       type='string', action='store', metavar='SENDER',
 | |
|                       help='The value of the From: header (required)')
 | |
|     parser.add_option('-r', '--recipient',
 | |
|                       type='string', action='append', metavar='RECIPIENT',
 | |
|                       default=[], dest='recipients',
 | |
|                       help='A To: header value (at least one required)')
 | |
|     opts, args = parser.parse_args()
 | |
|     if not opts.sender or not opts.recipients:
 | |
|         parser.print_help()
 | |
|         sys.exit(1)
 | |
|     directory = opts.directory
 | |
|     if not directory:
 | |
|         directory = '.'
 | |
|     # Create the enclosing (outer) message
 | |
|     outer = MIMEMultipart()
 | |
|     outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
 | |
|     outer['To'] = COMMASPACE.join(opts.recipients)
 | |
|     outer['From'] = opts.sender
 | |
|     outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
 | |
| 
 | |
|     for filename in os.listdir(directory):
 | |
|         path = os.path.join(directory, filename)
 | |
|         if not os.path.isfile(path):
 | |
|             continue
 | |
|         # Guess the content type based on the file's extension.  Encoding
 | |
|         # will be ignored, although we should check for simple things like
 | |
|         # gzip'd or compressed files.
 | |
|         ctype, encoding = mimetypes.guess_type(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)
 | |
|         if maintype == 'text':
 | |
|             fp = open(path)
 | |
|             # Note: we should handle calculating the charset
 | |
|             msg = MIMEText(fp.read(), _subtype=subtype)
 | |
|             fp.close()
 | |
|         elif maintype == 'image':
 | |
|             fp = open(path, 'rb')
 | |
|             msg = MIMEImage(fp.read(), _subtype=subtype)
 | |
|             fp.close()
 | |
|         elif maintype == 'audio':
 | |
|             fp = open(path, 'rb')
 | |
|             msg = MIMEAudio(fp.read(), _subtype=subtype)
 | |
|             fp.close()
 | |
|         else:
 | |
|             fp = open(path, 'rb')
 | |
|             msg = MIMEBase(maintype, subtype)
 | |
|             msg.set_payload(fp.read())
 | |
|             fp.close()
 | |
|             # Encode the payload using Base64
 | |
|             encoders.encode_base64(msg)
 | |
|         # Set the filename parameter
 | |
|         msg.add_header('Content-Disposition', 'attachment', filename=filename)
 | |
|         outer.attach(msg)
 | |
|     # Now send or store the message
 | |
|     composed = outer.as_string()
 | |
|     if opts.output:
 | |
|         fp = open(opts.output, 'w')
 | |
|         fp.write(composed)
 | |
|         fp.close()
 | |
|     else:
 | |
|         s = smtplib.SMTP('localhost')
 | |
|         s.sendmail(opts.sender, opts.recipients, composed)
 | |
|         s.quit()
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 | 
