mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
import asyncio
|
|
import functools
|
|
import json
|
|
import os
|
|
from uuid import uuid4
|
|
|
|
DEFAULT_JSON_SETTINGS = {
|
|
"indent": 4,
|
|
"sort_keys": True,
|
|
"separators": (',', ' : ')
|
|
}
|
|
|
|
|
|
class JSONAutosave:
|
|
def __init__(self, interval=5, **settings):
|
|
self.interval = interval
|
|
self._queue = {}
|
|
self._lock = asyncio.Lock()
|
|
self._json_settings = settings.pop("json_settings",
|
|
DEFAULT_JSON_SETTINGS)
|
|
self.loop = asyncio.get_event_loop()
|
|
self.task = self.loop.create_task(self._process_queue())
|
|
|
|
def add_to_queue(self, path, data):
|
|
self._queue[path] = data
|
|
|
|
async def _process_queue(self):
|
|
try:
|
|
while True:
|
|
print("looping")
|
|
queue = self._queue.copy()
|
|
self._queue = {}
|
|
for path, data in queue.items():
|
|
with await self._lock:
|
|
func = functools.partial(self._save_json, path, data)
|
|
try:
|
|
await self.loop.run_in_executor(None, func)
|
|
except Exception as e:
|
|
print(e) # Proper logging here
|
|
|
|
await asyncio.sleep(self.interval)
|
|
except asyncio.CancelledError:
|
|
pass
|
|
|
|
def _save_json(self, path, data):
|
|
print("Saving " + path)
|
|
path, _ = os.path.splitext(path)
|
|
tmp_file = "{}-{}.tmp".format(path, uuid4().fields[0])
|
|
with open(tmp_file, encoding="utf-8", mode="w") as f:
|
|
json.dump(data, f, **self._json_settings)
|
|
os.replace(tmp_file, path) |