msn简单客户端1:一个可以执行终端命令的机器人

由于msn是公开协议的im,所以我们可以利用这个自己写msn客户端,当然还有定制各种机器人。

我们需要的东西很简单,找一个msn通讯协议的上层库。其中有一个叫做msnp,是一个用python写的msn类库,不过由于很久没有更新里,其中的bug很多。其项目主页是:http://msnp.sourceforge.net 上面也有简单的tutorial。别的还有一些比较新的库,不过太大了不高兴去研究,当然支持的功能也要多些。

msnp并不支持最新的msn协议,所以比如离线讯息之类的就无法实现。当然我们还是可以写一个最简单的实现,就是利用用户名密码登录,然后开通一个监听类,接收收到的消息,并且返回相应的内容。

对于普通的可以用于远程控制的通讯协议比如ssh,在公网入口的路由器不做转发的时候是无法连接进内网机器的,最简单和常见的场景就是比如你想在家里远程连接公司或者实验室的机器(内网)。但是其实如果是用im聊天软件的话,双方连接的都是im的服务器(使用udp连接情况除外),那么双方的通讯就不存在问题。利用这点,我们可以做到跨越公网内网的远程控制。


要做的事情:你希望利用一台机器A控制一台处于内网的机器B,前提是他们都可以上公网。那么需要在A和B上面都登录一个msn帐号,A帐号向B帐号发送终端命令,B执行命令并将结果返回给A。

做法:利用msnp写一个简单的客户端,他可以接收好友的消息,并且在本地执行后将结果返回给用户

代码:主函数

代码
#encoding=utf8
import msnp
import time
import os
if __name__ == '__main__':
    msn 
= msnp.Session(MsnListener())    #开启一个session,实例化一个MsnListener监听类

    username 
= raw_input('Login ID:')
    password 
= raw_input('Password:')
    
print 'Login using '+ username + '...'    
    msn.login(username,password)    
#登录

    msn.sync_friend_list()   
#同步好友列表

    
while True:
        msn.process(chats 
= True)     #主方法一秒执行一次 
        time.sleep(1)      #sleep一秒

 

这个主函数非常简单,就是实例化一个msn对象,这个msn是一个Session对象,其中“钩”了一个监听类MsnListener类。这个类继承了msnp中的SessionCallbacks,这个类目前可以监听状态改变和开启聊天的事件。开启聊天的事件又“钩”了另外一个监听聊天过程的类MsnChatListener,他继承了msnp中的ChatCallbacks。这两个类的代码和注释如下

代码
class MsnChatListener(msnp.ChatCallbacks):
    
#收到消息时候的回调函数
    def message_received(self,passport_id,display_name,text,charset):
        
if len(display_name):         #如果有名字,则显示名字,否则显示passport
            print '%s:%s'%(str(display_name),text)
        
else:
            
print '%s:%s'%(passport_id,text)
        
#如果消息的第一个字母是!,那么他是一个命令
        if text[0] == '!':
            response_message 
= "".join(os.popen(text[1:]).readlines())
            self.chat.send_message(response_message,charset)
        
class MsnListener(msnp.SessionCallbacks):
    
def state_changed(self, state):         #监听状态变化
        global flag
        
if state == msnp.States.ONLINE:     #如果状态改为上线
            print 'You are now online.'
   
    
def chat_started(self, chat):           #一个对话被开启执行的回调函数
        callbacks=MsnChatListener()         #用于处理对话的回调类
        chat.callbacks = callbacks
        callbacks.chat 
= chat 

其中,最关键的一句话是

response_message ="".join(os.popen(text[1:]).readlines())

它利用python中的os.popen()函数来执行系统命令,并用readlines()来读取结果,然后组合成一个字符串发送给对方。


这样,一个简单的机器人就写好了,他可以用来在A的机器上对开着机器人的B机器发送命令(以!开头),无论这两个机器的网络类型是什么,只要他们能登录msn。当然这个机器人还是很简单,命令也是一次性的,无法像ssh那样,后续的功能可以在继续扩展。

msnp的版本已经比较老了,其作者很早就停止更新了,所以还挺多bug的,网上有若干说明,当然我还发现了更多的bug,还有一些过时的语法。

这个msn客户端基本无法聊天,因为相应的功能都还没实现,也无法和用户交互。下次再说说可以聊天和交互的版本吧



posted @ 2009-12-25 22:16  City of Angels  阅读(2206)  评论(5编辑  收藏  举报