1
0

main.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import logging, os
  2. import discord
  3. from discord.ext import commands
  4. import asyncpg, asyncio
  5. def sql_db_does_not_exist():
  6. logging.error("Database does not exist. Doublecheck if it has been created, and the user has access.")
  7. quit()
  8. def sql_authentication_error():
  9. logging.error("Database autentication failed. Doublecheck username & password, and if the user has been created.")
  10. quit()
  11. def hint_quit(): # Hint how to edit the settings and quit
  12. logging.info("")
  13. logging.info(" edit local_settings.py")
  14. logging.info("")
  15. quit()
  16. def missing_config(): # Copy or create settings file if missing
  17. logging.basicConfig(level=logging.DEBUG)
  18. if not os.path.exists("local_settings.py"):
  19. logging.error("Settings file not found.")
  20. logging.info("Copying local_settings_example.py to local_settings.py")
  21. try:
  22. os.system("cp local_settings_example.py local_settings.py")
  23. except FileNotFoundError:
  24. logging.info("local_settings_example.py not found, creating local_settings.py")
  25. with open("local_settings.py", "w") as settings_file:
  26. settings_file.writelines(
  27. [
  28. "import logging",
  29. "LOG_LEVEL = logging.INFO # Options: CRITICAL, ERROR, WARNING, INFO, and DEBUG",
  30. "",
  31. "DATABASE_NAME = \"\"",
  32. "DATABASE_USER = \"\"",
  33. "DATABASE_HOST = \"\"",
  34. "DATABASE_PASSWORD = \"\"",
  35. "",
  36. "WEB_HOST = \"\"",
  37. "WEB_SCHEME = \"\"",
  38. "",
  39. "DISCORD_TOKEN = \"\"",
  40. "COMMAND_PREFIX = \"\"",
  41. ]
  42. )
  43. logging.error("Settings undefined.")
  44. logging.info("Configure the settings:")
  45. hint_quit()
  46. def correct_setting(setting): # Hint to correct specific setting and quit
  47. logging.info("Correct the %s in local_settings.py", setting)
  48. hint_quit()
  49. # Attempt to import the local settings and quit gracefully on failure
  50. try:
  51. import local_settings as settings # Environment dependant settings stored in local_settings.py, untracked by .gitinore
  52. except ModuleNotFoundError: # Local settings module import failure
  53. missing_config() # Prepare for configuration and inform operator
  54. async def main():
  55. # Set loglevel
  56. try:
  57. logging.basicConfig(level=settings.LOG_LEVEL)
  58. except AttributeError:
  59. missing_config()
  60. # Define robot
  61. intents = discord.Intents.default()
  62. intents.message_content = True
  63. intents.invites = True
  64. try:
  65. bot = commands.Bot(
  66. command_prefix="/",
  67. description="Charlie's Angels bot",
  68. intents=intents,
  69. case_insensitive=True,
  70. )
  71. except AttributeError:
  72. missing_config()
  73. # Load extensions
  74. default_extensions = [
  75. "commands.admin",
  76. "commands.games",
  77. "commands.general",
  78. "commands.angels",
  79. "events.general",
  80. "events.angels",
  81. ]
  82. for ext in default_extensions:
  83. logging.info(f"Loading extension: {ext}")
  84. await bot.load_extension(ext)
  85. async def create_db_pool(): # Connect to database
  86. try:
  87. bot.pg = await asyncpg.create_pool(
  88. database=settings.DATABASE_NAME,
  89. user=settings.DATABASE_USER,
  90. host=settings.DATABASE_HOST,
  91. password=settings.DATABASE_PASSWORD,
  92. )
  93. except AttributeError:
  94. missing_config()
  95. except asyncpg.exceptions.InvalidPasswordError:
  96. sql_authentication_error()
  97. except asyncpg.exceptions.InvalidCatalogNameError:
  98. sql_db_does_not_exist()
  99. # Create database pool
  100. await create_db_pool()
  101. # Create database tables if they do not exist
  102. from query.initialise_database import init_db, check_db
  103. try:
  104. await check_db(bot.pg)
  105. except asyncpg.exceptions.UndefinedTableError:
  106. logging.info("User table does not exists, assuming empty database. Populating database...")
  107. await init_db(bot.pg)
  108. await bot.start(settings.DISCORD_TOKEN)
  109. # Run robot
  110. try:
  111. asyncio.run(main())
  112. except AttributeError:
  113. missing_config()
  114. except discord.errors.LoginFailure:
  115. logging.error("Invalid discord token.")
  116. correct_setting("DISCORD_TOKEN")
  117. except KeyboardInterrupt:
  118. logging.info("Received keyboard interrupt, exiting...")
  119. quit()