TimothyQiu's Blog

keep it simple stupid

Google Talk Bot in Python

分类:技术

上班或者出门在外的时候有没有想过用家里闲着的电脑干点什么事呢?嘛~一切的可能性都得建立在你能连接得到自己的电脑之上才行。家里的电脑不比服务器,IP 并不固定,怎么办呢?解决方法挺多,比如花生壳,比如用 corn 发定时邮件……

对于我来说,写个会告诉你自己 IP 的 GTalk 机器人,想 SSH 连回家之前问一下是最方便的了。Lua 的 XMPP 库完全不懂怎么用,那么就先学现卖用 Python 写咯~

获取本机的公网 IP

由于使用了路由器,直接 ifconfig 是得不到公网 IP 的。那么可以直接在自己的网站上放一个 PHP 页:

<?php echo $_SERVER['REMOTE_ADDR']; ?>

或者利用现成的服务,比如 WhatIsMyIP.com 的自动化支持页面。有了这样一个可以获得访问者 IP 的页面地址,那么就可以用 Python 的 urllib 模块获得该页面的内容,从而得到自己的 IP 地址:

import urllib
ip = urllib.urlopen('http://www.whatismyip.com/automation/n09230945.asp').read()

简单的 GTalk 机器人

Google Talk 因为使用的是开放的 XMPP 协议,用各种语言实现机器人非常容易。(同样用 XMPP 协议的还有网易泡泡和人人桌面,而且据说微软的 Live Messager 最近也要支持 XMPP 协议了呢……腾讯啊~你不考虑来一发么?)比如接下来用的就是 xmpppy 库。

#! /usr/bin/env python
# vim: set fileencoding=utf-8

import xmpp
import urllib
import sys
from datetime import datetime

# 用来当机器人的用户名和密码
username = 'username@gmail.com'
password = 'password'

# 用来获取 IP 的 URL
ipurl = 'http://automation.whatismyip.com/n09230945.asp'

# 命令对应回复的处理
commands = {
    'ip':   lambda text: urllib.urlopen(ipurl).read(),
    'echo': lambda text: text,
}

def MessageCB(conn, mess):
    text = mess.getBody()
    user = mess.getFrom()

    if text is None: text = ''

    mail = user.getNode() + '@' + user.getDomain()
    print datetime.now().strftime('%H:%M:%S'), mail, text

    if ' ' in text: command, args = text.split(' ', 1)
    else:           command, args = text, ''

    if commands.has_key(command):   reply = commands[command](args)
    else:                           reply = unicode('主人已经被我干掉了', 'utf-8')

    conn.send( xmpp.Message(user, reply) )

def StepOn(conn):
    try:
        result = conn.Process(1)
    except KeyboardInterrupt: return 0
    return 1

def GoOn(conn):
    while StepOn(conn): pass

conn = xmpp.Client('gmail.com', debug=[])

if not conn.connect( server=('talk.google.com', 5223) ):
    print 'Unable to connect to server.'
    sys.exit(1)

if not conn.auth(xmpp.JID(username).getNode(), password, 'python'):
    print 'Unable to authorize.'
    sys.exit(1)

conn.RegisterHandler('message', MessageCB)
conn.sendInitPresence()
print 'Bot started.'
GoOn(conn)

上面的这段主要就是定义了两个命令 ip 和 echo,分别负责回答本机 IP 和学舌,其它情况下机器人都只会回复「主人已经被我干掉了」。

要扩展起来,在 commands 字典里添加条目即可 :)

初次写 Python 代码,不知道是不是写得 Pythonic……

p.s. 最近升级了 php 后网站就非常不稳定,暂时还不知道肿么办貌似是因为我某次把 crond 服务干掉了,于是长期没有 logrotate 的原因 =3=

Python

添加新评论 »