Obsidian-Development/helia

[ISSUE] When settings.json loses its content the bot becomes braindead

Closed this issue · 3 comments

Describe the bug
When settings.json loses its contents the bot becomes braindead
Settings.json usually gets purged of contents when the machine the bot is hosted on runs out of storage space

To Reproduce
Just wait for host machine to run out of free storage space and the bug happens

Expected behavior
Bot not going braindead and settings.json not getting contents purged

it will need a rework of utils.py cog and extensive testing

more specifically

@asyncinit
class Settings:
    guild_id: int = 0
    settings: Dict = None

    async def __init__(self, _guild_id: int) -> None:
        self.guild_id = _guild_id

        async with async_open(
                dirname(abspath(__file__)) + "/../data/settings.json",
                "r") as f:
            self.settings = json.loads(await f.read())

    async def __save(self) -> NoReturn:
        async with async_open(
                dirname(abspath(__file__)) + "/../data/settings.json",
                "w") as f:
            await f.write(json.dumps(self.settings, indent=4))

    async def __create_guild_object(self) -> NoReturn:
        self.settings[str(str(self.guild_id))] = {}
        await self.__save()

    async def create_empty_field(self, field: AnyStr) -> NoReturn:
        try:
            self.settings[str(self.guild_id)][field] = None
            await self.__save()
        except:
            await self.__create_guild_object()
            self.settings[str(self.guild_id)][field] = None
            await self.__save()

    async def get_field(self, field: AnyStr, default_value: Any = None) -> Any:
        try:
            val = self.settings[str(self.guild_id)][field]
        except:
            await self.create_empty_field(field)
            val = self.settings[str(self.guild_id)][field]

        if val is not None or default_value is None:
            return self.settings[str(self.guild_id)][field]

        await self.set_field(field, default_value)
        return default_value

    async def set_field(self, field: AnyStr, value) -> NoReturn:
        try:
            self.settings[str(self.guild_id)][field] = value
            await self.__save()
        except:
            await self.create_empty_field(field)
            self.settings[str(self.guild_id)][field] = value
            await self.__save()

this class inside utils.py cog

Except i dont have too much idea on how to approach fixing this situation
Someone suggested reworking it to store settings in ram and dumping settings on a remote file storage - but i doubt i can rework it myself to do it that way