MushPy部分功能演示: 一个简单的聊天信息抓取模块
用这个简单演示部分MushPy的功能。MushPy是一个基于mushclient的使用python的开发框架,详见http://pkuxkx.com/forum/thread-13674-1-1.html
给个截图:
在这个演示中,将要展示如何制作触发器抓取聊天内容,并放入一个mushclient的notepad,并且在每行前插入日期时间。我知道有更好的聊天信息抓取模块,这个只是用来展示MushPy。
这里是全部code. 代码讲解在后面。
文件: chat.py- # -*- coding: cp936 -*-
- import mushpy as mpy
- from mushpy.common import *
- from mushpy.terminals import McTerminal
- from mushpy.objects import Trigger, Alias, Timer
- MODULE_CHAT_GROUP_NAME = 'group_chat'
- CHAT_NP_TITLE = u'Chat Log'
- chat_chan = McTerminal(CHAT_NP_TITLE, time_stamp=True, read_only=True)
- @Trigger.make(u"^(>)*( )*【(闲聊| 天色 |谣言|保卫|动作|江湖传闻|北侠公告|北侠QQ群|江湖逸事)】", name = 'CatchChat', group = MODULE_CHAT_GROUP_NAME )
- @Trigger.make(u"^(>)*( )*(你告诉|.+告诉你|你回答|.+回答你)", name = 'CatchTell', group = MODULE_CHAT_GROUP_NAME )
- def chat_log(name, line, wc):
- print >> chat_chan, line.strip('> ')
- @Alias.make(u"^cc( +.*)?$", name = 'ChatEmote', group = MODULE_CHAT_GROUP_NAME )
- @Alias.make(u"^c( +.*)?$", name = 'Chat', group = MODULE_CHAT_GROUP_NAME )
- def alias_send2chat(name, line, wc):
- if name == 'Chat':
- world.send(u"chat "+wc[0].strip())
- return
- if name == 'ChatEmote':
- world.send(u"chat* "+wc[0].strip())
- return
- def enable(whether=1):
- world.EnableTriggerGroup(MODULE_CHAT_GROUP_NAME, whether)
- world.EnableAliasGroup(MODULE_CHAT_GROUP_NAME, whether)
- def init():
- enable()
复制代码 首先是:- chat_chan = McTerminal(CHAT_NP_TITLE, time_stamp=True, read_only=True)
复制代码 这是MushPy一个很小但很便捷的feature。我们可以创建一个类似于文件对象的object,并且让写入此对象的字符都出现在一个notepad里!这样我们可以方便的利用python自建的print等语句,往mushclient notepad里写入。
上面的code创建了一个文件对象,它会创建一个mushclient的notepad,窗口名为“ChatLog”,每次往这个对象写入都会自动添加日期时间(time_stamp=True);并且规定该mushclient notepad窗口是只读的(read_only=True)。
这样,如果我们想往一个叫"ChatLog"的notepad写入,只需用python的print语句即可!!!例如:- print >> chat_chan, "要想写入的东西"
复制代码 日期时间会自动添加。
它的另一个好处是,可以用来替换系统自带的标准输出!!!- import sys
- sys.stdout = McTerminal("标准输出", read_only=True)
复制代码 这样的话,所有print语句都打印到一个叫“标准输出”的notepad!好处不仅仅是自己方便,关键是你所调用的其他库(例如标准库)所有往标准输出打印的内容,都可以在这个notepad里看到!!!相信用mushclient都能体会这一点(因为mushclient是GUI程序,没有stdout)。我有一个真实的例子,我用Python的unittest库为这个框架写测试代码,可是那个框架自带的程序把结果直接打印到标准输出。这样我是看不到测试结果的,因为GUI没有stdout。现在我替黄了系统的stdout之后,测试结果都在mushclient一个notepad里,非常好看!
接下来介绍强大便捷的触发器创建方法。这个里面涉及很多Python特有的属性,所以如果对python没有一定了解,可能不容易懂。- @Trigger.make(u"^(>)*( )*【(闲聊| 天色 |谣言|保卫|动作|江湖传闻|北侠公告|北侠QQ群|江湖逸事)】", name = 'CatchChat', group = MODULE_CHAT_GROUP_NAME )
- @Trigger.make(u"^(>)*( )*(你告诉|.+告诉你|你回答|.+回答你)", name = 'CatchTell', group = MODULE_CHAT_GROUP_NAME )
- def chat_log(name, line, wc):
- print >> chat_chan, line.strip('> ')
复制代码 这段代码作用是匹配那两个字符模式中的任意一个,并且调用函数chat_log()。这里创建触发器使用的Python的decorator。@Trigger.make(...)告诉我们,创建一个触发器,并且使用它所作用于的函数(也就是chat_log())作为触发器的回调函数。这个Trigger.make()里第一个参数必须制定要匹配的内容,后面的参数都是可选的。这些可选的参数使用Python的“keyword arguments”定义,如name = "CatchTell" 是触发器的名字,group="group_name" 是触发器的组名。详细参数可参考mushclient API:SetTriggerOption的文档。
再来说说这个回调函数chat_log()。这是一个普通的python函数,其参数接口符合一个mushclient触发器要求的回调函数接口:(name, line, wildcards)。其作用是把匹配的那一行抓取到指定的notepad,并去掉行首的“>”。这里用到前面说的类似文件对象的用法。看看多方便:- print >> chat_chan, line.strip('> ')
复制代码 如果用mushclient自带API的话,需要:- world.AppendToNotepad( datetime.now().strftime("%c") ) # 插入日期时间
- world.AppendToNotepad( line.strip('> ') + '\r\n' )
复制代码 这样一切都得自己做,都是重复性的。MushPy都为你做好了。
好,接着讲alias。- @Alias.make(u"^cc( +.*)?$", name = 'ChatEmote', group = MODULE_CHAT_GROUP_NAME )
- @Alias.make(u"^c( +.*)?$", name = 'Chat', group = MODULE_CHAT_GROUP_NAME )
- def alias_send2chat(name, line, wc):
- if name == 'Chat':
- world.send(u"chat "+wc[0].strip())
- return
- if name == 'ChatEmote':
- world.send(u"chat* "+wc[0].strip())
- return
复制代码 alias其实和trigger一样,只是trigger匹配从MUD来的信息,alias匹配命令行输入的信息。上面的代码一次做了两个alias,输入"c XXX"就是chat XXX,输入“cc emote XXX"就是chat* emote XXX。
最后,如何使用本模块?把chat.py放在某处(要在python的路径里)。在你的code某处:这就是我写MushPy的目的:方便开发,但更重要的是,模块化。
[ 本帖最后由 zzyb 于 2010-5-15 09:19 PM 编辑 ] |