zzyb 发表于 2010-5-15 20:57:53

MushPy部分功能演示: 一个简单的聊天信息抓取模块

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.strip())
      return
    if name == 'ChatEmote':
      world.send(u"chat* "+wc.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.strip())
      return
    if name == 'ChatEmote':
      world.send(u"chat* "+wc.strip())
      returnalias其实和trigger一样,只是trigger匹配从MUD来的信息,alias匹配命令行输入的信息。上面的代码一次做了两个alias,输入"c XXX"就是chat XXX,输入“cc emote XXX"就是chat* emote XXX。


最后,如何使用本模块?把chat.py放在某处(要在python的路径里)。在你的code某处:import chat
chat.init()这就是我写MushPy的目的:方便开发,但更重要的是,模块化。

[ 本帖最后由 zzyb 于 2010-5-15 09:19 PM 编辑 ]

hba 发表于 2010-5-15 21:03:56

这个notepad的容量有多大?带颜色抓取吗?

[ 本帖最后由 hba 于 2010-5-15 09:05 PM 编辑 ]

zzyb 发表于 2010-5-15 21:12:46

带颜色抓取吗?

Mushclient的notepad可以调颜色,但不支持多种颜色。

这个notepad的容量有多大?


这是好问题。我不知道。这个取决于mushclient。不过可以设置在写入notepad同时写入一个本地文件,并且定期清空notepad。


这个只是一个演示,演示一下MushPy的部分功能。
页: [1]
查看完整版本: MushPy部分功能演示: 一个简单的聊天信息抓取模块