简体   繁体   English

Python扭曲的irc:在privmsg方法中等待whois回复

[英]Python twisted irc: Wait for a whois reply inside privmsg method

I'm trying to make an IRC bot using the twisted.words.protocols.irc module. 我正在尝试使用twisted.words.protocols.irc模块制作一个IRC机器人。

The bot will parse messages from a channel and parse them for command strings. 机器人将解析来自通道的消息并解析它们以获取命令字符串。

Everything works fine except when I need the bot to identify a nick by sending a whois command. 一切正常,除非我需要机器人通过发送whois命令来识别昵称。 The whois reply will not be handled until the privmsg method (the method from which I'm doing the parsing) returns. 在privmsg方法(我正在从中进行解析的方法)返回之前,不会处理whois答复。
example: 例:

from twisted.words.protocols import irc

class MyBot(irc.IRClient):

..........

    def privmsg(self, user, channel, msg):
        """This method is called when the client recieves a message"""
        if msg.startswith(':whois '):
            nick = msg.split()[1]
            self.whois(nick)
            print(self.whoislist)

    def irc_RPL_WHOISCHANNELS(self, prefix, params):
        """This method is called when the client recieves a reply for whois"""
        self.whoislist[prefix] = params

Is there a way to somehow make the bot wait for a reply after self.whois(nick)? 有什么办法可以使机器人在self.whois(nick)之后等待回复吗?

Perhaps use a thread (I don't have any experience with those) . 也许使用线程(我对此没有任何经验)

Deferred is a core concept in Twisted, you must be familiar with it to use Twisted. Deferred是Twisted中的核心概念,您必须熟悉它才能使用Twisted。

Basically, your whois checking function should return a Deferred that will be fired when you receive whois-reply. 基本上,您的whois检查功能应返回Deferred ,当您收到whois-reply时将触发该Deferred

I managed to fix this by running all handler methods as threads, and then setting a field, following kirelagin's suggestion, before running a whois query, and modifying the method that recieves the data to change the field when it recieves a reply. 我设法通过将所有处理程序方法作为线程运行,然后在运行whois查询之前按照kirelagin的建议设置了一个字段来解决此问题,并修改了接收数据的方法以在收到答复时更改该字段。 Its not the most elegant solution but it works. 它不是最优雅的解决方案,但是可以工作。

Modified code: 修改后的代码:

class MyBot(irc.IRClient):
..........

    def privmsg(self, user, channel, msg):
        """This method is called when the client recieves a message"""
        if msg.startswith(':whois '):
            nick = msg.split()[1]

            self.whois_status = 'REQUEST'
            self.whois(nick)
            while not self.whois_status == 'ACK':
                sleep(1)

            print(self.whoislist)

    def irc_RPL_WHOISCHANNELS(self, prefix, params):
        """This method is called when the client recieves a reply for whois"""
        self.whoislist[prefix] = params

    def handleCommand(self, command, prefix, params):
        """Determine the function to call for the given command and call
        it with the given arguments.
        """
        method = getattr(self, "irc_%s" % command, None)
        try:
            # all handler methods are now threaded.
            if method is not None:
                thread.start_new_thread(method, (prefix, params))
            else:
                thread.start_new_thread(self.irc_unknown, (prefix, command, params))
        except:
            irc.log.deferr()

    def irc_RPL_WHOISCHANNELS(self, prefix, params):
        """docstring for irc_RPL_WHOISCHANNELS"""
        self.whoislist[prefix] = params

    def irc_RPL_ENDOFWHOIS(self, prefix, params):
        self.whois_status = 'ACK'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM