自动备份文件到gmail的python脚本
2009年4月23日 23:47
#!/usr/bin/env python
#-*- coding: UTF-8 -*-
import sys, os, smtplib, socket, email
from getpass import getpass
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Utils, Encoders
import mimetypes
kilobytes = 1024
megabytes = kilobytes * 1024
#chunksize = int(1 * kilobytes)
chunksize = int(24 * megabytes) # 24M
server = 'smtp.gmail.com'
fromaddr = 'youraccout@gmail.com'
toaddrs = 'youranotheraccout@gmail.com'
def genpart(data, contenttype):
maintype, subtype = contenttype.split('/')
if maintype == 'text':
retval = MIMEText(data, _subtype=subtype)
else:
retval = MIMEBase(maintype, subtype)
retval.set_payload(data)
Encoders.encode_base64(retval)
return retval
def attachment(filename):
fd = open(filename, 'rb')
mimetype, mimeencoding = mimetypes.guess_type(filename)
if mimeencoding or (mimetype is None):
mimetype = 'application/octet-stream'
retval = genpart(fd.read(), mimetype)
retval.add_header('Content-Disposition', 'attachment',
filename = filename)
fd.close()
return retval
def split(fromfile, todir, chunksize=chunksize):
if not os.path.exists(todir): # caller handles errors
os.mkdir(todir) # make dir, read/write parts
else:
for fname in os.listdir(todir): # delete any existing files
os.remove(os.path.join(todir, fname))
#try:
#os.mkdir(todir) # make dir, read/write parts
#except:
#print "mkdir %s error" % todir
#raise SystemExit
partnum = 0
input = open(fromfile, 'rb') # use binary mode on Windows
while 1: # eof=empty string from read
chunk = input.read(chunksize) # get next part <= chunksize
if not chunk: break
partnum = partnum+1
filename = os.path.join(todir, ('part%04d' % partnum))
fileobj = open(filename, 'wb')
fileobj.write(chunk)
fileobj.close() # or simply open().write()
input.close()
assert partnum <= 9999 # join sort fails if 5 digits
return partnum
def process_file(filename):
try:
dirname, ext = filename.split(".", 1)
except:
print "filename = %s" % filename
split(filename, dirname, chunksize)
absdir = os.path.join(os.path.abspath('.'), dirname)
return os.path.basename(filename), absdir
def send(gmail, subject, file):
msg = MIMEMultipart()
msg['To'] = '%s' % toaddrs
msg['From'] = '%s' % fromaddr
msg['Subject'] = '%s' % subject
msg['Date'] = Utils.formatdate(localtime = 1)
msg['Message-ID'] = Utils.make_msgid()
msg.attach(attachment(file))
message = str(msg)
try:
gmail.sendmail(fromaddr, toaddrs, message)
except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
print "%s may not have been sent!" % subject
print e
sys.exit(1)
else:
print "%s successfully sent " % subject
def walkdir(source, gmail):
if os.path.isfile(source):
size = os.stat(source)[6]
if size > chunksize:
filename, absdir = process_file(source)
print filename, absdir
for fname in os.listdir(absdir):
subject = filename+ '-' + fname
file = os.path.join(os.path.abspath(absdir), fname)
print subject, file
send(gmail, subject, file)
else:
print source
send(gmail, os.path.basename(source), source)
elif os.path.isdir(source):
for fname in os.listdir(source):
walkdir(os.path.join(source, fname), gmail)
if __name__ == '__main__':
source = sys.argv[1]
sys.stdout.write("username: %s\n" % fromaddr)
username = fromaddr
password = getpass("Enter password: ")
s = smtplib.SMTP(server)
code = s.ehlo()[0]
usesesmtp = 1
if not (200 <= code <= 299):
usesesmtp = 0
code = s.helo()[0]
if not (200 <= code <= 299):
raise SMTPHeloError(code, resp)
if usesesmtp and s.has_extn('starttls'):
print "Negotiating TLS...."
s.starttls()
code = s.ehlo()[0]
if not (200 <= code <= 299):
print "Couldn't EHLO after STARTTLS"
sys.exit(5)
print "Using TLS connection."
else:
print "Server does not support TLS; using normal connection."
try:
s.login(username, password)
except smtplib.SMTPException, e:
print "Authentication failed:", e
sys.exit(1)
walkdir(source, s)
#-*- coding: UTF-8 -*-
import sys, os, smtplib, socket, email
from getpass import getpass
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Utils, Encoders
import mimetypes
kilobytes = 1024
megabytes = kilobytes * 1024
#chunksize = int(1 * kilobytes)
chunksize = int(24 * megabytes) # 24M
server = 'smtp.gmail.com'
fromaddr = 'youraccout@gmail.com'
toaddrs = 'youranotheraccout@gmail.com'
def genpart(data, contenttype):
maintype, subtype = contenttype.split('/')
if maintype == 'text':
retval = MIMEText(data, _subtype=subtype)
else:
retval = MIMEBase(maintype, subtype)
retval.set_payload(data)
Encoders.encode_base64(retval)
return retval
def attachment(filename):
fd = open(filename, 'rb')
mimetype, mimeencoding = mimetypes.guess_type(filename)
if mimeencoding or (mimetype is None):
mimetype = 'application/octet-stream'
retval = genpart(fd.read(), mimetype)
retval.add_header('Content-Disposition', 'attachment',
filename = filename)
fd.close()
return retval
def split(fromfile, todir, chunksize=chunksize):
if not os.path.exists(todir): # caller handles errors
os.mkdir(todir) # make dir, read/write parts
else:
for fname in os.listdir(todir): # delete any existing files
os.remove(os.path.join(todir, fname))
#try:
#os.mkdir(todir) # make dir, read/write parts
#except:
#print "mkdir %s error" % todir
#raise SystemExit
partnum = 0
input = open(fromfile, 'rb') # use binary mode on Windows
while 1: # eof=empty string from read
chunk = input.read(chunksize) # get next part <= chunksize
if not chunk: break
partnum = partnum+1
filename = os.path.join(todir, ('part%04d' % partnum))
fileobj = open(filename, 'wb')
fileobj.write(chunk)
fileobj.close() # or simply open().write()
input.close()
assert partnum <= 9999 # join sort fails if 5 digits
return partnum
def process_file(filename):
try:
dirname, ext = filename.split(".", 1)
except:
print "filename = %s" % filename
split(filename, dirname, chunksize)
absdir = os.path.join(os.path.abspath('.'), dirname)
return os.path.basename(filename), absdir
def send(gmail, subject, file):
msg = MIMEMultipart()
msg['To'] = '%s' % toaddrs
msg['From'] = '%s' % fromaddr
msg['Subject'] = '%s' % subject
msg['Date'] = Utils.formatdate(localtime = 1)
msg['Message-ID'] = Utils.make_msgid()
msg.attach(attachment(file))
message = str(msg)
try:
gmail.sendmail(fromaddr, toaddrs, message)
except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
print "%s may not have been sent!" % subject
print e
sys.exit(1)
else:
print "%s successfully sent " % subject
def walkdir(source, gmail):
if os.path.isfile(source):
size = os.stat(source)[6]
if size > chunksize:
filename, absdir = process_file(source)
print filename, absdir
for fname in os.listdir(absdir):
subject = filename+ '-' + fname
file = os.path.join(os.path.abspath(absdir), fname)
print subject, file
send(gmail, subject, file)
else:
print source
send(gmail, os.path.basename(source), source)
elif os.path.isdir(source):
for fname in os.listdir(source):
walkdir(os.path.join(source, fname), gmail)
if __name__ == '__main__':
source = sys.argv[1]
sys.stdout.write("username: %s\n" % fromaddr)
username = fromaddr
password = getpass("Enter password: ")
s = smtplib.SMTP(server)
code = s.ehlo()[0]
usesesmtp = 1
if not (200 <= code <= 299):
usesesmtp = 0
code = s.helo()[0]
if not (200 <= code <= 299):
raise SMTPHeloError(code, resp)
if usesesmtp and s.has_extn('starttls'):
print "Negotiating TLS...."
s.starttls()
code = s.ehlo()[0]
if not (200 <= code <= 299):
print "Couldn't EHLO after STARTTLS"
sys.exit(5)
print "Using TLS connection."
else:
print "Server does not support TLS; using normal connection."
try:
s.login(username, password)
except smtplib.SMTPException, e:
print "Authentication failed:", e
sys.exit(1)
walkdir(source, s)
硬盘紧张,想把以前下的图书传到gmail中。
gmail附件最大只能为25M,所以需要先分割文件,为保险每块为24M。
split函数实现的就是命令split,所以要合并文件,只需用 cat filename-part0001 filename-part0002 filename-part0003 > filename 就可以了。
需要有两个gmail,使用一个向另一个发送邮件。
发送邮件部分是从Python网络编程中拿来的。