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.

пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # -*- coding: utf-8 -*-
  2. import re
  3. from classes import BaseCommand
  4. import config
  5. import wiki
  6. class Command(BaseCommand):
  7. """Get the number of pending AfC submissions, open redirect requests, and
  8. open file upload requests."""
  9. name = "status"
  10. hooks = ["join", "msg"]
  11. def check(self, data):
  12. commands = ["status", "count", "num", "number"]
  13. if data.is_command and data.command in commands:
  14. return True
  15. try:
  16. if data.line[1] == "JOIN" and data.chan == "#wikipedia-en-afc":
  17. if data.nick != config.irc["frontend"]["nick"]:
  18. return True
  19. except IndexError:
  20. pass
  21. return False
  22. def process(self, data):
  23. self.site = wiki.get_site()
  24. self.site._maxlag = None
  25. if data.line[1] == "JOIN":
  26. status = " ".join(("\x02Current status:\x0F", self.get_status()))
  27. self.connection.notice(data.nick, status)
  28. return
  29. if data.args:
  30. action = data.args[0].lower()
  31. if action.startswith("sub") or action == "s":
  32. subs = self.count_submissions()
  33. msg = "there are \x0305{0}\x0301 pending AfC submissions (\x0302WP:AFC\x0301)."
  34. self.connection.reply(data, msg.format(subs))
  35. elif action.startswith("redir") or action == "r":
  36. redirs = self.count_redirects()
  37. msg = "there are \x0305{0}\x0301 open redirect requests (\x0302WP:AFC/R\x0301)."
  38. self.connection.reply(data, msg.format(redirs))
  39. elif action.startswith("file") or action == "f":
  40. files = self.count_redirects()
  41. msg = "there are \x0305{0}\x0301 open file upload requests (\x0302WP:FFU\x0301)."
  42. self.connection.reply(data, msg.format(files))
  43. elif action.startswith("agg") or action == "a":
  44. try:
  45. agg_num = int(data.args[1])
  46. except IndexError:
  47. agg_data = (self.count_submissions(),
  48. self.count_redirects(), self.count_files())
  49. agg_num = self.get_aggregate_number(agg_data)
  50. except ValueError:
  51. msg = "\x0303{0}\x0301 isn't a number!"
  52. self.connection.reply(data, msg.format(data.args[1]))
  53. return
  54. aggregate = self.get_aggregate(agg_num)
  55. msg = "aggregate is \x0305{0}\x0301 (AfC {1})."
  56. self.connection.reply(data, msg.format(agg_num, aggregate))
  57. else:
  58. msg = "unknown argument: \x0303{0}\x0301. Valid args are 'subs', 'redirs', 'files', 'agg'."
  59. self.connection.reply(data, msg.format(data.args[0]))
  60. else:
  61. self.connection.reply(data, self.get_status())
  62. def get_status(self):
  63. subs = self.count_submissions()
  64. redirs = self.count_redirects()
  65. files = self.count_files()
  66. agg_num = self.get_aggregate_number((subs, redirs, files))
  67. aggregate = self.get_aggregate(agg_num)
  68. msg = "Articles for creation {0} (\x0302AFC\x0301: \x0305{1}\x0301; \x0302AFC/R\x0301: \x0305{2}\x0301; \x0302FFU\x0301: \x0305{3}\x0301)."
  69. return msg.format(aggregate, subs, redirs, files)
  70. def count_submissions(self):
  71. """Returns the number of open AFC submissions (count of CAT:PEND)."""
  72. cat = self.site.get_category("Pending AfC submissions")
  73. subs = len(cat.members(limit=500))
  74. # Remove [[Wikipedia:Articles for creation/Redirects]] and
  75. # [[Wikipedia:Files for upload]], which aren't real submissions:
  76. subs -= 2
  77. return subs
  78. def count_redirects(self):
  79. """Returns the number of open redirect submissions. Calculated as the
  80. total number of submissions minus the closed ones."""
  81. title = "Wikipedia:Articles for creation/Redirects"
  82. content = self.site.get_page(title).get()
  83. total = len(re.findall("^\s*==(.*?)==\s*$", content, re.MULTILINE))
  84. closed = content.lower().count("{{afc-c|b}}")
  85. redirs = total - closed
  86. return redirs
  87. def count_files(self):
  88. """Returns the number of open WP:FFU (Files For Upload) requests.
  89. Calculated as the total number of requests minus the closed ones."""
  90. content = self.site.get_page("Wikipedia:Files for upload").get()
  91. total = len(re.findall("^\s*==(.*?)==\s*$", content, re.MULTILINE))
  92. closed = content.lower().count("{{ifu-c|b}}")
  93. files = total - closed
  94. return files
  95. def get_aggregate(self, num):
  96. """Returns a human-readable AFC status based on the number of pending
  97. AFC submissions, open redirect requests, and open FFU requests. This
  98. does not match {{AFC status}} directly because my algorithm factors in
  99. WP:AFC/R and WP:FFU while the template only looks at the main
  100. submissions. My reasoning is that AFC/R and FFU are still part of
  101. the project, so even if there are no pending submissions, a backlog at
  102. FFU (for example) indicates that our work is *not* done and the
  103. project-wide backlog is most certainly *not* clear."""
  104. if num == 0:
  105. return "is \x02\x0303clear\x0301\x0F"
  106. elif num < 125: # < 25 subs
  107. return "is \x0303almost clear\x0301"
  108. elif num < 200: # < 40 subs
  109. return "is \x0312normal\x0301"
  110. elif num < 275: # < 55 subs
  111. return "is \x0307lightly backlogged\x0301"
  112. elif num < 350: # < 70 subs
  113. return "is \x0304backlogged\x0301"
  114. elif num < 500: # < 100 subs
  115. return "is \x02\x0304heavily backlogged\x0301\x0F"
  116. else: # >= 100 subs
  117. return "is \x02\x1F\x0304severely backlogged\x0301\x0F"
  118. def get_aggregate_number(self, (subs, redirs, files)):
  119. """Returns an 'aggregate number' based on the real number of pending
  120. submissions in CAT:PEND (subs), open redirect submissions in WP:AFC/R
  121. (redirs), and open files-for-upload requests in WP:FFU (files)."""
  122. num = (subs * 5) + (redirs * 2) + (files * 2)
  123. return num