Experimental Discord bot written in Python
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

utils.py 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """
  2. General utility functions.
  3. """
  4. import re
  5. from datetime import datetime, timedelta
  6. from discord import Guild
  7. from discord.ext.commands import Cog, Group
  8. def parse_timedelta(s: str) -> timedelta:
  9. """
  10. Parses a timespan. Format examples:
  11. "30m"
  12. "10s"
  13. "90d"
  14. "1h30m"
  15. "73d18h22m52s"
  16. """
  17. p = re.compile('^(?:[0-9]+[dhms])+$')
  18. if p.match(s) is None:
  19. raise ValueError("Illegal timespan value '{s}'.")
  20. p = re.compile('([0-9]+)([dhms])')
  21. days = 0
  22. hours = 0
  23. minutes = 0
  24. seconds = 0
  25. for m in p.finditer(s):
  26. scalar = int(m.group(1))
  27. unit = m.group(2)
  28. if unit == 'd':
  29. days = scalar
  30. elif unit == 'h':
  31. hours = scalar
  32. elif unit == 'm':
  33. minutes = scalar
  34. elif unit == 's':
  35. seconds = scalar
  36. return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
  37. def describe_timedelta(td: timedelta, max_components: int = 2) -> str:
  38. """
  39. Formats a human-readable description of a time span. E.g. "3 days 2 hours".
  40. """
  41. d = td.days
  42. h = td.seconds // 3600
  43. m = (td.seconds // 60) % 60
  44. s = td.seconds % 60
  45. components = []
  46. if d != 0:
  47. components.append('1 day' if d == 1 else f'{d} days')
  48. if h != 0:
  49. components.append('1 hour' if h == 1 else f'{h} hours')
  50. if m != 0:
  51. components.append('1 minute' if m == 1 else f'{m} minutes')
  52. if s != 0 or len(components) == 0:
  53. components.append('1 second' if s == 1 else f'{s} seconds')
  54. if len(components) > max_components:
  55. components = components[0:max_components]
  56. return ' '.join(components)
  57. def first_command_group(cog: Cog) -> Group:
  58. """
  59. Returns the first command Group found in a cog.
  60. """
  61. for member_name in dir(cog):
  62. member = getattr(cog, member_name)
  63. if isinstance(member, Group):
  64. return member
  65. return None
  66. def bot_log(guild: Guild, cog_class, message: str) -> None:
  67. """
  68. Logs a message to stdout with time, cog, and guild info.
  69. """
  70. now = datetime.now() # local
  71. s = f'[{now.strftime("%Y-%m-%dT%H:%M:%S")}|'
  72. s += f'{cog_class.__name__}|' if cog_class else '-|'
  73. s += f'{guild.name}] ' if guild else '-] '
  74. s += message
  75. print(s)