Experimental Discord bot written in Python
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

storage.py 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import json
  2. from os.path import exists
  3. from discord import Guild
  4. from config import CONFIG
  5. class Storage:
  6. """
  7. Static class for managing persisted bot state.
  8. """
  9. # discord.Guild.id -> dict
  10. __guild_id_to_state = {}
  11. def state_for_guild(guild: Guild) -> dict:
  12. """
  13. Returns the state for the given guild, loading from disk if necessary.
  14. Always returns a dict.
  15. """
  16. state: dict = __guild_id_to_state[guild.id]
  17. if state is not None:
  18. # Already in memory
  19. return state
  20. # Load from disk if possible
  21. __trace(f'No loaded state for guild {guild.id}. Attempting to load from disk.')
  22. state = __load_guild_state(guild)
  23. __guild_id_to_state[guild.id] = state
  24. return state
  25. def save_guild_state(guild: Guild) -> NoneType:
  26. """
  27. Saves state for the given guild to disk, if any exists.
  28. """
  29. state: dict = __guild_id_to_state[guild.id]
  30. if state is None:
  31. # Nothing to save
  32. return
  33. __save_guild_state(guild, state)
  34. def __save_guild_state(guild: Guild, state: dict) -> NoneType:
  35. """
  36. Saves state for a guild to a JSON file on disk.
  37. """
  38. path: str = __guild_path(guild)
  39. __trace('Saving state for guild {guild.id} to {path}')
  40. with open(path, 'w') as file:
  41. # Pretty printing to make more legible for debugging
  42. # Sorting keys to help with diffs
  43. json.dump(state, file, indent='\t', sort_keys=True)
  44. __trace('State saved')
  45. def __load_guild_state(guild: Guild) -> dict:
  46. """
  47. Loads state for a guild from a JSON file on disk.
  48. """
  49. path: str = __guild_path(guild)
  50. if not exists(path):
  51. __trace(f'No state on disk for guild {guild.id}. Returning {{}}.')
  52. return {}
  53. __trace('Loading state from disk for guild {guild.id}')
  54. with open(path, 'r') as file:
  55. state = json.load(file)
  56. __trace('State loaded')
  57. return state
  58. def __guild_path(guild: Guild) -> str:
  59. """
  60. Returns the JSON file path where guild state should be written.
  61. """
  62. config_value: str = CONFIG['statePath']
  63. path: str = config_value if config_value.endswith('/') else f'{config_value}/'
  64. return f'{path}guild_{guild.id}.json'
  65. def __trace(message: str) -> NoneType:
  66. print(f'{Storage.__name__}: {message}')