absfuyu 5.6.0__py3-none-any.whl → 5.7.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 +1 -1
  2. absfuyu/__main__.py +1 -1
  3. absfuyu/cli/__init__.py +1 -1
  4. absfuyu/cli/color.py +1 -1
  5. absfuyu/cli/config_group.py +1 -1
  6. absfuyu/cli/do_group.py +1 -1
  7. absfuyu/cli/game_group.py +1 -1
  8. absfuyu/cli/tool_group.py +1 -1
  9. absfuyu/config/__init__.py +1 -1
  10. absfuyu/core/__init__.py +1 -1
  11. absfuyu/core/baseclass.py +1 -1
  12. absfuyu/core/baseclass2.py +1 -1
  13. absfuyu/core/decorator.py +1 -1
  14. absfuyu/core/docstring.py +1 -1
  15. absfuyu/core/dummy_cli.py +1 -1
  16. absfuyu/core/dummy_func.py +1 -1
  17. absfuyu/dxt/__init__.py +1 -1
  18. absfuyu/dxt/dictext.py +1 -1
  19. absfuyu/dxt/dxt_support.py +1 -1
  20. absfuyu/dxt/intext.py +1 -1
  21. absfuyu/dxt/listext.py +1 -1
  22. absfuyu/dxt/strext.py +1 -1
  23. absfuyu/extra/__init__.py +1 -1
  24. absfuyu/extra/beautiful.py +1 -1
  25. absfuyu/extra/da/__init__.py +4 -2
  26. absfuyu/extra/da/dadf.py +109 -11
  27. absfuyu/extra/da/dadf_base.py +1 -1
  28. absfuyu/extra/da/df_func.py +1 -1
  29. absfuyu/extra/da/mplt.py +1 -1
  30. absfuyu/extra/data_analysis.py +1 -1
  31. absfuyu/extra/pdf.py +2 -4
  32. absfuyu/extra/xml.py +90 -0
  33. absfuyu/fun/__init__.py +1 -1
  34. absfuyu/fun/rubik.py +1 -1
  35. absfuyu/fun/tarot.py +1 -1
  36. absfuyu/game/__init__.py +1 -1
  37. absfuyu/game/game_stat.py +1 -1
  38. absfuyu/game/sudoku.py +1 -1
  39. absfuyu/game/tictactoe.py +1 -1
  40. absfuyu/game/wordle.py +1 -1
  41. absfuyu/general/__init__.py +1 -1
  42. absfuyu/general/content.py +1 -1
  43. absfuyu/general/human.py +1 -1
  44. absfuyu/general/shape.py +1 -1
  45. absfuyu/logger.py +1 -1
  46. absfuyu/pkg_data/__init__.py +1 -1
  47. absfuyu/pkg_data/deprecated.py +1 -1
  48. absfuyu/sort.py +1 -1
  49. absfuyu/tools/__init__.py +1 -1
  50. absfuyu/tools/checksum.py +1 -1
  51. absfuyu/tools/converter.py +1 -1
  52. absfuyu/tools/generator.py +1 -1
  53. absfuyu/tools/inspector.py +1 -1
  54. absfuyu/tools/keygen.py +1 -1
  55. absfuyu/tools/obfuscator.py +1 -1
  56. absfuyu/tools/passwordlib.py +1 -1
  57. absfuyu/tools/shutdownizer.py +1 -1
  58. absfuyu/tools/sw.py +4 -3
  59. absfuyu/tools/web.py +1 -1
  60. absfuyu/typings.py +1 -1
  61. absfuyu/util/__init__.py +1 -1
  62. absfuyu/util/api.py +1 -1
  63. absfuyu/util/json_method.py +1 -1
  64. absfuyu/util/lunar.py +1 -1
  65. absfuyu/util/path.py +1 -1
  66. absfuyu/util/performance.py +1 -1
  67. absfuyu/util/shorten_number.py +1 -1
  68. absfuyu/util/text_table.py +1 -1
  69. absfuyu/util/zipped.py +1 -1
  70. absfuyu/version.py +1 -1
  71. {absfuyu-5.6.0.dist-info → absfuyu-5.7.0.dist-info}/METADATA +5 -4
  72. absfuyu-5.7.0.dist-info/RECORD +80 -0
  73. absfuyu-5.6.0.dist-info/RECORD +0 -79
  74. {absfuyu-5.6.0.dist-info → absfuyu-5.7.0.dist-info}/WHEEL +0 -0
  75. {absfuyu-5.6.0.dist-info → absfuyu-5.7.0.dist-info}/entry_points.txt +0 -0
  76. {absfuyu-5.6.0.dist-info → absfuyu-5.7.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/__init__.py CHANGED
@@ -22,7 +22,7 @@ Using in cmd:
22
22
  __title__ = "absfuyu"
23
23
  __author__ = "AbsoluteWinter"
24
24
  __license__ = "MIT License"
25
- __version__ = "5.6.0"
25
+ __version__ = "5.7.0"
26
26
  __all__ = [
27
27
  "core",
28
28
  "config",
absfuyu/__main__.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU
3
3
  -------
4
4
  COMMAND LINE INTERFACE
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/cli/__init__.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU
3
3
  -------
4
4
  COMMAND LINE INTERFACE
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/cli/color.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Color
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Config
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/cli/do_group.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Do
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/cli/game_group.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Game
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/cli/tool_group.py CHANGED
@@ -3,7 +3,7 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Tool
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Configuration
3
3
  ----------------------
4
4
  Package configuration module
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/core/__init__.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Bases for other features
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/core/baseclass.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Bases for other features
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Bases for other features (with library)
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/core/decorator.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Decorator
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/core/docstring.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Sphinx docstring decorator
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/core/dummy_cli.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Dummy cli
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Core
3
3
  -------------
4
4
  Dummy functions when other libraries are unvailable
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/dxt/__init__.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  Extension for data type such as ``list``, ``str``, ``dict``, ...
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
 
9
9
  Features:
absfuyu/dxt/dictext.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  dict extension
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  Support classes
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/dxt/intext.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  int extension
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/dxt/listext.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  list extension
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/dxt/strext.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  str extension
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/extra/__init__.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Extra
3
3
  --------------
4
4
  Features that require additional libraries
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Beautiful
3
3
  ------------------
4
4
  A decorator that makes output more beautiful
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,8 +3,8 @@ Absfuyu: Data Analysis
3
3
  ----------------------
4
4
  Data Analyst
5
5
 
6
- Version: 5.6.0
7
- Date updated: 12/09/2025 (dd/mm/yyyy)
6
+ Version: 5.7.0
7
+ Date updated: 16/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -18,7 +18,9 @@ DA_MODE = False
18
18
 
19
19
  try:
20
20
  import numpy as np
21
+ import openpyxl
21
22
  import pandas as pd
23
+ import xlsxwriter
22
24
  except ImportError:
23
25
  from subprocess import run
24
26
 
absfuyu/extra/da/dadf.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Data Analysis
3
3
  ----------------------
4
4
  Data Analyst DataFrame
5
5
 
6
- Version: 5.6.0
7
- Date updated: 12/09/2025 (dd/mm/yyyy)
6
+ Version: 5.7.0
7
+ Date updated: 16/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -17,6 +17,7 @@ __all__ = [
17
17
  "DataAnalystDataFrameNAMixin",
18
18
  "DataAnalystDataFrameOtherMixin",
19
19
  "DataAnalystDataFrameDateMixin",
20
+ "DataAnalystDataFrameExportMixin",
20
21
  "DataAnalystDataFrameCityMixin",
21
22
  ]
22
23
 
@@ -31,6 +32,8 @@ from typing import Any, Literal, Self
31
32
 
32
33
  import numpy as np
33
34
  import pandas as pd
35
+ from xlsxwriter import Workbook
36
+ from xlsxwriter.worksheet import Worksheet
34
37
 
35
38
  try:
36
39
  from typing import override # type: ignore
@@ -183,7 +186,9 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
183
186
  @deprecated("5.1.0", reason="Use pd.DataFrame.assign(...) method instead")
184
187
  def add_blank_column(self, column_name: str, fill: Any = np.nan, /) -> Self:
185
188
  """
186
- Add a blank column
189
+ [DEPRECATED] Add a blank column.
190
+
191
+ E.g: Use `pd.DataFrame.assign(new_col=lambda x: x['old_col'])` instead
187
192
 
188
193
  Parameters
189
194
  ----------
@@ -246,9 +251,7 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
246
251
  """
247
252
  if n is None:
248
253
  pass
249
- splited_data: pd.DataFrame = self[col].str.split(
250
- pat=pattern, n=n, expand=True, regex=regex
251
- )
254
+ splited_data: pd.DataFrame = self[col].str.split(pat=pattern, n=n, expand=True, regex=regex) # type: ignore
252
255
  num_of_splitted_cols = splited_data.shape[1]
253
256
  new_col_names = [f"{col}_{x}" for x in range(num_of_splitted_cols)]
254
257
  self[new_col_names] = splited_data
@@ -262,6 +265,7 @@ class DataAnalystDataFrameRowMethodMixin(DFBase):
262
265
  Data Analyst ``pd.DataFrame`` - Row method
263
266
 
264
267
  - Get different rows
268
+ - Add blank row
265
269
  """
266
270
 
267
271
  @versionadded("4.0.0")
@@ -297,6 +301,26 @@ class DataAnalystDataFrameRowMethodMixin(DFBase):
297
301
  )
298
302
  return self.__class__(out)
299
303
 
304
+ @versionadded("5.7.0")
305
+ def add_blank_row(self, fill: Any = np.nan, /) -> Self:
306
+ """
307
+ Add a new row to the end of a DataFrame.
308
+
309
+ Parameters
310
+ ----------
311
+ fill : Any, default np.nan
312
+ Value to fill in the new row (e.g., np.nan, None, "", 0).
313
+
314
+ Returns
315
+ -------
316
+ Self
317
+ DataFrame with the new row appended.
318
+ """
319
+ # Create a dict with all columns filled with fill
320
+ new_row = {col: fill for col in self.columns}
321
+ self.loc[len(self)] = new_row # type: ignore
322
+ return self
323
+
300
324
 
301
325
  # Info
302
326
  # ---------------------------------------------------------------------------
@@ -486,7 +510,7 @@ class DataAnalystDataFrameInfoMixin(DFBase):
486
510
  if top is not None:
487
511
  list_of_keep: list = (
488
512
  col_df[destination_column]
489
- .head(set_min_max(top - 1, min_value=1, max_value=col_df.shape[0]))
513
+ .head(set_min_max(top - 1, min_value=1, max_value=col_df.shape[0])) # type: ignore
490
514
  .to_list()
491
515
  )
492
516
  # logger.debug(list_of_keep)
@@ -561,7 +585,7 @@ class DataAnalystDataFrameNAMixin(DFBase):
561
585
  except KeyError:
562
586
  if getattr(self, "add_blank_column", None) is not None:
563
587
  # Compatible with DataAnalystDataFrameColumnMethodMixin
564
- self.add_blank_column(column_name, fill_when_not_exist)
588
+ self.add_blank_column(column_name, fill_when_not_exist) # type: ignore
565
589
  return self
566
590
 
567
591
  def get_missing_values(
@@ -679,7 +703,7 @@ class DataAnalystDataFrameNAMixin(DFBase):
679
703
  3 -1.435079 400 400 REPLACED ywahcasi 2024-05-20
680
704
  4 0.118993 861 800 REPLACED saoupuby 2019-04-28
681
705
  """
682
- self[col] = self[col].apply(lambda x: callable(x) if pd.notnull(x) else x)
706
+ self[col] = self[col].apply(lambda x: callable(x) if pd.notnull(x) else x) # type: ignore
683
707
  return self
684
708
 
685
709
  @versionadded("5.1.0") # type: ignore
@@ -750,7 +774,7 @@ class DataAnalystDataFrameNAMixin(DFBase):
750
774
 
751
775
  # Column name
752
776
  cname = "applied_row_null" if col_name is None else col_name
753
- self[cname] = self.apply(apply_func, axis=1)
777
+ self[cname] = self.apply(apply_func, axis=1) # type: ignore
754
778
 
755
779
  return self
756
780
 
@@ -825,7 +849,7 @@ class DataAnalystDataFrameOtherMixin(DFBase):
825
849
 
826
850
  if getattr(self, "drop_columns", None) is not None:
827
851
  # Compatible with DataAnalystDataFrameColumnMethodMixin
828
- self.drop_columns(cols)
852
+ self.drop_columns(cols) # type: ignore
829
853
 
830
854
  out = self.merge(other, how="left", on=on)
831
855
  return self.__class__(out)
@@ -1018,6 +1042,79 @@ class DataAnalystDataFrameDateMixin(DFBase):
1018
1042
  return self
1019
1043
 
1020
1044
 
1045
+ # Export
1046
+ # ---------------------------------------------------------------------------
1047
+ class DataAnalystDataFrameExportMixin(DFBase):
1048
+ """
1049
+ Data Analyst ``pd.DataFrame`` - Export method
1050
+
1051
+ - da_export
1052
+ """
1053
+
1054
+ def da_export(self, path: str, sheet_name: str = "Sheet1", cols_contain_number: list[str] | None = None) -> None:
1055
+ """
1056
+ Export DataFrame with `xlsxwriter` engine
1057
+
1058
+ Parameters
1059
+ ----------
1060
+ path : Path | str
1061
+ Path to export
1062
+
1063
+ sheet_name : str
1064
+ Sheet name
1065
+
1066
+ cols_contain_number : list[str]
1067
+ Columns that contain number value (to format as number)
1068
+ """
1069
+ # Using xlsxwriter engine
1070
+ with pd.ExcelWriter(path, engine="xlsxwriter") as writer:
1071
+ self.to_excel(writer, sheet_name=sheet_name, index=False, float_format="%.2f", na_rep="")
1072
+
1073
+ # Format style
1074
+ workbook: Workbook = writer.book # type: ignore
1075
+ header_fmt = workbook.add_format(
1076
+ {
1077
+ "bold": True,
1078
+ "text_wrap": True,
1079
+ "border": 1,
1080
+ "align": "center",
1081
+ "valign": "vcenter",
1082
+ # "bg_color": "#A0BEFD",
1083
+ }
1084
+ )
1085
+ number_fmt = workbook.add_format(
1086
+ {
1087
+ "num_format": "#,##0",
1088
+ "align": "center",
1089
+ "valign": "vcenter",
1090
+ }
1091
+ ) # 1,000,000
1092
+ text_fmt = workbook.add_format({"valign": "vcenter"})
1093
+ text_center_fmt = workbook.add_format({"align": "center", "valign": "vcenter"})
1094
+
1095
+ # Format sheet
1096
+ worksheet: Worksheet = writer.sheets[sheet_name]
1097
+
1098
+ # Format header - First row
1099
+ for col_num, value in enumerate(self.columns.values):
1100
+ worksheet.write(0, col_num, value, header_fmt)
1101
+
1102
+ # Auto width + col format
1103
+ for i, col in enumerate(self.columns):
1104
+ # Max str len of each column
1105
+ max_len = max(self[col].astype(str).map(len).max(), len(col)) + 2
1106
+ worksheet.set_column(i, i, max_len) # Set width
1107
+
1108
+ # Format style
1109
+ if cols_contain_number is None:
1110
+ continue
1111
+
1112
+ if col in cols_contain_number:
1113
+ worksheet.set_column(i, i, max_len, number_fmt)
1114
+ else:
1115
+ worksheet.set_column(i, i, max_len, text_fmt)
1116
+
1117
+
1021
1118
  # City
1022
1119
  # ---------------------------------------------------------------------------
1023
1120
  class DataAnalystDataFrameCityMixin(DFBase):
@@ -1091,6 +1188,7 @@ class DataAnalystDataFrameCityMixin(DFBase):
1091
1188
  class DADF(
1092
1189
  GetClassMembersMixin,
1093
1190
  DataAnalystDataFrameCityMixin,
1191
+ DataAnalystDataFrameExportMixin,
1094
1192
  DataAnalystDataFrameDateMixin,
1095
1193
  DataAnalystDataFrameOtherMixin,
1096
1194
  DataAnalystDataFrameNAMixin,
@@ -3,7 +3,7 @@ Absfuyu: Data Analysis
3
3
  ----------------------
4
4
  Data Analyst DataFrame - Base/Core
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -3,7 +3,7 @@ Absfuyu: Data Analysis
3
3
  ----------------------
4
4
  DF Function
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/extra/da/mplt.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Data Analysis
3
3
  ----------------------
4
4
  Matplotlib Helper
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
@@ -4,7 +4,7 @@ Absfuyu: Data Analysis [W.I.P]
4
4
  Extension for ``pd.DataFrame``
5
5
  (deprecated)
6
6
 
7
- Version: 5.6.0
7
+ Version: 5.7.0
8
8
  Date updated: 12/09/2025 (dd/mm/yyyy)
9
9
  """
10
10
 
absfuyu/extra/pdf.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: PDF
3
3
  ------------
4
4
  PDF Tool [W.I.P]
5
5
 
6
- Version: 5.6.0
7
- Date updated: 12/09/2025 (dd/mm/yyyy)
6
+ Version: 5.7.0
7
+ Date updated: 16/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -41,8 +41,6 @@ else:
41
41
 
42
42
  # Class
43
43
  # ---------------------------------------------------------------------------
44
-
45
-
46
44
  class PDFTool(BaseClass):
47
45
  def __init__(self) -> None:
48
46
  super().__init__()
absfuyu/extra/xml.py ADDED
@@ -0,0 +1,90 @@
1
+ """
2
+ Absfuyu: XML
3
+ ------------
4
+ XML Tool [W.I.P]
5
+
6
+ Version: 5.7.0
7
+ Date updated: 16/09/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module level
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["XML2Dict"]
13
+
14
+
15
+ # Library
16
+ # ---------------------------------------------------------------------------
17
+ from pathlib import Path
18
+ from typing import Any, Self
19
+
20
+ from absfuyu.core.baseclass import GetClassMembersMixin
21
+
22
+ XML_MODE = False
23
+
24
+ try:
25
+ import xmltodict
26
+ except ImportError:
27
+ from subprocess import run
28
+
29
+ from absfuyu.config import ABSFUYU_CONFIG
30
+
31
+ if ABSFUYU_CONFIG._get_setting("auto-install-extra").value: # type: ignore
32
+ cmd = "python -m pip install -U absfuyu[full]".split()
33
+ run(cmd)
34
+ else:
35
+ raise SystemExit("This feature is in absfuyu[full] package") # noqa: B904
36
+ else:
37
+ XML_MODE = True
38
+
39
+
40
+ # Class
41
+ # ---------------------------------------------------------------------------
42
+ class XML2Dict(GetClassMembersMixin):
43
+ """
44
+ Automatically convert .xml file to dict
45
+
46
+
47
+ Usage
48
+ -----
49
+ >>> XML2Dict(<path>)
50
+ >>> XML2Dict.parsed_data
51
+ """
52
+
53
+ def __init__(self, text: str) -> None:
54
+ """
55
+ Automatically convert .xml file to dict
56
+
57
+ Parameters
58
+ ----------
59
+ text : str
60
+ ``.xml`` format text
61
+ """
62
+ self._text = text
63
+
64
+ self.parsed_data: dict[str, Any] = self._parse_xml()
65
+
66
+ def __repr__(self) -> str:
67
+ return f"{self.__class__.__name__}()"
68
+
69
+ def _parse_xml(self) -> dict[str, Any]:
70
+ """Convert xml to dict"""
71
+ return xmltodict.parse(self._text, encoding="utf-8") # type: ignore
72
+
73
+ @classmethod
74
+ def from_path(cls, xml_path: str | Path) -> Self:
75
+ """
76
+ Convert from .xml file path
77
+
78
+ Parameters
79
+ ----------
80
+ xml_path : str | Path
81
+ Path to .xml file
82
+
83
+ Returns
84
+ -------
85
+ Self
86
+ xml to dict
87
+ """
88
+ with Path(xml_path).open("r", encoding="utf-8") as f:
89
+ dat = "\n".join(f.readlines())
90
+ return cls(dat)
absfuyu/fun/__init__.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Fun
3
3
  ------------
4
4
  Some fun or weird stuff
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/fun/rubik.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Fun
3
3
  ------------
4
4
  Rubik
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
 
9
9
 
absfuyu/fun/tarot.py CHANGED
@@ -4,7 +4,7 @@ Absfuyu: Tarot
4
4
  Tarot stuff
5
5
 
6
6
 
7
- Version: 5.6.0
7
+ Version: 5.7.0
8
8
  Date updated: 12/09/2025 (dd/mm/yyyy)
9
9
 
10
10
  Usage:
absfuyu/game/__init__.py CHANGED
@@ -3,7 +3,7 @@ Absfuyu: Game
3
3
  -------------
4
4
  Contain some game that can be played on terminal
5
5
 
6
- Version: 5.6.0
6
+ Version: 5.7.0
7
7
  Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
absfuyu/game/game_stat.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Game: Game Stat
3
3
 
4
- Version: 5.6.0
4
+ Version: 5.7.0
5
5
  Date updated: 12/09/2025 (dd/mm/yyyy)
6
6
  """
7
7