61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
|
import os
|
||
|
import stat
|
||
|
import json
|
||
|
import asyncio
|
||
|
|
||
|
|
||
|
class WalletStorage:
|
||
|
VERSION = 1
|
||
|
|
||
|
def __init__(self, path=None):
|
||
|
self.path = path
|
||
|
|
||
|
def sync_read(self):
|
||
|
with open(self.path, 'r') as f:
|
||
|
json_data = f.read()
|
||
|
json_dict = json.loads(json_data)
|
||
|
if json_dict.get('version') == self.VERSION:
|
||
|
return json_dict
|
||
|
else:
|
||
|
return self.upgrade(json_dict)
|
||
|
|
||
|
async def read(self):
|
||
|
return await asyncio.get_running_loop().run_in_executor(
|
||
|
None, self.sync_read
|
||
|
)
|
||
|
|
||
|
def upgrade(self, json_dict):
|
||
|
version = json_dict.pop('version', -1)
|
||
|
if version == -1:
|
||
|
pass
|
||
|
json_dict['version'] = self.VERSION
|
||
|
return json_dict
|
||
|
|
||
|
def sync_write(self, json_dict):
|
||
|
|
||
|
json_data = json.dumps(json_dict, indent=4, sort_keys=True)
|
||
|
if self.path is None:
|
||
|
return json_data
|
||
|
|
||
|
temp_path = "{}.tmp.{}".format(self.path, os.getpid())
|
||
|
with open(temp_path, "w") as f:
|
||
|
f.write(json_data)
|
||
|
f.flush()
|
||
|
os.fsync(f.fileno())
|
||
|
|
||
|
if os.path.exists(self.path):
|
||
|
mode = os.stat(self.path).st_mode
|
||
|
else:
|
||
|
mode = stat.S_IREAD | stat.S_IWRITE
|
||
|
try:
|
||
|
os.rename(temp_path, self.path)
|
||
|
except Exception: # pylint: disable=broad-except
|
||
|
os.remove(self.path)
|
||
|
os.rename(temp_path, self.path)
|
||
|
os.chmod(self.path, mode)
|
||
|
|
||
|
async def write(self, json_dict):
|
||
|
return await asyncio.get_running_loop().run_in_executor(
|
||
|
None, self.sync_write, json_dict
|
||
|
)
|