Python twisted irc - 登录时的服务器密码

Posted

技术标签:

【中文标题】Python twisted irc - 登录时的服务器密码【英文标题】:Python twisted irc - server password on login 【发布时间】:2014-05-24 21:40:14 【问题描述】:

我正在尝试使用 Twisted 在 Python 中创建一个简单的 IRC 机器人。我已经走了很远,但是当我需要提供密码才能进入服务器时遇到了问题。

我知道如何实现加入特定频道的密码,但我不知道如何在加入 IRC 服务器本身时提供用户名和密码。

我需要提供密码的原因是我希望机器人与保镖兼容 (ZNC)。

(请原谅糟糕的缩进)

这是我目前尝试过的

import re
import urllib2
import random
import time
import sys
from htmlParser import HTMLParser
from twisted.internet import reactor
from twisted.words.protocols import irc
from twisted.internet import protocol

def is_valid_int(num):
"""Check if input is valid integer"""
    try:
        int(num)
        return True
    except ValueError:
        return False

def isAdmin(user):
    with open("admins.txt", "r") as adminfile:
        lines = adminfile.readlines()
        if not lines:
            return False

        if user in lines:
            return True
        else:
            return False

class Bot(irc.IRCClient):
    def _get_nickname(self):
        return self.factory.nickname

    nickname = property(_get_nickname)

    # @Event Signed on
    def signedOn(self):
        self.join(self.factory.channel)
        print "Signed on as %s." % (self.nickname,)

    # @Event Joined
    def joined(self, channel):
        print "Joined %s." % (channel,)

    # @Event Privmsg
    def privmsg(self, user, channel, msg):
        if msg == "!time":
            msg = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
            self.msg(channel, msg)

        # Google searhc
        elif msg.startswith("!google"):
            msg = msg.split(" ", 2)
            msg = "https://www.google.com/search?q=" + msg[1]
            self.msg(channel, msg)

        # Quit connection
        elif msg.startswith("!quit"):
        self.quit("byebye")

        # Set nickname
        elif msg.startswith("!nick"):
        msg = msg.split(" ", 2)
        newNick = msg[1]
        self.setNick(newNick)

        # Invite to channel
        elif msg.startswith("!invite"):
        msg = msg.split(" ", 2)
        channel = msg[1]
        self.join(channel)
        print("Joined channel %s" % channel)

        # Leave channel
        elif msg.startswith("!leave"):
        msg = msg.split(" ", 2)
        channel = msg[1]
        self.leave(channel)
        print("Left channel %s" % (channel))

        # Dice roll
        elif msg.startswith("!roll"):
            user = user.split("!", 2)
            nick = user[0]
            self.msg(channel, nick + " rolled a " + str(random.randint(0,100)))
            print("Rolled dice...")

        # Op user
        elif msg.startswith("!op") or msg.startswith("!+o"):
            msg = msg.split(" ", 2)
            nick = msg[1]

            if isAdmin(nick) == True:
                self.mode(channel, True, "o", user=nick)
            else:
                self.msg(channel, "Not registered as admin, contact bot owner.")

        # Deop user
        elif msg.startswith("!deop") or msg.startswith("!-o"):
            msg = msg.split(" ", 2)
            nick = msg[1]

            if isAdmin(nick) == True:
                self.mode(channel, False, "o", user=nick)
            else:
                self.msg(channel, "Not registered as admin, contact bot owner.")

        # Voice user
        elif msg.startswith("!voice") or msg.startswith("!+v"):
            msg = msg.split(" ", 2)
            nick = msg[1]

            if isAdmin(nick) == True:
                self.mode(channel, True, "v", user=nick)
            else:
                self.msg(channel, "Not registered as admin, contact bot owner.")

        # Devoice user
        elif msg.startswith("!devoice") or msg.startswith("!-v"):
            msg = msg.split(" ", 2)
            nick = msg[1]

            if isAdmin(nick) == True:
                self.mode(channel, False, "v", user=nick)
            else:
                self.msg(channel, "Not registered as admin, contact bot owner.")



class BotFactory(protocol.ClientFactory):
"""Factory for our bot"""
protocol = Bot

    def __init__(self, channel, nickname="IRCBot", username=None, password=None):
        self.channel = channel
        self.nickname = nickname
        self.username = username
        self.password = password

    def clientConnectionLost(self, connector, reason):
        print "Lost connection: (%s)" % (reason,)

    def clientConnectionFailed(self, connector, reason):
        print "Could not connect: %s" % (reason,)


if __name__ == "__main__":
reactor.connectTCP("my.irc.server.com", 6667, BotFactory("Channel", "IRCBot", "Name", "Password"))
reactor.run()

我在 Twisted 文档中找不到任何关于服务器密码的信息,只有频道密码。非常感谢任何帮助!

【问题讨论】:

【参考方案1】:

看看

http://twistedmatrix.com/documents/current/api/twisted.words.protocols.irc.IRCClient.html

我注意到属性password,带有描述:

password =
    Password used to log on to the server. May be None. 

在我看来,您可以在Bot 类上设置密码属性,因此

class Bot(irc.IRCClient):
    def _get_nickname(self):
        return self.factory.nickname

    nickname = property(_get_nickname)
    password = "PASSWORD"

    ...

这有意义吗?它有效吗?

一切顺利:)

【讨论】:

刚试了一下,好像不行。 :( 我没有收到任何错误消息,连接只是超时或什么的。 应该可以!刚刚查看了 IRCClient 的源代码github.com/twisted/twisted/blob/trunk/twisted/words/protocols/… 查看函数registerconnectionMade。正如我所看到的,实现符合 rfc1459(IRC,tools.ietf.org/html/rfc1459.html)第 4.1 节描述连接注册,所以我认为你的问题出在其他地方。 你的 IRC 服务器日志说什么? 我无权访问服务器日志,所以我无法检查...不幸的是我没有弄清楚:/它没有抛出任何异常,我只是得到这个:“失败实例:回溯(无帧失败)::连接已完全关闭。”大约 5 分钟后 我刚看了你的代码,有些东西很不对劲,你似乎没有理解协议和协议工厂之间的关系。感觉就像你有点过头了。我为您编写了一个小脚本,请根据您的需要调整带有大写字母的变量并运行它。请发布输出。然后我会尽力帮助你。 gist.github.com/brunsgaard/6c9d3f2c6dd344180430

以上是关于Python twisted irc - 登录时的服务器密码的主要内容,如果未能解决你的问题,请参考以下文章

Python Twisted IRC,发送颜色信息

如何使用 Twisted 列出 IRC 服务器的频道

Twisted irc python bot - 缓冲消息

Twisted Python IRC Bot - 如何在 bot 运行命令时监听命令?

Twisted Python IRC bot - 如何异步执行函数以便它不会阻塞机器人?

如何使用twisted每隔几秒发送一次IRC消息?