I've written some code using the information here as a guide line,
List users in IRC channel using Twisted Python IRC framework
I can successfully log the NAMES list to the console, however I've so far been unable to retrieve it to work with it further. Here is an excerpt of the code related to this matter:
class Alfred(irc.IRCClient):
""" An IRC bot """
# Voodoo magic for names
def __init__(self, *args, **kwargs):
self._namescallback = {}
def names(self, channel):
channel = channel.lower()
d = defer.Deferred()
if channel not in self._namescallback:
self. _namescallback[channel] = ([], [])
self._namescallback[channel][0].append(d)
self.sendLine("NAMES %s" % channel)
return d
def irc_RPL_NAMREPLY(self, prefix, params):
channel = params[2].lower()
nicklist = params[3].split(' ')
if channel not in self._namescallback:
return
n = self._namescallback[channel][1]
n += nicklist
def irc_RPL_ENDOFNAMES(self, prefix, params):
channel = params[1].lower()
if channel not in self._namescallback:
return
callbacks, namelist = self._namescallback[channel]
for cb in callbacks:
cb.callback(namelist)
del self._namescallback[channel]
# End of voodoo magic
def get_names(self, nicklist):
# Log the output to the log
log.msg(nicklist)
def has_op(self, channel, user):
self.names('#' + channel).addCallback(self.get_names)
def change_mode(self, channel, user, msg):
target = msg[5:-3]
params = [channel, '+o']
self.has_op(channel, user)
self.mode(channel, True, '+o', user=target)
What I want to achieve is to within the has_op function get a hold of the so called nicklist. So far I've been unable to do this using a trial and error approach, where I've tried to use print and return statements in reasonable places but this has yielded no output what so ever or instance / attribute errors. Obviously, I'm at a loss and I really need some guidance.
The idea of doing this "within" has_op
is probably preventing you from making progress.
Make it work at all and then consider how you might improve the factoring of the implementation.
Notice that get_names
has the data that you're interested in already. What do you want to do with that information? Check to see if it contains a certain name? For that, you'll need to know which name you're considering. To do this, you can use the feature of Deferred.addCallback
that lets you pass an extra argument to the callback:
def get_names(self, nicklist, user):
if user in nicklist:
log.msg("%r has op!" % (user,))
def has_op(self, channel, user):
self.names('#' + channel).addCallback(self.get_names, user)
Now perhaps what you really want isn't to log this information but to make a decision based on it in change_mode
(I'm only guessing, of course).
If this is so, then you want to take advantage of another Deferred
feature - the ability of each callback attached to a Deferred
to process and change the result of the Deferred
.
You can change has_op
so that instead of logging information it also returns a Deferred
- but this Deferred
can have a True
result if the given user has op in the given channel and a False
result of they don't.
def get_names(self, nicklist, user):
return user in nicklist
def has_op(self, channel, user):
return self.names('#' + channel).addCallback(self.get_names, user)
Now you can use this functionality in change_mode
:
def change_mode(self, channel, user, msg):
target = msg[5:-3]
checking = self.has_op(channel, user)
checking.addCallback(self._ofIfNotOp, channel, target)
def _opIfNotOp(self, isOp, channel, user):
if not isOp:
self.mode(channel, True, '+o', user=user)