2007年04月22日

下面是用Python发送email的示例。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import email
import mimetypes
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
import smtplib

def sendEmail(authInfo, fromAdd, toAdd, subject, plainText, htmlText):

        strFrom = fromAdd
        strTo = ‘, ‘.join(toAdd)

        server = authInfo.get(’server’)
        user = authInfo.get(‘user’)
        passwd = authInfo.get(‘password’)

        if not (server and user and passwd) :
                print ‘incomplete login info, exit now’
                return

        # 设定root信息
        msgRoot = MIMEMultipart(‘related’)
        msgRoot['Subject'] = subject
        msgRoot['From'] = strFrom
        msgRoot['To'] = strTo
        msgRoot.preamble = ‘This is a multi-part message in MIME format.’

        # Encapsulate the plain and HTML versions of the message body in an
        # ‘alternative’ part, so message agents can decide which they want to display.
        msgAlternative = MIMEMultipart(‘alternative’)
        msgRoot.attach(msgAlternative)

        #设定纯文本信息
        msgText = MIMEText(plainText, ‘plain’, ‘utf-8′)
        msgAlternative.attach(msgText)

        #设定HTML信息
        msgText = MIMEText(htmlText, ‘html’, ‘utf-8′)
        msgAlternative.attach(msgText)

       #设定内置图片信息
        fp = open(‘test.jpg’, ‘rb’)
        msgImage = MIMEImage(fp.read())
        fp.close()
        msgImage.add_header(‘Content-ID’, ‘<image1>’)
        msgRoot.attach(msgImage)

       #发送邮件
        smtp = smtplib.SMTP()
       #设定调试级别,依情况而定
        smtp.set_debuglevel(1)
        smtp.connect(server)
        smtp.login(user, passwd)
        smtp.sendmail(strFrom, strTo, msgRoot.as_string())
        smtp.quit()
        return

if __name__ == ‘__main__’ :
        authInfo = {}
        authInfo['server'] = ’smtp.somehost.com’
        authInfo['user'] = ‘username’
        authInfo['password'] = ‘password’
        fromAdd = ‘username@somehost.com’
        toAdd = ['someone@somehost.com', 'other@somehost.com']
        subject = ‘邮件主题’
        plainText = ‘这里是普通文本’
        htmlText = ‘<B>HTML文本</B>’
        sendEmail(authInfo, fromAdd, toAdd, subject, plainText, htmlText)

2007年04月18日

Python提供的os module容许我们在Python代码中调用shell命令,例如:
import os
os.system("ls /share/zlib.so")
则会返回/usr/lib目录下所有文件
-rw-r–r– 1 work work 46333 2007-04-17 15:52 zlib.so
结果同在命令提示符下执行
ls /usr/lib

如果要捕获输出,则使用
import os
text = os.popen("ls /usr/lib")
此时text保存shell输出的内容
print text
-rw-r–r– 1 work work 46333 2007-04-17 15:52 zlib.so

不幸的是,有时我们需要启动的程序需要进行一些交互,才能完成,例如在不同主机间拷贝文件的命令scp(需要输入密码),以及ftp工具lftp(虽然可以在登录时指定用户名和密码,仍然需要在交互方式下输入文件传输指令)等等。
此时os.system或者os.popen便无能为力了,因为它们无法模拟用户与所启动进程间的交互,不过我们可以利用pexpect来做。

pexpect是一个开源python项目,用来启动(spawn)其它程序,进行控制,模拟用户对输出进行响应。

pexpect的使用很简单,首先到这里下载:
http://sourceforge.net/project/showfiles.php?group_id=59762

tar zxf pexpect-2.1.tar.gz
cd pexpect-2.1
python setup.py install

然后就可以直接调用了
pexpect提供的函数主要有三个

pexpect.spawn(‘command’)
接收参数为一个字符串,也就是我们需要启动的程序,返回该程序的句柄

pexpect.expect(’some pattern’)
接收参数为一个正则表达式字符串,用来定位程序的返回结果
每次pexpect.expect()运行之后
就可以用pexpect.before和pexpect.after来获取expect定位之前和之后的响应文本

pexpect.send(‘command’)
接收参数为字符串,即用户输入的命令。pexpect.sendline(‘command’)的功能与此类似,只是会在命令后加上回车符

下面是一个lftp登录的例子:


#! /usr/bin/python
# -*- coding: utf-8 -*-

import pexpect
child = pexpect.spawn (‘lftp sftp://user:password@192.168.1.1′)
child.sendline (‘ls’)

child.expect (‘lftp .*> ‘)
print child.before   # 输出ls命令的结果.

child.sendline (‘get /share/somefile’)
child.expect (‘lftp .*> ‘)
print child.before   # 输出get的运行结果,判断文件是否正确获取.

child.sendline(‘quit;’)

类似的,我们可以写出在python中调用scp, ssh之类命令的程序。
更多的细节,请参考pexpect的文档
http://pexpect.sourceforge.net/

2007年04月16日

Python访问MySQL的模块,以前叫MySQLdb,后来更名为mysql-python,安装似乎也有变化。

有时会遇到这样的问题:
$ sudo python setup.py
installsh: line 1: mysql_config: command not found
Traceback (most recent call last):
  File "setup.py", line 16, in ?
    metadata, options = get_config()
  File "/Users/farocco/MySQL-python-1.2.2/setup_posix.py", line 43, in
get_config
    libs = mysql_config("libs_r")
  File "/Users/farocco/MySQL-python-1.2.2/setup_posix.py", line 24, in
mysql_config
    raise EnvironmentError, "%s not found" % mysql_config.path
EnvironmentError: mysql_config not found

按照mysql-python的文档一步步来做,仍然会遇到这种问题,其实原因出在mysql_config上。
首先需要定位到本机的mysql_config,此文件处在mysql安装位置的bin目录下(假设Mysql安装在/data/mysql下,则路径为/data/mysql/bin/mysql_config)
修改setup_posix.py文件,在26行显示地设定mysql_config:
mysql_config.path = "/data/mysql/bin/mysql_config"

再次运行
python setup.py build
python setup.py install
安装完成