MapleX 3.0.0.dev4__tar.gz → 3.0.1__tar.gz

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.
Files changed (31) hide show
  1. {maplex-3.0.0.dev4/src/MapleX.egg-info → maplex-3.0.1}/PKG-INFO +3 -8
  2. {maplex-3.0.0.dev4 → maplex-3.0.1}/README.md +1 -6
  3. {maplex-3.0.0.dev4 → maplex-3.0.1}/pyproject.toml +2 -2
  4. maplex-3.0.1/readmes/LoggingBestPractice.md +20 -0
  5. maplex-3.0.1/readmes/README_Json.md +321 -0
  6. {maplex-3.0.0.dev4 → maplex-3.0.1}/readmes/README_Logger.md +62 -19
  7. {maplex-3.0.0.dev4 → maplex-3.0.1/src/MapleX.egg-info}/PKG-INFO +3 -8
  8. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/MapleX.egg-info/SOURCES.txt +1 -1
  9. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/__init__.py +3 -2
  10. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/json.py +27 -5
  11. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/mapleLogger.py +37 -4
  12. maplex-3.0.0.dev4/readmes/LoggingTips.md +0 -1
  13. maplex-3.0.0.dev4/readmes/README_Json.md +0 -93
  14. {maplex-3.0.0.dev4 → maplex-3.0.1}/LICENSE +0 -0
  15. {maplex-3.0.0.dev4 → maplex-3.0.1}/MANIFEST.in +0 -0
  16. {maplex-3.0.0.dev4 → maplex-3.0.1}/logErrorOutputSample.png +0 -0
  17. {maplex-3.0.0.dev4 → maplex-3.0.1}/logOutputSample.png +0 -0
  18. {maplex-3.0.0.dev4 → maplex-3.0.1}/readmes/README_ConsoleColors.md +0 -0
  19. {maplex-3.0.0.dev4 → maplex-3.0.1}/readmes/README_Exceptions.md +0 -0
  20. {maplex-3.0.0.dev4 → maplex-3.0.1}/readmes/README_MapleTree.md +0 -0
  21. {maplex-3.0.0.dev4 → maplex-3.0.1}/setup.cfg +0 -0
  22. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/MapleX.egg-info/dependency_links.txt +0 -0
  23. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/MapleX.egg-info/requires.txt +0 -0
  24. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/MapleX.egg-info/top_level.txt +0 -0
  25. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/mapleColors.py +0 -0
  26. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/mapleExceptions.py +0 -0
  27. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/mapleTreeEditor.py +0 -0
  28. {maplex-3.0.0.dev4 → maplex-3.0.1}/src/maplex/utils.py +0 -0
  29. {maplex-3.0.0.dev4 → maplex-3.0.1}/tests/test_logger_unittest.py +0 -0
  30. {maplex-3.0.0.dev4 → maplex-3.0.1}/tests/test_maplejson_unittest.py +0 -0
  31. {maplex-3.0.0.dev4 → maplex-3.0.1}/tests/test_mapletree_unittest.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MapleX
3
- Version: 3.0.0.dev4
3
+ Version: 3.0.1
4
4
  Summary: A Python library for simple logging, json file operations, Maple file format operations, and console color utilities.
5
- Author: RyujiHazama
5
+ Author: Ryuji Hazama
6
6
  Project-URL: PyPI, https://pypi.org/project/MapleX/
7
7
  Project-URL: Homepage, https://github.com/Ryuji-Hazama
8
8
  Project-URL: Repository, https://github.com/Ryuji-Hazama/MapleTree
@@ -78,7 +78,7 @@ Also outputs to the log file:
78
78
 
79
79
  [More details](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/README_Logger.md)
80
80
 
81
- [Logging Tips](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingTips.md)
81
+ [Logging Best Practice](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingBestPractice.md)
82
82
 
83
83
  ## MapleJson
84
84
 
@@ -185,11 +185,6 @@ All datas after "\nEOF\n" will be ignored
185
185
  - `--upgrade` option for upgrade from older version.
186
186
  - `--break-system-package` option for Python on Linux OS outside the `venv`. ***This might brak the system Python package dependencies.***
187
187
 
188
- ### Manual Installation
189
-
190
- 1. Download `./dist/maplex-<version>-py3-none-any.whl`
191
- 2. Run `[python[3] -m] pip install /path/to/downloaded/maplex-<version>-py3-none-any.whl [--break-system-packages]`
192
-
193
188
  ### Build the Package by Yourself
194
189
 
195
190
  &nbsp;&nbsp;&nbsp;&nbsp;Run `python[3] -m build`
@@ -56,7 +56,7 @@ Also outputs to the log file:
56
56
 
57
57
  [More details](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/README_Logger.md)
58
58
 
59
- [Logging Tips](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingTips.md)
59
+ [Logging Best Practice](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingBestPractice.md)
60
60
 
61
61
  ## MapleJson
62
62
 
@@ -163,11 +163,6 @@ All datas after "\nEOF\n" will be ignored
163
163
  - `--upgrade` option for upgrade from older version.
164
164
  - `--break-system-package` option for Python on Linux OS outside the `venv`. ***This might brak the system Python package dependencies.***
165
165
 
166
- ### Manual Installation
167
-
168
- 1. Download `./dist/maplex-<version>-py3-none-any.whl`
169
- 2. Run `[python[3] -m] pip install /path/to/downloaded/maplex-<version>-py3-none-any.whl [--break-system-packages]`
170
-
171
166
  ### Build the Package by Yourself
172
167
 
173
168
  &nbsp;&nbsp;&nbsp;&nbsp;Run `python[3] -m build`
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "MapleX"
7
- version = "3.0.0.dev4"
7
+ version = "3.0.1"
8
8
  description = """A Python library for simple logging, json file operations, Maple file format operations, and console color utilities."""
9
9
  keywords = ["logging", "logger", "json", "file operations", "maple file format", "console colors"]
10
10
  readme = "README.md"
11
11
  license-files = ["LICENSE"]
12
12
  authors = [
13
- {name = "RyujiHazama"}
13
+ {name = "Ryuji Hazama"}
14
14
  ]
15
15
  dependencies = [
16
16
  "cryptography>=46.0.3",
@@ -0,0 +1,20 @@
1
+ # Logging Best Practice
2
+
3
+ ## What Is "Logging"
4
+
5
+ ### The flight recorder of the application
6
+
7
+ &nbsp;&nbsp;&nbsp;&nbsp;When you are developing an application, you might experience that your application is crashing silently. Then you will insert a bunch of `print()` lines to determine where the application failed, and what was causing the error. That is a log, and those outputs are showing the exact path of your process, and help you understand what is working correctly, why, and where your code failed after the application halts.
8
+
9
+ &nbsp;&nbsp;&nbsp;&nbsp;However, those logs are disappearing when you close the output terminal, or the terminal was automatically closed by the application. That is why you need to output logs to a file like a flight recorder in a black box.
10
+
11
+ ### Four W's of Logging
12
+
13
+ &nbsp;&nbsp;&nbsp;&nbsp;Every time the event occurs, the logger should capture the "Four W's" to get the details of the event.
14
+
15
+ - **When** &mdash; When the event occured.
16
+ - **Whrere** &mdash; Where the event happened.
17
+ - **What** &mdash; What was the event.
18
+ - **Weight** &mdash; How seriouc is the event?
19
+
20
+ ### Logging vs `print()`
@@ -0,0 +1,321 @@
1
+ # MapleJson Class
2
+
3
+ &nbsp;&nbsp;&nbsp;&nbsp;MapleJson class is a class library to manage the JSON formatted files.
4
+
5
+ - You can read a JSON file as a `dict` data.
6
+ - You can write the `dict` data into a file as a JSON formatted string
7
+ - You can save the data as an encrypted data string.
8
+ - You can decrypt the encrypted data.
9
+
10
+ ## Class Initialization
11
+
12
+ ```python
13
+
14
+ def __init__(
15
+ filePath: str,
16
+ fileEncoding: str = 'utf-8',
17
+ indent: int = 4,
18
+ ensure_ascii: bool = False,
19
+ encrypt: bool = False,
20
+ key: bytes = None
21
+ ) -> None:
22
+ ```
23
+
24
+ |Property|Required|Value|Version|
25
+ |--------|--------|-----|-------|
26
+ |**`filePath`**|\*|JSON file path|3.0.0|
27
+ |**`fileEncoding`**||File encoding|3.0.0|
28
+ |**`indent`**||Indent size for save as a JSON file|3.0.0|
29
+ |**`ensureAscii`**||Ensure ASCII flag when save to a file|3.0.0|
30
+ |**`encrypt`**||Encryption flag|3.0.0|
31
+ |**`key`**|(\*)|Encryption key (32 bytes)|3.0.0|
32
+
33
+ &nbsp;&nbsp;&nbsp;&nbsp;Initialize the class with a file path.
34
+
35
+ ### File encoding
36
+
37
+ &nbsp;&nbsp;&nbsp;&nbsp;You can set a specific file character encoding. Default: `UTF-8`
38
+
39
+ &nbsp;&nbsp;&nbsp;&nbsp;E.g.: If you are using `Shift_JIS` (Japanese system), you should initialize the class like the example below:
40
+
41
+ ```python
42
+ from maplex import MapleJson
43
+
44
+ jsonInstance = MapleJson("jsonFile.json", fileEncoding="shift_jis")
45
+ ```
46
+
47
+ ### Indent size
48
+
49
+ &nbsp;&nbsp;&nbsp;&nbsp;You can set the block indent size with `indent` parameter. Default: `4`
50
+
51
+ &nbsp;&nbsp;&nbsp;&nbsp;If you set `indent=2`, the file will be save like the example below:
52
+
53
+ ```json
54
+ {
55
+ "Data": {
56
+ "Key": "Value",
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Ensure ASCII
62
+
63
+ &nbsp;&nbsp;&nbsp;&nbsp;You can set the flag to ensure ASCII encoding.
64
+
65
+ &nbsp;&nbsp;&nbsp;&nbsp;If you don't set the parameter (Default: `False`), the file contents after saving are look like the example below:
66
+
67
+ ```json
68
+ {
69
+ "data": {
70
+ "japanese": "値",
71
+ "russian": "значение",
72
+ "english": "value"
73
+ }
74
+ }
75
+ ```
76
+
77
+ &nbsp;&nbsp;&nbsp;&nbsp;But, if you set `ensureAscii=True`, the file contents after saving will be changed like:
78
+
79
+ ```json
80
+ {
81
+ "data": {
82
+ "japanese": "\u5024",
83
+ "russian": "\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435",
84
+ "english": "value"
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### Encrypt
90
+
91
+ &nbsp;&nbsp;&nbsp;&nbsp;If you set `encrypt=True`, set the [encryption key](#key), and save data to a file using the `MapleJson` class, the file will be encrypted with AES-128 (using Fernet).
92
+
93
+ &nbsp;&nbsp;&nbsp;&nbsp;The encrypted file can be read using the `MapleJson` class, and it is also necessary to set `encrypt=True` and use the same key.
94
+
95
+ &nbsp;&nbsp;&nbsp;&nbsp;**There is no *redo*** in encryption. **DO NOT FORGET** your encryption key, or *you will lose your data FOREVER.*
96
+
97
+ ### Key
98
+
99
+ &nbsp;&nbsp;&nbsp;&nbsp;A 32-byte byte-string key for encryption.
100
+
101
+ &nbsp;&nbsp;&nbsp;&nbsp;If you set `encrypt=True` when initializing the class, you must also set the key.
102
+
103
+ &nbsp;&nbsp;&nbsp;&nbsp;Encryption example:
104
+
105
+ ```python
106
+ from maplex import MapleJson
107
+
108
+ key = b'Yj6wIw5VR3Z-4nXXdWTZAhwU6j2SIgSQNl7QbYgDyCA='
109
+ jsonData = MapleJson("sampleFile.json", encrypt=True, key=key)
110
+
111
+ sampleData = {
112
+ "setting1": True,
113
+ "setting2": "value2",
114
+ "setting3": 12345
115
+ }
116
+
117
+ jsonData.write(sampleData)
118
+ ```
119
+
120
+ &nbsp;&nbsp;&nbsp;&nbsp;Inside the `sampleFile.json` will be:
121
+
122
+ ```text
123
+ gAAAAABph_yYxWIyHpS1HImudFoWQQ5WTh2VsPxO4dcXGbYujR62dW1wpZDUf1cZJF-jGzDfTLGHi6e4ihQJRTvNibgIm3sRFLJUyRClRUBSsd1mMmZ0YzFk_ZuinaNSLox3RILZwIMCCE0XbWjw_vs5x_gCKXJQdtEYZ3bSWcSyYBHBAqh3OxA=
124
+ ```
125
+
126
+ &nbsp;&nbsp;&nbsp;&nbsp;The you can read the data with:
127
+
128
+ ```python
129
+ from maplex import MapleJson
130
+
131
+ # Set the same key that was used in encryption
132
+ key = b'Yj6wIw5VR3Z-4nXXdWTZAhwU6j2SIgSQNl7QbYgDyCA='
133
+ jsonData = MapleJson("sampleFile.json", encrypt=True, key=key)
134
+ dictFromJson = jsonData.read()
135
+
136
+ print(dictFromJson)
137
+ ```
138
+
139
+ &nbsp;&nbsp;&nbsp;&nbsp;The console output will be:
140
+
141
+ ```text
142
+ {'setting1': True, 'setting2': 'value2', 'setting3': 12345}
143
+ ```
144
+
145
+ &nbsp;&nbsp;&nbsp;&nbsp;**DO NOT FORGET YOUR ENCRYPTION KEY**, or you will lose your data *FOREVER.* There is no redo in encryption.
146
+
147
+ ## Functions
148
+
149
+ ### `read()`
150
+
151
+ ```python
152
+ def read(
153
+ *keys: str
154
+ ) -> dict | None:
155
+ ```
156
+
157
+ |Property|Required|Value|Version|
158
+ |--------|--------|-----|-------|
159
+ |**`*keys`**||Dict keys|3.0.0|
160
+
161
+ &nbsp;&nbsp;&nbsp;&nbsp;This function reads a JSON file, which is specified at the class instance, and returns the data as a `dict` object.
162
+
163
+ &nbsp;&nbsp;&nbsp;&nbsp;While the data in the `sampleFile.json` is:
164
+
165
+ ```json
166
+ {
167
+ "settings": {
168
+ "setting1": True,
169
+ "setting2": "value2",
170
+ "setting3": 12345
171
+ },
172
+ "data": {
173
+ "data1": "value1",
174
+ "data2": 67890
175
+ }
176
+ }
177
+ ```
178
+
179
+ &nbsp;&nbsp;&nbsp;&nbsp;Read with:
180
+
181
+ ```python
182
+ from maplex import MapleJson
183
+
184
+ jsonFile = MapleJson("sampleFile.json")
185
+ jsonData = jsonFile.read()
186
+
187
+ print(jsonData)
188
+ ```
189
+
190
+ &nbsp;&nbsp;&nbsp;&nbsp;The output will be:
191
+
192
+ ```text
193
+ {'settings': {'setting1': True, 'setting2': 'value2', 'setting3': 12345}, 'data': {'data1': 'value1', 'data2': 67890}}
194
+ ```
195
+
196
+ &nbsp;&nbsp;&nbsp;&nbsp;If you provide the key(s) in the parameter, the function returns the object of the key, and returns `None` if the key does not exist.
197
+
198
+ ```python
199
+ from maplex import MapleJson
200
+
201
+ jsonFile = MapleJson("sampleFile.json")
202
+ jsonData = jsonFile.read("data")
203
+
204
+ print(jsonData)
205
+ ```
206
+
207
+ &nbsp;&nbsp;&nbsp;&nbsp;This outputs:
208
+
209
+ ```text
210
+ {'data1': 'value1', 'data2': 67890}
211
+ ```
212
+
213
+ ### `write()`
214
+
215
+ ```python
216
+ def write(
217
+ data: dict
218
+ ) -> None:
219
+ ```
220
+
221
+ |Property|Required|Value|Version|
222
+ |--------|--------|-----|-------|
223
+ |**`data`**|\*|Dict object to save|3.0.0|
224
+
225
+ &nbsp;&nbsp;&nbsp;&nbsp;This function saves the `dict` object to a file in JSON format.
226
+
227
+ &nbsp;&nbsp;&nbsp;&nbsp;This overwrites the existing file and creates a new file if the file does not exist.
228
+
229
+ ```python
230
+ from maplex import MapleJson
231
+
232
+ jsonFile = MapleJson("sampleFile")
233
+ jsonData = {"data1": True, "data2": "value2", "data3": 12345}
234
+ jsonFile.write(jsonData)
235
+ ```
236
+
237
+ &nbsp;&nbsp;&nbsp;&nbsp;This creates a file that contains the following data:
238
+
239
+ ```json
240
+ {
241
+ "data1": True,
242
+ "data2": "value2",
243
+ "data3": 12345
244
+ }
245
+ ```
246
+
247
+ &nbsp;&nbsp;&nbsp;&nbsp;The function **overwrites the entire file** with the provided data. So you should be careful, especially when reading with the key(s) and saving their data.
248
+
249
+ &nbsp;&nbsp;&nbsp;&nbsp;While the data in the `sampleFile.json` is:
250
+
251
+ ```json
252
+ {
253
+ "settings": {
254
+ "setting1": True,
255
+ "setting2": "value2",
256
+ "setting3": 12345
257
+ },
258
+ "data": {
259
+ "data1": "value1",
260
+ "data2": 67890
261
+ }
262
+ }
263
+ ```
264
+
265
+ ```python
266
+ from maplex import MapleJson
267
+
268
+ jsonFile = MapleJson("sampleFile.json")
269
+ jsonData = jsonFile.read("settings")
270
+ jsonFile.write(jsonData)
271
+ ```
272
+
273
+ &nbsp;&nbsp;&nbsp;&nbsp;This code changes the file contents like the sample below:
274
+
275
+ ```json
276
+ {
277
+ "setting1": True,
278
+ "setting2": "value2",
279
+ "setting3": 12345
280
+ }
281
+ ```
282
+
283
+ ### `generateKey()`
284
+
285
+ ```python
286
+ def generateKey(
287
+ setAsCurrent: bool = False
288
+ ) -> bytes:
289
+ ```
290
+
291
+ |Property|Required|Value|Version|
292
+ |--------|--------|-----|-------|
293
+ |**`setAsCurrent`**||Using the generated key as a current encryption key|3.0.0|
294
+
295
+ &nbsp;&nbsp;&nbsp;&nbsp;The function returns the randomly generated encryption byte-string key.
296
+
297
+ - If you set `setAsCurrent=False`, nothing will be changed in the instance state.
298
+ - If you set `setAsCurrent=True` while the encryption state was set as `True`, the instance encryption key is overwritten by the newly generated key.
299
+ - If you set `setAsCurrent=True` while the encryption state was set as `False`, the instance encryption state is changed to `True` and the newly generated key is set as an encryption key.
300
+
301
+ &nbsp;&nbsp;&nbsp;&nbsp;E.g. Encrypt a json file:
302
+
303
+ ```python
304
+ from maplex import MapleJson
305
+
306
+ jsonFile = MapleJson("sampleFile.json")
307
+ jsonData = jsonFile.read()
308
+ key = jsonFile.generateKey(True)
309
+ # YOU MUST SAVE THE KEY in the safe storage.
310
+ jsonFile.write(jsonData)
311
+ ```
312
+
313
+ &nbsp;&nbsp;&nbsp;&nbsp;The code will encrypt the `sampleFile.json` with AES-128 encryption with the randomly generated key.
314
+
315
+ &nbsp;&nbsp;&nbsp;&nbsp;**There is no *redo*** in encryption. **DO NOT FORGET** your encryption key, or *you will lose your data FOREVER.*
316
+
317
+ ## Getters and Setters
318
+
319
+ &nbsp;&nbsp;&nbsp;&nbsp;Every class parameter has its own getter and setter functions, and you can set, change, or get those values after initializing the class.
320
+
321
+ - You need to set the encryption key when you set the encryption to `True`.
@@ -30,37 +30,50 @@ def __init__(
30
30
 
31
31
  &nbsp;&nbsp;&nbsp;&nbsp;The parameter overwrites the settings configured in `config.mpl`.
32
32
 
33
- ## Usage
33
+ ## Functions
34
+
35
+ ### `getLogger()`
36
+
37
+ ```python
38
+ def getLogger(
39
+ name = "",
40
+ **kwargs
41
+ ) -> maplex.Logger:
42
+ ```
43
+
44
+ |Property|Required|Value|Version|
45
+ |--------|--------|-----|-------|
46
+ |**`name`**||Primary funcion name|`v3.0`|
47
+ |**`**kwargs`**||Other parameters|`v3.0`|
48
+
49
+ &nbsp;&nbsp;&nbsp;&nbsp;This get or creates a Logger instance.
50
+
51
+ &nbsp;&nbsp;&nbsp;&nbsp;If you already have a Logger class instance with the same name, the function returns the existing instance, and you can save your resources on the machine.
34
52
 
35
53
  ```python
36
54
  from maplex
37
55
 
38
- logger = maplex.getLogger("FunctionName")
39
- logger.info("Hello there!")
56
+ logger = maplex.getLogger(__name__)
40
57
  ```
41
58
 
42
- This outputs:
59
+ ## Getters and Setters
43
60
 
44
- ```console
45
- [INFO ][FunctionName] <module>(4) Hello there!
46
- ```
61
+ &nbsp;&nbsp;&nbsp;&nbsp;Every class parameter has its own getter and setter functions, and you can set, change, or get those values after initializing the class.
47
62
 
48
- File output will be: `AppLog.log`
63
+ ## Logging Methods
49
64
 
50
- ```log
51
- (PsNo) yyyy-MM-dd HH:mm:ss.fff [INFO ][FunctionName] <module>(4) Hello there!
65
+ ```python
66
+ def trace(object: any) -> None:
67
+ def debug(object: any) -> None:
68
+ def info(object: any) -> None:
69
+ def warn(object: any) -> None:
70
+ def error(object: any) -> None:
71
+ def fatal(object: any) -> None:
52
72
  ```
53
73
 
54
- ### Log Level
55
-
56
- - `TRACE`
57
- - `DEBUG`
58
- - `INFO`
59
- - `WARN`
60
- - `ERROR`
61
- - `FATAL`
74
+ &nbsp;&nbsp;&nbsp;&nbsp;Each function outputs the log in each log level.
62
75
 
63
- ### ShowError function
76
+ ## `ShowError` Function
64
77
 
65
78
  &nbsp;&nbsp;&nbsp;&nbsp;This outputs the error logs and stuck trace.
66
79
 
@@ -82,6 +95,36 @@ def ShowError(
82
95
 
83
96
  - If `fatal=True`, it outputs log as a `FATAL` log level.
84
97
 
98
+ ## Usage
99
+
100
+ ```python
101
+ from maplex
102
+
103
+ logger = maplex.getLogger("FunctionName")
104
+ logger.info("Hello there!")
105
+ ```
106
+
107
+ This outputs:
108
+
109
+ ```console
110
+ [INFO ][FunctionName] <module>(4) Hello there!
111
+ ```
112
+
113
+ File output will be: `AppLog.log`
114
+
115
+ ```log
116
+ (PsNo) yyyy-MM-dd HH:mm:ss.fff [INFO ][FunctionName] <module>(4) Hello there!
117
+ ```
118
+
119
+ ### Log Level
120
+
121
+ - `TRACE`
122
+ - `DEBUG`
123
+ - `INFO`
124
+ - `WARN`
125
+ - `ERROR`
126
+ - `FATAL`
127
+
85
128
  ## Settings
86
129
 
87
130
  - You can configure log settings with a JSON formatted file (default: `config.json`).
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MapleX
3
- Version: 3.0.0.dev4
3
+ Version: 3.0.1
4
4
  Summary: A Python library for simple logging, json file operations, Maple file format operations, and console color utilities.
5
- Author: RyujiHazama
5
+ Author: Ryuji Hazama
6
6
  Project-URL: PyPI, https://pypi.org/project/MapleX/
7
7
  Project-URL: Homepage, https://github.com/Ryuji-Hazama
8
8
  Project-URL: Repository, https://github.com/Ryuji-Hazama/MapleTree
@@ -78,7 +78,7 @@ Also outputs to the log file:
78
78
 
79
79
  [More details](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/README_Logger.md)
80
80
 
81
- [Logging Tips](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingTips.md)
81
+ [Logging Best Practice](https://github.com/Ryuji-Hazama/MapleTree/blob/main/readmes/LoggingBestPractice.md)
82
82
 
83
83
  ## MapleJson
84
84
 
@@ -185,11 +185,6 @@ All datas after "\nEOF\n" will be ignored
185
185
  - `--upgrade` option for upgrade from older version.
186
186
  - `--break-system-package` option for Python on Linux OS outside the `venv`. ***This might brak the system Python package dependencies.***
187
187
 
188
- ### Manual Installation
189
-
190
- 1. Download `./dist/maplex-<version>-py3-none-any.whl`
191
- 2. Run `[python[3] -m] pip install /path/to/downloaded/maplex-<version>-py3-none-any.whl [--break-system-packages]`
192
-
193
188
  ### Build the Package by Yourself
194
189
 
195
190
  &nbsp;&nbsp;&nbsp;&nbsp;Run `python[3] -m build`
@@ -4,7 +4,7 @@ README.md
4
4
  logErrorOutputSample.png
5
5
  logOutputSample.png
6
6
  pyproject.toml
7
- readmes/LoggingTips.md
7
+ readmes/LoggingBestPractice.md
8
8
  readmes/README_ConsoleColors.md
9
9
  readmes/README_Exceptions.md
10
10
  readmes/README_Json.md
@@ -4,7 +4,7 @@ Logger: A simple logging utility for tracking events and debugging.
4
4
  """
5
5
 
6
6
  from .mapleColors import ConsoleColors
7
- from .json import MapleJson
7
+ from .json import MapleJson, getMapleJson
8
8
  from .mapleLogger import Logger, getLogger, getDailyLogger
9
9
  from .mapleExceptions import (
10
10
  InvalidMapleFileFormatException,
@@ -27,6 +27,7 @@ from .utils import winHide, winUnHide
27
27
  __all__ = [
28
28
  'ConsoleColors',
29
29
  'getDailyLogger',
30
+ 'getMapleJson',
30
31
  'getLogger',
31
32
  'InvalidMapleFileFormatException',
32
33
  'KeyEmptyException',
@@ -48,6 +49,6 @@ __all__ = [
48
49
  'winUnHide'
49
50
  ]
50
51
 
51
- __version__ = "3.0.0.dev4"
52
+ __version__ = "3.0.1"
52
53
  __author__ = "Ryuji Hazama"
53
54
  __license__ = "MIT"
@@ -63,7 +63,7 @@ class MapleJson:
63
63
 
64
64
  return self.encrypt
65
65
 
66
- def setEncryption(self, encrypt: bool, key=None) -> None:
66
+ def setEncryption(self, encrypt: bool, key: bytes | None = None) -> None:
67
67
 
68
68
  self.encrypt = encrypt
69
69
 
@@ -74,7 +74,7 @@ class MapleJson:
74
74
  self.key = key
75
75
  self.fernet = Fernet(key) if encrypt and key else None
76
76
 
77
- def getKey(self) -> bytes:
77
+ def getKey(self) -> bytes | None:
78
78
 
79
79
  return self.key
80
80
 
@@ -87,7 +87,7 @@ class MapleJson:
87
87
  #####################
88
88
  # Basic File Operations
89
89
 
90
- def read(self, *keys) -> dict | None:
90
+ def read(self, *keys: str) -> dict | None:
91
91
 
92
92
  try:
93
93
 
@@ -158,7 +158,6 @@ class MapleJson:
158
158
  #####################
159
159
  # Utility Methods
160
160
 
161
- #
162
161
  #####################
163
162
  # Generate Encryption Key
164
163
 
@@ -180,4 +179,27 @@ class MapleJson:
180
179
  self.fernet = Fernet(key)
181
180
  self.encrypt = True
182
181
 
183
- return key
182
+ return key
183
+
184
+ _json: dict[str, MapleJson] = {}
185
+
186
+ # Get or create a MapleJson instance
187
+
188
+ def getMapleJson(filePath: str,
189
+ fileEncoding: str = 'utf-8',
190
+ indent: int = 4,
191
+ ensureAscii: bool = False,
192
+ encrypt: bool = False,
193
+ key: bytes = None
194
+ ) -> MapleJson:
195
+
196
+ if filePath not in _json:
197
+
198
+ _json[filePath] = MapleJson(filePath,
199
+ fileEncoding,
200
+ indent,
201
+ ensureAscii,
202
+ encrypt,
203
+ key)
204
+
205
+ return _json[filePath]
@@ -37,6 +37,9 @@ class Logger:
37
37
  self.consoleColors = ConsoleColors()
38
38
  self.fileMode = "append" if fileMode is None else fileMode
39
39
  self.encoding = encoding
40
+ self.timestampFormat = "%F %X.%f" # Timestamp format for logs (set this in config in future)
41
+ self.consoleAlignWidth = 16 # Width for function name alignment in logs (set this in config in future)
42
+ self.fileAlignWidth = 4 # Width for function name alignment in logs (set this in config in future)
40
43
 
41
44
  try:
42
45
 
@@ -53,6 +56,7 @@ class Logger:
53
56
  self.__checkOutputDirectory(workingDirectory)
54
57
  self.__setLogFileName(self.fileMode)
55
58
  self.__setFuncName(kwargs.get("getLogger", False), func)
59
+ self.__setAlignWidth(self.consoleAlignWidth, self.fileAlignWidth)
56
60
  self.__setLogFileSize(maxLogSize)
57
61
  self.__setOutputLogLevels(cmdLogLevel, fileLogLevel)
58
62
  self.__setFileEncoding(encoding)
@@ -210,6 +214,26 @@ class Logger:
210
214
  self.func = ""
211
215
  self.callerName = f"{caller}."
212
216
 
217
+ def __setAlignWidth(self, consoleAlignWidth: int | None = None, fileAlignWidth: int | None = None) -> None:
218
+
219
+ '''Set function name alignment width'''
220
+
221
+ if consoleAlignWidth is not None and type(consoleAlignWidth) is int and consoleAlignWidth > 0:
222
+
223
+ self.consoleAlignWidth = consoleAlignWidth
224
+
225
+ else:
226
+
227
+ self.consoleAlignWidth = 16
228
+
229
+ if fileAlignWidth is not None and type(fileAlignWidth) is int and fileAlignWidth > 0:
230
+
231
+ self.fileAlignWidth = fileAlignWidth
232
+
233
+ else:
234
+
235
+ self.fileAlignWidth = 4
236
+
213
237
  def __setLogFileSize(self, maxLogSize: any) -> None:
214
238
 
215
239
  self.maxLogSize = 0
@@ -551,16 +575,26 @@ class Logger:
551
575
  # Export to console and log file
552
576
 
553
577
  if loglevel >= self.consoleLogLevel:
554
- print(f"[{col}{loglevel.name:5}{Reset}]{Green}{self.func}{Reset} {bBlack}{callerFunc}({callerLine}){Reset} {message}")
578
+ consolePrefix = f"[{col}{loglevel.name:5}{Reset}]{Green}{self.func}{Reset} {bBlack}{callerFunc}({callerLine}){Reset}"
579
+ colorLength = len(col) + len(Reset) + len(Green) + len(Reset) + len(bBlack) + len(Reset)
580
+ consolePrefixLength = len(consolePrefix) - colorLength
581
+ consoleAlignWidth = self.consoleAlignWidth * (consolePrefixLength // self.consoleAlignWidth + (1 if consolePrefixLength % self.consoleAlignWidth != 0 else 0))
582
+ consoleAlignWidth += colorLength
583
+ print(f"{consolePrefix:<{consoleAlignWidth}}: {message}")
555
584
 
556
585
  if loglevel >= self.fileLogLevel:
557
586
 
587
+ timeStamp = datetime.now().strftime(self.timestampFormat)[:-3]
588
+ prefixString = f"({self.pid}) {timeStamp} [{loglevel.name:5}]{self.func} {self.callerName}{callerFunc}({callerLine})"
589
+ prefixLength = len(prefixString)
590
+ alignWidth = self.fileAlignWidth * (prefixLength // self.fileAlignWidth + (1 if prefixLength % self.fileAlignWidth != 0 else 0))
591
+
558
592
  for i in range(3):
559
593
 
560
594
  try:
561
595
 
562
596
  with open(self.logfile, "a", encoding=self.encoding) as f:
563
- print(f"({self.pid}) {f"{datetime.now():%F %X.%f}"[:-3]} [{loglevel.name:5}]{self.func} {self.callerName}{callerFunc}({callerLine}) {message}", file=f)
597
+ print(f"{prefixString:<{alignWidth}}: {message}", file=f)
564
598
 
565
599
  break
566
600
 
@@ -703,8 +737,7 @@ class Logger:
703
737
 
704
738
  self.logWriter(logLevel, message, callerDepth=2)
705
739
 
706
- self.logWriter(logLevel, ex, callerDepth=2)
707
- self.logWriter(logLevel, traceback.format_exc(), callerDepth=2)
740
+ self.logWriter(logLevel, f"{ex}\n{traceback.format_exc()}", callerDepth=2)
708
741
 
709
742
  #
710
743
  ################################
@@ -1 +0,0 @@
1
- # Logging Tips
@@ -1,93 +0,0 @@
1
- # MapleJson Class
2
-
3
- &nbsp;&nbsp;&nbsp;&nbsp;MapleJson class is a class library to manage the JSON formatted files.
4
-
5
- - You can read a JSON file as a `dict` data.
6
- - You can write the `dict` data into a file as a JSON formatted string
7
- - You can save the data as an encrypted data string.
8
- - You can decrypt the encrypted data.
9
-
10
- ## Class Initialization
11
-
12
- ```python
13
-
14
- def __init__(
15
- filePath: str,
16
- fileEncoding: str = 'utf-8',
17
- indent: int = 4,
18
- ensure_ascii: bool = False,
19
- encrypt: bool = False,
20
- key: bytes = None
21
- ) -> None:
22
- ```
23
-
24
- |Property|Required|Value|Version|
25
- |--------|--------|-----|-------|
26
- |**filePath**|\*|JSON file path|3.0.0|
27
- |**fileEncoding**||File encoding|3.0.0|
28
- |**indent**||Indent size for save as a JSON file|3.0.0|
29
- |**ensureAscii**||Ensure ASCII flag when save to a file|3.0.0|
30
- |**encrypt**||Encryption flag|3.0.0|
31
- |**key**|(\*)|Encryption key|3.0.0|
32
-
33
- &nbsp;&nbsp;&nbsp;&nbsp;Initialize the class with a file path.
34
-
35
- ### File encoding
36
-
37
- &nbsp;&nbsp;&nbsp;&nbsp;You can set a specific file character encoding. Default: `UTF-8`
38
-
39
- &nbsp;&nbsp;&nbsp;&nbsp;E.g.: If you are using `Shift_JIS` (Japanese system), you should initialize the class like the example below:
40
-
41
- ```python
42
- from maplex import MapleJson
43
-
44
- jsonInstance = MapleJson("jsonFile.json", fileEncoding="shift_jis")
45
- ```
46
-
47
- ### Indent size
48
-
49
- &nbsp;&nbsp;&nbsp;&nbsp;You can set the block indent size with `indent` parameter. Default: `4`
50
-
51
- &nbsp;&nbsp;&nbsp;&nbsp;If you set `indent=2`, the file will be save like the example below:
52
-
53
- ```json
54
- {
55
- "Data": {
56
- "Key": "Value",
57
- }
58
- }
59
- ```
60
-
61
- ### Ensure ASCII
62
-
63
- &nbsp;&nbsp;&nbsp;&nbsp;You can set the flag to ensure ASCII encoding.
64
-
65
- &nbsp;&nbsp;&nbsp;&nbsp;If you don't set the parameter (Default: `False`), the file contents after saving are look like the example below:
66
-
67
- ```json
68
- {
69
- "data": {
70
- "japanese": "値",
71
- "russian": "значение",
72
- "english": "value"
73
- }
74
- }
75
- ```
76
-
77
- &nbsp;&nbsp;&nbsp;&nbsp;But, if you set `ensureAscii=True`, the file contents after saving will be changed like:
78
-
79
- ```json
80
- {
81
- "data": {
82
- "japanese": "\u5024",
83
- "russian": "\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435",
84
- "english": "value"
85
- }
86
- }
87
- ```
88
-
89
- ### Encrypt
90
-
91
- ### Key
92
-
93
- ## Functions
File without changes
File without changes
File without changes
File without changes
File without changes