absfuyu 3.4.0__tar.gz → 4.1.0__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.

Potentially problematic release.


This version of absfuyu might be problematic. Click here for more details.

Files changed (89) hide show
  1. {absfuyu-3.4.0 → absfuyu-4.1.0}/LICENSE +21 -21
  2. {absfuyu-3.4.0 → absfuyu-4.1.0}/PKG-INFO +6 -9
  3. {absfuyu-3.4.0 → absfuyu-4.1.0}/pyproject.toml +57 -24
  4. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/__init__.py +1 -1
  5. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/cli/do_group.py +51 -2
  6. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/config/__init__.py +13 -13
  7. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/core.py +18 -16
  8. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/extra/data_analysis.py +74 -28
  9. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/fun/__init__.py +24 -23
  10. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/fun/tarot.py +6 -7
  11. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/game/__init__.py +2 -2
  12. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/game/game_stat.py +1 -1
  13. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/game/sudoku.py +6 -5
  14. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/game/tictactoe.py +4 -4
  15. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/general/content.py +7 -7
  16. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/general/data_extension.py +44 -63
  17. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/general/generator.py +4 -2
  18. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/logger.py +2 -2
  19. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/pkg_data/__init__.py +13 -20
  20. absfuyu-4.1.0/src/absfuyu/tools/checksum.py +56 -0
  21. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/converter.py +33 -10
  22. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/obfuscator.py +1 -1
  23. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/__init__.py +13 -14
  24. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/api.py +7 -7
  25. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/json_method.py +9 -9
  26. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/lunar.py +7 -8
  27. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/path.py +23 -21
  28. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/performance.py +8 -8
  29. absfuyu-4.1.0/src/absfuyu/util/shorten_number.py +228 -0
  30. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/zipped.py +18 -6
  31. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_data_analysis.py +1 -0
  32. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_everything.py +7 -2
  33. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_fun.py +3 -3
  34. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_tarot.py +3 -3
  35. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_util.py +34 -6
  36. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_version.py +13 -14
  37. {absfuyu-3.4.0 → absfuyu-4.1.0}/.gitignore +0 -0
  38. {absfuyu-3.4.0 → absfuyu-4.1.0}/README.md +0 -0
  39. {absfuyu-3.4.0 → absfuyu-4.1.0}/dev_requirements.txt +0 -0
  40. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/Makefile +0 -0
  41. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/conf.py +0 -0
  42. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/index.rst +0 -0
  43. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/info.md +0 -0
  44. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/make.bat +0 -0
  45. {absfuyu-3.4.0 → absfuyu-4.1.0}/docs/modules.rst +0 -0
  46. {absfuyu-3.4.0 → absfuyu-4.1.0}/images/repository-image-crop.png +0 -0
  47. {absfuyu-3.4.0 → absfuyu-4.1.0}/images/repository-image-white.png +0 -0
  48. {absfuyu-3.4.0 → absfuyu-4.1.0}/images/repository-image.png +0 -0
  49. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/__main__.py +0 -0
  50. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/cli/__init__.py +0 -0
  51. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/cli/color.py +0 -0
  52. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/cli/config_group.py +0 -0
  53. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/cli/game_group.py +0 -0
  54. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/config/config.json +0 -0
  55. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/everything.py +0 -0
  56. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/__init__.py +0 -0
  57. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/beautiful.py +0 -0
  58. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/dev/__init__.py +0 -0
  59. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/dev/password_hash.py +0 -0
  60. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/dev/passwordlib.py +0 -0
  61. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/dev/project_starter.py +0 -0
  62. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/dev/shutdownizer.py +0 -0
  63. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/extensions/extra/__init__.py +0 -0
  64. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/fun/WGS.py +0 -0
  65. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/game/wordle.py +0 -0
  66. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/general/__init__.py +0 -0
  67. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/general/human.py +0 -0
  68. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/pkg_data/chemistry.pkl +0 -0
  69. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/pkg_data/tarot.pkl +0 -0
  70. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/py.typed +0 -0
  71. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/sort.py +0 -0
  72. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/__init__.py +0 -0
  73. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/keygen.py +0 -0
  74. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/stats.py +0 -0
  75. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/tools/web.py +0 -0
  76. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/util/pkl.py +0 -0
  77. {absfuyu-3.4.0 → absfuyu-4.1.0}/src/absfuyu/version.py +0 -0
  78. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/__init__.py +0 -0
  79. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/conftest.py +0 -0
  80. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_beautiful.py +0 -0
  81. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_config.py +0 -0
  82. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_data_extension.py +0 -0
  83. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_extensions.py +0 -0
  84. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_game.py +0 -0
  85. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_generator.py +0 -0
  86. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_logger.py +0 -0
  87. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_passwordlib.py +0 -0
  88. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_pkg_data.py +0 -0
  89. {absfuyu-3.4.0 → absfuyu-4.1.0}/tests/test_tools.py +0 -0
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2022-2024 AbsoluteWinter
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2025 AbsoluteWinter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: absfuyu
3
- Version: 3.4.0
3
+ Version: 4.1.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/
@@ -18,24 +18,20 @@ Classifier: Natural Language :: English
18
18
  Classifier: Operating System :: OS Independent
19
19
  Classifier: Programming Language :: Python :: 3
20
20
  Classifier: Programming Language :: Python :: 3 :: Only
21
- Classifier: Programming Language :: Python :: 3.8
22
- Classifier: Programming Language :: Python :: 3.9
23
- Classifier: Programming Language :: Python :: 3.10
24
21
  Classifier: Programming Language :: Python :: 3.11
25
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
26
24
  Classifier: Topic :: Software Development :: Libraries
27
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
26
  Classifier: Topic :: Utilities
29
- Requires-Python: <4,>=3.8
27
+ Requires-Python: <4,>=3.11
30
28
  Requires-Dist: bs4
31
29
  Requires-Dist: click>=8.0.0
32
30
  Requires-Dist: colorama
33
31
  Requires-Dist: deprecated
34
- Requires-Dist: importlib-resources; python_version < '3.10'
35
32
  Requires-Dist: python-dateutil
36
33
  Requires-Dist: requests
37
- Requires-Dist: tomli>=1.1.0; python_version < '3.11'
38
- Requires-Dist: typing-extensions>=4.0.1; python_version < '3.11'
34
+ Requires-Dist: typing-extensions>=4.5.0; python_version < '3.12'
39
35
  Requires-Dist: unidecode
40
36
  Provides-Extra: beautiful
41
37
  Requires-Dist: rich; extra == 'beautiful'
@@ -50,6 +46,7 @@ Requires-Dist: absfuyu-res; extra == 'full'
50
46
  Requires-Dist: numpy; extra == 'full'
51
47
  Requires-Dist: pandas; extra == 'full'
52
48
  Requires-Dist: rich; extra == 'full'
49
+ Requires-Dist: tqdm; extra == 'full'
53
50
  Provides-Extra: res
54
51
  Requires-Dist: absfuyu-res; extra == 'res'
55
52
  Description-Content-Type: text/markdown
@@ -5,7 +5,7 @@
5
5
  # 4. Build package (hatch build)
6
6
  # 5. Generating docs (hatch run docs:build)
7
7
  # 6. Publish packge (hatch publish)
8
- ## Run entire workflow: hatch run workflow:perform
8
+ ## Run entire workflow: hatch run workflow:<major | minor | patch>
9
9
  ## `hatch env show` for more information
10
10
 
11
11
  # MARK: BUILD ====================
@@ -18,17 +18,15 @@ build-backend = "hatchling.build"
18
18
  name = "absfuyu"
19
19
  description = "A small collection of code"
20
20
  readme = { "file" = "README.md", "content-type" = "text/markdown" }
21
- requires-python = ">=3.8, <4"
21
+ requires-python = ">=3.11, <4"
22
22
  license = { text = "MIT License" }
23
23
  keywords = ["utilities"]
24
24
  authors = [{ name = "somewhatcold (AbsoluteWinter)" }]
25
25
  classifiers = [
26
26
  "Programming Language :: Python :: 3",
27
- "Programming Language :: Python :: 3.8",
28
- "Programming Language :: Python :: 3.9",
29
- "Programming Language :: Python :: 3.10",
30
27
  "Programming Language :: Python :: 3.11",
31
28
  "Programming Language :: Python :: 3.12",
29
+ "Programming Language :: Python :: 3.13",
32
30
  "Programming Language :: Python :: 3 :: Only",
33
31
  "License :: OSI Approved :: MIT License",
34
32
  "Operating System :: OS Independent",
@@ -46,11 +44,9 @@ dependencies = [
46
44
  "click>=8.0.0",
47
45
  "colorama",
48
46
  "Deprecated",
49
- "importlib_resources; python_version < '3.10'",
50
47
  "python-dateutil",
51
48
  "requests",
52
- "tomli>=1.1.0; python_version < '3.11'",
53
- "typing_extensions>=4.0.1; python_version < '3.11'",
49
+ "typing_extensions>=4.5.0; python_version < '3.12'",
54
50
  "unidecode",
55
51
  ]
56
52
 
@@ -64,7 +60,7 @@ Issues = "https://github.com/AbsoluteWinter/absfuyu-public/issues"
64
60
 
65
61
  [project.optional-dependencies]
66
62
  res = ["absfuyu-res"]
67
- full = ["absfuyu-res", "numpy", "pandas", "rich"]
63
+ full = ["absfuyu-res", "numpy", "pandas", "rich", "tqdm"]
68
64
  beautiful = ["rich"]
69
65
  extra = ["numpy", "pandas"]
70
66
  dev = ["hatch", "pytest"]
@@ -113,7 +109,7 @@ Use `hatch run all:install` when occur "no module named" error
113
109
  install = "pip install -e .[full]" # This command fix "no module named"
114
110
 
115
111
  [[tool.hatch.envs.all.matrix]] # hatch env run -e all test
116
- python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
112
+ python = ["3.11", "3.12", "3.13"]
117
113
 
118
114
  [tool.hatch.envs.types]
119
115
  dependencies = ["mypy>=1.0.0"]
@@ -175,12 +171,12 @@ detached = true
175
171
  skip-install = true
176
172
  description = """
177
173
  Package workflow:
178
- hatch run workflow:perform
174
+ hatch run workflow:<option>
179
175
 
180
- Note:
181
- - perform: bump version patch
182
- - perform2: bump version minor
183
- - perform3: bump version major
176
+ Options:
177
+ - patch: release version patch
178
+ - minor: release version minor
179
+ - major: release version major
184
180
  """
185
181
 
186
182
  [tool.hatch.envs.workflow.scripts]
@@ -190,25 +186,54 @@ test = [
190
186
  "hatch run all:test", # Test
191
187
  ]
192
188
  build = [
189
+ # Update license year - Convert to hex due to unable to run multiple lines
190
+ # Source code:
191
+ # import re;from datetime import datetime;from pathlib import Path
192
+ # print("Updating license year...");p=r"([12]\d{3})(-[12]\d{3})?"
193
+ # n=str(datetime.now().year);l=list(Path.cwd().glob("*license*"))[0]
194
+ # with open(l)as f:c=f.readlines()
195
+ # for i,x in enumerate(c):
196
+ # s=re.search(p,x);y=s.groups()[0]if s else n
197
+ # if y!=n:c[i]=re.sub(p,f"{y}-{n}",x)
198
+ # with open(l,"w",encoding="utf-8")as f:f.writelines(c)
199
+ # print("License year updated")
200
+ """
201
+ python -c \"exec(bytes.fromhex('696d706f72742072653b66726f6d20646174657\
202
+ 4696d6520696d706f7274206461746574696d653b66726f6d20706174686c696220696d\
203
+ 706f727420506174680a7072696e7428225570646174696e67206c6963656e736520796\
204
+ 561722e2e2e22293b703d7222285b31325d5c647b337d29282d5b31325d5c647b337d29\
205
+ 3f220a6e3d737472286461746574696d652e6e6f7728292e79656172293b6c3d6c69737\
206
+ 428506174682e63776428292e676c6f6228222a6c6963656e73652a2229295b305d0a77\
207
+ 697468206f70656e286c29617320663a633d662e726561646c696e657328290a666f722\
208
+ 0692c7820696e20656e756d65726174652863293a0a20202020733d72652e7365617263\
209
+ 6828702c78293b793d732e67726f75707328295b305d6966207320656c7365206e0a202\
210
+ 0202069662079213d6e3a635b695d3d72652e73756228702c66227b797d2d7b6e7d222c\
211
+ 78290a77697468206f70656e286c2c2277222c656e636f64696e673d227574662d38222\
212
+ 9617320663a662e77726974656c696e65732863290a7072696e7428224c6963656e7365\
213
+ 207965617220757064617465642229').decode('utf-8'))\"
214
+ """,
215
+ # "python support_scripts/update_license_year.py", # Update license year
193
216
  "hatch clean", # Clean dist/ folder
194
217
  "hatch -v build", # Build package
195
218
  "hatch run docs:build", # Build docs
196
- "hatch publish", # Publish
197
219
  ]
198
- perform = [
220
+ patch = [
199
221
  "test",
200
222
  "hatch version patch", # Bump version patch
201
223
  "build",
224
+ "hatch publish", # Publish
202
225
  ]
203
- perform2 = [
226
+ minor = [
204
227
  "test",
205
228
  "hatch version minor", # Bump version minor
206
229
  "build",
230
+ "hatch publish", # Publish
207
231
  ]
208
- perform3 = [
232
+ major = [
209
233
  "test",
210
234
  "hatch version major", # Bump version major
211
235
  "build",
236
+ "hatch publish", # Publish
212
237
  ]
213
238
 
214
239
  # MARK: TOOL: pytest
@@ -227,7 +252,7 @@ markers = [ # pytest -m <marker> -v
227
252
 
228
253
  # MARK: TOOL: mypy
229
254
  [tool.mypy]
230
- # python_version = "3.8"
255
+ python_version = "3.11"
231
256
  mypy_path = "src"
232
257
  check_untyped_defs = true
233
258
  # disallow_any_generics = true
@@ -247,7 +272,7 @@ no_implicit_reexport = true
247
272
  [tool.ruff]
248
273
  line-length = 88
249
274
  indent-width = 4
250
- target-version = "py38"
275
+ target-version = "py311"
251
276
  include = ["pyproject.toml", "src/**", "tests/**"]
252
277
 
253
278
  [tool.ruff.format]
@@ -263,19 +288,27 @@ ignore = [
263
288
  "E266", # too many leading "#" for block comment
264
289
  "E501", # line too long
265
290
  "W291", # trailing whitespace
291
+ "B905", # `zip()` without an explicit `strict=` parameter
266
292
  ]
267
293
 
268
294
  [tool.ruff.lint.per-file-ignores]
269
295
  "__init__.py" = ["E402", "F401"] # module level import not at top of file
270
296
  "core.py" = ["E402"]
271
- "human.py" = ["E741"] # Ambiguous variable name
272
- "test_everything.py" = ["F403"] # unable to detect undefined names
297
+ "human.py" = [
298
+ "E741", # Ambiguous variable name
299
+ ]
300
+ "test_everything.py" = [
301
+ "F403", # unable to detect undefined names
302
+ ]
273
303
  "test_version.py" = [
274
304
  # Within an `except` clause, raise exceptions with `raise ... from err`
275
305
  # or `raise ... from None` to distinguish them from errors in exception handling
276
306
  "B904",
277
307
  ]
278
- "tests/*" = ["F401"] # imported but unused
308
+ "tests/*" = [
309
+ "F401", # imported but unused
310
+ ]
311
+ "shorten_number.py" = ["B007"] # Loop control variable not used within loop body
279
312
 
280
313
  # MARK: TOOL: black
281
314
  [tool.black]
@@ -22,7 +22,7 @@ Using in cmd (`absfuyu[cli]` required):
22
22
  __title__ = "absfuyu"
23
23
  __author__ = "AbsoluteWinter"
24
24
  __license__ = "MIT License"
25
- __version__ = "3.4.0"
25
+ __version__ = "4.1.0"
26
26
  __all__ = [
27
27
  "core",
28
28
  "config",
@@ -3,13 +3,14 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Do
5
5
 
6
- Version: 1.1.0
7
- Date updated: 15/08/2024 (dd/mm/yyyy)
6
+ Version: 1.3.0
7
+ Date updated: 01/02/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  __all__ = ["do_group"]
11
11
 
12
12
  import subprocess
13
+ from typing import Literal
13
14
 
14
15
  import click
15
16
 
@@ -17,6 +18,8 @@ from absfuyu import __title__
17
18
  from absfuyu.cli.color import COLOR
18
19
  from absfuyu.core import __package_feature__
19
20
  from absfuyu.general.human import Human2
21
+ from absfuyu.tools.checksum import checksum_operation
22
+ from absfuyu.util.zipped import Zipper
20
23
  from absfuyu.version import PkgVersion
21
24
 
22
25
 
@@ -85,6 +88,50 @@ def info(date: str) -> None:
85
88
  print(instance.info())
86
89
 
87
90
 
91
+ @click.command(name="unzip")
92
+ @click.argument("dir", type=str)
93
+ def unzip_files_in_dir(dir: str) -> None:
94
+ """Unzip every files in directory"""
95
+
96
+ engine = Zipper(dir)
97
+ engine.unzip()
98
+ print("Done")
99
+
100
+
101
+ @click.command(name="checksum")
102
+ @click.argument("file_path", type=str)
103
+ @click.option(
104
+ "--hashmode",
105
+ "-m",
106
+ "hash_mode",
107
+ type=click.Choice(["md5", "sha1", "sha256", "sha512"]),
108
+ default="sha256",
109
+ show_default=True,
110
+ help="Hash mode",
111
+ )
112
+ @click.option(
113
+ "--compare",
114
+ "-c",
115
+ "hash_to_compare",
116
+ type=str,
117
+ default=None,
118
+ show_default=True,
119
+ help="Hash to compare",
120
+ )
121
+ def file_checksum(
122
+ file_path: str,
123
+ hash_mode: str | Literal["md5", "sha1", "sha256", "sha512"],
124
+ hash_to_compare: str,
125
+ ) -> None:
126
+ """Checksum for file"""
127
+
128
+ res = checksum_operation(file_path, hash_mode=hash_mode)
129
+ if hash_to_compare:
130
+ print(res == hash_to_compare)
131
+ else:
132
+ print(res)
133
+
134
+
88
135
  @click.group(name="do")
89
136
  def do_group() -> None:
90
137
  """Perform functionalities"""
@@ -96,3 +143,5 @@ do_group.add_command(install)
96
143
  do_group.add_command(advice)
97
144
  do_group.add_command(fs)
98
145
  do_group.add_command(info)
146
+ do_group.add_command(unzip_files_in_dir)
147
+ do_group.add_command(file_checksum)
@@ -3,8 +3,8 @@ Absfuyu: Configuration
3
3
  ----------------------
4
4
  Package configuration module
5
5
 
6
- Version: 2.0.4
7
- Date updated: 06/04/2024 (dd/mm/yyyy)
6
+ Version: 2.0.5
7
+ Date updated: 14/11/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -19,7 +19,7 @@ __all__ = [
19
19
  # Library
20
20
  ###########################################################################
21
21
  from pathlib import Path
22
- from typing import Any, Dict, List, Optional, TypedDict
22
+ from typing import Any, TypedDict
23
23
 
24
24
  from absfuyu.core import CONFIG_PATH
25
25
  from absfuyu.util.json_method import JsonFile
@@ -55,7 +55,7 @@ class ConfigFormat(TypedDict):
55
55
  :type version: VersionDictFormat
56
56
  """
57
57
 
58
- setting: Dict[str, SettingDictFormat]
58
+ setting: dict[str, SettingDictFormat]
59
59
 
60
60
 
61
61
  # Class
@@ -82,7 +82,7 @@ class Setting:
82
82
  return self.__str__()
83
83
 
84
84
  @classmethod
85
- def from_dict(cls, dict_data: Dict[str, SettingDictFormat]):
85
+ def from_dict(cls, dict_data: dict[str, SettingDictFormat]):
86
86
  """
87
87
  Convert ``dict`` into ``Setting`` (``len==1`` only)
88
88
  """
@@ -104,11 +104,11 @@ class Setting:
104
104
  """Update current value"""
105
105
  self.value = value
106
106
 
107
- def to_dict(self) -> Dict[str, SettingDictFormat]:
107
+ def to_dict(self) -> dict[str, SettingDictFormat]:
108
108
  """
109
109
  Convert ``Setting`` into ``dict``
110
110
  """
111
- output: Dict[str, SettingDictFormat] = {
111
+ output: dict[str, SettingDictFormat] = {
112
112
  self.name: {"default": self.default, "help": self.help, "value": self.value}
113
113
  }
114
114
  return output
@@ -119,7 +119,7 @@ class Config:
119
119
  Config handling
120
120
  """
121
121
 
122
- def __init__(self, config_file: Path, name: Optional[str] = None) -> None:
122
+ def __init__(self, config_file: Path, name: str | None = None) -> None:
123
123
  """
124
124
  config_file: Path to `.json` config file
125
125
  """
@@ -132,7 +132,7 @@ class Config:
132
132
  self.name = self.config_path.name
133
133
 
134
134
  # Data
135
- self.settings: List[Setting] = None # type: ignore
135
+ self.settings: list[Setting] = None # type: ignore
136
136
  self._fetch_data() # Load data
137
137
 
138
138
  def __str__(self) -> str:
@@ -145,7 +145,7 @@ class Config:
145
145
  def _fetch_data(self) -> None:
146
146
  """Load data from ``self.config_file`` file"""
147
147
  data: dict = self.json_engine.load_json()
148
- settings: Dict[str, SettingDictFormat] = data.get("setting") # type: ignore
148
+ settings: dict[str, SettingDictFormat] = data.get("setting") # type: ignore
149
149
  self.settings = [Setting.from_dict({k: v}) for k, v in settings.items()]
150
150
 
151
151
  def _prepare_data(self) -> ConfigFormat:
@@ -164,7 +164,7 @@ class Config:
164
164
 
165
165
  # Setting method
166
166
  @property
167
- def setting_list(self) -> List[str]:
167
+ def setting_list(self) -> list[str]:
168
168
  """List of name of available settings"""
169
169
  return [setting.name for setting in self.settings]
170
170
 
@@ -183,7 +183,7 @@ class Config:
183
183
  [setting.reset() for setting in self.settings] # type: ignore
184
184
  self.save()
185
185
 
186
- def show_settings(self) -> List[Setting]:
186
+ def show_settings(self) -> list[Setting]:
187
187
  """
188
188
  Returns a list of available settings
189
189
  (wrapper for ``Config.settings``)
@@ -276,7 +276,7 @@ class Config:
276
276
 
277
277
  # Init
278
278
  ###########################################################################
279
- ABSFUYU_CONFIG = Config(CONFIG_PATH)
279
+ ABSFUYU_CONFIG = Config(CONFIG_PATH) # type: ignore
280
280
 
281
281
  # TODO: Create a config file when not available [W.I.P]
282
282
  # _settings = [
@@ -3,8 +3,8 @@ Absfuyu: Core
3
3
  -------------
4
4
  Contain type hints and other stuffs
5
5
 
6
- Version: 2.2.0
7
- Date updated: 14/04/2024 (dd/mm/yyyy)
6
+ Version: 2.3.0
7
+ Date updated: 01/02/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
@@ -21,18 +21,11 @@ __all__ = [
21
21
  __package_feature__ = ["beautiful", "extra", "res", "full", "dev"]
22
22
 
23
23
 
24
- from pathlib import Path
25
-
26
- # import sys
27
- # from sys import version_info as _python_version
28
-
29
- # if sys.version_info.minor >= 10:
30
- # from importlib.resources import files
31
- # else:
32
- # try:
33
- # from importlib_resources import files
34
- # except:
35
- # raise ImportError("Please install importlib-resources")
24
+ # Library
25
+ ###########################################################################
26
+ from importlib import import_module
27
+ from importlib.resources import files
28
+ from typing import Iterable
36
29
 
37
30
 
38
31
  class CLITextColor:
@@ -50,7 +43,16 @@ class CLITextColor:
50
43
  RESET = "\x1b[39m"
51
44
 
52
45
 
53
- CORE_PATH = Path(__file__).parent.absolute()
54
- # CORE_PATH = files("absfuyu")
46
+ # CORE_PATH = Path(__file__).parent.absolute()
47
+ CORE_PATH = files("absfuyu")
55
48
  CONFIG_PATH = CORE_PATH.joinpath("config", "config.json")
56
49
  DATA_PATH = CORE_PATH.joinpath("pkg_data")
50
+
51
+
52
+ # tqdm wrapper
53
+ try:
54
+ tqdm = import_module("tqdm").tqdm
55
+ except ModuleNotFoundError:
56
+
57
+ def tqdm(iterable: Iterable, **kwargs):
58
+ return iterable