A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
5.8 KiB

  1. # -*- coding: utf-8 -*-
  2. # Report the status of AFC submissions, either as an automatic message on join or a request via !status.
  3. import json
  4. import re
  5. import urllib
  6. from irc.base_command import BaseCommand
  7. class AFCStatus(BaseCommand):
  8. def get_hooks(self):
  9. return ["join", "msg"]
  10. def get_help(self, command):
  11. return "Get the number of pending AfC submissions, open redirect requests, and open file upload requests."
  12. def check(self, data):
  13. if data.is_command and (data.command == "status" or
  14. data.command == "count" or data.command == "num" or
  15. data.command == "number" or data.command == "afc_status"):
  16. return True
  17. try:
  18. if data.line[1] == "JOIN" and data.chan == "#wikipedia-en-afc":
  19. return True
  20. except IndexError:
  21. pass
  22. return False
  23. def process(self, data):
  24. if data.line[1] == "JOIN":
  25. notice = self.get_join_notice()
  26. self.connection.notice(data.nick, notice)
  27. return
  28. if data.args:
  29. if data.args[0].startswith("sub") or data.args[0] == "s":
  30. subs = self.count_submissions()
  31. self.connection.reply(data, "there are currently %s pending AfC submissions." % subs)
  32. elif data.args[0].startswith("redir") or data.args[0] == "r":
  33. redirs = self.count_redirects()
  34. self.connection.reply(data, "there are currently %s open redirect requests." % redirs)
  35. elif data.args[0].startswith("file") or data.args[0] == "f":
  36. files = self.count_redirects()
  37. self.connection.reply(data, "there are currently %s open file upload requests." % files)
  38. elif data.args[0].startswith("agg") or data.args[0] == "a":
  39. try:
  40. agg_num = int(data.args[1])
  41. except IndexError:
  42. agg_data = (self.count_submissions(), self.count_redirects(), self.count_files())
  43. agg_num = self.get_aggregate_number(agg_data)
  44. except ValueError:
  45. self.connection.reply(data, "\x0303%s\x0301 isn't a number!" % data.args[1])
  46. return
  47. aggregate = self.get_aggregate(agg_num)
  48. self.connection.reply(data, "aggregate is currently %s (AfC %s)." % (agg_num, aggregate))
  49. elif data.args[0].startswith("join") or data.args[0] == "j":
  50. notice = self.get_join_notice()
  51. self.connection.reply(data, notice)
  52. else:
  53. self.connection.reply(data, "unknown argument: \x0303%s\x0301. Valid args are 'subs', 'redirs', 'files', 'agg', and 'join'." % data.args[0])
  54. else:
  55. subs = self.count_submissions()
  56. redirs = self.count_redirects()
  57. files = self.count_files()
  58. self.connection.reply(data, "there are currently %s pending submissions, %s open redirect requests, and %s open file upload requests."
  59. % (subs, redirs, files))
  60. def get_join_notice(self):
  61. subs = self.count_submissions()
  62. redirs = self.count_redirects()
  63. files = self.count_files()
  64. agg_num = self.get_aggregate_number((subs, redirs, files))
  65. aggregate = self.get_aggregate(agg_num)
  66. return ("\x02Current status:\x0F Articles for Creation %s (\x0302AFC\x0301: \x0305%s\x0301; \x0302AFC/R\x0301: \x0305%s\x0301; \x0302FFU\x0301: \x0305%s\x0301)"
  67. % (aggregate, subs, redirs, files))
  68. def count_submissions(self):
  69. params = {'action': 'query', 'list': 'categorymembers', 'cmlimit':'500', 'format': 'json'}
  70. params['cmtitle'] = "Category:Pending_AfC_submissions"
  71. data = urllib.urlencode(params)
  72. raw = urllib.urlopen("http://en.wikipedia.org/w/api.php", data).read()
  73. res = json.loads(raw)
  74. subs = len(res['query']['categorymembers'])
  75. subs -= 2 # remove [[Wikipedia:Articles for creation/Redirects]] and [[Wikipedia:Files for upload]], which aren't real submissions
  76. return subs
  77. def count_redirects(self):
  78. content = self.get_page("Wikipedia:Articles_for_creation/Redirects")
  79. total = len(re.findall("^\s*==(.*?)==\s*$", content, re.MULTILINE))
  80. closed = content.lower().count("{{afc-c|b}}")
  81. redirs = total - closed
  82. return redirs
  83. def count_files(self):
  84. content = self.get_page("Wikipedia:Files_for_upload")
  85. total = len(re.findall("^\s*==(.*?)==\s*$", content, re.MULTILINE))
  86. closed = content.lower().count("{{ifu-c|b}}")
  87. files = total - closed
  88. return files
  89. def get_page(self, pagename):
  90. params = {'action': 'query', 'prop': 'revisions', 'rvprop':'content', 'rvlimit':'1', 'format': 'json'}
  91. params['titles'] = pagename
  92. data = urllib.urlencode(params)
  93. raw = urllib.urlopen("http://en.wikipedia.org/w/api.php", data).read()
  94. res = json.loads(raw)
  95. pageid = res['query']['pages'].keys()[0]
  96. content = res['query']['pages'][pageid]['revisions'][0]['*']
  97. return content
  98. def get_aggregate(self, num):
  99. if num == 0:
  100. agg = "is \x02\x0303clear\x0301\x0F"
  101. elif num < 60:
  102. agg = "is \x0303almost clear\x0301"
  103. elif num < 125:
  104. agg = "has a \x0312small backlog\x0301"
  105. elif num < 175:
  106. agg = "has an \x0307average backlog\x0301"
  107. elif num < 250:
  108. agg = "is \x0304backlogged\x0301"
  109. elif num < 300:
  110. agg = "is \x02\x0304heavily backlogged\x0301\x0F"
  111. else:
  112. agg = "is \x02\x1F\x0304severely backlogged\x0301\x0F"
  113. return agg
  114. def get_aggregate_number(self, (subs, redirs, files)):
  115. num = (subs * 5) + (redirs * 2) + (files * 2)
  116. return num