MapleX 3.1.0.dev3__py3-none-any.whl → 3.1.0.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maplex/__init__.py +2 -2
- maplex/jsonHandler.py +14 -2
- maplex/library/logger/__init__.py +2 -0
- maplex/library/logger/consts.py +4 -1
- maplex/library/logger/file_handler.py +101 -1
- maplex/mapleLogger.py +7 -43
- {maplex-3.1.0.dev3.dist-info → maplex-3.1.0.dev5.dist-info}/METADATA +1 -1
- maplex-3.1.0.dev5.dist-info/RECORD +19 -0
- maplex/json.py +0 -297
- maplex-3.1.0.dev3.dist-info/RECORD +0 -20
- {maplex-3.1.0.dev3.dist-info → maplex-3.1.0.dev5.dist-info}/WHEEL +0 -0
- {maplex-3.1.0.dev3.dist-info → maplex-3.1.0.dev5.dist-info}/licenses/LICENSE +0 -0
- {maplex-3.1.0.dev3.dist-info → maplex-3.1.0.dev5.dist-info}/top_level.txt +0 -0
maplex/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ MapleExceptions: A set of custom exceptions for handling specific error cases in
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from .mapleColors import ConsoleColors
|
|
10
|
-
from .
|
|
10
|
+
from .jsonHandler import MapleJson, getMapleJson
|
|
11
11
|
from .mapleLogger import Logger, getLogger, getDailyLogger
|
|
12
12
|
from .mapleExceptions import (
|
|
13
13
|
InvalidMapleFileFormatException,
|
|
@@ -52,7 +52,7 @@ __all__ = [
|
|
|
52
52
|
'winUnHide'
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
__version__ = "3.1.0.
|
|
55
|
+
__version__ = "3.1.0.dev5"
|
|
56
56
|
__author__ = "Ryuji Hazama"
|
|
57
57
|
__license__ = "MIT"
|
|
58
58
|
|
maplex/jsonHandler.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import json
|
|
3
1
|
import os
|
|
4
2
|
import base64
|
|
5
3
|
from cryptography.fernet import Fernet
|
|
4
|
+
import datetime
|
|
5
|
+
import json
|
|
6
|
+
import pathlib
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
sys.path.append(str(pathlib.Path(__file__).parent))
|
|
10
|
+
|
|
6
11
|
from mapleExceptions import *
|
|
7
12
|
|
|
8
13
|
class MapleJson:
|
|
@@ -149,6 +154,13 @@ class MapleJson:
|
|
|
149
154
|
|
|
150
155
|
def write(self, data: object, *keys: str) -> None:
|
|
151
156
|
|
|
157
|
+
"""
|
|
158
|
+
Writes data to the JSON file. If keys are provided, the data will be nested accordingly.
|
|
159
|
+
|
|
160
|
+
:param data: The data to write.
|
|
161
|
+
:param keys: Optional keys to nest the data under.
|
|
162
|
+
"""
|
|
163
|
+
|
|
152
164
|
try:
|
|
153
165
|
|
|
154
166
|
if len(keys) > 0:
|
|
@@ -3,11 +3,13 @@ Split mapleLogger.py into multiple files for better organization and maintainabi
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from .config import LoggerConfig
|
|
6
|
+
from .file_handler import FileHandler
|
|
6
7
|
from .formatter import Formatter
|
|
7
8
|
from .log_levels import LogLevel
|
|
8
9
|
from .utilities import *
|
|
9
10
|
|
|
10
11
|
__all__ = [
|
|
12
|
+
"FileHandler",
|
|
11
13
|
"Formatter",
|
|
12
14
|
"LoggerConfig",
|
|
13
15
|
"LogLevel",
|
maplex/library/logger/consts.py
CHANGED
|
@@ -22,4 +22,7 @@ CALLER_NAME = "CallerName"
|
|
|
22
22
|
PROCESS_ID = "pid"
|
|
23
23
|
|
|
24
24
|
FILE_FORMAT = '({pid}) {timestamp} [{level}]{func} {callerName}{callerFunc}({callerLine})'
|
|
25
|
-
CONSOLE_FORMAT = '[{level}]{func} {callerFunc}{callerLine}'
|
|
25
|
+
CONSOLE_FORMAT = '[{level}]{func} {callerFunc}{callerLine}'
|
|
26
|
+
|
|
27
|
+
FILE_MODE_OVERWRITE = 'overwrite'
|
|
28
|
+
FILE_MODE_DAILY = 'daily'
|
|
@@ -1,3 +1,103 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import os
|
|
3
|
+
import pathlib
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
sys.path.append(str(pathlib.Path(__file__).parent.parent.parent))
|
|
7
|
+
|
|
8
|
+
from .consts import *
|
|
9
|
+
from mapleExceptions import MapleLoggerException
|
|
10
|
+
|
|
1
11
|
"""
|
|
2
12
|
File handler for logging.
|
|
3
|
-
"""
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
class FileHandler:
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
FileHandler handles log file size management for the Logger class. It checks the size of the log file and creates a new one if the size exceeds the specified limit.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
logFilePath: str,
|
|
24
|
+
maxFileSize: int,
|
|
25
|
+
fileMode: str
|
|
26
|
+
) -> None:
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
Initialize a FileHandler instance.
|
|
30
|
+
|
|
31
|
+
:param logFilePath: The path to the log file.
|
|
32
|
+
:param maxFileSize: The maximum size of the log file in bytes.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
self.logFilePath = logFilePath
|
|
36
|
+
self.maxFileSize = maxFileSize
|
|
37
|
+
self.fileMode = fileMode
|
|
38
|
+
|
|
39
|
+
def __file_size_exceeded(self) -> bool:
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
Check if the log file exists and if its size exceeds the maximum file size.
|
|
43
|
+
:return: True if the file size exceeds the maximum, False otherwise.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
if os.path.exists(self.logFilePath):
|
|
47
|
+
|
|
48
|
+
fileSize = os.path.getsize(self.logFilePath)
|
|
49
|
+
return fileSize >= self.maxFileSize
|
|
50
|
+
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
def __overwrite_log_file(self) -> None:
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
Overwrite the log file by swapping the current log file with a new one.
|
|
57
|
+
The old log file is renamed with "_old" suffix and a new log file is created with the original name.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
oldLogFilePath = self.logFilePath + "_old"
|
|
61
|
+
|
|
62
|
+
if os.path.exists(oldLogFilePath):
|
|
63
|
+
os.remove(oldLogFilePath)
|
|
64
|
+
|
|
65
|
+
os.rename(self.logFilePath, oldLogFilePath)
|
|
66
|
+
|
|
67
|
+
async def check_file_size(self) -> None:
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
Check the log file size and create a new log file if the size exceeds the maximum file size.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
|
|
75
|
+
if self.maxFileSize < 1 or not self.__file_size_exceeded():
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
if self.fileMode == FILE_MODE_OVERWRITE:
|
|
79
|
+
|
|
80
|
+
self.__overwrite_log_file()
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if self.fileMode == FILE_MODE_DAILY:
|
|
84
|
+
|
|
85
|
+
dateStr = ""
|
|
86
|
+
|
|
87
|
+
else:
|
|
88
|
+
|
|
89
|
+
dateStr = f"_{datetime.now():%Y%m%d_%H%M%S}"
|
|
90
|
+
|
|
91
|
+
i = 0
|
|
92
|
+
logCopyFilePath = f"{self.logFilePath}{dateStr}{i}.log"
|
|
93
|
+
|
|
94
|
+
while os.path.exists(logCopyFilePath):
|
|
95
|
+
|
|
96
|
+
i += 1
|
|
97
|
+
logCopyFilePath = f"{self.logFilePath}{dateStr}{i}.log"
|
|
98
|
+
|
|
99
|
+
os.rename(self.logFilePath, logCopyFilePath)
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
|
|
103
|
+
raise MapleLoggerException(f"Failed to manage log file size: {e}")
|
maplex/mapleLogger.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
import inspect
|
|
3
2
|
import os
|
|
4
3
|
from os import path
|
|
5
4
|
import sys
|
|
6
5
|
import traceback
|
|
7
6
|
from typing import Literal
|
|
8
7
|
|
|
9
|
-
from .json import MapleJson
|
|
10
8
|
from .library.logger import *
|
|
11
9
|
from .mapleExceptions import *
|
|
12
10
|
|
|
@@ -57,6 +55,11 @@ class Logger:
|
|
|
57
55
|
}
|
|
58
56
|
self.config = LoggerConfig(loggerParams)
|
|
59
57
|
self.formatter = Formatter(self.config.serialize())
|
|
58
|
+
self.fileHandler = FileHandler(
|
|
59
|
+
logFilePath=self.config.logfile,
|
|
60
|
+
maxFileSize=self.config.maxLogSize,
|
|
61
|
+
fileMode=self.config.fileMode
|
|
62
|
+
)
|
|
60
63
|
self.DEFAULT_CALLER_DEPTH = 3
|
|
61
64
|
|
|
62
65
|
except Exception as ex:
|
|
@@ -183,51 +186,12 @@ class Logger:
|
|
|
183
186
|
if i == 2:
|
|
184
187
|
raise
|
|
185
188
|
|
|
189
|
+
self.fileHandler.check_file_size()
|
|
190
|
+
|
|
186
191
|
except Exception as ex:
|
|
187
192
|
|
|
188
193
|
raise MapleLoggerException(f"Failed to write log: {ex}") from ex
|
|
189
194
|
|
|
190
|
-
if self.config.maxLogSize > 0:
|
|
191
|
-
|
|
192
|
-
# Check file size
|
|
193
|
-
|
|
194
|
-
try:
|
|
195
|
-
|
|
196
|
-
if path.exists(self.config.logfile) and path.getsize(self.config.logfile) > self.config.maxLogSize:
|
|
197
|
-
|
|
198
|
-
# Rename log file
|
|
199
|
-
|
|
200
|
-
if self.config.fileMode == "overwrite":
|
|
201
|
-
|
|
202
|
-
if path.isfile(f"{self.config.logfile}_old.log"):
|
|
203
|
-
|
|
204
|
-
os.remove(f"{self.config.logfile}_old.log")
|
|
205
|
-
|
|
206
|
-
os.rename(self.config.logfile, f"{self.config.logfile}_old.log")
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
elif self.config.fileMode == "daily":
|
|
210
|
-
|
|
211
|
-
dateStr = ""
|
|
212
|
-
|
|
213
|
-
else:
|
|
214
|
-
|
|
215
|
-
dateStr = f"_{datetime.now():%Y%m%d_%H%M%S}"
|
|
216
|
-
|
|
217
|
-
i = 0
|
|
218
|
-
logCopyFile = f"{self.config.logfile}{dateStr}{i}.log"
|
|
219
|
-
|
|
220
|
-
while path.isfile(logCopyFile):
|
|
221
|
-
|
|
222
|
-
i += 1
|
|
223
|
-
logCopyFile = f"{self.config.logfile}{dateStr}{i}.log"
|
|
224
|
-
|
|
225
|
-
os.rename(self.config.logfile, logCopyFile)
|
|
226
|
-
|
|
227
|
-
except Exception as ex:
|
|
228
|
-
|
|
229
|
-
raise MapleLoggerException(f"Failed to rotate log file: {ex}") from ex
|
|
230
|
-
|
|
231
195
|
#
|
|
232
196
|
################################
|
|
233
197
|
# Trace
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MapleX
|
|
3
|
-
Version: 3.1.0.
|
|
3
|
+
Version: 3.1.0.dev5
|
|
4
4
|
Summary: A Python library for simple logging, json file operations, Maple file format operations, and console color utilities.
|
|
5
5
|
Author: Ryuji Hazama
|
|
6
6
|
Project-URL: PyPI, https://pypi.org/project/MapleX/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
maplex/__init__.py,sha256=H0C9rORHtlwLhVbk4DEXHCYeBIWRqPpioh1OWSRmuqc,1881
|
|
2
|
+
maplex/jsonHandler.py,sha256=HZ4uCUMzs2oaAYWgInc6gzo960q46e7IOk7tTMzqdAE,7445
|
|
3
|
+
maplex/mapleColors.py,sha256=ASg-GstHkyXsq4mVMuFz8Qaq3nQeFayQWcCy9iHzjTs,1543
|
|
4
|
+
maplex/mapleExceptions.py,sha256=zN-GLYNGSWalQ8GiFH-BxRzYhSfbv6V-1O3cA46yAUo,4924
|
|
5
|
+
maplex/mapleLogger.py,sha256=rhSAFkrFt5vsHigvmyXaMp7kOi7LLA_oS5di6uIrYco,10380
|
|
6
|
+
maplex/mapleTreeEditor.py,sha256=5596bARJWHXyGUeXWRYx9lKSfaZdBmGQLvkF_OiKzZ0,29249
|
|
7
|
+
maplex/utils.py,sha256=TcUdfn9uhk9zwMTxtWgsZ1ZKdc2_i0ysgrksMbzvX1I,603
|
|
8
|
+
maplex/library/logger/__init__.py,sha256=TzK7rP_gnljIa_cSpApJgxQBD4huQO9qS5HJGcyuXAI,419
|
|
9
|
+
maplex/library/logger/config.py,sha256=l7YYUv3ZpO3q8Z_7SHGQ6rql8nd1-s5g9SBeZ6gZGi8,10924
|
|
10
|
+
maplex/library/logger/consts.py,sha256=b7fn9TYjJhPgaNPCtYP6f-8SoMGclbRY7TjuyR44kMI,780
|
|
11
|
+
maplex/library/logger/file_handler.py,sha256=MJpguK3oj3v3igGAQCHwtcxtLyC9bVDlUxs1ZekHPS4,2746
|
|
12
|
+
maplex/library/logger/formatter.py,sha256=aThfUV9vxtcSkNNFp9ukCtZFJbuHIuZsAQjpXc03cFc,7260
|
|
13
|
+
maplex/library/logger/log_levels.py,sha256=q4NpokbM6vEabLC7OS-JHZgnhbDROk0yHa5-uM3t_Uw,186
|
|
14
|
+
maplex/library/logger/utilities.py,sha256=-IIPsvrebE4K2fP0fIHT-D55463Zkq3M4SlD0dEZINI,2874
|
|
15
|
+
maplex-3.1.0.dev5.dist-info/licenses/LICENSE,sha256=M7R85ReZ2srvowIPO_c9sHI3DV7QmxnLH93esXVhwGI,1068
|
|
16
|
+
maplex-3.1.0.dev5.dist-info/METADATA,sha256=QYh9oUNUMi-YQxFGHlyXvJA7H4Zf7x8cgVuIhwN5xyY,7389
|
|
17
|
+
maplex-3.1.0.dev5.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
18
|
+
maplex-3.1.0.dev5.dist-info/top_level.txt,sha256=ME8uFV82K0y0KYJrHVTMgc0hEBV67iXXUKsvom7BO5g,7
|
|
19
|
+
maplex-3.1.0.dev5.dist-info/RECORD,,
|
maplex/json.py
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import base64
|
|
5
|
-
from cryptography.fernet import Fernet
|
|
6
|
-
from . import mapleExceptions as mExc
|
|
7
|
-
|
|
8
|
-
class MapleJson:
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
MapleJson is a utility class for handling JSON files with optional encryption support. It provides methods to read and write JSON data, as well as manage encryption keys.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
def __init__(self,
|
|
15
|
-
filePath: str,
|
|
16
|
-
fileEncoding: str = 'utf-8',
|
|
17
|
-
indent: int = 4,
|
|
18
|
-
ensureAscii: bool = False,
|
|
19
|
-
encrypt: bool = False,
|
|
20
|
-
key: bytes = None
|
|
21
|
-
) -> None:
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
|
-
Initialize a MapleJson instance.
|
|
25
|
-
|
|
26
|
-
:param filePath: Path to the JSON file.
|
|
27
|
-
:param fileEncoding: Encoding of the JSON file.
|
|
28
|
-
:param indent: Indentation level for JSON formatting.
|
|
29
|
-
:param ensureAscii: Whether to ensure ASCII characters in JSON.
|
|
30
|
-
:param encrypt: Whether to encrypt the JSON file.
|
|
31
|
-
:param key: Encryption key for the JSON file.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
self.filePath = filePath
|
|
35
|
-
self.fileEncoding = fileEncoding
|
|
36
|
-
self.indent = indent
|
|
37
|
-
self.ensureAscii = ensureAscii
|
|
38
|
-
self.encrypt = encrypt
|
|
39
|
-
self.key = key
|
|
40
|
-
self.fernet = Fernet(key) if encrypt and key else None
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
#####################
|
|
44
|
-
# Getter / Setter
|
|
45
|
-
|
|
46
|
-
def getFilePath(self) -> str:
|
|
47
|
-
|
|
48
|
-
return self.filePath
|
|
49
|
-
|
|
50
|
-
def setFilePath(self, filePath: str) -> None:
|
|
51
|
-
|
|
52
|
-
self.filePath = filePath
|
|
53
|
-
|
|
54
|
-
def getFileEncoding(self) -> str:
|
|
55
|
-
|
|
56
|
-
return self.fileEncoding
|
|
57
|
-
|
|
58
|
-
def setFileEncoding(self, fileEncoding: str) -> None:
|
|
59
|
-
|
|
60
|
-
self.fileEncoding = fileEncoding
|
|
61
|
-
|
|
62
|
-
def getIndent(self) -> int:
|
|
63
|
-
|
|
64
|
-
return self.indent
|
|
65
|
-
|
|
66
|
-
def setIndent(self, indent: int) -> None:
|
|
67
|
-
|
|
68
|
-
self.indent = indent
|
|
69
|
-
|
|
70
|
-
def getEnsureAscii(self) -> bool:
|
|
71
|
-
|
|
72
|
-
return self.ensureAscii
|
|
73
|
-
|
|
74
|
-
def setEnsureAscii(self, ensureAscii: bool) -> None:
|
|
75
|
-
|
|
76
|
-
self.ensureAscii = ensureAscii
|
|
77
|
-
|
|
78
|
-
def isEncrypted(self) -> bool:
|
|
79
|
-
|
|
80
|
-
return self.encrypt
|
|
81
|
-
|
|
82
|
-
def setEncryption(self, encrypt: bool, key: bytes | None = None) -> None:
|
|
83
|
-
|
|
84
|
-
self.encrypt = encrypt
|
|
85
|
-
|
|
86
|
-
if encrypt and not key:
|
|
87
|
-
|
|
88
|
-
raise mExc.KeyEmptyException(self.filePath)
|
|
89
|
-
|
|
90
|
-
self.key = key
|
|
91
|
-
self.fernet = Fernet(key) if encrypt and key else None
|
|
92
|
-
|
|
93
|
-
def getKey(self) -> bytes | None:
|
|
94
|
-
|
|
95
|
-
return self.key
|
|
96
|
-
|
|
97
|
-
def setKey(self, key: bytes) -> None:
|
|
98
|
-
|
|
99
|
-
self.key = key
|
|
100
|
-
self.fernet = Fernet(key) if self.encrypt and key else None
|
|
101
|
-
|
|
102
|
-
#
|
|
103
|
-
#####################
|
|
104
|
-
# Basic File Operations
|
|
105
|
-
|
|
106
|
-
def read(self, *keys: str) -> object | None:
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
|
|
110
|
-
with open(self.filePath, 'rb') as file:
|
|
111
|
-
|
|
112
|
-
data = file.read()
|
|
113
|
-
|
|
114
|
-
if self.encrypt and self.fernet:
|
|
115
|
-
|
|
116
|
-
decryptedData = self.fernet.decrypt(data)
|
|
117
|
-
jsonData = json.loads(decryptedData.decode(self.fileEncoding))
|
|
118
|
-
|
|
119
|
-
else:
|
|
120
|
-
|
|
121
|
-
jsonData = json.loads(data.decode(self.fileEncoding))
|
|
122
|
-
|
|
123
|
-
# Navigate through keys if provided
|
|
124
|
-
|
|
125
|
-
if keys:
|
|
126
|
-
|
|
127
|
-
for jsonKey in keys:
|
|
128
|
-
|
|
129
|
-
if jsonData is None:
|
|
130
|
-
|
|
131
|
-
return None
|
|
132
|
-
|
|
133
|
-
jsonData = jsonData.get(jsonKey, None)
|
|
134
|
-
|
|
135
|
-
return jsonData
|
|
136
|
-
|
|
137
|
-
except FileNotFoundError:
|
|
138
|
-
|
|
139
|
-
raise mExc.MapleFileNotFoundException(self.filePath)
|
|
140
|
-
|
|
141
|
-
except Exception as e:
|
|
142
|
-
|
|
143
|
-
raise mExc.MapleException(f"Error reading JSON file: {e}")
|
|
144
|
-
|
|
145
|
-
def readOrDefault(self, default: object, *keys: str) -> object:
|
|
146
|
-
|
|
147
|
-
result = self.read(*keys)
|
|
148
|
-
return result if result is not None else default
|
|
149
|
-
|
|
150
|
-
def write(self, data: object, *keys: str) -> None:
|
|
151
|
-
|
|
152
|
-
"""
|
|
153
|
-
Writes data to the JSON file. If keys are provided, the data will be nested accordingly.
|
|
154
|
-
|
|
155
|
-
:param data: The data to write.
|
|
156
|
-
:param keys: Optional keys to nest the data under.
|
|
157
|
-
"""
|
|
158
|
-
|
|
159
|
-
try:
|
|
160
|
-
|
|
161
|
-
if len(keys) > 0:
|
|
162
|
-
|
|
163
|
-
# Read existing data to preserve other keys
|
|
164
|
-
|
|
165
|
-
existingData = self.read() or {}
|
|
166
|
-
|
|
167
|
-
# Navigate to the correct location in the nested structure
|
|
168
|
-
|
|
169
|
-
currentLevel = existingData
|
|
170
|
-
|
|
171
|
-
for i, jsonKey in enumerate(keys):
|
|
172
|
-
|
|
173
|
-
if i == len(keys) - 1:
|
|
174
|
-
|
|
175
|
-
currentLevel[jsonKey] = data
|
|
176
|
-
|
|
177
|
-
else:
|
|
178
|
-
|
|
179
|
-
if jsonKey not in currentLevel or not isinstance(currentLevel[jsonKey], dict):
|
|
180
|
-
|
|
181
|
-
currentLevel[jsonKey] = {}
|
|
182
|
-
|
|
183
|
-
currentLevel = currentLevel[jsonKey]
|
|
184
|
-
|
|
185
|
-
dataToWrite = existingData
|
|
186
|
-
|
|
187
|
-
else:
|
|
188
|
-
|
|
189
|
-
dataToWrite = data
|
|
190
|
-
|
|
191
|
-
jsonData = json.dumps(
|
|
192
|
-
dataToWrite,
|
|
193
|
-
indent=self.indent,
|
|
194
|
-
ensure_ascii=self.ensureAscii,
|
|
195
|
-
default=self.datetimeSerializer
|
|
196
|
-
).encode(self.fileEncoding)
|
|
197
|
-
|
|
198
|
-
if self.encrypt and self.fernet:
|
|
199
|
-
|
|
200
|
-
encryptedData = self.fernet.encrypt(jsonData)
|
|
201
|
-
|
|
202
|
-
with open(self.filePath, 'wb') as file:
|
|
203
|
-
|
|
204
|
-
file.write(encryptedData)
|
|
205
|
-
|
|
206
|
-
else:
|
|
207
|
-
|
|
208
|
-
with open(self.filePath, 'wb') as file:
|
|
209
|
-
|
|
210
|
-
file.write(jsonData)
|
|
211
|
-
|
|
212
|
-
except Exception as e:
|
|
213
|
-
|
|
214
|
-
raise mExc.MapleException(f"Error writing JSON file: {e}")
|
|
215
|
-
|
|
216
|
-
#
|
|
217
|
-
#####################
|
|
218
|
-
# Utility Methods
|
|
219
|
-
|
|
220
|
-
#####################
|
|
221
|
-
# Generate Encryption Key
|
|
222
|
-
|
|
223
|
-
def generateKey(self, setAsCurrent: bool = False) -> bytes:
|
|
224
|
-
|
|
225
|
-
"""
|
|
226
|
-
Generates a new Fernet encryption key.
|
|
227
|
-
Args:
|
|
228
|
-
setAsCurrent (bool): If True, sets the generated key as the current key for the instance.
|
|
229
|
-
Returns:
|
|
230
|
-
bytes: The generated encryption key.
|
|
231
|
-
"""
|
|
232
|
-
|
|
233
|
-
key = Fernet.generate_key()
|
|
234
|
-
|
|
235
|
-
if setAsCurrent:
|
|
236
|
-
|
|
237
|
-
self.key = key
|
|
238
|
-
self.fernet = Fernet(key)
|
|
239
|
-
self.encrypt = True
|
|
240
|
-
|
|
241
|
-
return key
|
|
242
|
-
|
|
243
|
-
def datetimeSerializer(self, obj: object) -> str:
|
|
244
|
-
|
|
245
|
-
if isinstance(obj, (datetime.datetime, datetime.date)):
|
|
246
|
-
|
|
247
|
-
return obj.isoformat()
|
|
248
|
-
|
|
249
|
-
raise TypeError(f"Type {type(obj)} not serializable")
|
|
250
|
-
|
|
251
|
-
def datetimeDeserializer(self, obj: str) -> datetime.datetime | datetime.date | str:
|
|
252
|
-
|
|
253
|
-
try:
|
|
254
|
-
|
|
255
|
-
return datetime.datetime.fromisoformat(obj)
|
|
256
|
-
|
|
257
|
-
except ValueError:
|
|
258
|
-
|
|
259
|
-
try:
|
|
260
|
-
|
|
261
|
-
return datetime.date.fromisoformat(obj)
|
|
262
|
-
|
|
263
|
-
except ValueError:
|
|
264
|
-
|
|
265
|
-
return obj
|
|
266
|
-
|
|
267
|
-
_json: dict[str, MapleJson] = {}
|
|
268
|
-
|
|
269
|
-
# Get or create a MapleJson instance
|
|
270
|
-
|
|
271
|
-
def getMapleJson(filePath: str,
|
|
272
|
-
fileEncoding: str = 'utf-8',
|
|
273
|
-
indent: int = 4,
|
|
274
|
-
ensureAscii: bool = False,
|
|
275
|
-
encrypt: bool = False,
|
|
276
|
-
key: bytes = None
|
|
277
|
-
) -> MapleJson:
|
|
278
|
-
|
|
279
|
-
if filePath not in _json:
|
|
280
|
-
|
|
281
|
-
_json[filePath] = MapleJson(filePath,
|
|
282
|
-
fileEncoding,
|
|
283
|
-
indent,
|
|
284
|
-
ensureAscii,
|
|
285
|
-
encrypt,
|
|
286
|
-
key)
|
|
287
|
-
|
|
288
|
-
return _json[filePath]
|
|
289
|
-
|
|
290
|
-
""" * * * * * * * * * * * * * """
|
|
291
|
-
"""
|
|
292
|
-
ToDo list:
|
|
293
|
-
|
|
294
|
-
* Json *
|
|
295
|
-
|
|
296
|
-
"""
|
|
297
|
-
""" * * * * * * * * * * * * * """
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
maplex/__init__.py,sha256=KKQAEzHHxQQKsPx25n46VC_A0Rskamo5NARDofUkkjE,1874
|
|
2
|
-
maplex/json.py,sha256=K8znWB4N0bAKAZLuMRWvjtbAGsFZibGAp151wEwyGlY,7393
|
|
3
|
-
maplex/jsonHandler.py,sha256=K1iqcwp9pGJTHu4E4TmYyeIB2Er4yMdG8Nkc5EaIryc,7143
|
|
4
|
-
maplex/mapleColors.py,sha256=ASg-GstHkyXsq4mVMuFz8Qaq3nQeFayQWcCy9iHzjTs,1543
|
|
5
|
-
maplex/mapleExceptions.py,sha256=zN-GLYNGSWalQ8GiFH-BxRzYhSfbv6V-1O3cA46yAUo,4924
|
|
6
|
-
maplex/mapleLogger.py,sha256=8HgyE83Y9ApodPEs_DwLfDYoAPeoG_QN8YhF2MU5eSk,11415
|
|
7
|
-
maplex/mapleTreeEditor.py,sha256=5596bARJWHXyGUeXWRYx9lKSfaZdBmGQLvkF_OiKzZ0,29249
|
|
8
|
-
maplex/utils.py,sha256=TcUdfn9uhk9zwMTxtWgsZ1ZKdc2_i0ysgrksMbzvX1I,603
|
|
9
|
-
maplex/library/logger/__init__.py,sha256=WsPn25mg8JzMHuPy94E7BapO0Z0SB5hQGiyYoAaB_1c,362
|
|
10
|
-
maplex/library/logger/config.py,sha256=l7YYUv3ZpO3q8Z_7SHGQ6rql8nd1-s5g9SBeZ6gZGi8,10924
|
|
11
|
-
maplex/library/logger/consts.py,sha256=rRGxrzXw5WRdGI0_AK2JtXoZWQTH-EniCz0wgMQjG9M,719
|
|
12
|
-
maplex/library/logger/file_handler.py,sha256=TbIgMTlZ8eR3bTP5UB9OBVF0_s1Pi299S2joRZfuRTc,33
|
|
13
|
-
maplex/library/logger/formatter.py,sha256=aThfUV9vxtcSkNNFp9ukCtZFJbuHIuZsAQjpXc03cFc,7260
|
|
14
|
-
maplex/library/logger/log_levels.py,sha256=q4NpokbM6vEabLC7OS-JHZgnhbDROk0yHa5-uM3t_Uw,186
|
|
15
|
-
maplex/library/logger/utilities.py,sha256=-IIPsvrebE4K2fP0fIHT-D55463Zkq3M4SlD0dEZINI,2874
|
|
16
|
-
maplex-3.1.0.dev3.dist-info/licenses/LICENSE,sha256=M7R85ReZ2srvowIPO_c9sHI3DV7QmxnLH93esXVhwGI,1068
|
|
17
|
-
maplex-3.1.0.dev3.dist-info/METADATA,sha256=SnDmFrDTqD3Jmi4qXgSzU-bdXWB6yxQBJtE5aQvRDy8,7389
|
|
18
|
-
maplex-3.1.0.dev3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
19
|
-
maplex-3.1.0.dev3.dist-info/top_level.txt,sha256=ME8uFV82K0y0KYJrHVTMgc0hEBV67iXXUKsvom7BO5g,7
|
|
20
|
-
maplex-3.1.0.dev3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|