A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

78 行
2.8 KiB

  1. # -*- coding: utf-8 -*-
  2. """
  3. EarwigBot's IRC Watcher Component
  4. The IRC watcher runs on a wiki recent-changes server and listens for edits.
  5. Users cannot interact with this part of the bot. When an event occurs, run it
  6. through irc/watcher_logic.py's process() function, which can result in either
  7. wiki bot tasks being started (listed in wiki/tasks/) or messages being sent to
  8. channels in the IRC frontend.
  9. """
  10. from core import config
  11. from irc.classes import Connection, RC, BrokenSocketException
  12. from irc import watcher_logic
  13. frontend_conn = None
  14. def get_connection():
  15. """Return a new Connection() instance with information about our server
  16. connection, but don't actually connect yet."""
  17. cf = config.irc.watcher
  18. connection = Connection(cf.host, cf.port, cf.nick, cf.nick, cf.realname)
  19. return connection
  20. def main(connection, f_conn=None):
  21. """Main loop for the Watcher IRC Bot component. get_connection() should
  22. have already been called and the connection should have been started with
  23. connection.connect(). Accept the frontend connection as well as an optional
  24. parameter in order to send messages directly to frontend IRC channels."""
  25. global frontend_conn
  26. frontend_conn = f_conn
  27. read_buffer = str()
  28. while 1:
  29. try:
  30. read_buffer = read_buffer + connection.get()
  31. except BrokenSocketException:
  32. return
  33. lines = read_buffer.split("\n")
  34. read_buffer = lines.pop()
  35. for line in lines:
  36. line = line.strip().split()
  37. if line[1] == "PRIVMSG":
  38. chan = line[2]
  39. # ignore messages originating from channels not in our list, to
  40. # prevent someone PMing us false data
  41. if chan not in config.irc.watcher.channels:
  42. continue
  43. msg = ' '.join(line[3:])[1:]
  44. rc = RC(msg) # new RC object to store this event's data
  45. rc.parse() # parse a message into pagenames, usernames, etc.
  46. process(rc) # report to frontend channels or start tasks
  47. if line[0] == "PING": # if we are pinged, pong back to the server
  48. connection.send("PONG %s" % line[1])
  49. # when we've finished starting up, join all watcher channels
  50. if line[1] == "376":
  51. for chan in config.irc.watcher.channels:
  52. connection.join(chan)
  53. def process(rc):
  54. """Process a message from IRC (technically, an RC object). The actual
  55. processing is configurable, so we don't have that hard-coded here. We
  56. simply call irc/watcher_logic.py's process() function and expect a list of
  57. channels back, which we report the event data to."""
  58. chans = watcher_logic.process(rc)
  59. if chans and frontend_conn:
  60. pretty = rc.get_pretty()
  61. for chan in chans:
  62. frontend_conn.say(chan, pretty)