-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathKindlenote.py
executable file
·220 lines (166 loc) · 6.6 KB
/
Kindlenote.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/python
from getpass import getpass
import optparse
import os
import smtplib
from socket import error as sockError
import sys
### Parse command-line options
parser = optparse.OptionParser(usage='Usage: %prog [options] <files>')
parser.add_option('-c', '--convert', help='add convert tag to the subject line',
dest='convert', default=False, action='store_true')
parser.add_option('-D', '--debug', help='Turn on debugging output', dest='DEBUG', default=False, action='store_true')
parser.add_option('-e', '--extension', help='''Select a default extension to apply to unrecognized file formats
Recognized file formats are .doc, .rtf, .htm, .html, .txt, .zip, .mobi, .docx, .pdf''', dest='extension')
if not sys.argv[1:]: # No arguments provided.
parser.print_help()
sys.exit(2)
(opts, files) = parser.parse_args()
if not opts.extension:
ext = ".txt"
if opts.DEBUG: print "No format option given. Using",ext
else:
if opts.extension[0] != '.':
opts.extension = "." + opts.extension
ext = opts.extension
if opts.DEBUG: print "Format option given. Using extension",ext
if not files: # No filenames provided.
print "You must provide at least one file to send."
sys.exit(2)
##Continue with imports
try:
import config
except ImportError:
print """config.py not found.
Your config file, config.py, needs to be filled in. Take config_sample.py and copy it to config.py, fill in your smtp details, and fire away."""
sys.exit(1)
##Attachment imports##
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
################################################
################################################
##Config File Check##
def checkConfig():
if not (config.smtpServer and config.smtpPort and config.userName and
config.to_addr and config.from_addr and config.maxAttachments):
#Make sure the required items are there.
print "There was a problem with your config. One or more of the required values are not set."
print "Please correct your config.py file and try again"
sys.exit(1) # Exits the program since the config file is not right.
else:
print "Config file has data in the required fields"
################################################
##Function Declarations##
def sendMail(from_addr, to_addr, mesg, smtpObject,attach=[], convertFlag = False):
if opts.DEBUG: print "Entering sendMail()"
msg = MIMEMultipart()
msg['From'] = from_addr
msg['To'] = to_addr
msg['Date'] = formatdate(localtime=True)
subject = "Item from Kindlenote"
if convertFlag:
if opts.DEBUG:
print "Adding convert!"
subject += " - Convert"
msg['Subject'] = subject
if opts.DEBUG: print "Done setting headers"
msg.attach(MIMEText("Thanks for using Kindlenote"))
for files in attach:
if opts.DEBUG: print "Beginning attach of file", files
part = MIMEBase('application', "octet-stream")
part.set_payload( open (files,"rb").read())
#Fix the attachment name.
files = os.path.basename(files)
#Rename the file in the attachment to .txt
#We have to do this after we open it, it's just the name in python that we add to the header.
#Amazon only allows certain extensions to the kindle.
##Microsoft Word (.doc)
##Rich Text Format (.rtf)
##HTML (.htm, .html)
##Text (.txt) documents
##Archived documents (zip , x-zip) and compressed archived documents
##Mobi book
##Docx
##PDF
#Those are the formats that are allowed. Currently the function removes the extension altogether.
allowedExtensions=[".doc",".rtf",".htm",".html",".txt",".zip",".mobi",".docx",".pdf"]
dot_idx = files.rfind(".") # Check for an extension.
if files[dot_idx:] not in allowedExtensions:
if opts.DEBUG: print "Extension",files[dot_idx:],"not recognized. Setting to", ext
if dot_idx >= 0:
# Remove everything from the end until (and including) the last dot
files = files[:dot_idx]
files += ext
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="'+files+'"')
msg.attach(part)
if opts.DEBUG: print "Done attaching file", files
if opts.DEBUG: print "Beginning the send"
try:
smtpObject.sendmail(from_addr, to_addr, msg.as_string())
except smtplib.SMTPException:
print "There was a problem sending your message"
else:
print "Message sent successfully"
def smtpLogin(userName, passWord, smtpObject):
if passWord == '':
#The password wasn't set in the config file. We need to prompt the user for it.
passWord = getpass()
try:
smtpObject.login(userName, passWord)
del(userName) # Can't be too careful.
del(passWord)
except smtplib.SMTPAuthenticationError:
print "There was an error during authentication. Check your credentials in config.py"
sys.exit(1)
else:
if opts.DEBUG:
print "Authentication with "+config.smtpServer+" successful."
def checkArgs (arguments): # Checks files that are specified at command line exist. Adds all command line items to a stack so it only has to loop once.
filesToSend = []
for arg in arguments:
if os.access(arg, os.R_OK):
if arg not in filesToSend:
filesToSend.append(arg)
else:
print "Duplicate file:", arg
else:
print "File", arg, "doesn't exist. Skipping."
#filesDontExist = True #Removing since we don't need to exit, just say that we're skipping that file.
if len(filesToSend) == 0:
print "Exiting since no files listed" # Shouldn't happen, but just in case.
sys.exit(1) # Exiting due to a parameter's files not existing.
return filesToSend
################################################
##PROGRAM STARTS HERE##
################################################
checkConfig()
#Try to connect to our server.
try:
if config.smtpSSL:
server = smtplib.SMTP_SSL(config.smtpServer, config.smtpPort)
else:
server = smtplib.SMTP(config.smtpServer, config.smtpPort)
server.ehlo_or_helo_if_needed()
except sockError as e:
print e
sys.exit(1)
except (smtplib.SMTPException,smtplib.SMTPConnectError):
print "There was a problem connecting"
sys.exit(1)
else:
if opts.DEBUG:
print "Connection to " + config.smtpServer + " successful"
smtpLogin(config.userName, config.passWord, server)
# Filter out invalid files.
fileList = checkArgs (files)
# Split all the files into batches of config.maxAttachments files.
batchStarts = xrange(0, len(fileList), config.maxAttachments)
batches = [fileList[x:x+config.maxAttachments] for x in batchStarts]
for batch in batches:
if opts.DEBUG: print "Sending batch."
sendMail(config.from_addr,config.to_addr,'This is a test message',server, batch, opts.convert)
if opts.DEBUG: print "Done sending batch."