Good Example of Twisted IRC Server?
Asked Answered
P

3

5

I'm in the process of experimenting a bit with the twisted libraries for IRC servers/clients. I've found a few good examples of how to implement an IRC client but seem to find anything good on the server side of things. Could anybody provide some insight into how to create a basic IRC server in twisted?

Edit: What about building off of this? Am I going the right direction here?

from twisted.internet.protocol import ServerFactory
from twisted.internet import reactor
from twisted.words.protocols.irc import IRC


class IRCServer(IRC):
    def connectionMade(self):
        print "client connected"

    def handleCommand(self, command, prefix, params):
        print "handle comm"
        IRC.handleCommand(self, command, prefix, params)

    def dataReceived(self, data):
        print "data: %s" % data
        IRC.dataReceived(self, data)

    def irc_unknown(self, prefix, command, params):
        print "%s, %s, %s, IRC UNKNOWN" % (prefix, command, params)

    def irc_USER(self, prefix, params):
        print "USER: %s, %s" % (prefix, params)

    def irc_NICK(self, prefix, params):
        print "NICK: %s, %s" % (prefix, params)



class IRCServerFactory(ServerFactory):
    protocol = IRCServer

factory = IRCServerFactory()
reactor.listenTCP(8002, factory)
reactor.run()

When I try to join the channel I am never able to. I was getting an error relating to not having a handler for a command, so I wrote up the irc_USER and irc_NICK methods but that merely got rid of the error, it didn't solve the problem of not connecting/not working.

Pollinosis answered 29/6, 2010 at 14:8 Comment(0)
S
8

Perhaps something like this?

exarkun@boson:/tmp/irc-server$ cat > passwd
alice:secret
bob:19820522
exarkun@boson:/tmp/irc-server$ twistd -n words --irc-port 6667 --auth file:passwd
2010-06-29 11:51:26-0400 [-] Log opened.
2010-06-29 11:51:26-0400 [-] twistd 10.0.0+r29436 (/usr/bin/python 2.6.4) starting up.
2010-06-29 11:51:26-0400 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2010-06-29 11:51:26-0400 [-] twisted.words.service.IRCFactory starting on 6667
2010-06-29 11:51:26-0400 [-] Starting factory <twisted.words.service.IRCFactory instance at 0x9ddbf8c>

If you'd like to see how this is implemented, see twisted/words/tap.py

twisted.words.protocols.irc.IRC is a very basic implementation of just the parsing parts of an IRC server. It implements no actual server logic such as channels, modes, messages, etc. You can build a server on it, but you have to build almost the whole thing. This is precisely what the code invoked by twistd words does. You may want to refer to its implementation to see a successful example of what the code in your question is aiming towards.

Scrupulous answered 29/6, 2010 at 15:53 Comment(2)
So are you saying that I am going the right direction, but I'll need to continue adding features/methods to support the full protocol? Or would it be better to start from scratch and not use words.protocols.irc.IRC and just use words.Service? I'm somewhat confused as to why there is twisted.service and then twisted.irc then? Which one is the proper one to work from?Pollinosis
The intent of twisted.words.service is that you can base an IRC server on it. There may be a gap between intent and reality; this is a part of Twisted which isn't extremely widely used. That doesn't mean twisted.words.service won't work for you though, since that depends on exactly what your goals are. As for why there is both twisted.words.protocols.irc.IRC and twisted.words.service, that's easy - the former is used as the basis of the implementation of the latter.Scrupulous
S
0

I came across this book which has the following code which will run a full on twistd words server and allow you to create channels etc. Here's the code from the book.

from twisted.cred import checkers, portal
from twisted.internet import reactor
from twisted.words import service

wordsRealm = service.InMemoryWordsRealm("example.com")
wordsRealm.createGroupOnRequest = True

checker = checkers.FilePasswordDB("authfile.txt")
portal = portal.Portal(wordsRealm, [checker])

reactor.listenTCP(6667, service.IRCFactory(wordsRealm, portal))
reactor.run()

The book: http://books.google.com/books?id=_g5UNxWUKsMC&printsec=frontcover#v=onepage Go to page 119 and you'll find it's description. Buy the book, it's a good one.

Sarson answered 26/10, 2014 at 1:48 Comment(0)
S
0

If you want a simple 'anonymous' twisted IRC server, this is basically the easiest way to go about it:

from twisted.application import internet, service
from twisted.cred import checkers, portal, credentials
from twisted.cred.checkers import ICredentialsChecker
from twisted.internet import defer
from twisted.words import service as wordsservice
from zope.interface import implements

wordsRealm = wordsservice.InMemoryWordsRealm("example.com")
wordsRealm.createGroupOnRequest = True
wordsRealm.createUserOnRequest = True

class UserAnon:
  implements(ICredentialsChecker)
  credentialInterfaces = (credentials.IUsernamePassword, credentials.IUsernameHashedPassword)

  def __init__(self):
    pass

  def addUser(self, username, password):
    pass

  def _cbPasswordMatch(self, matched, username):
    return username

  def requestAvatarId(self, credentials):
    return defer.succeed(credentials.username)

class IRCAnonymous(wordsservice.IRCUser):
  def irc_NICK(self, prefix, params):
    self.password = 'doesntmatter'
    wordsservice.IRCUser.irc_NICK(self, prefix, params)


checker = UserAnon()
portal = portal.Portal(wordsRealm, [checker])

servicefactory = wordsservice.IRCFactory(wordsRealm, portal)
servicefactory.protocol=IRCAnonymous

application = service.Application("ircserver")
ircservice = internet.TCPServer(6667, servicefactory)
ircservice.setServiceParent(application)

You can then execute this from twistd with twistd -nol- -y irc_server.py.

The tricky bit as mentioned in other answers is that the various message messages on the twisted protocol object have expectations on their input/returns, so you'll have to go to the module documentation, and sometimes the sourcecode to figure out whats needed there.

Staggers answered 24/6, 2015 at 2:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.