KiTTY, un bot Discord qui est un petit chat :) Il est basé sur une ancienne version du bot Red, sous Python 3.6 et qui a des fonctionnalités bien sympatiques !
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

300 lines
11KB

  1. from .dataIO import dataIO
  2. from copy import deepcopy
  3. import discord
  4. import os
  5. import argparse
  6. default_path = "data/red/settings.json"
  7. class Settings:
  8. def __init__(self, path=default_path, parse_args=True):
  9. self.path = path
  10. self.check_folders()
  11. self.default_settings = {
  12. "TOKEN": None,
  13. "EMAIL": None,
  14. "PASSWORD": None,
  15. "OWNER": None,
  16. "PREFIXES": [],
  17. "default": {"ADMIN_ROLE": "Transistor",
  18. "MOD_ROLE": "Process",
  19. "PREFIXES": []}
  20. }
  21. self._memory_only = False
  22. if not dataIO.is_valid_json(self.path):
  23. self.bot_settings = deepcopy(self.default_settings)
  24. self.save_settings()
  25. else:
  26. current = dataIO.load_json(self.path)
  27. if current.keys() != self.default_settings.keys():
  28. for key in self.default_settings.keys():
  29. if key not in current.keys():
  30. current[key] = self.default_settings[key]
  31. print("Adding " + str(key) +
  32. " field to red settings.json")
  33. dataIO.save_json(self.path, current)
  34. self.bot_settings = dataIO.load_json(self.path)
  35. if "default" not in self.bot_settings:
  36. self.update_old_settings_v1()
  37. if "LOGIN_TYPE" in self.bot_settings:
  38. self.update_old_settings_v2()
  39. if parse_args:
  40. self.parse_cmd_arguments()
  41. def parse_cmd_arguments(self):
  42. parser = argparse.ArgumentParser(description="Red - Discord Bot")
  43. parser.add_argument("--owner", help="ID of the owner. Only who hosts "
  44. "Red should be owner, this has "
  45. "security implications")
  46. parser.add_argument("--co-owner", action="append", default=[],
  47. help="ID of a co-owner. Only people who have "
  48. "access to the system that is hosting Red "
  49. "should be co-owners, as this gives them "
  50. "complete access to the system's data. "
  51. "This has serious security implications if "
  52. "misused. Can be multiple.")
  53. parser.add_argument("--prefix", "-p", action="append",
  54. help="Global prefix. Can be multiple")
  55. parser.add_argument("--admin-role", help="Role seen as admin role by "
  56. "Red")
  57. parser.add_argument("--mod-role", help="Role seen as mod role by Red")
  58. parser.add_argument("--no-prompt",
  59. action="store_true",
  60. help="Disables console inputs. Features requiring "
  61. "console interaction could be disabled as a "
  62. "result")
  63. parser.add_argument("--no-cogs",
  64. action="store_true",
  65. help="Starts Red with no cogs loaded, only core")
  66. parser.add_argument("--self-bot",
  67. action='store_true',
  68. help="Specifies if Red should log in as selfbot")
  69. parser.add_argument("--memory-only",
  70. action="store_true",
  71. help="Arguments passed and future edits to the "
  72. "settings will not be saved to disk")
  73. parser.add_argument("--dry-run",
  74. action="store_true",
  75. help="Makes Red quit with code 0 just before the "
  76. "login. This is useful for testing the boot "
  77. "process.")
  78. parser.add_argument("--debug",
  79. action="store_true",
  80. help="Enables debug mode")
  81. args = parser.parse_args()
  82. if args.owner:
  83. self.owner = args.owner
  84. if args.prefix:
  85. self.prefixes = sorted(args.prefix, reverse=True)
  86. if args.admin_role:
  87. self.default_admin = args.admin_role
  88. if args.mod_role:
  89. self.default_mod = args.mod_role
  90. self.no_prompt = args.no_prompt
  91. self.self_bot = args.self_bot
  92. self._memory_only = args.memory_only
  93. self._no_cogs = args.no_cogs
  94. self.debug = args.debug
  95. self._dry_run = args.dry_run
  96. self.co_owners = args.co_owner
  97. self.save_settings()
  98. def check_folders(self):
  99. folders = ("data", os.path.dirname(self.path), "cogs", "cogs/utils")
  100. for folder in folders:
  101. if not os.path.exists(folder):
  102. print("Creating " + folder + " folder...")
  103. os.makedirs(folder)
  104. def save_settings(self):
  105. if not self._memory_only:
  106. dataIO.save_json(self.path, self.bot_settings)
  107. def update_old_settings_v1(self):
  108. # This converts the old settings format
  109. mod = self.bot_settings["MOD_ROLE"]
  110. admin = self.bot_settings["ADMIN_ROLE"]
  111. del self.bot_settings["MOD_ROLE"]
  112. del self.bot_settings["ADMIN_ROLE"]
  113. self.bot_settings["default"] = {"MOD_ROLE": mod,
  114. "ADMIN_ROLE": admin,
  115. "PREFIXES": []
  116. }
  117. self.save_settings()
  118. def update_old_settings_v2(self):
  119. # The joys of backwards compatibility
  120. settings = self.bot_settings
  121. if settings["EMAIL"] == "EmailHere":
  122. settings["EMAIL"] = None
  123. if settings["PASSWORD"] == "":
  124. settings["PASSWORD"] = None
  125. if settings["LOGIN_TYPE"] == "token":
  126. settings["TOKEN"] = settings["EMAIL"]
  127. settings["EMAIL"] = None
  128. settings["PASSWORD"] = None
  129. else:
  130. settings["TOKEN"] = None
  131. del settings["LOGIN_TYPE"]
  132. self.save_settings()
  133. @property
  134. def owner(self):
  135. return self.bot_settings["OWNER"]
  136. @owner.setter
  137. def owner(self, value):
  138. self.bot_settings["OWNER"] = value
  139. @property
  140. def token(self):
  141. return os.environ.get("RED_TOKEN", self.bot_settings["TOKEN"])
  142. @token.setter
  143. def token(self, value):
  144. self.bot_settings["TOKEN"] = value
  145. self.bot_settings["EMAIL"] = None
  146. self.bot_settings["PASSWORD"] = None
  147. @property
  148. def email(self):
  149. return os.environ.get("RED_EMAIL", self.bot_settings["EMAIL"])
  150. @email.setter
  151. def email(self, value):
  152. self.bot_settings["EMAIL"] = value
  153. self.bot_settings["TOKEN"] = None
  154. @property
  155. def password(self):
  156. return os.environ.get("RED_PASSWORD", self.bot_settings["PASSWORD"])
  157. @password.setter
  158. def password(self, value):
  159. self.bot_settings["PASSWORD"] = value
  160. @property
  161. def login_credentials(self):
  162. if self.token:
  163. return (self.token,)
  164. elif self.email and self.password:
  165. return (self.email, self.password)
  166. else:
  167. return tuple()
  168. @property
  169. def prefixes(self):
  170. return self.bot_settings["PREFIXES"]
  171. @prefixes.setter
  172. def prefixes(self, value):
  173. assert isinstance(value, list)
  174. self.bot_settings["PREFIXES"] = value
  175. @property
  176. def default_admin(self):
  177. if "default" not in self.bot_settings:
  178. self.update_old_settings()
  179. return self.bot_settings["default"].get("ADMIN_ROLE", "")
  180. @default_admin.setter
  181. def default_admin(self, value):
  182. if "default" not in self.bot_settings:
  183. self.update_old_settings()
  184. self.bot_settings["default"]["ADMIN_ROLE"] = value
  185. @property
  186. def default_mod(self):
  187. if "default" not in self.bot_settings:
  188. self.update_old_settings_v1()
  189. return self.bot_settings["default"].get("MOD_ROLE", "")
  190. @default_mod.setter
  191. def default_mod(self, value):
  192. if "default" not in self.bot_settings:
  193. self.update_old_settings_v1()
  194. self.bot_settings["default"]["MOD_ROLE"] = value
  195. @property
  196. def servers(self):
  197. ret = {}
  198. server_ids = list(
  199. filter(lambda x: str(x).isdigit(), self.bot_settings))
  200. for server in server_ids:
  201. ret.update({server: self.bot_settings[server]})
  202. return ret
  203. def get_server(self, server):
  204. if server is None:
  205. return self.bot_settings["default"].copy()
  206. assert isinstance(server, discord.Server)
  207. return self.bot_settings.get(server.id,
  208. self.bot_settings["default"]).copy()
  209. def get_server_admin(self, server):
  210. if server is None:
  211. return self.default_admin
  212. assert isinstance(server, discord.Server)
  213. if server.id not in self.bot_settings:
  214. return self.default_admin
  215. return self.bot_settings[server.id].get("ADMIN_ROLE", "")
  216. def set_server_admin(self, server, value):
  217. if server is None:
  218. return
  219. assert isinstance(server, discord.Server)
  220. if server.id not in self.bot_settings:
  221. self.add_server(server.id)
  222. self.bot_settings[server.id]["ADMIN_ROLE"] = value
  223. self.save_settings()
  224. def get_server_mod(self, server):
  225. if server is None:
  226. return self.default_mod
  227. assert isinstance(server, discord.Server)
  228. if server.id not in self.bot_settings:
  229. return self.default_mod
  230. return self.bot_settings[server.id].get("MOD_ROLE", "")
  231. def set_server_mod(self, server, value):
  232. if server is None:
  233. return
  234. assert isinstance(server, discord.Server)
  235. if server.id not in self.bot_settings:
  236. self.add_server(server.id)
  237. self.bot_settings[server.id]["MOD_ROLE"] = value
  238. self.save_settings()
  239. def get_server_prefixes(self, server):
  240. if server is None or server.id not in self.bot_settings:
  241. return self.prefixes
  242. return self.bot_settings[server.id].get("PREFIXES", [])
  243. def set_server_prefixes(self, server, prefixes):
  244. if server is None:
  245. return
  246. assert isinstance(server, discord.Server)
  247. if server.id not in self.bot_settings:
  248. self.add_server(server.id)
  249. self.bot_settings[server.id]["PREFIXES"] = prefixes
  250. self.save_settings()
  251. def get_prefixes(self, server):
  252. """Returns server's prefixes if set, otherwise global ones"""
  253. p = self.get_server_prefixes(server)
  254. return p if p else self.prefixes
  255. def add_server(self, sid):
  256. self.bot_settings[sid] = self.bot_settings["default"].copy()
  257. self.save_settings()