Experimental Discord bot written in Python
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

urlspamcog.py 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from discord import Guild, Message
  2. from discord.ext import commands
  3. import re
  4. from datetime import timedelta
  5. from cogs.basecog import BaseCog
  6. from config import CONFIG
  7. from storage import Storage
  8. class URLSpamCog(BaseCog):
  9. CONFIG_KEY_EARLY_URL_TIMEOUT = "urlspam_early_url_timeout"
  10. CONFIG_KEY_EARLY_URL_ACTION = "urlspam_early_url_action"
  11. def __init__(self, bot):
  12. super().__init__(bot)
  13. def __early_url_timeout(self, guild: Guild) -> int:
  14. return Storage.get_config_value(guild, self.CONFIG_KEY_EARLY_URL_TIMEOUT) or \
  15. self.get_cog_default('early_url_timeout')
  16. def __early_url_action(self, guild: Guild) -> str:
  17. return Storage.get_config_value(guild, self.CONFIG_KEY_EARLY_URL_ACTION) or \
  18. self.get_cog_default('early_url_action')
  19. @commands.Cog.listener()
  20. async def on_message(self, message: Message):
  21. if message.guild is None or message.channel is None:
  22. # DM or something
  23. return
  24. action = self.__early_url_action(message.guild)
  25. if action == 'nothing':
  26. return
  27. if message.author.permissions_in(message.channel).ban_members:
  28. # Mods are exempt
  29. return
  30. if not self.__contains_url(message.content):
  31. return
  32. join_age = message.created_at - message.author.joined_at
  33. join_age_str = self.__format_timedelta(join_age)
  34. if join_age.total_seconds() < self.__early_url_timeout(message.guild):
  35. if action == 'modwarn':
  36. await self.warn(message.guild, f'User {message.author.mention} ' +
  37. f'posted a URL {join_age_str} after joining.\n\n> {message.content}')
  38. # TODO: Emoji actions
  39. elif action == 'delete':
  40. await message.delete()
  41. # TODO: Info to mods
  42. elif action == 'kick':
  43. await message.author.kick(reason=f'User posted a link {join_age_str} after joining')
  44. # TODO: Info to mods
  45. elif action == 'ban':
  46. await message.author.ban(reason=f'User posted a link {join_age_str} after joining', delete_message_days=1)
  47. # TODO: Info to mods
  48. def __contains_url(self, text: str) -> bool:
  49. p = re.compile(r'http(?:s)?://[^\s]+')
  50. return p.search(text) is not None
  51. def __format_timedelta(self, timespan: timedelta) -> str:
  52. parts = []
  53. d = timespan.days
  54. h = timespan.seconds // 3600
  55. m = (timespan.seconds // 60) % 60
  56. s = timespan.seconds % 60
  57. if d > 0:
  58. parts.append(f'{d} days')
  59. if d > 0 or h > 0:
  60. parts.append(f'{h} hours')
  61. if d > 0 or h > 0 or m > 0:
  62. parts.append(f'{m} minutes')
  63. parts.append(f'{s} seconds')
  64. # Limit the precision to the two most significant elements
  65. while len(parts) > 2:
  66. parts.pop(-1)
  67. return ' '.join(parts)