absfuyu 5.0.1__py3-none-any.whl → 5.2.0__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.
Potentially problematic release.
This version of absfuyu might be problematic. Click here for more details.
- absfuyu/__init__.py +1 -1
- absfuyu/__main__.py +3 -3
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +30 -14
- absfuyu/cli/config_group.py +9 -2
- absfuyu/cli/do_group.py +13 -6
- absfuyu/cli/game_group.py +9 -2
- absfuyu/cli/tool_group.py +15 -9
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +448 -79
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +70 -4
- absfuyu/core/docstring.py +43 -25
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +15 -4
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +5 -2
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +34 -3
- absfuyu/dxt/listext.py +300 -113
- absfuyu/dxt/strext.py +75 -15
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +36 -0
- absfuyu/extra/da/dadf.py +1177 -0
- absfuyu/extra/da/dadf_base.py +186 -0
- absfuyu/extra/da/df_func.py +97 -0
- absfuyu/extra/da/mplt.py +219 -0
- absfuyu/extra/data_analysis.py +10 -1067
- absfuyu/fun/__init__.py +2 -2
- absfuyu/fun/tarot.py +2 -2
- absfuyu/game/__init__.py +2 -2
- absfuyu/game/game_stat.py +2 -2
- absfuyu/game/sudoku.py +2 -2
- absfuyu/game/tictactoe.py +2 -3
- absfuyu/game/wordle.py +2 -2
- absfuyu/general/__init__.py +2 -2
- absfuyu/general/content.py +2 -2
- absfuyu/general/human.py +2 -2
- absfuyu/general/shape.py +2 -2
- absfuyu/logger.py +2 -2
- absfuyu/pkg_data/__init__.py +2 -2
- absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu/sort.py +2 -2
- absfuyu/tools/__init__.py +28 -2
- absfuyu/tools/checksum.py +27 -7
- absfuyu/tools/converter.py +120 -34
- absfuyu/tools/generator.py +251 -110
- absfuyu/tools/inspector.py +463 -0
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +45 -7
- absfuyu/tools/passwordlib.py +88 -24
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +136 -0
- absfuyu/util/__init__.py +18 -4
- absfuyu/util/api.py +36 -16
- absfuyu/util/json_method.py +43 -14
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +190 -82
- absfuyu/util/performance.py +122 -7
- absfuyu/util/shorten_number.py +40 -10
- absfuyu/util/text_table.py +306 -0
- absfuyu/util/zipped.py +8 -7
- absfuyu/version.py +2 -2
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/METADATA +9 -2
- absfuyu-5.2.0.dist-info/RECORD +76 -0
- absfuyu-5.0.1.dist-info/RECORD +0 -68
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/tools/passwordlib.py
CHANGED
|
@@ -3,13 +3,13 @@ Absfuyu: Passwordlib
|
|
|
3
3
|
--------------------
|
|
4
4
|
Password library
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 15/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
11
11
|
# ---------------------------------------------------------------------------
|
|
12
|
-
__all__ = ["PasswordGenerator", "TOTP"]
|
|
12
|
+
__all__ = ["PasswordGenerator", "PasswordHash", "TOTP"]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
# Library
|
|
@@ -21,12 +21,12 @@ import re
|
|
|
21
21
|
from typing import ClassVar, Literal, NamedTuple
|
|
22
22
|
from urllib.parse import quote, urlencode
|
|
23
23
|
|
|
24
|
-
from absfuyu.core import BaseClass
|
|
24
|
+
from absfuyu.core.baseclass import BaseClass
|
|
25
|
+
from absfuyu.core.docstring import deprecated, versionadded
|
|
25
26
|
from absfuyu.dxt import DictExt, Text
|
|
26
27
|
from absfuyu.logger import logger
|
|
27
28
|
from absfuyu.pkg_data import DataList, DataLoader
|
|
28
29
|
from absfuyu.tools.generator import Charset, Generator
|
|
29
|
-
from absfuyu.util import set_min
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
# Function
|
|
@@ -88,6 +88,18 @@ def _password_check(password: str) -> bool:
|
|
|
88
88
|
# Class
|
|
89
89
|
# ---------------------------------------------------------------------------
|
|
90
90
|
class PasswordHash(NamedTuple):
|
|
91
|
+
"""
|
|
92
|
+
Password hash
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
salt : bytes
|
|
97
|
+
Salt
|
|
98
|
+
|
|
99
|
+
key : bytes
|
|
100
|
+
Key
|
|
101
|
+
"""
|
|
102
|
+
|
|
91
103
|
salt: bytes
|
|
92
104
|
key: bytes
|
|
93
105
|
|
|
@@ -102,7 +114,17 @@ class PasswordGenerator(BaseClass):
|
|
|
102
114
|
@staticmethod
|
|
103
115
|
def password_hash(password: str) -> PasswordHash:
|
|
104
116
|
"""
|
|
105
|
-
Generate hash for password
|
|
117
|
+
Generate hash for password.
|
|
118
|
+
|
|
119
|
+
Parameters
|
|
120
|
+
----------
|
|
121
|
+
password : str
|
|
122
|
+
Password string
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
PasswordHash
|
|
127
|
+
Password hash contains salt and key
|
|
106
128
|
"""
|
|
107
129
|
salt = os.urandom(32)
|
|
108
130
|
key = hashlib.pbkdf2_hmac(
|
|
@@ -116,7 +138,19 @@ class PasswordGenerator(BaseClass):
|
|
|
116
138
|
|
|
117
139
|
@staticmethod
|
|
118
140
|
def password_check(password: str) -> dict:
|
|
119
|
-
"""
|
|
141
|
+
"""
|
|
142
|
+
Check password's characteristic.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
password : str
|
|
147
|
+
Password string
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
dict
|
|
152
|
+
Password's characteristic.
|
|
153
|
+
"""
|
|
120
154
|
data = Text(password).analyze()
|
|
121
155
|
data = DictExt(data).apply(lambda x: True if x > 0 else False) # type: ignore
|
|
122
156
|
data.__setitem__("length", len(password))
|
|
@@ -131,7 +165,7 @@ class PasswordGenerator(BaseClass):
|
|
|
131
165
|
include_special: bool = True,
|
|
132
166
|
) -> str:
|
|
133
167
|
r"""
|
|
134
|
-
Generate a random password
|
|
168
|
+
Generate a random password.
|
|
135
169
|
|
|
136
170
|
Parameters
|
|
137
171
|
----------
|
|
@@ -141,13 +175,13 @@ class PasswordGenerator(BaseClass):
|
|
|
141
175
|
| (Default: ``8``)
|
|
142
176
|
|
|
143
177
|
include_uppercase : bool
|
|
144
|
-
Include uppercase character in the password
|
|
178
|
+
Include uppercase character in the password, by default ``True``
|
|
145
179
|
|
|
146
180
|
include_number : bool
|
|
147
|
-
Include digit character in the password
|
|
181
|
+
Include digit character in the password, by default ``True``
|
|
148
182
|
|
|
149
183
|
include_special : bool
|
|
150
|
-
Include special character in the password
|
|
184
|
+
Include special character in the password, by default ``True``
|
|
151
185
|
|
|
152
186
|
Returns
|
|
153
187
|
-------
|
|
@@ -178,7 +212,7 @@ class PasswordGenerator(BaseClass):
|
|
|
178
212
|
while True:
|
|
179
213
|
pwd = Generator.generate_string(
|
|
180
214
|
charset=charset,
|
|
181
|
-
size=
|
|
215
|
+
size=max(length, 8), # type: ignore
|
|
182
216
|
times=1,
|
|
183
217
|
string_type_if_1=True,
|
|
184
218
|
)
|
|
@@ -205,16 +239,16 @@ class PasswordGenerator(BaseClass):
|
|
|
205
239
|
Parameters
|
|
206
240
|
----------
|
|
207
241
|
num_of_blocks : int
|
|
208
|
-
Number of word used
|
|
242
|
+
Number of word used, by default ``5``
|
|
209
243
|
|
|
210
244
|
block_divider : str
|
|
211
|
-
Character symbol that between each word
|
|
245
|
+
Character symbol that between each word, by default ``"-"``
|
|
212
246
|
|
|
213
247
|
first_letter_cap : bool
|
|
214
|
-
Capitalize first character of each word
|
|
248
|
+
Capitalize first character of each word, by default ``True``
|
|
215
249
|
|
|
216
250
|
include_number : bool
|
|
217
|
-
Add number to the end of each word
|
|
251
|
+
Add number to the end of each word, by default ``True``
|
|
218
252
|
|
|
219
253
|
custom_word_list : list[str] | None
|
|
220
254
|
Custom word list for passphrase generation, by default uses a list of 360K+ words
|
|
@@ -255,6 +289,33 @@ class PasswordGenerator(BaseClass):
|
|
|
255
289
|
class TOTP(BaseClass):
|
|
256
290
|
"""
|
|
257
291
|
A class to represent a Time-based One-Time Password (TOTP) generator.
|
|
292
|
+
|
|
293
|
+
Parameters
|
|
294
|
+
----------
|
|
295
|
+
secret : str
|
|
296
|
+
The shared secret key used to generate the TOTP.
|
|
297
|
+
|
|
298
|
+
name : str, optional
|
|
299
|
+
| The name associated with the TOTP.
|
|
300
|
+
| If not provided, by default ``"None"``.
|
|
301
|
+
|
|
302
|
+
issuer : str, optional
|
|
303
|
+
The issuer of the TOTP.
|
|
304
|
+
|
|
305
|
+
algorithm : Literal["SHA1", "SHA256", "SHA512"], optional
|
|
306
|
+
| The hashing algorithm used to generate the TOTP.
|
|
307
|
+
| Must be one of ``"SHA1"``, ``"SHA256"``, or ``"SHA512"``.
|
|
308
|
+
| By default ``"SHA1"``.
|
|
309
|
+
|
|
310
|
+
digit : int, optional
|
|
311
|
+
| The number of digits in the generated TOTP.
|
|
312
|
+
| Must be greater than 0.
|
|
313
|
+
| By default ``6``.
|
|
314
|
+
|
|
315
|
+
period : int, optional
|
|
316
|
+
| The time step in seconds for TOTP generation.
|
|
317
|
+
| Must be greater than 0.
|
|
318
|
+
| by default ``30``.
|
|
258
319
|
"""
|
|
259
320
|
|
|
260
321
|
URL_SCHEME: ClassVar[str] = "otpauth://totp/"
|
|
@@ -277,23 +338,26 @@ class TOTP(BaseClass):
|
|
|
277
338
|
The shared secret key used to generate the TOTP.
|
|
278
339
|
|
|
279
340
|
name : str, optional
|
|
280
|
-
The name associated with the TOTP.
|
|
341
|
+
| The name associated with the TOTP.
|
|
342
|
+
| If not provided, by default ``"None"``.
|
|
281
343
|
|
|
282
344
|
issuer : str, optional
|
|
283
345
|
The issuer of the TOTP.
|
|
284
346
|
|
|
285
347
|
algorithm : Literal["SHA1", "SHA256", "SHA512"], optional
|
|
286
|
-
The hashing algorithm used to generate the TOTP.
|
|
287
|
-
Must be one of ``"SHA1"``, ``"SHA256"``, or ``"SHA512"``.
|
|
288
|
-
|
|
348
|
+
| The hashing algorithm used to generate the TOTP.
|
|
349
|
+
| Must be one of ``"SHA1"``, ``"SHA256"``, or ``"SHA512"``.
|
|
350
|
+
| By default ``"SHA1"``.
|
|
289
351
|
|
|
290
352
|
digit : int, optional
|
|
291
|
-
The number of digits in the generated TOTP.
|
|
292
|
-
|
|
353
|
+
| The number of digits in the generated TOTP.
|
|
354
|
+
| Must be greater than 0.
|
|
355
|
+
| By default ``6``.
|
|
293
356
|
|
|
294
357
|
period : int, optional
|
|
295
|
-
The time step in seconds for TOTP generation.
|
|
296
|
-
|
|
358
|
+
| The time step in seconds for TOTP generation.
|
|
359
|
+
| Must be greater than 0.
|
|
360
|
+
| by default ``30``.
|
|
297
361
|
"""
|
|
298
362
|
self.secret = secret.upper()
|
|
299
363
|
self.name = name if name else "None"
|
absfuyu/tools/shutdownizer.py
CHANGED
absfuyu/tools/web.py
CHANGED
absfuyu/typings.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Pre-defined typing
|
|
5
|
+
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 14/03/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
# Type
|
|
14
|
+
"T",
|
|
15
|
+
"T_co",
|
|
16
|
+
"T_contra",
|
|
17
|
+
"P",
|
|
18
|
+
"R",
|
|
19
|
+
"_CALLABLE",
|
|
20
|
+
"CT",
|
|
21
|
+
"N",
|
|
22
|
+
"_Number",
|
|
23
|
+
"override",
|
|
24
|
+
# Protocol
|
|
25
|
+
"SupportsShowMethods",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Library
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
from collections.abc import Callable
|
|
32
|
+
from typing import Any, ParamSpec, Protocol, TypeVar, overload
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
from typing import override # type: ignore
|
|
36
|
+
except ImportError:
|
|
37
|
+
from absfuyu.core.decorator import dummy_decorator as override
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Type
|
|
41
|
+
# ---------------------------------------------------------------------------
|
|
42
|
+
# Types where neither is possible are invariant
|
|
43
|
+
T = TypeVar("T") # Type invariant
|
|
44
|
+
# Type variables that are covariant can be substituted
|
|
45
|
+
# with a more specific type without causing errors
|
|
46
|
+
T_co = TypeVar("T_co", covariant=True) # Type covariant
|
|
47
|
+
# Type variables that are contravariant can be substituted
|
|
48
|
+
# with a more general type without causing errors
|
|
49
|
+
T_contra = TypeVar("T_contra", contravariant=True) # Type contravariant
|
|
50
|
+
|
|
51
|
+
# Callable
|
|
52
|
+
P = ParamSpec("P") # Parameter type
|
|
53
|
+
R = TypeVar("R") # Return type - Can be anything
|
|
54
|
+
_CALLABLE = Callable[P, R]
|
|
55
|
+
|
|
56
|
+
# Class type - Can be any subtype of `type`
|
|
57
|
+
CT = TypeVar("CT", bound=type)
|
|
58
|
+
|
|
59
|
+
# Number type
|
|
60
|
+
N = TypeVar("N", int, float) # Must be int or float
|
|
61
|
+
_Number = int | float
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Protocol
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
class SupportsShowMethods(Protocol):
|
|
67
|
+
"""
|
|
68
|
+
Support class with ``show_all_methods()``
|
|
69
|
+
and ``show_all_properties()`` method
|
|
70
|
+
from ``absfuyu.core.basclass.ShowAllMethodsMixin``
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
@overload
|
|
74
|
+
@classmethod
|
|
75
|
+
def show_all_methods(cls) -> dict[str, list[str]]: ...
|
|
76
|
+
|
|
77
|
+
@overload
|
|
78
|
+
@classmethod
|
|
79
|
+
def show_all_methods(
|
|
80
|
+
cls,
|
|
81
|
+
print_result: bool = False,
|
|
82
|
+
include_classmethod: bool = True,
|
|
83
|
+
classmethod_indicator: str = "<classmethod>",
|
|
84
|
+
include_staticmethod: bool = True,
|
|
85
|
+
staticmethod_indicator: str = "<staticmethod>",
|
|
86
|
+
include_private_method: bool = False,
|
|
87
|
+
) -> dict[str, list[str]]: ...
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def show_all_methods(cls, *args, **kwargs) -> Any: ...
|
|
91
|
+
|
|
92
|
+
@overload
|
|
93
|
+
@classmethod
|
|
94
|
+
def show_all_properties(cls) -> dict[str, list[str]]: ...
|
|
95
|
+
|
|
96
|
+
@overload
|
|
97
|
+
@classmethod
|
|
98
|
+
def show_all_properties(
|
|
99
|
+
cls, print_result: bool = False
|
|
100
|
+
) -> dict[str, list[str]]: ...
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def show_all_properties(cls, *args, **kwargs) -> Any: ...
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Note
|
|
107
|
+
# ---------------------------------------------------------------------------
|
|
108
|
+
# Iterable : __iter__
|
|
109
|
+
# Iterator(Iterable) : __next__, __iter__
|
|
110
|
+
# Reversible(Iterable) : __reversed__, __iter__
|
|
111
|
+
# Sized : __len__
|
|
112
|
+
# Container : __contains__
|
|
113
|
+
# Collection(Sized, Iterable, Container) : __len__, __iter__, __contains__
|
|
114
|
+
# Set(Collection) : __contains__, __iter__, __len__
|
|
115
|
+
# MutableSet(Set) : __contains__, __iter__, __len__
|
|
116
|
+
# Mapping(Collection) : __getitem__, __iter__, and __len__
|
|
117
|
+
# MutableMapping(Mapping) : __getitem__, __setitem__, __delitem__,__iter__, __len__
|
|
118
|
+
# Sequence(Reversible, Collection) : __reversed__, __len__, __iter__, __contains__
|
|
119
|
+
# MutableSequence(Sequence) : __getitem__, __setitem__, __delitem__, __reversed__, __len__, __iter__, __contains__
|
|
120
|
+
|
|
121
|
+
# Iterable : str, dict, list, tuple, set
|
|
122
|
+
# Iterator(Iterable) : Generator
|
|
123
|
+
# Reversible(Iterable) : str, dict, list, tuple
|
|
124
|
+
# Sized : str, dict, list, tuple, set
|
|
125
|
+
# Container : str, dict, list, tuple, set
|
|
126
|
+
# Collection(Sized, Iterable, Container) : str, dict, list, tuple, set
|
|
127
|
+
# Set(Collection) : set
|
|
128
|
+
# MutableSet(Set) : set
|
|
129
|
+
# Mapping(Collection) : dict
|
|
130
|
+
# MutableMapping(Mapping) : dict
|
|
131
|
+
# Sequence(Reversible, Collection) : str, list, tuple
|
|
132
|
+
# MutableSequence(Sequence) : list
|
|
133
|
+
|
|
134
|
+
# __iter__: for <...> in <...>
|
|
135
|
+
# __len__: len(<...>)
|
|
136
|
+
# __contains__: if <...> in <...>
|
absfuyu/util/__init__.py
CHANGED
|
@@ -3,10 +3,20 @@ Absufyu: Utilities
|
|
|
3
3
|
------------------
|
|
4
4
|
Some random utilities
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 12/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
"get_installed_package",
|
|
14
|
+
"set_min",
|
|
15
|
+
"set_max",
|
|
16
|
+
"set_min_max",
|
|
17
|
+
"stop_after_day",
|
|
18
|
+
]
|
|
19
|
+
|
|
10
20
|
# Library
|
|
11
21
|
# ---------------------------------------------------------------------------
|
|
12
22
|
import pkgutil
|
|
@@ -137,8 +147,12 @@ def set_min_max(
|
|
|
137
147
|
>>> set_min_max(808)
|
|
138
148
|
100
|
|
139
149
|
"""
|
|
140
|
-
|
|
141
|
-
current_value =
|
|
150
|
+
# Set min
|
|
151
|
+
# current_value = set_min(current_value, min_value=min_value)
|
|
152
|
+
current_value = max(current_value, min_value)
|
|
153
|
+
# Set max
|
|
154
|
+
# current_value = set_max(current_value, max_value=max_value)
|
|
155
|
+
current_value = min(current_value, max_value)
|
|
142
156
|
return current_value
|
|
143
157
|
|
|
144
158
|
|
absfuyu/util/api.py
CHANGED
|
@@ -3,8 +3,8 @@ Absufyu: API
|
|
|
3
3
|
------------
|
|
4
4
|
Fetch data stuff
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 12/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -25,7 +25,8 @@ from typing import NamedTuple
|
|
|
25
25
|
|
|
26
26
|
import requests
|
|
27
27
|
|
|
28
|
-
from absfuyu.core import
|
|
28
|
+
from absfuyu.core.baseclass import BaseClass
|
|
29
|
+
from absfuyu.core.docstring import versionadded, versionchanged
|
|
29
30
|
from absfuyu.logger import logger
|
|
30
31
|
|
|
31
32
|
|
|
@@ -33,8 +34,15 @@ from absfuyu.logger import logger
|
|
|
33
34
|
# ---------------------------------------------------------------------------
|
|
34
35
|
class PingResult(NamedTuple):
|
|
35
36
|
"""
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
Ping result
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
host : str
|
|
42
|
+
Host name/IP
|
|
43
|
+
|
|
44
|
+
result : str
|
|
45
|
+
Ping result in ms
|
|
38
46
|
"""
|
|
39
47
|
|
|
40
48
|
host: str
|
|
@@ -90,28 +98,40 @@ def ping_windows(host: list[str], ping_count: int = 3) -> list[PingResult]:
|
|
|
90
98
|
|
|
91
99
|
# Class
|
|
92
100
|
# ---------------------------------------------------------------------------
|
|
93
|
-
class APIRequest:
|
|
94
|
-
"""
|
|
101
|
+
class APIRequest(BaseClass):
|
|
102
|
+
"""
|
|
103
|
+
API data with cache feature
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
api_url : str
|
|
108
|
+
API link
|
|
109
|
+
|
|
110
|
+
encoding : str | None, optional
|
|
111
|
+
Data encoding, by default ``"utf-8"``
|
|
112
|
+
"""
|
|
95
113
|
|
|
96
114
|
def __init__(
|
|
97
115
|
self,
|
|
98
116
|
api_url: str,
|
|
99
|
-
*,
|
|
117
|
+
*,
|
|
100
118
|
encoding: str | None = "utf-8",
|
|
101
119
|
) -> None:
|
|
102
120
|
"""
|
|
103
|
-
|
|
104
|
-
|
|
121
|
+
Create APIRequest instance
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
api_url : str
|
|
126
|
+
API link
|
|
127
|
+
|
|
128
|
+
encoding : str | None, optional
|
|
129
|
+
Data encoding, by default ``"utf-8"``
|
|
105
130
|
"""
|
|
131
|
+
|
|
106
132
|
self.url = api_url
|
|
107
133
|
self.encoding = encoding
|
|
108
134
|
|
|
109
|
-
def __str__(self) -> str:
|
|
110
|
-
return f"{self.__class__.__name__}({self.url})"
|
|
111
|
-
|
|
112
|
-
def __repr__(self) -> str:
|
|
113
|
-
return self.__str__()
|
|
114
|
-
|
|
115
135
|
def fetch_data(self, *, update: bool = False, json_cache: str | Path):
|
|
116
136
|
"""
|
|
117
137
|
Fetch data from an API then cache it for later use
|
absfuyu/util/json_method.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Json Method
|
|
|
3
3
|
--------------------
|
|
4
4
|
``.json`` file handling
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 12/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -16,7 +16,6 @@ __all__ = ["JsonFile"]
|
|
|
16
16
|
# ---------------------------------------------------------------------------
|
|
17
17
|
import json
|
|
18
18
|
from pathlib import Path
|
|
19
|
-
from typing import Any
|
|
20
19
|
|
|
21
20
|
from absfuyu.core import BaseClass
|
|
22
21
|
|
|
@@ -26,6 +25,20 @@ from absfuyu.core import BaseClass
|
|
|
26
25
|
class JsonFile(BaseClass):
|
|
27
26
|
"""
|
|
28
27
|
``.json`` file handling
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
json_file_location : str | Path
|
|
32
|
+
.json file location
|
|
33
|
+
|
|
34
|
+
encoding : str | None, optional
|
|
35
|
+
Data encoding, by default ``"utf-8"``
|
|
36
|
+
|
|
37
|
+
indent : int | str | None, optional
|
|
38
|
+
Indentation when export to json file, by default ``4``
|
|
39
|
+
|
|
40
|
+
sort_keys : bool, optional
|
|
41
|
+
Sort the keys before export to json file, by default ``True``
|
|
29
42
|
"""
|
|
30
43
|
|
|
31
44
|
def __init__(
|
|
@@ -37,26 +50,40 @@ class JsonFile(BaseClass):
|
|
|
37
50
|
sort_keys: bool = True,
|
|
38
51
|
) -> None:
|
|
39
52
|
"""
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
``.json`` file handling
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
json_file_location : str | Path
|
|
58
|
+
.json file location
|
|
59
|
+
|
|
60
|
+
encoding : str | None, optional
|
|
61
|
+
Data encoding, by default ``"utf-8"``
|
|
62
|
+
|
|
63
|
+
indent : int | str | None, optional
|
|
64
|
+
Indentation when export to json file, by default ``4``
|
|
65
|
+
|
|
66
|
+
sort_keys : bool, optional
|
|
67
|
+
Sort the keys before export to json file, by default ``True``
|
|
44
68
|
"""
|
|
69
|
+
|
|
45
70
|
self.json_file_location = Path(json_file_location)
|
|
46
71
|
self.encoding = encoding
|
|
47
72
|
self.indent = indent
|
|
48
73
|
self.sort_keys = sort_keys
|
|
49
|
-
self.data: dict
|
|
74
|
+
self.data: dict = {}
|
|
50
75
|
|
|
51
76
|
def __str__(self) -> str:
|
|
52
77
|
return f"{self.__class__.__name__}({self.json_file_location.name})"
|
|
53
78
|
|
|
54
|
-
def load_json(self) -> dict
|
|
79
|
+
def load_json(self) -> dict:
|
|
55
80
|
"""
|
|
56
81
|
Load ``.json`` file
|
|
57
82
|
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
dict
|
|
86
|
+
``.json`` data
|
|
60
87
|
"""
|
|
61
88
|
with open(self.json_file_location, "r", encoding=self.encoding) as file:
|
|
62
89
|
self.data = json.load(file)
|
|
@@ -68,11 +95,13 @@ class JsonFile(BaseClass):
|
|
|
68
95
|
with open(self.json_file_location, "w", encoding=self.encoding) as file:
|
|
69
96
|
file.writelines(json_data)
|
|
70
97
|
|
|
71
|
-
def update_data(self, data: dict
|
|
98
|
+
def update_data(self, data: dict) -> None:
|
|
72
99
|
"""
|
|
73
100
|
Update ``.json`` data without save
|
|
74
101
|
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
data : dict
|
|
105
|
+
``.json`` data
|
|
77
106
|
"""
|
|
78
107
|
self.data = data
|