Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | #!/usr/bin/env python |
2 | ||
3 | """Send the contents of a directory as a MIME message. | |
4 | ||
5 | Usage: dirmail [options] from to [to ...]* | |
6 | ||
7 | Options: | |
8 | -h / --help | |
9 | Print this message and exit. | |
10 | ||
11 | -d directory | |
12 | --directory=directory | |
13 | Mail the contents of the specified directory, otherwise use the | |
14 | current directory. Only the regular files in the directory are sent, | |
15 | and we don't recurse to subdirectories. | |
16 | ||
17 | `from' is the email address of the sender of the message. | |
18 | ||
19 | `to' is the email address of the recipient of the message, and multiple | |
20 | recipients may be given. | |
21 | ||
22 | The email is sent by forwarding to your local SMTP server, which then does the | |
23 | normal delivery process. Your local machine must be running an SMTP server. | |
24 | """ | |
25 | ||
26 | import sys | |
27 | import os | |
28 | import getopt | |
29 | import smtplib | |
30 | # For guessing MIME type based on file name extension | |
31 | import mimetypes | |
32 | ||
33 | from email import Encoders | |
34 | from email.Message import Message | |
35 | from email.MIMEAudio import MIMEAudio | |
36 | from email.MIMEBase import MIMEBase | |
37 | from email.MIMEMultipart import MIMEMultipart | |
38 | from email.MIMEImage import MIMEImage | |
39 | from email.MIMEText import MIMEText | |
40 | ||
41 | COMMASPACE = ', ' | |
42 | ||
43 | ||
44 | def usage(code, msg=''): | |
45 | print >> sys.stderr, __doc__ | |
46 | if msg: | |
47 | print >> sys.stderr, msg | |
48 | sys.exit(code) | |
49 | ||
50 | ||
51 | def main(): | |
52 | try: | |
53 | opts, args = getopt.getopt(sys.argv[1:], 'hd:', ['help', 'directory=']) | |
54 | except getopt.error, msg: | |
55 | usage(1, msg) | |
56 | ||
57 | dir = os.curdir | |
58 | for opt, arg in opts: | |
59 | if opt in ('-h', '--help'): | |
60 | usage(0) | |
61 | elif opt in ('-d', '--directory'): | |
62 | dir = arg | |
63 | ||
64 | if len(args) < 2: | |
65 | usage(1) | |
66 | ||
67 | sender = args[0] | |
68 | recips = args[1:] | |
69 | ||
70 | # Create the enclosing (outer) message | |
71 | outer = MIMEMultipart() | |
72 | outer['Subject'] = 'Contents of directory %s' % os.path.abspath(dir) | |
73 | outer['To'] = COMMASPACE.join(recips) | |
74 | outer['From'] = sender | |
75 | outer.preamble = 'You will not see this in a MIME-aware mail reader.\n' | |
76 | # To guarantee the message ends with a newline | |
77 | outer.epilogue = '' | |
78 | ||
79 | for filename in os.listdir(dir): | |
80 | path = os.path.join(dir, filename) | |
81 | if not os.path.isfile(path): | |
82 | continue | |
83 | # Guess the content type based on the file's extension. Encoding | |
84 | # will be ignored, although we should check for simple things like | |
85 | # gzip'd or compressed files. | |
86 | ctype, encoding = mimetypes.guess_type(path) | |
87 | if ctype is None or encoding is not None: | |
88 | # No guess could be made, or the file is encoded (compressed), so | |
89 | # use a generic bag-of-bits type. | |
90 | ctype = 'application/octet-stream' | |
91 | maintype, subtype = ctype.split('/', 1) | |
92 | if maintype == 'text': | |
93 | fp = open(path) | |
94 | # Note: we should handle calculating the charset | |
95 | msg = MIMEText(fp.read(), _subtype=subtype) | |
96 | fp.close() | |
97 | elif maintype == 'image': | |
98 | fp = open(path, 'rb') | |
99 | msg = MIMEImage(fp.read(), _subtype=subtype) | |
100 | fp.close() | |
101 | elif maintype == 'audio': | |
102 | fp = open(path, 'rb') | |
103 | msg = MIMEAudio(fp.read(), _subtype=subtype) | |
104 | fp.close() | |
105 | else: | |
106 | fp = open(path, 'rb') | |
107 | msg = MIMEBase(maintype, subtype) | |
108 | msg.set_payload(fp.read()) | |
109 | fp.close() | |
110 | # Encode the payload using Base64 | |
111 | Encoders.encode_base64(msg) | |
112 | # Set the filename parameter | |
113 | msg.add_header('Content-Disposition', 'attachment', filename=filename) | |
114 | outer.attach(msg) | |
115 | ||
116 | # Now send the message | |
117 | s = smtplib.SMTP() | |
118 | s.connect() | |
119 | s.sendmail(sender, recips, outer.as_string()) | |
120 | s.close() | |
121 | ||
122 | ||
123 | if __name__ == '__main__': | |
124 | main() |