spacepaste

  1.  
  2. from __future__ import print_function
  3. # twisted imports
  4. from twisted.words.protocols import irc
  5. from twisted.internet import reactor, protocol
  6. from twisted.python import log
  7. # system imports
  8. import time, sys
  9. class MessageLogger:
  10. """
  11. An independent logger class (because separation of application
  12. and protocol logic is a good thing).
  13. """
  14. def __init__(self, file):
  15. self.file = file
  16. def log(self, message):
  17. """Write a message to the file."""
  18. timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
  19. self.file.write('%s %s\n' % (timestamp, message))
  20. self.file.flush()
  21. def close(self):
  22. self.file.close()
  23. class LogBot(irc.IRCClient):
  24. """A logging IRC bot."""
  25. nickname = "twistedbot"
  26. def connectionMade(self):
  27. irc.IRCClient.connectionMade(self)
  28. self.logger = MessageLogger(open(self.factory.filename, "a"))
  29. self.logger.log("[connected at %s]" %
  30. time.asctime(time.localtime(time.time())))
  31. def connectionLost(self, reason):
  32. irc.IRCClient.connectionLost(self, reason)
  33. self.logger.log("[disconnected at %s]" %
  34. time.asctime(time.localtime(time.time())))
  35. self.logger.close()
  36. # callbacks for events
  37. def signedOn(self):
  38. """Called when bot has successfully signed on to server."""
  39. self.join(self.factory.channel)
  40. def joined(self, channel):
  41. """This will get called when the bot joins the channel."""
  42. self.logger.log("[I have joined %s]" % channel)
  43. def privmsg(self, user, channel, msg):
  44. """This will get called when the bot receives a message."""
  45. user = user.split('!', 1)[0]
  46. self.logger.log("<%s> %s" % (user, msg))
  47. # Check to see if they're sending me a private message
  48. if channel == self.nickname:
  49. msg = "It isn't nice to whisper! Play nice with the group."
  50. #run function
  51. runfunction(self)
  52. self.msg(user, msg)
  53. return
  54. # Otherwise check to see if it is a message directed at me
  55. if msg.startswith(self.nickname + ":"):
  56. msg = "%s: I am a log bot" % user
  57. self.msg(channel, msg)
  58. self.logger.log("<%s> %s" % (self.nickname, msg))
  59. def runfuntion(self):
  60. print("-----Ran function")
  61. def action(self, user, channel, msg):
  62. """This will get called when the bot sees someone do an action."""
  63. user = user.split('!', 1)[0]
  64. self.logger.log("* %s %s" % (user, msg))
  65. # irc callbacks
  66. def irc_NICK(self, prefix, params):
  67. """Called when an IRC user changes their nickname."""
  68. old_nick = prefix.split('!')[0]
  69. new_nick = params[0]
  70. self.logger.log("%s is now known as %s" % (old_nick, new_nick))
  71. # For fun, override the method that determines how a nickname is changed on
  72. # collisions. The default method appends an underscore.
  73. def alterCollidedNick(self, nickname):
  74. """
  75. Generate an altered version of a nickname that caused a collision in an
  76. effort to create an unused related name for subsequent registration.
  77. """
  78. return nickname + '^'
  79. class LogBotFactory(protocol.ClientFactory):
  80. """A factory for LogBots.
  81. A new protocol instance will be created each time we connect to the server.
  82. """
  83. def __init__(self, channel, filename):
  84. self.channel = channel
  85. self.filename = filename
  86. def buildProtocol(self, addr):
  87. p = LogBot()
  88. p.factory = self
  89. return p
  90. def clientConnectionLost(self, connector, reason):
  91. """If we get disconnected, reconnect to server."""
  92. connector.connect()
  93. def clientConnectionFailed(self, connector, reason):
  94. print("connection failed:", reason)
  95. reactor.stop()
  96. if __name__ == '__main__':
  97. # initialize logging
  98. log.startLogging(sys.stdout)
  99. # create factory protocol and application
  100. f = LogBotFactory(sys.argv[1], sys.argv[2])
  101. # connect factory to this host and port
  102. reactor.connectTCP("irc.freenode.net", 6667, f)
  103. # run bot
  104. reactor.run()
  105.