Additional IRC commands and bot tasks for EarwigBot https://en.wikipedia.org/wiki/User:EarwigBot
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

122 linhas
4.2 KiB

  1. # Copyright (C) 2016 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. #
  3. # Permission is hereby granted, free of charge, to any person obtaining a copy
  4. # of this software and associated documentation files (the "Software"), to deal
  5. # in the Software without restriction, including without limitation the rights
  6. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. # copies of the Software, and to permit persons to whom the Software is
  8. # furnished to do so, subject to the following conditions:
  9. #
  10. # The above copyright notice and this permission notice shall be included in
  11. # all copies or substantial portions of the Software.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. # SOFTWARE.
  20. import re
  21. from socket import gaierror, gethostbyname
  22. from time import time
  23. from earwigbot.commands import Command
  24. from earwigbot.exceptions import APIError
  25. class BlockMonitor(Command):
  26. """Monitors for on-wiki blocked users joining a particular channel."""
  27. name = "block_monitor"
  28. hooks = ["join"]
  29. def setup(self):
  30. try:
  31. config = self.config.commands[self.name]
  32. self._monitor_chan = config["monitorChannel"]
  33. self._report_chan = config["reportChannel"]
  34. except KeyError:
  35. self._monitor_chan = self._report_chan = None
  36. self.logger.warn("Cannot use without being properly configured")
  37. self._last = None
  38. def check(self, data):
  39. return (
  40. self._monitor_chan and self._report_chan and data.chan == self._monitor_chan
  41. )
  42. def process(self, data):
  43. ip = self._get_ip(data.host)
  44. if not ip:
  45. return
  46. if self._last and self._last[0] == ip:
  47. if time() - self._last[1] < 60 * 5:
  48. self._last = (ip, time())
  49. return
  50. self._last = (ip, time())
  51. block = self._get_block_for_ip(ip)
  52. if not block:
  53. return
  54. msg = (
  55. "\x02[{note}]\x0f Joined user \x02{nick}\x0f is {type}blocked "
  56. "on-wiki ([[User:{user}]]) because: {reason}"
  57. )
  58. self.say(self._report_chan, msg.format(nick=data.nick, **block))
  59. log = (
  60. "Reporting block ({note}): {nick} is [[User:{user}]], "
  61. "{type}blocked because: {reason}"
  62. )
  63. self.logger.info(log.format(nick=data.nick, **block))
  64. def _get_ip(self, host):
  65. """Return the IP corresponding to a particular hostname."""
  66. match = re.search(r"/ip\.(.*?)$", host)
  67. if match:
  68. return match.group(1)
  69. try:
  70. return gethostbyname(host)
  71. except gaierror:
  72. return None
  73. def _get_block_for_ip(self, ip):
  74. """Return a dictionary of blockinfo for an IP."""
  75. site = self.bot.wiki.get_site()
  76. try:
  77. result = site.api_query(
  78. action="query",
  79. list="blocks|globalblocks",
  80. bkip=ip,
  81. bgip=ip,
  82. bklimit=1,
  83. bglimit=1,
  84. bkprop="user|reason|range",
  85. bgprop="address|reason|range",
  86. )
  87. except APIError:
  88. return
  89. lblocks = result["query"]["blocks"]
  90. gblocks = result["query"]["globalblocks"]
  91. if not lblocks and not gblocks:
  92. return
  93. block = lblocks[0] if lblocks else gblocks[0]
  94. if block["rangestart"] != block["rangeend"]:
  95. block["type"] = "range"
  96. else:
  97. block["type"] = "IP-"
  98. if not lblocks:
  99. block["type"] = "globally " + block["type"]
  100. block["user"] = block["address"]
  101. if re.search(r"web[ _-]?host", block["reason"], re.IGNORECASE):
  102. block["note"] = "webhost warning"
  103. else:
  104. block["note"] = "alert"
  105. return block