absfuyu 4.1.1__py3-none-any.whl → 5.0.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.

Files changed (76) hide show
  1. absfuyu/__init__.py +4 -4
  2. absfuyu/__main__.py +13 -1
  3. absfuyu/cli/__init__.py +4 -2
  4. absfuyu/cli/color.py +7 -0
  5. absfuyu/cli/do_group.py +9 -91
  6. absfuyu/cli/tool_group.py +136 -0
  7. absfuyu/config/__init__.py +17 -34
  8. absfuyu/core/__init__.py +49 -0
  9. absfuyu/core/baseclass.py +299 -0
  10. absfuyu/core/baseclass2.py +165 -0
  11. absfuyu/core/decorator.py +67 -0
  12. absfuyu/core/docstring.py +163 -0
  13. absfuyu/core/dummy_cli.py +67 -0
  14. absfuyu/core/dummy_func.py +47 -0
  15. absfuyu/dxt/__init__.py +42 -0
  16. absfuyu/dxt/dictext.py +201 -0
  17. absfuyu/dxt/dxt_support.py +79 -0
  18. absfuyu/dxt/intext.py +586 -0
  19. absfuyu/dxt/listext.py +508 -0
  20. absfuyu/dxt/strext.py +530 -0
  21. absfuyu/{extensions → extra}/__init__.py +3 -2
  22. absfuyu/extra/beautiful.py +251 -0
  23. absfuyu/{extensions/extra → extra}/data_analysis.py +51 -82
  24. absfuyu/fun/__init__.py +110 -135
  25. absfuyu/fun/tarot.py +9 -17
  26. absfuyu/game/__init__.py +6 -0
  27. absfuyu/game/game_stat.py +6 -0
  28. absfuyu/game/sudoku.py +7 -1
  29. absfuyu/game/tictactoe.py +12 -5
  30. absfuyu/game/wordle.py +14 -8
  31. absfuyu/general/__init__.py +6 -79
  32. absfuyu/general/content.py +22 -36
  33. absfuyu/general/generator.py +17 -42
  34. absfuyu/general/human.py +108 -228
  35. absfuyu/general/shape.py +1334 -0
  36. absfuyu/logger.py +8 -13
  37. absfuyu/pkg_data/__init__.py +137 -99
  38. absfuyu/pkg_data/deprecated.py +133 -0
  39. absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
  40. absfuyu/sort.py +6 -130
  41. absfuyu/tools/__init__.py +2 -2
  42. absfuyu/tools/checksum.py +44 -22
  43. absfuyu/tools/converter.py +82 -50
  44. absfuyu/tools/keygen.py +25 -30
  45. absfuyu/tools/obfuscator.py +246 -112
  46. absfuyu/tools/passwordlib.py +330 -0
  47. absfuyu/tools/shutdownizer.py +287 -0
  48. absfuyu/tools/web.py +2 -9
  49. absfuyu/util/__init__.py +15 -15
  50. absfuyu/util/api.py +10 -15
  51. absfuyu/util/json_method.py +7 -24
  52. absfuyu/util/lunar.py +3 -9
  53. absfuyu/util/path.py +22 -27
  54. absfuyu/util/performance.py +43 -67
  55. absfuyu/util/shorten_number.py +65 -14
  56. absfuyu/util/zipped.py +9 -15
  57. absfuyu-5.0.0.dist-info/METADATA +143 -0
  58. absfuyu-5.0.0.dist-info/RECORD +68 -0
  59. absfuyu/core.py +0 -57
  60. absfuyu/everything.py +0 -32
  61. absfuyu/extensions/beautiful.py +0 -188
  62. absfuyu/extensions/dev/__init__.py +0 -244
  63. absfuyu/extensions/dev/password_hash.py +0 -80
  64. absfuyu/extensions/dev/passwordlib.py +0 -258
  65. absfuyu/extensions/dev/project_starter.py +0 -60
  66. absfuyu/extensions/dev/shutdownizer.py +0 -156
  67. absfuyu/extensions/extra/__init__.py +0 -24
  68. absfuyu/fun/WGS.py +0 -134
  69. absfuyu/general/data_extension.py +0 -1796
  70. absfuyu/tools/stats.py +0 -226
  71. absfuyu/util/pkl.py +0 -67
  72. absfuyu-4.1.1.dist-info/METADATA +0 -121
  73. absfuyu-4.1.1.dist-info/RECORD +0 -61
  74. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/WHEEL +0 -0
  75. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/entry_points.txt +0 -0
  76. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/tools/checksum.py CHANGED
@@ -3,33 +3,35 @@ Absufyu: Checksum
3
3
  -----------------
4
4
  Check MD5, SHA256, ...
5
5
 
6
- Version: 1.1.0
7
- Date updated: 01/02/2025 (dd/mm/yyyy)
6
+ Version: 5.0.0
7
+ Date updated: 13/02/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
11
- ###########################################################################
12
- __all__ = ["Checksum", "checksum_operation"]
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["Checksum", "ChecksumMode"]
13
13
 
14
14
 
15
15
  # Library
16
- ###########################################################################
16
+ # ---------------------------------------------------------------------------
17
17
  import hashlib
18
+ from enum import StrEnum
18
19
  from pathlib import Path
19
20
  from typing import Literal
20
21
 
21
- from absfuyu.core import tqdm
22
-
23
- # Function
24
- ###########################################################################
22
+ from absfuyu.core import BaseClass, deprecated, tqdm, versionadded, versionchanged
25
23
 
26
24
 
27
- # Deprecated
28
- def checksum_operation(
25
+ # Function
26
+ # ---------------------------------------------------------------------------
27
+ @deprecated("5.0.0")
28
+ def _checksum_operation(
29
29
  file: Path | str,
30
30
  hash_mode: str | Literal["md5", "sha1", "sha256", "sha512"] = "sha256",
31
31
  ) -> str:
32
- """This performs checksum"""
32
+ """
33
+ This performs checksum
34
+ """
33
35
  if hash_mode.lower() == "md5":
34
36
  hash_engine = hashlib.md5()
35
37
  elif hash_mode.lower() == "sha1":
@@ -51,13 +53,39 @@ def checksum_operation(
51
53
  return hash_engine.hexdigest()
52
54
 
53
55
 
54
- class Checksum:
56
+ # Class
57
+ # ---------------------------------------------------------------------------
58
+ class ChecksumMode(StrEnum):
59
+ MD5 = "md5"
60
+ SHA1 = "sha1"
61
+ SHA256 = "sha256"
62
+ SHA512 = "sha512"
63
+
64
+
65
+ @versionchanged("4.1.1", reason="Checksum for entire folder is possible")
66
+ @versionadded("4.1.0")
67
+ class Checksum(BaseClass):
55
68
  def __init__(
56
69
  self,
57
70
  path: str | Path,
58
- hash_mode: str | Literal["md5", "sha1", "sha256", "sha512"] = "sha256",
71
+ hash_mode: (
72
+ ChecksumMode | Literal["md5", "sha1", "sha256", "sha512"]
73
+ ) = ChecksumMode.SHA256,
59
74
  save_result_to_file: bool = False,
60
75
  ) -> None:
76
+ """Checksum engine
77
+
78
+ Parameters
79
+ ----------
80
+ path : str | Path
81
+ Path to file/directory to perform checksum
82
+
83
+ hash_mode : ChecksumMode | Literal["md5", "sha1", "sha256", "sha512"], optional
84
+ Hash mode, by default ``"sha256"``
85
+
86
+ save_result_to_file : bool, optional
87
+ Save checksum result(s) to file, by default False
88
+ """
61
89
  self.path = Path(path)
62
90
  self.hash_mode = hash_mode
63
91
  self.save_result_to_file = save_result_to_file
@@ -109,7 +137,7 @@ class Checksum:
109
137
  str
110
138
  Checksum hash
111
139
  """
112
- if self.path.absolute().is_dir():
140
+ if self.path.absolute().is_dir(): # Dir
113
141
  new_path = self.path.joinpath(self.checksum_result_file_name)
114
142
  # List of files
115
143
  if recursive:
@@ -125,7 +153,7 @@ class Checksum:
125
153
  name = x.relative_to(self.path)
126
154
  res.append(f"{self._checksum_operation(x)} | {name}")
127
155
  output = "\n".join(res)
128
- else:
156
+ else: # File
129
157
  new_path = self.path.with_name(self.checksum_result_file_name)
130
158
  output = self._checksum_operation(self.path)
131
159
 
@@ -135,9 +163,3 @@ class Checksum:
135
163
  f.write(output)
136
164
 
137
165
  return output
138
-
139
-
140
- # Run
141
- ###########################################################################
142
- if __name__ == "__main__":
143
- pass
@@ -3,8 +3,8 @@ Absufyu: Converter
3
3
  ------------------
4
4
  Convert stuff
5
5
 
6
- Version: 1.3.0
7
- Date updated: 01/02/2025 (dd/mm/yyyy)
6
+ Version: 5.0.0
7
+ Date updated: 11/02/2025 (dd/mm/yyyy)
8
8
 
9
9
  Feature:
10
10
  --------
@@ -14,51 +14,61 @@ Feature:
14
14
  """
15
15
 
16
16
  # Module level
17
- ###########################################################################
18
- __all__ = ["Text2Chemistry", "Str2Pixel", "Base64EncodeDecode"]
17
+ # ---------------------------------------------------------------------------
18
+ __all__ = [
19
+ "Text2Chemistry",
20
+ "Str2Pixel",
21
+ "Base64EncodeDecode",
22
+ ]
19
23
 
20
24
 
21
25
  # Library
22
- ###########################################################################
26
+ # ---------------------------------------------------------------------------
23
27
  import base64
24
28
  import math
25
29
  import re
26
30
  import string
27
31
  from itertools import chain, combinations
28
32
  from pathlib import Path
33
+ from typing import Self
29
34
 
30
- from absfuyu.core import CLITextColor
35
+ from absfuyu.core import BaseClass, CLITextColor, versionadded
31
36
  from absfuyu.logger import logger
32
- from absfuyu.pkg_data import DataList
37
+ from absfuyu.pkg_data import DataList, DataLoader
33
38
  from absfuyu.util import set_min
34
- from absfuyu.util.pkl import Pickler
35
39
 
36
40
 
37
41
  # Class
38
- ###########################################################################
39
- class Base64EncodeDecode:
42
+ # ---------------------------------------------------------------------------
43
+ @versionadded("3.0.0")
44
+ class Base64EncodeDecode(BaseClass):
40
45
  """
41
46
  Encode and decode base64
42
47
  """
43
48
 
44
49
  @staticmethod
45
50
  def encode(data: str) -> str:
51
+ """Base64 encode"""
46
52
  return base64.b64encode(data.encode()).decode()
47
53
 
48
54
  @staticmethod
49
55
  def decode(data: str) -> str:
56
+ """Base64 decode"""
50
57
  return base64.b64decode(data).decode()
51
58
 
52
59
  @staticmethod
60
+ @versionadded("4.1.0")
53
61
  def encode_image(img_path: Path | str, data_tag: bool = False) -> str:
54
- """Encode image file into base64 string
62
+ """
63
+ Encode image file into base64 string
55
64
 
56
65
  Parameters
57
66
  ----------
58
67
  img_path : Path | str
59
68
  Path to image
69
+
60
70
  data_tag : bool, optional
61
- Add data tag before base64 string, by default False
71
+ Add data tag before base64 string, by default ``False``
62
72
 
63
73
  Returns
64
74
  -------
@@ -73,11 +83,9 @@ class Base64EncodeDecode:
73
83
  return b64_data
74
84
 
75
85
 
76
- class ChemistryElement:
86
+ class ChemistryElement(BaseClass):
77
87
  """Chemistry Element"""
78
88
 
79
- _VERSION = (1, 1, 0)
80
-
81
89
  def __init__(self, name: str, number: int, symbol: str, atomic_mass: float) -> None:
82
90
  """
83
91
  name: element name
@@ -91,10 +99,6 @@ class ChemistryElement:
91
99
  self.atomic_mass = atomic_mass
92
100
 
93
101
  def __str__(self) -> str:
94
- return self.symbol
95
-
96
- def __repr__(self) -> str:
97
- # return self.symbol
98
102
  return f"{self.__class__.__name__}({self.symbol})"
99
103
 
100
104
  def to_dict(self) -> dict[str, str | int | float]:
@@ -111,7 +115,7 @@ class ChemistryElement:
111
115
  }
112
116
 
113
117
  @classmethod
114
- def from_dict(cls, data: dict[str, str | int | float]) -> "ChemistryElement":
118
+ def from_dict(cls, data: dict[str, str | int | float]) -> Self:
115
119
  """
116
120
  Convert from ``dict`` data
117
121
 
@@ -127,25 +131,22 @@ class ChemistryElement:
127
131
  )
128
132
 
129
133
 
130
- class Text2Chemistry:
134
+ class Text2Chemistry(BaseClass):
131
135
  def __init__(self) -> None:
132
136
  self.data_location = DataList.CHEMISTRY
133
137
 
134
138
  def __str__(self) -> str:
135
139
  return f"{self.__class__.__name__}()"
136
140
 
137
- def __repr__(self) -> str:
138
- return self.__str__()
139
-
140
141
  def _load_chemistry_data(self) -> list[ChemistryElement]:
141
142
  """
142
143
  Load chemistry pickle data
143
144
  """
144
- data: list[dict] = Pickler.load(self.data_location) # type: ignore
145
+ data: list[dict] = DataLoader(self.data_location).load()
145
146
  return [ChemistryElement.from_dict(x) for x in data]
146
147
 
147
148
  @property
148
- def unvailable_characters(self):
149
+ def unvailable_characters(self) -> set[str]:
149
150
  """
150
151
  Characters that can not be converted (unvailable chemistry symbol)
151
152
 
@@ -159,7 +160,7 @@ class Text2Chemistry:
159
160
  # logger.debug(available)
160
161
  return base.difference(available)
161
162
 
162
- def convert(self, text: str) -> list[list[ChemistryElement]]:
163
+ def convert(self, text: str) -> list[list[ChemistryElement]] | list:
163
164
  """
164
165
  Convert text to chemistry symbol
165
166
 
@@ -231,8 +232,41 @@ class Text2Chemistry:
231
232
 
232
233
  return output
233
234
 
235
+ @staticmethod
236
+ @versionadded("4.2.0")
237
+ def beautify_result(
238
+ result: list[list[ChemistryElement]] | list,
239
+ ) -> str:
240
+ """
241
+ Beautify the result from ``Text2Chemistry.convert()``
234
242
 
235
- class Str2Pixel:
243
+ Parameters
244
+ ----------
245
+ result : list[list[ChemistryElement]] | list
246
+ Convert ``Text2Chemistry.convert()`` result
247
+
248
+ Returns
249
+ -------
250
+ str
251
+ Beautified output
252
+ """
253
+ if len(result) == 0:
254
+ res = "No possible combination"
255
+ else:
256
+ msg = []
257
+ for i, solution in enumerate(result, start=1):
258
+ max_word_len = max([len(x.name) for x in solution])
259
+ msg.append(f"Option {i:02}: {', '.join([x.symbol for x in solution])}")
260
+ for x in solution:
261
+ msg.append(
262
+ f"{x.symbol.ljust(2)} ({x.number:02}. {x.name.ljust(max_word_len)} - {round(x.atomic_mass, 2)})"
263
+ )
264
+ msg.append("---")
265
+ res = "\n".join(msg)
266
+ return res
267
+
268
+
269
+ class Str2Pixel(BaseClass):
236
270
  """Convert str into pixel"""
237
271
 
238
272
  PIXEL = "\u2588"
@@ -245,11 +279,17 @@ class Str2Pixel:
245
279
  pixel_symbol_overwrite: str | None = None,
246
280
  ) -> None:
247
281
  """
248
- str_data: Pixel string data (Format: <number_of_pixel><color_code>)
249
- pixel_size: Pixel size (Default: 2)
250
- pixel_symbol_overwrite: Overwrite pixel symbol (Default: None)
282
+ Parameters
283
+ ----------
284
+ str_data : str
285
+ Pixel string data (Format: ``<number_of_pixel><color_code>``)
286
+ Example: 50w20b = 50 white pixels and 20 black pixels
251
287
 
252
- Example: 50w20b = 50 white pixels and 20 black pixels
288
+ pixel_size : int, optional
289
+ Pixel size, by default ``2``
290
+
291
+ pixel_symbol_overwrite : str | None, optional
292
+ Overwrite pixel symbol, by default ``None``
253
293
  """
254
294
  self.data = str_data
255
295
  if pixel_symbol_overwrite is None:
@@ -257,12 +297,6 @@ class Str2Pixel:
257
297
  else:
258
298
  self.pixel = pixel_symbol_overwrite
259
299
 
260
- def __str__(self) -> str:
261
- return f"{self.__class__.__name__}(pixel={self.pixel})"
262
-
263
- def __repr__(self) -> str:
264
- return self.__str__()
265
-
266
300
  def _extract_pixel(self):
267
301
  """Split str_data into corresponding int and str"""
268
302
  num = re.split("[a-zA-Z]", self.data) # type: ignore
@@ -273,13 +307,17 @@ class Str2Pixel:
273
307
  return [x for y in zip(num, char) for x in y]
274
308
 
275
309
  def convert(self, line_break: bool = True) -> str:
276
- """
277
- Convert data into pixel
310
+ """Convert data into pixel
278
311
 
279
- :param line_break: add ``\\n`` at the end of line (Default: ``False``)
280
- :type line_break: bool
281
- :returns: Converted colored pixels
282
- :rtype: str
312
+ Parameters
313
+ ----------
314
+ line_break : bool, optional
315
+ Add ``\\n`` at the end of line, by default ``True``
316
+
317
+ Returns
318
+ -------
319
+ str
320
+ Converted colored pixels
283
321
  """
284
322
  # Extract pixel
285
323
  pixel_map = self._extract_pixel()
@@ -324,9 +362,3 @@ class Str2Pixel:
324
362
  return out + "\n"
325
363
  else:
326
364
  return out
327
-
328
-
329
- # Run
330
- ###########################################################################
331
- if __name__ == "__main__":
332
- logger.setLevel(10)
absfuyu/tools/keygen.py CHANGED
@@ -5,23 +5,25 @@ Mod7 product key generator (90's)
5
5
 
6
6
  This is for educational and informative purposes only.
7
7
 
8
- Version: 2.0.2
9
- Date updated: 05/04/2024 (dd/mm/yyyy)
8
+ Version: 5.0.0
9
+ Date updated: 25/02/2025 (dd/mm/yyyy)
10
10
  """
11
11
 
12
12
  # Module level
13
- ###########################################################################
13
+ # ---------------------------------------------------------------------------
14
14
  __all__ = ["Keygen"]
15
15
 
16
16
 
17
17
  # Library
18
- ###########################################################################
18
+ # ---------------------------------------------------------------------------
19
19
  import random
20
20
 
21
+ from absfuyu.core import BaseClass
22
+
21
23
 
22
24
  # Class
23
- ###########################################################################
24
- class Keygen:
25
+ # ---------------------------------------------------------------------------
26
+ class Keygen(BaseClass):
25
27
  """Key generator"""
26
28
 
27
29
  @staticmethod
@@ -39,8 +41,8 @@ class Keygen:
39
41
  except Exception:
40
42
  raise ValueError("Invalid string") # noqa: B904
41
43
 
42
- @staticmethod
43
- def _mod7_gen(num_of_digits: int, *, fillchar: str = "0") -> str:
44
+ @classmethod
45
+ def _mod7_gen(cls, num_of_digits: int, *, fillchar: str = "0") -> str:
44
46
  """
45
47
  Generate a number with desired length that is divisible by 7
46
48
 
@@ -76,14 +78,14 @@ class Keygen:
76
78
  continue
77
79
 
78
80
  # Check divide by 7
79
- if __class__._is_mod7(mod7_num): # type: ignore
81
+ if cls._is_mod7(str(mod7_num)):
80
82
  mod7_valid = True
81
83
 
82
84
  # Output
83
85
  return str(mod7_num).rjust(num_of_digits, fillchar)
84
86
 
85
- @staticmethod
86
- def mod7_cd_key(fast: bool = False) -> str:
87
+ @classmethod
88
+ def mod7_cd_key(cls, fast: bool = False) -> str:
87
89
  """
88
90
  CD Key generator
89
91
 
@@ -123,13 +125,13 @@ class Keygen:
123
125
  part1_valid = True # Break loop
124
126
 
125
127
  # PART 02
126
- part2 = __class__._mod7_gen(num_of_digits=7) # type: ignore
128
+ part2 = cls._mod7_gen(num_of_digits=7)
127
129
 
128
130
  # OUTPUT
129
131
  return f"{part1}-{part2}"
130
132
 
131
- @staticmethod
132
- def mod7_11_digit_key(fast: bool = False) -> str:
133
+ @classmethod
134
+ def mod7_11_digit_key(cls, fast: bool = False) -> str:
133
135
  """
134
136
  11-digit CD Key generator
135
137
 
@@ -171,13 +173,13 @@ class Keygen:
171
173
  part1_valid = True
172
174
 
173
175
  # PART 02
174
- part2 = __class__._mod7_gen(num_of_digits=7) # type: ignore
176
+ part2 = cls._mod7_gen(num_of_digits=7)
175
177
 
176
178
  # OUTPUT
177
179
  return f"{part1}-{part2}"
178
180
 
179
- @staticmethod
180
- def mod7_oem_key(fast: bool = False) -> str:
181
+ @classmethod
182
+ def mod7_oem_key(cls, fast: bool = False) -> str:
181
183
  """
182
184
  OEM Key generator
183
185
 
@@ -214,7 +216,7 @@ class Keygen:
214
216
  y_part = random.choice(year_choice)
215
217
 
216
218
  # NUM PART
217
- num_part = __class__._mod7_gen(num_of_digits=6) # type: ignore
219
+ num_part = cls._mod7_gen(num_of_digits=6)
218
220
 
219
221
  # NUM PART 02
220
222
  num_part_2 = str(random.randint(0, 99999)).rjust(5, "0")
@@ -222,8 +224,8 @@ class Keygen:
222
224
  # OUTPUT
223
225
  return f"{abc_part}{y_part}-OEM-0{num_part}-{num_part_2}"
224
226
 
225
- @staticmethod
226
- def mod7_combo(fast: bool = False):
227
+ @classmethod
228
+ def mod7_combo(cls, fast: bool = False):
227
229
  """
228
230
  A combo that consist of CD, 11-digit, and OEM Key
229
231
 
@@ -239,15 +241,8 @@ class Keygen:
239
241
  Mod7 Key combo
240
242
  """
241
243
  out = {
242
- "CD Key": __class__.mod7_cd_key(fast=fast), # type: ignore
243
- "OEM Key": __class__.mod7_oem_key(fast=fast), # type: ignore
244
- "11-digit Key": __class__.mod7_11_digit_key(fast=fast), # type: ignore
244
+ "CD Key": cls.mod7_cd_key(fast=fast),
245
+ "OEM Key": cls.mod7_oem_key(fast=fast),
246
+ "11-digit Key": cls.mod7_11_digit_key(fast=fast),
245
247
  }
246
248
  return out
247
-
248
-
249
- # Run
250
- ###########################################################################
251
- if __name__ == "__main__":
252
- test = Keygen()
253
- print(test.mod7_combo())