absfuyu 4.1.0__py3-none-any.whl → 4.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/cli/__init__.py +4 -2
- absfuyu/cli/do_group.py +14 -38
- absfuyu/cli/tool_group.py +136 -0
- absfuyu/core.py +4 -5
- absfuyu/extensions/__init__.py +1 -0
- absfuyu/pkg_data/__init__.py +2 -1
- absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
- absfuyu/tools/checksum.py +104 -6
- absfuyu/tools/converter.py +36 -7
- absfuyu/{extensions/dev → tools}/passwordlib.py +52 -50
- absfuyu/tools/shutdownizer.py +266 -0
- absfuyu/util/shorten_number.py +1 -1
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/METADATA +13 -18
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/RECORD +19 -21
- absfuyu/extensions/dev/__init__.py +0 -244
- absfuyu/extensions/dev/password_hash.py +0 -80
- absfuyu/extensions/dev/project_starter.py +0 -60
- absfuyu/extensions/dev/shutdownizer.py +0 -156
- absfuyu/extensions/extra/__init__.py +0 -24
- /absfuyu/extensions/{extra/data_analysis.py → data_analysis.py} +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/WHEEL +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
1
|
"""
|
|
5
2
|
Absfuyu: Passwordlib
|
|
6
3
|
--------------------
|
|
7
4
|
Password library
|
|
8
5
|
|
|
9
|
-
Version: 1.0.
|
|
10
|
-
Date updated:
|
|
6
|
+
Version: 1.0.0
|
|
7
|
+
Date updated: 11/02/2025 (dd/mm/yyyy)
|
|
11
8
|
"""
|
|
12
9
|
|
|
10
|
+
# Module level
|
|
11
|
+
###########################################################################
|
|
12
|
+
__all__ = ["PasswordGenerator"]
|
|
13
|
+
|
|
14
|
+
|
|
13
15
|
# Library
|
|
14
16
|
###########################################################################
|
|
15
|
-
# from collections import namedtuple
|
|
16
17
|
import hashlib
|
|
18
|
+
import lzma
|
|
17
19
|
import os
|
|
18
20
|
import random
|
|
19
21
|
import re
|
|
20
|
-
from typing import
|
|
21
|
-
|
|
22
|
-
from absfuyu_res import DATA
|
|
22
|
+
from typing import NamedTuple, Optional
|
|
23
23
|
|
|
24
24
|
from absfuyu.general.data_extension import DictExt, Text
|
|
25
25
|
from absfuyu.general.generator import Charset, Generator
|
|
26
26
|
from absfuyu.logger import logger
|
|
27
|
+
from absfuyu.pkg_data import DataList
|
|
27
28
|
from absfuyu.util import set_min
|
|
28
29
|
from absfuyu.util.pkl import Pickler
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
# Function
|
|
32
33
|
###########################################################################
|
|
33
|
-
def
|
|
34
|
+
def _password_check(password: str) -> bool:
|
|
34
35
|
"""
|
|
35
36
|
Verify the strength of ``password``.
|
|
36
37
|
A password is considered strong if:
|
|
@@ -84,13 +85,13 @@ def password_check(password: str) -> bool:
|
|
|
84
85
|
|
|
85
86
|
# Class
|
|
86
87
|
###########################################################################
|
|
87
|
-
class
|
|
88
|
-
|
|
88
|
+
class PasswordHash(NamedTuple):
|
|
89
|
+
salt: bytes
|
|
90
|
+
key: bytes
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
self._words: List[str] = Pickler.load(DATA.PASSWORDLIB)
|
|
92
|
+
|
|
93
|
+
class PasswordGenerator:
|
|
94
|
+
"""Password Generator"""
|
|
94
95
|
|
|
95
96
|
def __str__(self) -> str:
|
|
96
97
|
return f"{self.__class__.__name__}()"
|
|
@@ -98,38 +99,31 @@ class Password:
|
|
|
98
99
|
def __repr__(self) -> str:
|
|
99
100
|
return self.__str__()
|
|
100
101
|
|
|
101
|
-
|
|
102
|
+
@staticmethod
|
|
103
|
+
def password_hash(password: str) -> PasswordHash:
|
|
102
104
|
"""
|
|
103
105
|
Generate hash for password
|
|
104
106
|
"""
|
|
105
107
|
salt = os.urandom(32)
|
|
106
108
|
key = hashlib.pbkdf2_hmac(
|
|
107
109
|
hash_name="sha256",
|
|
108
|
-
password=
|
|
110
|
+
password=password.encode("utf-8"),
|
|
109
111
|
salt=salt,
|
|
110
112
|
iterations=100000,
|
|
111
113
|
)
|
|
112
|
-
out = {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
114
|
+
# out = {
|
|
115
|
+
# "salt": salt,
|
|
116
|
+
# "key": key,
|
|
117
|
+
# }
|
|
118
|
+
out = PasswordHash(salt, key)
|
|
116
119
|
return out
|
|
117
120
|
|
|
118
121
|
@staticmethod
|
|
119
|
-
def password_check(password: str):
|
|
122
|
+
def password_check(password: str) -> dict:
|
|
120
123
|
data = Text(password).analyze()
|
|
124
|
+
data = DictExt(data).apply(lambda x: True if x > 0 else False) # type: ignore
|
|
121
125
|
data.__setitem__("length", len(password))
|
|
122
|
-
|
|
123
|
-
return data
|
|
124
|
-
|
|
125
|
-
@property
|
|
126
|
-
def words(self) -> List[str]:
|
|
127
|
-
"""
|
|
128
|
-
Word list to generate passphrase
|
|
129
|
-
|
|
130
|
-
:rtype: list[str]
|
|
131
|
-
"""
|
|
132
|
-
return self._words
|
|
126
|
+
return dict(data)
|
|
133
127
|
|
|
134
128
|
# Password generator
|
|
135
129
|
@staticmethod
|
|
@@ -187,24 +181,26 @@ class Password:
|
|
|
187
181
|
while True:
|
|
188
182
|
pwd = Generator.generate_string(
|
|
189
183
|
charset=charset,
|
|
190
|
-
size=set_min(length, min_value=8),
|
|
184
|
+
size=set_min(length, min_value=8), # type: ignore
|
|
191
185
|
times=1,
|
|
192
186
|
string_type_if_1=True,
|
|
193
187
|
)
|
|
194
188
|
|
|
195
189
|
analyze = Text(pwd).analyze() # Count each type of char
|
|
196
190
|
|
|
197
|
-
s = sum([1 for x in analyze.values() if x > 0])
|
|
191
|
+
s = sum([1 for x in analyze.values() if x > 0]) # type: ignore
|
|
198
192
|
if s > check: # Break loop if each type of char has atleast 1
|
|
199
193
|
break
|
|
200
|
-
return pwd
|
|
194
|
+
return pwd # type: ignore
|
|
201
195
|
|
|
196
|
+
@staticmethod
|
|
202
197
|
def generate_passphrase(
|
|
203
|
-
self,
|
|
204
198
|
num_of_blocks: int = 5,
|
|
205
199
|
block_divider: Optional[str] = None,
|
|
206
200
|
first_letter_cap: bool = True,
|
|
207
201
|
include_number: bool = True,
|
|
202
|
+
*,
|
|
203
|
+
custom_word_list: list[str] | None = None,
|
|
208
204
|
) -> str:
|
|
209
205
|
"""
|
|
210
206
|
Generate a random passphrase
|
|
@@ -223,6 +219,9 @@ class Password:
|
|
|
223
219
|
include_number : bool
|
|
224
220
|
Add number to the end of each word (Default: ``True``)
|
|
225
221
|
|
|
222
|
+
custom_word_list : list[str] | None
|
|
223
|
+
Custom word list for passphrase generation, by default uses a list of 360K+ words
|
|
224
|
+
|
|
226
225
|
Returns
|
|
227
226
|
-------
|
|
228
227
|
str
|
|
@@ -234,25 +233,28 @@ class Password:
|
|
|
234
233
|
>>> print(Password().generate_passphrase())
|
|
235
234
|
Myomectomies7-Sully4-Torpedomen7-Netful2-Begaud8
|
|
236
235
|
"""
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
value += str(random.choice(range(10)))
|
|
243
|
-
return value
|
|
236
|
+
words: list[str] = (
|
|
237
|
+
(lzma.decompress(Pickler.load(DataList.PASSWORDLIB)).decode().split(",")) # type: ignore
|
|
238
|
+
if not custom_word_list
|
|
239
|
+
else custom_word_list
|
|
240
|
+
)
|
|
244
241
|
|
|
245
242
|
if not block_divider:
|
|
246
243
|
block_divider = "-"
|
|
247
244
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
dat = [random.choice(words) for _ in range(num_of_blocks)]
|
|
246
|
+
|
|
247
|
+
if first_letter_cap:
|
|
248
|
+
dat = list(map(lambda x: x.title(), dat))
|
|
249
|
+
|
|
250
|
+
if include_number:
|
|
251
|
+
idx = random.choice(range(5))
|
|
252
|
+
dat[idx] += str(random.choice(range(10)))
|
|
253
|
+
|
|
254
|
+
return block_divider.join(dat)
|
|
251
255
|
|
|
252
256
|
|
|
253
257
|
# Run
|
|
254
258
|
###########################################################################
|
|
255
259
|
if __name__ == "__main__":
|
|
256
260
|
logger.setLevel(10)
|
|
257
|
-
# print(os.urandom(32))
|
|
258
|
-
print(Password.password_check(Password.generate_password()))
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Shutdownizer
|
|
3
|
+
---------------------
|
|
4
|
+
This shutdowns
|
|
5
|
+
|
|
6
|
+
Version: 1.0.0
|
|
7
|
+
Date updated: 07/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module level
|
|
11
|
+
###########################################################################
|
|
12
|
+
__all__ = ["ShutDownizer", "ShutdownEngine"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Library
|
|
16
|
+
###########################################################################
|
|
17
|
+
import os
|
|
18
|
+
import subprocess
|
|
19
|
+
import sys
|
|
20
|
+
from abc import ABC, abstractmethod
|
|
21
|
+
from datetime import datetime, time, timedelta
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Annotated
|
|
24
|
+
|
|
25
|
+
from absfuyu.logger import logger
|
|
26
|
+
|
|
27
|
+
# TODO: Schedule shutdown, random time shutdown, test
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Class
|
|
31
|
+
###########################################################################
|
|
32
|
+
class ShutDownizer:
|
|
33
|
+
"""
|
|
34
|
+
ShutDownizer
|
|
35
|
+
|
|
36
|
+
Shutdown tool because why not
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self) -> None:
|
|
40
|
+
self.os: str = sys.platform
|
|
41
|
+
logger.debug(f"Current OS: {self.os}")
|
|
42
|
+
|
|
43
|
+
if self.os in ["win32", "cygwin"]: # Windows
|
|
44
|
+
self.engine = ShutdownEngineWin() # type: ignore
|
|
45
|
+
elif self.os == "darwin": # MacOS
|
|
46
|
+
self.engine = ShutdownEngineMac() # type: ignore
|
|
47
|
+
elif self.os == "linux": # Linux
|
|
48
|
+
self.engine = ShutdownEngineLinux() # type: ignore
|
|
49
|
+
else:
|
|
50
|
+
raise SystemError("OS not supported")
|
|
51
|
+
|
|
52
|
+
def __str__(self) -> str:
|
|
53
|
+
return f"{self.__class__.__name__}({self.os})"
|
|
54
|
+
|
|
55
|
+
def __repr__(self) -> str:
|
|
56
|
+
return self.__str__()
|
|
57
|
+
|
|
58
|
+
def shutdown(self) -> None:
|
|
59
|
+
"""Shutdown"""
|
|
60
|
+
self.engine.shutdown()
|
|
61
|
+
|
|
62
|
+
def restart(self) -> None:
|
|
63
|
+
"""Restart"""
|
|
64
|
+
self.engine.restart()
|
|
65
|
+
|
|
66
|
+
def cancel(self) -> None:
|
|
67
|
+
"""Cancel"""
|
|
68
|
+
self.engine.cancel()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ShutdownEngine(ABC):
|
|
72
|
+
"""
|
|
73
|
+
Abstract shutdown class for different type of OS
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __str__(self) -> str:
|
|
77
|
+
return f"{self.__class__.__name__}()"
|
|
78
|
+
|
|
79
|
+
def __repr__(self) -> str:
|
|
80
|
+
return self.__str__()
|
|
81
|
+
|
|
82
|
+
def _execute_cmd(self, cmd: str | list) -> None:
|
|
83
|
+
"""Execute the cmd"""
|
|
84
|
+
try:
|
|
85
|
+
if isinstance(cmd, str):
|
|
86
|
+
subprocess.run(cmd.split())
|
|
87
|
+
elif isinstance(cmd, list):
|
|
88
|
+
subprocess.run(cmd)
|
|
89
|
+
except Exception:
|
|
90
|
+
logger.error(f'"{cmd}" failed to run')
|
|
91
|
+
raise ValueError(f'"{cmd}" failed to run') # noqa
|
|
92
|
+
|
|
93
|
+
def _execute_multiple_cmds(self, cmds: list) -> None:
|
|
94
|
+
if not isinstance(cmds, list):
|
|
95
|
+
raise ValueError("cmds must be a <list>")
|
|
96
|
+
for cmd in cmds:
|
|
97
|
+
try:
|
|
98
|
+
logger.debug(f"Executing: {cmd}")
|
|
99
|
+
self._execute_cmd(cmd)
|
|
100
|
+
break
|
|
101
|
+
except Exception:
|
|
102
|
+
logger.error(f'"{cmd}" failed to run')
|
|
103
|
+
|
|
104
|
+
@abstractmethod
|
|
105
|
+
def shutdown(self) -> None:
|
|
106
|
+
"""Shutdown"""
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
@abstractmethod
|
|
110
|
+
def restart(self) -> None:
|
|
111
|
+
"""Restart"""
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
@abstractmethod
|
|
115
|
+
def sleep(self) -> None:
|
|
116
|
+
"""Sleep"""
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
@abstractmethod
|
|
120
|
+
def abort(self) -> None:
|
|
121
|
+
"""Abort/Cancel"""
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
def cancel(self) -> None:
|
|
125
|
+
"""Abort/Cancel"""
|
|
126
|
+
self.abort()
|
|
127
|
+
|
|
128
|
+
def _calculate_time(
|
|
129
|
+
self,
|
|
130
|
+
h: Annotated[int, "positive"] = 0,
|
|
131
|
+
m: Annotated[int, "positive"] = 0,
|
|
132
|
+
aggregate: bool = True,
|
|
133
|
+
) -> int:
|
|
134
|
+
"""This calculate time for schedule shutdown
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
h : int, optional
|
|
139
|
+
Hours to add (24h format), by default 0
|
|
140
|
+
m : int, optional
|
|
141
|
+
Minutes to add (24h format), by default 0
|
|
142
|
+
aggregate : bool, optional
|
|
143
|
+
| This add hours and and minutes to `time.now()`, by default ``True``
|
|
144
|
+
| - ``True`` : Add hours and minutes to current time
|
|
145
|
+
| - ``False``: Use ``h`` and ``m`` as fixed time point to shutdown
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
int
|
|
150
|
+
Seconds left to shutdown
|
|
151
|
+
"""
|
|
152
|
+
now = datetime.now()
|
|
153
|
+
if aggregate:
|
|
154
|
+
delta = timedelta(hours=h, minutes=m)
|
|
155
|
+
out = delta.seconds
|
|
156
|
+
else:
|
|
157
|
+
new_time = datetime.combine(now.date(), time(hour=h, minute=m))
|
|
158
|
+
diff = new_time - now
|
|
159
|
+
out = diff.seconds
|
|
160
|
+
return out
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class ShutdownEngineWin(ShutdownEngine):
|
|
164
|
+
"""ShutDownizer - Windows"""
|
|
165
|
+
|
|
166
|
+
def shutdown(self) -> None:
|
|
167
|
+
cmds = ["shutdown -f -s -t 0"]
|
|
168
|
+
self._execute_multiple_cmds(cmds)
|
|
169
|
+
|
|
170
|
+
def restart(self) -> None:
|
|
171
|
+
cmds = ["shutdown -r"]
|
|
172
|
+
self._execute_multiple_cmds(cmds)
|
|
173
|
+
|
|
174
|
+
def sleep(self) -> None:
|
|
175
|
+
cmds = ["rundll32.exe powrprof.dll,SetSuspendState 0,1,0"]
|
|
176
|
+
self._execute_multiple_cmds(cmds)
|
|
177
|
+
|
|
178
|
+
def abort(self) -> None:
|
|
179
|
+
cmds = ["shutdown -a"]
|
|
180
|
+
self._execute_multiple_cmds(cmds)
|
|
181
|
+
|
|
182
|
+
def _punish(self, *, are_you_sure_about_this: bool = False) -> None:
|
|
183
|
+
"""Create a `batch` script that shut down computer when boot up"""
|
|
184
|
+
if not are_you_sure_about_this:
|
|
185
|
+
return None
|
|
186
|
+
try:
|
|
187
|
+
startup_folder_win = Path(os.getenv("appdata")).joinpath( # type: ignore
|
|
188
|
+
"Microsoft", "Windows", "Start Menu", "Programs", "Startup"
|
|
189
|
+
)
|
|
190
|
+
with open(startup_folder_win.joinpath("system.bat"), "w") as f:
|
|
191
|
+
f.write("shutdown -f -s -t 0")
|
|
192
|
+
except Exception:
|
|
193
|
+
logger.error("Cannot write file to startup folder")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class ShutdownEngineMac(ShutdownEngine):
|
|
197
|
+
"""ShutDownizer - MacOS"""
|
|
198
|
+
|
|
199
|
+
def shutdown(self) -> None:
|
|
200
|
+
cmds = [
|
|
201
|
+
["osascript", "-e", 'tell application "System Events" to shut down'],
|
|
202
|
+
"pmset sleepnow",
|
|
203
|
+
"shutdown -h now",
|
|
204
|
+
"sudo shutdown -h now",
|
|
205
|
+
]
|
|
206
|
+
self._execute_multiple_cmds(cmds)
|
|
207
|
+
|
|
208
|
+
def restart(self) -> None:
|
|
209
|
+
cmds = [
|
|
210
|
+
["osascript", "-e", 'tell application "System Events" to restart'],
|
|
211
|
+
"shutdown -r now",
|
|
212
|
+
"sudo shutdown -r now",
|
|
213
|
+
]
|
|
214
|
+
self._execute_multiple_cmds(cmds)
|
|
215
|
+
|
|
216
|
+
def sleep(self) -> None:
|
|
217
|
+
cmds = [
|
|
218
|
+
["osascript", "-e", 'tell application "System Events" to sleep'],
|
|
219
|
+
"pmset sleepnow",
|
|
220
|
+
"shutdown -s now",
|
|
221
|
+
"sudo shutdown -s now",
|
|
222
|
+
]
|
|
223
|
+
self._execute_multiple_cmds(cmds)
|
|
224
|
+
|
|
225
|
+
def abort(self) -> None:
|
|
226
|
+
cmds = [
|
|
227
|
+
["osascript", "-e", 'tell application "System Events" to cancel shutdown'],
|
|
228
|
+
"killall shutdown",
|
|
229
|
+
"shutdown -c",
|
|
230
|
+
"sudo shutdown -c",
|
|
231
|
+
]
|
|
232
|
+
self._execute_multiple_cmds(cmds)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class ShutdownEngineLinux(ShutdownEngine):
|
|
236
|
+
"""ShutDownizer - Linux"""
|
|
237
|
+
|
|
238
|
+
def shutdown(self) -> None:
|
|
239
|
+
cmds = [
|
|
240
|
+
"gnome-session-quit --power-off",
|
|
241
|
+
"systemctl --user poweroff",
|
|
242
|
+
"sudo shutdown -h now",
|
|
243
|
+
]
|
|
244
|
+
self._execute_multiple_cmds(cmds)
|
|
245
|
+
|
|
246
|
+
def restart(self) -> None:
|
|
247
|
+
cmds = [
|
|
248
|
+
"gnome-session-quit --reboot",
|
|
249
|
+
"systemctl reboot",
|
|
250
|
+
"sudo shutdown -r now",
|
|
251
|
+
]
|
|
252
|
+
self._execute_multiple_cmds(cmds)
|
|
253
|
+
|
|
254
|
+
def sleep(self) -> None:
|
|
255
|
+
cmds = ["systemctl suspend", "sudo shutdown -s now"]
|
|
256
|
+
self._execute_multiple_cmds(cmds)
|
|
257
|
+
|
|
258
|
+
def abort(self) -> None:
|
|
259
|
+
cmds = ["sudo shutdown -c"]
|
|
260
|
+
self._execute_multiple_cmds(cmds)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
# Run
|
|
264
|
+
###########################################################################
|
|
265
|
+
if __name__ == "__main__":
|
|
266
|
+
pass
|
absfuyu/util/shorten_number.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: absfuyu
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: A small collection of code
|
|
5
5
|
Project-URL: Homepage, https://github.com/AbsoluteWinter/absfuyu-public
|
|
6
6
|
Project-URL: Documentation, https://absolutewinter.github.io/absfuyu-docs/
|
|
@@ -42,30 +42,26 @@ Provides-Extra: extra
|
|
|
42
42
|
Requires-Dist: numpy; extra == 'extra'
|
|
43
43
|
Requires-Dist: pandas; extra == 'extra'
|
|
44
44
|
Provides-Extra: full
|
|
45
|
-
Requires-Dist: absfuyu-res; extra == 'full'
|
|
46
45
|
Requires-Dist: numpy; extra == 'full'
|
|
47
46
|
Requires-Dist: pandas; extra == 'full'
|
|
48
47
|
Requires-Dist: rich; extra == 'full'
|
|
49
48
|
Requires-Dist: tqdm; extra == 'full'
|
|
50
|
-
Provides-Extra: res
|
|
51
|
-
Requires-Dist: absfuyu-res; extra == 'res'
|
|
52
49
|
Description-Content-Type: text/markdown
|
|
53
50
|
|
|
54
51
|
<div align="center">
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
<h1 align="center">
|
|
53
|
+
<img src="https://github.com/AbsoluteWinter/AbsoluteWinter.github.io/blob/main/absfuyu/images/repository-image-crop.png?raw=true" alt="absfuyu"/>
|
|
54
|
+
</h1>
|
|
55
|
+
<p align="center">
|
|
56
|
+
<a href="https://pypi.org/project/absfuyu/"><img src="https://img.shields.io/pypi/pyversions/absfuyu?style=flat-square&logo=python" alt="PyPI Supported Versions"/></a>
|
|
57
|
+
<a href="https://pypi.org/project/absfuyu/"><img src="https://img.shields.io/pypi/dm/absfuyu?style=flat-square&color=blue" alt="PyPI Downloads"/></a>
|
|
58
|
+
<a href="https://pypi.org/project/absfuyu/"><img src="https://img.shields.io/pypi/v/absfuyu?style=flat-square&logo=pypi" /></a>
|
|
59
|
+
<a><img src="https://img.shields.io/pypi/l/absfuyu?style=flat-square&logo=github&color=blue"/></a>
|
|
60
|
+
<a><img src="https://img.shields.io/badge/code%20style-black-black?style=flat-square"/></a>
|
|
61
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json&style=flat-square" alt="Ruff" style="max-width:100%;"></a>
|
|
62
|
+
</p>
|
|
66
63
|
</div>
|
|
67
64
|
|
|
68
|
-
|
|
69
65
|
---
|
|
70
66
|
|
|
71
67
|
## **SUMMARY:**
|
|
@@ -75,7 +71,7 @@ Description-Content-Type: text/markdown
|
|
|
75
71
|
## **INSTALLATION:**
|
|
76
72
|
|
|
77
73
|
```bash
|
|
78
|
-
|
|
74
|
+
pip install -U absfuyu
|
|
79
75
|
```
|
|
80
76
|
|
|
81
77
|
## **USAGE:**
|
|
@@ -115,7 +111,6 @@ python -m pip install -e .[full,dev]
|
|
|
115
111
|
hatch env show
|
|
116
112
|
```
|
|
117
113
|
|
|
118
|
-
|
|
119
114
|
## **LICENSE:**
|
|
120
115
|
|
|
121
116
|
MIT License
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
absfuyu/__init__.py,sha256=
|
|
1
|
+
absfuyu/__init__.py,sha256=pCNxLstlkcm5DQrRNeNbP_U_9QssMWcUpS9SHvjE33k,638
|
|
2
2
|
absfuyu/__main__.py,sha256=OpMwc35W5VANzw6gvlqJaJOl2H89i_frFZbleUQwDss,163
|
|
3
|
-
absfuyu/core.py,sha256=
|
|
3
|
+
absfuyu/core.py,sha256=J7XASHaSjhVyf9qtDU8LDMyJrUgW-yEecgxZP16u7PI,1233
|
|
4
4
|
absfuyu/everything.py,sha256=PGIXlqgxyADFPygohVYVIb7fZz72L_xXrlLX0WImuYg,788
|
|
5
5
|
absfuyu/logger.py,sha256=Pue3oWYYSF03A-fVp3E137jzlZVI71mYqddic8myauQ,13141
|
|
6
6
|
absfuyu/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
absfuyu/sort.py,sha256=Z9nK15WehmZjlUNwvAOwF4FhV-rFcqlXkCcehNYmo78,6827
|
|
8
8
|
absfuyu/version.py,sha256=KMaeXNl93L4VU2RnTySoFv23IDyTvHfy84nyatFcKaE,14128
|
|
9
|
-
absfuyu/cli/__init__.py,sha256=
|
|
9
|
+
absfuyu/cli/__init__.py,sha256=mYX6lVAat9UOI9qR-ZDFw_4WOLVA9r-jTtW8d2fBEKM,1181
|
|
10
10
|
absfuyu/cli/color.py,sha256=7M3XqFllt26tv_NR5qKgyTId6wnVADtUB74cDYy8pOQ,497
|
|
11
11
|
absfuyu/cli/config_group.py,sha256=FsyYm2apSyAA2PAD12CpHAizenRds_QlLf8j0AlLuVo,1230
|
|
12
|
-
absfuyu/cli/do_group.py,sha256=
|
|
12
|
+
absfuyu/cli/do_group.py,sha256=8LdDgx3BYfhpM2d4q-SO9jA_ZcenNKLYr0Q7Hgj4TPg,2919
|
|
13
13
|
absfuyu/cli/game_group.py,sha256=ySpL2hm4VCplhNY0s22kBGI5eFCdJj9fm1T58yftU74,2348
|
|
14
|
+
absfuyu/cli/tool_group.py,sha256=JcmzcXMcMc1OVhAkcKeUPujVlsWyn_DafsrB_1f9rD8,3155
|
|
14
15
|
absfuyu/config/__init__.py,sha256=4r77tFm3mgHX8H1uWWNXC_FZ8hiSJzsYAyiStZiVj5w,8641
|
|
15
16
|
absfuyu/config/config.json,sha256=-ZQnmDuLq0aAFfsrQbSNR3tq5k9Eu9IVUQgYD9htIQM,646
|
|
16
|
-
absfuyu/extensions/__init__.py,sha256=
|
|
17
|
+
absfuyu/extensions/__init__.py,sha256=gt9YF5R5O7Pavqc8Hne0LFe0B4YOYV8gqfsiAyHqkD0,190
|
|
17
18
|
absfuyu/extensions/beautiful.py,sha256=eGfmJ72UQTVvevMCr80RoyYuCYxLaHkvAm1Kk2pkqc0,5331
|
|
18
|
-
absfuyu/extensions/
|
|
19
|
-
absfuyu/extensions/dev/password_hash.py,sha256=AO8VSW9s9VyrTCGgrN-HLqYIUWAYFSds6vLYrhH-ako,1826
|
|
20
|
-
absfuyu/extensions/dev/passwordlib.py,sha256=RvN-AOYann_K-OXVJOmtfTi38uYlcr7Gd2OnGe0I1og,6812
|
|
21
|
-
absfuyu/extensions/dev/project_starter.py,sha256=RkTHwMXdChB45d7rrDuDMzo3a34-P514JlOmYHHNads,1593
|
|
22
|
-
absfuyu/extensions/dev/shutdownizer.py,sha256=Vm9AUsUGyvRWRYAl4fp4CriSmixzBtV8ZGvqmNjdEvo,4027
|
|
23
|
-
absfuyu/extensions/extra/__init__.py,sha256=gUB8fIOz4V9xQxk689dMe7NFFu_r-CneCsi32DtjQAo,552
|
|
24
|
-
absfuyu/extensions/extra/data_analysis.py,sha256=JR8smS6gVRZ4jJtboshCpC3jFabVLQ8LBhWOA-sfIG4,32969
|
|
19
|
+
absfuyu/extensions/data_analysis.py,sha256=JR8smS6gVRZ4jJtboshCpC3jFabVLQ8LBhWOA-sfIG4,32969
|
|
25
20
|
absfuyu/fun/WGS.py,sha256=Aug9BsLTawBDkjdCQ3oqWAfGGeY6ZSBV1kENrTVnlUA,9461
|
|
26
21
|
absfuyu/fun/__init__.py,sha256=AOaq3NdgaK7e5hk622Wspiu6Z2biVK-jpk2FChn05rA,6366
|
|
27
22
|
absfuyu/fun/tarot.py,sha256=Y0z5rNWLOmqfJV961L_9LzUORRNR89Vegy7KqgNR9xs,2539
|
|
@@ -35,14 +30,17 @@ absfuyu/general/content.py,sha256=IfX5SkgoD-sjYJrbRHRIS5-g6fGp_X65A07ViB0zLpk,17
|
|
|
35
30
|
absfuyu/general/data_extension.py,sha256=tvZM4moHNxqOh_iT6ekFELZgfhiIoZ8SUqm9wUIaokU,48938
|
|
36
31
|
absfuyu/general/generator.py,sha256=PW_4Z-YZ30StwDuUUfHD7B0qnVKMo_ZZHHKj54BzgXk,9731
|
|
37
32
|
absfuyu/general/human.py,sha256=drZT1nI_YwGMOwZu8pbzf3frM-SUY15cOcnUpc4pzQk,12241
|
|
38
|
-
absfuyu/pkg_data/__init__.py,sha256=
|
|
33
|
+
absfuyu/pkg_data/__init__.py,sha256=8iHOGp-MWSao_u6a6-iQmSfMReinwbWbjR7EdrWmQeY,4867
|
|
39
34
|
absfuyu/pkg_data/chemistry.pkl,sha256=kYWNa_PVffoDnzT8b9Jvimmf_GZshPe1D-SnEKERsLo,4655
|
|
35
|
+
absfuyu/pkg_data/passwordlib_lzma.pkl,sha256=rT5lJT8t42BATU5Cp2qFwbnZkbx-QlUgodSvR0wFY6I,891877
|
|
40
36
|
absfuyu/pkg_data/tarot.pkl,sha256=ssXTCC_BQgslO5F-3a9HivbxFQ6BioIe2E1frPVi2m0,56195
|
|
41
37
|
absfuyu/tools/__init__.py,sha256=VDmmMLEfiRyUWPVrPYc8JUEa5TXjLguKVnyI3YavFv0,118
|
|
42
|
-
absfuyu/tools/checksum.py,sha256=
|
|
43
|
-
absfuyu/tools/converter.py,sha256=
|
|
38
|
+
absfuyu/tools/checksum.py,sha256=gB8LvOeQRRuI1dYMmNZINF0QyUKyQZiZ7oJJ0m7QMDY,4807
|
|
39
|
+
absfuyu/tools/converter.py,sha256=STA5NZZt5Xj0YRTup8tvh1YE2z7Y1AWRbEbU3EAS0TY,11589
|
|
44
40
|
absfuyu/tools/keygen.py,sha256=drj8OUDCXrLvcVf9_Shd5UMShm_mBTxa9Sg_BrAT5yM,7356
|
|
45
41
|
absfuyu/tools/obfuscator.py,sha256=kiaFvMw2RwEfZvXKdbUrEYA_AuVETivoL2eVmtUWU4w,8669
|
|
42
|
+
absfuyu/tools/passwordlib.py,sha256=q-KOGld-LN6ndv8HLs5Yq6iJEI9lrb_fDc4kFwh9M8c,7104
|
|
43
|
+
absfuyu/tools/shutdownizer.py,sha256=W5sYoqvumTKj8fYIt1D0f5BtWCHUNBB9IO65f3P4G5w,7674
|
|
46
44
|
absfuyu/tools/stats.py,sha256=zZNK59qn0xqQlyw5CP3MP5WRMSxncdKZythqvgNR1lQ,5191
|
|
47
45
|
absfuyu/tools/web.py,sha256=Mb5RYj1Fu5eB-mYMusyrE2JG6_ZPEf8WT72Z8q6Ep74,1406
|
|
48
46
|
absfuyu/util/__init__.py,sha256=1V2DwIUt-bSiSURnk6AzfKB0HRLHwoi8_6RaIvywlzU,3716
|
|
@@ -52,10 +50,10 @@ absfuyu/util/lunar.py,sha256=xW7HcgyIRjWBhQv36RimNZIT8Ed_X83moqr5h5-Ku9k,13750
|
|
|
52
50
|
absfuyu/util/path.py,sha256=p4Ac98FfW5pXLNRRuQ_QEx_G7-UOSBKABAg_xrOq7u4,16628
|
|
53
51
|
absfuyu/util/performance.py,sha256=F-aLJ-5wmwkiOdl9_wZcFRKifL9zOahw52JeL4TbCuQ,9105
|
|
54
52
|
absfuyu/util/pkl.py,sha256=ZZf6-PFC2uRGXqARNi0PGH3A0IXwMP0sYPWZJXENvak,1559
|
|
55
|
-
absfuyu/util/shorten_number.py,sha256=
|
|
53
|
+
absfuyu/util/shorten_number.py,sha256=CZRG0fh9y3bpmFnY9xy5gWEv1kceD1nJmQGKDxPbwCQ,6574
|
|
56
54
|
absfuyu/util/zipped.py,sha256=CU_le1MynFwHfpajCRRJ7_A-r1jfMjt9uu72jLooW6w,3111
|
|
57
|
-
absfuyu-4.
|
|
58
|
-
absfuyu-4.
|
|
59
|
-
absfuyu-4.
|
|
60
|
-
absfuyu-4.
|
|
61
|
-
absfuyu-4.
|
|
55
|
+
absfuyu-4.2.0.dist-info/METADATA,sha256=6uiXP8Ru7sBlWoFQmoqC2sJdBO9qu3fo5sER0rnAnu0,3737
|
|
56
|
+
absfuyu-4.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
57
|
+
absfuyu-4.2.0.dist-info/entry_points.txt,sha256=bW5CgJRTTWJ2Pywojo07sf-YucRPcnHzMmETh5avbX0,79
|
|
58
|
+
absfuyu-4.2.0.dist-info/licenses/LICENSE,sha256=pFCHBSNSzdXwYG1AHpq7VcofI1NMQ1Fc77RzZ4Ln2O4,1097
|
|
59
|
+
absfuyu-4.2.0.dist-info/RECORD,,
|