A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

130 rindas
4.9 KiB

  1. # -*- coding: utf-8 -*-
  2. # Manage wiki tasks from IRC, and check on thread status.
  3. import threading, re
  4. from irc.base_command import BaseCommand
  5. from irc.data import *
  6. from wiki import task_manager
  7. from config.main import *
  8. from config.irc import *
  9. class Tasks(BaseCommand):
  10. def get_hooks(self):
  11. return ["msg"]
  12. def get_help(self, command):
  13. return "Manage wiki tasks from IRC, and check on thread status."
  14. def check(self, data):
  15. if data.is_command and data.command in ["tasks", "threads", "tasklist"]:
  16. return True
  17. return False
  18. def process(self, data):
  19. self.data = data
  20. if data.host not in OWNERS:
  21. self.connection.reply(data, "at this time, you must be a bot owner to use this command.")
  22. return
  23. if not data.args:
  24. if data.command == "tasklist":
  25. self.do_list()
  26. else:
  27. self.connection.reply(data, "no arguments provided. Maybe you wanted '!{cmnd} list', '!{cmnd} start', or '!{cmnd} listall'?".format(cmnd=data.command))
  28. return
  29. if data.args[0] == "list":
  30. self.do_list()
  31. elif data.args[0] == "start":
  32. self.do_start()
  33. elif data.args[0] in ["listall", "all"]:
  34. self.do_listall()
  35. else: # they asked us to do something we don't know
  36. self.connection.reply(data, "unknown argument: \x0303{}\x0301.".format(data.args[0]))
  37. def do_list(self):
  38. threads = threading.enumerate()
  39. normal_threads = []
  40. task_threads = []
  41. for thread in threads:
  42. tname = thread.name
  43. if tname == "MainThread":
  44. tname = self.get_main_thread_name()
  45. normal_threads.append("\x0302{}\x0301 (as main thread, id {})".format(tname, thread.ident))
  46. elif tname in ["irc-frontend", "irc-watcher", "wiki-scheduler"]:
  47. normal_threads.append("\x0302{}\x0301 (id {})".format(tname, thread.ident))
  48. else:
  49. tname, start_time = re.findall("^(.*?) \((.*?)\)$", tname)[0]
  50. task_threads.append("\x0302{}\x0301 (id {}, spawned at {})".format(tname, thread.ident, start_time))
  51. if task_threads:
  52. msg = "\x02{}\x0F threads active: {}, and \x02{}\x0F task threads: {}.".format(len(threads), ', '.join(normal_threads), len(task_threads), ', '.join(task_threads))
  53. else:
  54. msg = "\x02{}\x0F threads active: {}, and \x020\x0F task threads.".format(len(threads), ', '.join(normal_threads))
  55. self.connection.reply(self.data, msg)
  56. def do_listall(self):
  57. tasks = task_manager.task_list.keys()
  58. threadlist = threading.enumerate()
  59. threads = map(lambda t: t.name, threadlist)
  60. tasklist = []
  61. tasks.sort()
  62. for task in tasks:
  63. threads_running_task = [t for t in threads if t.name.startswith(task)]
  64. ids = map(lambda t: t.ident, threads_running_task)
  65. if not ids:
  66. tasklist.append("\x0302{}\x0301 (idle)".format(task))
  67. elif len(ids) == 1:
  68. tasklist.append("\x0302{}\x0301 (\x02active\x0F as id {})".format(task, ids[0]))
  69. else:
  70. tasklist.append("\x0302{}\x0301 (\x02active\x0F as ids {})".format(task, ' ,'.join(ids)))
  71. tasklist = ", ".join(tasklist)
  72. msg = "{} tasks loaded: {}.".format(len(tasks), tasklist)
  73. self.connection.reply(self.data, msg)
  74. def do_start(self):
  75. data = self.data
  76. try:
  77. task_name = data.args[1]
  78. except IndexError: # no task name given
  79. self.connection.reply(data, "what task do you want me to start?")
  80. return
  81. try:
  82. data.parse_kwargs()
  83. except KwargParseException, arg:
  84. self.connection.reply(data, "error parsing argument: \x0303{}\x0301.".format(arg))
  85. return
  86. if task_name not in task_manager.task_list.keys(): # this task does not exist or hasn't been loaded
  87. self.connection.reply(data, "task could not be found; either wiki/tasks/{}.py doesn't exist, or it wasn't loaded correctly.".format(task_name))
  88. return
  89. if data.kwargs:
  90. task_manager.start_task(task_name, **data.kwargs)
  91. self.connection.reply(data, "task \x0302{}\x0301 started with arguments: {}.".format(task_name, data.kwargs))
  92. else:
  93. task_manager.start_task(task_name)
  94. self.connection.reply(data, "task \x0302{}\x0301 started.".format(task_name))
  95. def get_main_thread_name(self):
  96. """Return the "proper" name of the MainThread; e.g. "irc-frontend" or "irc-watcher"."""
  97. if enable_irc_frontend:
  98. return "irc-frontend"
  99. elif enable_wiki_schedule:
  100. return "wiki-scheduler"
  101. else:
  102. return "irc-watcher"