-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsonfile.py
More file actions
103 lines (86 loc) · 3.1 KB
/
jsonfile.py
File metadata and controls
103 lines (86 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import gzip
import json
import logging.config
from pathlib import Path
class JsonText(dict):
def __str__(self):
return json.dumps(self, ensure_ascii=False, indent='\t', sort_keys=True)
def read_text(self, text: str):
data = json.loads(text)
self.clear()
self.update(data)
class JsonFile(JsonText):
def __init__(self, filename: [Path, str], encoding: str = 'utf-8', log: logging.Logger = None):
super().__init__()
if isinstance(filename, Path):
self._path = filename
else:
self._path = Path(filename)
self._encoding = encoding
self._log = log
@property
def encoding(self) -> str:
return self._encoding
@property
def log(self) -> logging.Logger:
return self._log
@property
def path(self) -> Path:
return self._path
def _read(self):
with open(self.path, 'rt', encoding=self.encoding) as f:
return f.read()
def read(self):
self.read_text(self._read())
def try_read(self) -> bool:
try:
if self.path.is_file():
self.read()
return True
else:
if self.log:
self.log.warning(f'{self.path} not available')
except:
if self.log:
self.log.exception(f'Unable to read: {self.path}')
return False
def _write(self, text: str):
with open(self.path, 'wt', encoding=self.encoding, newline='\n') as f:
f.write(text)
def try_write(self, create_backup: bool = False, check_for_changes: bool = False) -> bool:
try:
self.write(create_backup, check_for_changes)
return True
except:
if self.log:
self.log.exception(f'Unable to write: {self.path}')
return False
def write(self, create_backup: bool = False, check_for_changes: bool = False):
text = str(self)
if (create_backup or check_for_changes) and self.path.is_file():
if check_for_changes:
try:
old = self._read()
if old == text:
if self.log:
self.log.debug(f'No change: {self.path}')
return
except:
if self.log:
self.log.exception(f'Unable to check for changes: {self.path}')
if create_backup:
ext = self._path.suffix
backup_path = self.path.with_suffix('.bak' + ext)
try:
self.path.replace(backup_path)
except:
if self.log:
self.log.exception(f'Unable to replace backup: {backup_path}')
self._write(text)
class JsonGzip(JsonFile):
def _read(self):
with gzip.open(self.path, 'rt', encoding=self.encoding) as f:
return f.read()
def _write(self, text: str):
with gzip.open(self.path, 'wt', compresslevel=9, encoding=self.encoding, newline='\n') as f:
f.write(text)