/examples/ircclient.py

https://bitbucket.org/prologic/circuits/ · Python · 186 lines · 88 code · 48 blank · 50 comment · 10 complexity · ca0367b8f98d5e4cd835aef14df73db0 MD5 · raw file

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """Example IRC Client
  4. A basic IRC client with a very basic console interface.
  5. For usage type:
  6. ./ircclient.py --help
  7. """
  8. from __future__ import print_function
  9. import os
  10. from socket import gethostname
  11. from optparse import OptionParser
  12. from circuits import handler, Component
  13. from circuits import __version__ as systemVersion
  14. from circuits.io import stdin
  15. from circuits.net.events import connect
  16. from circuits.net.sockets import TCPClient
  17. from circuits.protocols.irc import IRC, PRIVMSG, USER, NICK, JOIN
  18. USAGE = "%prog [options] host [port]"
  19. VERSION = "%prog v" + systemVersion
  20. def parse_options():
  21. parser = OptionParser(usage=USAGE, version=VERSION)
  22. parser.add_option(
  23. "-n", "--nick",
  24. action="store", default=os.environ["USER"], dest="nick",
  25. help="Nickname to use"
  26. )
  27. parser.add_option(
  28. "-c", "--channel",
  29. action="store", default="#circuits", dest="channel",
  30. help="Channel to join"
  31. )
  32. opts, args = parser.parse_args()
  33. if len(args) < 1:
  34. parser.print_help()
  35. raise SystemExit(1)
  36. return opts, args
  37. class Client(Component):
  38. # Set a separate channel in case we want multiple ``Client`` instances.
  39. channel = "ircclient"
  40. def init(self, host, port=6667, opts=None):
  41. self.host = host
  42. self.port = port
  43. self.opts = opts
  44. self.hostname = gethostname()
  45. self.nick = opts.nick
  46. self.ircchannel = opts.channel
  47. # Add TCPClient and IRC to the system.
  48. TCPClient(channel=self.channel).register(self)
  49. IRC(channel=self.channel).register(self)
  50. def ready(self, component):
  51. """ready Event
  52. This event is triggered by the underlying ``TCPClient`` Component
  53. when it is ready to start making a new connection.
  54. """
  55. self.fire(connect(self.host, self.port))
  56. def connected(self, host, port):
  57. """connected Event
  58. This event is triggered by the underlying ``TCPClient`` Component
  59. when a successfully connection has been made.
  60. """
  61. print("Connected to %s:%d" % (host, port))
  62. nick = self.nick
  63. hostname = self.hostname
  64. name = "%s on %s using circuits/%s" % (nick, hostname, systemVersion)
  65. self.fire(NICK(nick))
  66. self.fire(USER(nick, nick, self.hostname, name))
  67. def numeric(self, source, numeric, *args):
  68. """numeric Event
  69. This event is triggered by the ``IRC`` Protocol Component when we have
  70. received an IRC Numberic Event from server we are connected to.
  71. """
  72. if numeric == 1:
  73. self.fire(JOIN(self.ircchannel))
  74. elif numeric == 433:
  75. self.nick = newnick = "%s_" % self.nick
  76. self.fire(NICK(newnick))
  77. def join(self, source, channel):
  78. """join Event
  79. This event is triggered by the ``IRC`` Protocol Component when a
  80. user has joined a channel.
  81. """
  82. if source[0].lower() == self.nick.lower():
  83. print("Joined %s" % channel)
  84. else:
  85. print(
  86. "--> %s (%s) has joined %s" % (
  87. source[0], "@".join(source[1:]), channel
  88. )
  89. )
  90. def notice(self, source, target, message):
  91. """notice Event
  92. This event is triggered by the ``IRC`` Protocol Component for each
  93. notice we receieve from the server.
  94. """
  95. print("-%s- %s" % (source[0], message))
  96. def privmsg(self, source, target, message):
  97. """privmsg Event
  98. This event is triggered by the ``IRC`` Protocol Component for each
  99. message we receieve from the server.
  100. """
  101. if target[0] == "#":
  102. print("<%s> %s" % (source[0], message))
  103. else:
  104. print("-%s- %s" % (source[0], message))
  105. @handler("read", channel="stdin")
  106. def stdin_read(self, data):
  107. """read Event (on channel ``stdin``)
  108. This is the event handler for ``read`` events specifically from the
  109. ``stdin`` channel. This is triggered each time stdin has data that
  110. it has read.
  111. """
  112. data = data.strip().decode("utf-8")
  113. print("<{0:s}> {1:s}".format(self.nick, data))
  114. self.fire(PRIVMSG(self.ircchannel, data))
  115. def main():
  116. opts, args = parse_options()
  117. host = args[0]
  118. if len(args) > 1:
  119. port = int(args[1])
  120. else:
  121. port = 6667
  122. # Configure and run the system.
  123. client = Client(host, port, opts=opts)
  124. stdin.register(client)
  125. client.run()
  126. if __name__ == "__main__":
  127. main()