来自另一个来源的扭曲延迟变量
Twisted deferred variable from another source
我是 运行 一个 IRC 机器人,我终于弄明白了如何通过 whois 正确地获得用户的授权。我现在正在寻求实现此检查以引用我的数据库,而不是依赖于他们的用户名。
我有一个命令
def privmsg(self, user, channel, msg):
if msg.startswith(".join"):
# sends whois signal
irc.IRCClient.whois(self, user, None)
我需要从输出源(IRC 服务器)调用的函数中获取变量,因此我不能只是 AddCallback
auth = ???
player = db.getplayer(auth)
我正在通过
接收授权
def irc_330(self, prefix, params):
auth = params[2]
我似乎无法弄清楚如何将变量发送回第一个函数,甚至如何等待该信号返回。我的第一个函数将传递 irc_330() 在它开始之前所做的任何事情。
我能想到的唯一解决方案是创建一个回调函数,该函数将等待其中的函数调用,然后 return 我需要什么。但这似乎根本不对。
您 运行 遇到的问题是 IRCClient
的 API 相当
糟糕(对此感到抱歉!)。具体来说,它有 API 个像 .whois()
这样的
应该 return一个Deferred
,但不要。
您可以通过制作这些 API 的 自己的 版本来解决此问题,
事实上,return一个Deferred
.
一般的想法是 IRC 请求和响应没有请求 ID,所以
他们总是按顺序回答。这意味着你需要建立一个队列
first-in/first-out 个请求,以便您可以将它们与回复匹配
到达。此外,您需要将延迟触发与查询的 end 相匹配
(在您的情况下,WHOIS,因此 RPL_ENDOFWHOIS
),因为 IRC 服务器可能
或者可能不会发送特定字段作为响应的一部分。
下面是一个示例实现:
from collections import deque
from twisted.internet.defer import Deferred
from twisted.words.protocols.irc import IRCClient
class NoAccount(Exception):
"No account found."
class MyClient(IRCClient, object):
def __init__(self):
self._whoisQueue = deque()
def deferredWhois(self, nick):
result = Deferred()
self._whoisQueue.append((result, nick))
self.whois(nick)
return result
def irc_330(self, prefix, params):
self._currentActiveNick = params[2]
def irc_RPL_ENDOFWHOIS(self, prefix, params):
deferredToFire, who = self._whoisQueue.popleft()
currentActiveNick = self._currentActiveNick
self._currentActiveNick = None
if currentActiveNick is None:
deferredToFire.errback(NoAccount(who))
else:
deferredToFire.callback(currentActiveNick)
这使得 deferredWhois
方法 return 成为 Deferred
给定昵称的帐户名称。
希望对您有所帮助!
我是 运行 一个 IRC 机器人,我终于弄明白了如何通过 whois 正确地获得用户的授权。我现在正在寻求实现此检查以引用我的数据库,而不是依赖于他们的用户名。
我有一个命令
def privmsg(self, user, channel, msg):
if msg.startswith(".join"):
# sends whois signal
irc.IRCClient.whois(self, user, None)
我需要从输出源(IRC 服务器)调用的函数中获取变量,因此我不能只是 AddCallback
auth = ???
player = db.getplayer(auth)
我正在通过
接收授权def irc_330(self, prefix, params):
auth = params[2]
我似乎无法弄清楚如何将变量发送回第一个函数,甚至如何等待该信号返回。我的第一个函数将传递 irc_330() 在它开始之前所做的任何事情。
我能想到的唯一解决方案是创建一个回调函数,该函数将等待其中的函数调用,然后 return 我需要什么。但这似乎根本不对。
您 运行 遇到的问题是 IRCClient
的 API 相当
糟糕(对此感到抱歉!)。具体来说,它有 API 个像 .whois()
这样的
应该 return一个Deferred
,但不要。
您可以通过制作这些 API 的 自己的 版本来解决此问题,
事实上,return一个Deferred
.
一般的想法是 IRC 请求和响应没有请求 ID,所以
他们总是按顺序回答。这意味着你需要建立一个队列
first-in/first-out 个请求,以便您可以将它们与回复匹配
到达。此外,您需要将延迟触发与查询的 end 相匹配
(在您的情况下,WHOIS,因此 RPL_ENDOFWHOIS
),因为 IRC 服务器可能
或者可能不会发送特定字段作为响应的一部分。
下面是一个示例实现:
from collections import deque
from twisted.internet.defer import Deferred
from twisted.words.protocols.irc import IRCClient
class NoAccount(Exception):
"No account found."
class MyClient(IRCClient, object):
def __init__(self):
self._whoisQueue = deque()
def deferredWhois(self, nick):
result = Deferred()
self._whoisQueue.append((result, nick))
self.whois(nick)
return result
def irc_330(self, prefix, params):
self._currentActiveNick = params[2]
def irc_RPL_ENDOFWHOIS(self, prefix, params):
deferredToFire, who = self._whoisQueue.popleft()
currentActiveNick = self._currentActiveNick
self._currentActiveNick = None
if currentActiveNick is None:
deferredToFire.errback(NoAccount(who))
else:
deferredToFire.callback(currentActiveNick)
这使得 deferredWhois
方法 return 成为 Deferred
给定昵称的帐户名称。
希望对您有所帮助!