1

すっごく Skybot (IRC bot) に基づく IRC bot があります。私はそのドキュメントを調べましたが、それを行う方法は述べられていません。join、quit、part、set mode などの irc コマンドを chan から入力できるようにしたいのですが。簡単な例:

.part #hello ~ ちゃんのパート .mode #hello +b Tom - Bans Tom

それは、イベントに関するドキュメントに記載されているものです

@hook.event(irc_command)

イベント フックは、特定の IRC コマンドが発行されるたびに呼び出されます。たとえば、「*」をパラメーターとして指定すると、すべての行でトリガーされます。「PRIVMSG」を指定すると、実際のチャット行でのみトリガーされます (ニックネームの変更ではありません)。

このような場合の最初の引数は、["#channel", "text"] の形式の 2 つの要素のリストになります。

これが単純なコマンドの仕組みです。

from util import hook, http


@hook.command
def calc(inp,say=None):
    'Does calculation'

    h = http.get_html('http://www.google.com/search', q=inp)

    m = h.xpath('//h2[@class="r"]/text()')

    if not m:
        say("I can't calculate " + inp + ".")

    res = ' '.join(m[0].split())

    say(res + ".")

hook.py

    import inspect
import re


def _hook_add(func, add, name=''):
    if not hasattr(func, '_hook'):
        func._hook = []
    func._hook.append(add)

    if not hasattr(func, '_filename'):
        func._filename = func.func_code.co_filename

    if not hasattr(func, '_args'):
        argspec = inspect.getargspec(func)
        if name:
            n_args = len(argspec.args)
            if argspec.defaults:
                n_args -= len(argspec.defaults)
            if argspec.keywords:
                n_args -= 1
            if argspec.varargs:
                n_args -= 1
            if n_args != 1:
                err = '%ss must take 1 non-keyword argument (%s)' % (name,
                            func.__name__)
                raise ValueError(err)

        args = []
        if argspec.defaults:
            end = bool(argspec.keywords) + bool(argspec.varargs)
            args.extend(argspec.args[-len(argspec.defaults):
                        end if end else None])
        if argspec.keywords:
            args.append(0)  # means kwargs present
        func._args = args

    if not hasattr(func, '_thread'):  # does function run in its own thread?
        func._thread = False


def sieve(func):
    if func.func_code.co_argcount != 5:
        raise ValueError(
                'sieves must take 5 arguments: (bot, input, func, type, args)')
    _hook_add(func, ['sieve', (func,)])
    return func


def command(arg=None, **kwargs):
    args = {}

    def command_wrapper(func):
        args.setdefault('name', func.func_name)
        _hook_add(func, ['command', (func, args)], 'command')
        return func

    if kwargs or not inspect.isfunction(arg):
        if arg is not None:
            args['name'] = arg
        args.update(kwargs)
        return command_wrapper
    else:
        return command_wrapper(arg)


def event(arg=None, **kwargs):
    args = kwargs

    def event_wrapper(func):
        args['name'] = func.func_name
        args.setdefault('events', ['*'])
        _hook_add(func, ['event', (func, args)], 'event')
        return func

    if inspect.isfunction(arg):
        return event_wrapper(arg, kwargs)
    else:
        if arg is not None:
            args['events'] = arg.split()
        return event_wrapper


def singlethread(func):
    func._thread = True
    return func


def regex(regex, flags=0, **kwargs):
    args = kwargs

    def regex_wrapper(func):
        args['name'] = func.func_name
        args['regex'] = regex
        args['re'] = re.compile(regex, flags)
        _hook_add(func, ['regex', (func, args)], 'regex')
        return func

    if inspect.isfunction(regex):
        raise ValueError("regex decorators require a regex to match against")
    else:
        return regex_wrapper

およびmisc.pyには、1 つの hook.event コマンドがあります。

#autorejoin channels
@hook.event('KICK')
def rejoin(paraml, conn=None):
    if paraml[1] == conn.nick:
        if paraml[0].lower() in conn.channels:
            conn.join(paraml[0])


#join channels when invited
@hook.event('INVITE')
def invite(paraml, conn=None):
    conn.join(paraml[-1])



@hook.event('004')
def onjoin(paraml, conn=None):
    # identify to services
    nickserv_password = conn.conf.get('nickserv_password', '')
    nickserv_name = conn.conf.get('nickserv_name', 'nickserv')
    nickserv_command = conn.conf.get('nickserv_command', 'IDENTIFY %s')
    if nickserv_password:
        conn.msg(nickserv_name, nickserv_command % nickserv_password)
        time.sleep(1)

    # set mode on self
    mode = conn.conf.get('mode')
    if mode:
        conn.cmd('MODE', [conn.nick, mode])

    # join channels
    for channel in conn.channels:
        conn.join(channel)
        time.sleep(1)  # don't flood JOINs

    # set user-agent
    ident, rev = get_version()

main.py、 conn が定義されている場所。

class Input(dict):
    def __init__(self, conn, raw, prefix, command, params,
                    nick, user, host, paraml, msg):

        chan = paraml[0].lower()
        if chan == conn.nick.lower():  # is a PM
            chan = nick

        def say(msg):
            conn.msg(chan, msg)

        def reply(msg):
            if chan == nick:  # PMs don't need prefixes
                conn.msg(chan, msg)
            else:
                conn.msg(chan, nick + ': ' + msg)

        def pm(msg):
            conn.msg(nick, msg)

        def set_nick(nick):
            conn.set_nick(nick)

        def me(msg):
            conn.msg(chan, "\x01%s %s\x01" % ("ACTION", msg))

        def notice(msg):
            conn.cmd('NOTICE', [nick, msg])

        dict.__init__(self, conn=conn, raw=raw, prefix=prefix, command=command,
                    params=params, nick=nick, user=user, host=host,
                    paraml=paraml, msg=msg, server=conn.server, chan=chan,
                    notice=notice, say=say, reply=reply, pm=pm, bot=bot,
                    me=me, set_nick=set_nick, lastparam=paraml[-1])

    # make dict keys accessible as attributes
    def __getattr__(self, key):
        return self[key]

    def __setattr__(self, key, value):
        self[key] = value

どうすればいいのかよくわかりません。ご協力いただきありがとうございます!

4

0 に答える 0