reykit 1.1.52__py3-none-any.whl → 1.1.54__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.
reykit/remail.py CHANGED
@@ -16,7 +16,7 @@ from email.mime.application import MIMEApplication
16
16
 
17
17
  from .rbase import Base, throw
18
18
  from .rdata import unique
19
- from .ros import FileBytes, get_file_bytes
19
+ from .ros import FileBytes, read_file_bytes
20
20
 
21
21
 
22
22
  __all__ = (
@@ -236,7 +236,7 @@ class Email(Base):
236
236
 
237
237
  ## Attachment.
238
238
  for file_name, file_source in attachment.items():
239
- file_bytes = get_file_bytes(file_source)
239
+ file_bytes = read_file_bytes(file_source)
240
240
  attachment[file_name] = file_bytes
241
241
 
242
242
  # Create email.
reykit/ros.py CHANGED
@@ -50,17 +50,19 @@ from .rsys import run_cmd
50
50
 
51
51
 
52
52
  __all__ = (
53
- 'get_path',
53
+ 'format_path',
54
+ 'join_path',
54
55
  'get_md5',
55
56
  'make_dir',
56
57
  'find_relpath',
57
- 'get_file_str',
58
- 'get_file_bytes',
58
+ 'read_file_str',
59
+ 'read_file_bytes',
59
60
  'read_toml',
60
61
  'File',
61
62
  'Folder',
62
63
  'TempFile',
63
64
  'TempFolder',
65
+ 'FileCache',
64
66
  'doc_to_docx',
65
67
  'extract_docx_content',
66
68
  'extract_pdf_content',
@@ -71,13 +73,13 @@ __all__ = (
71
73
  type FilePath = str
72
74
  type FileText = str
73
75
  type FileData = bytes
74
- type FileStr = FilePath | FileText | TextIOBase
75
- type FileBytes = FilePath | FileData | BufferedIOBase
76
+ type FileSourceStr = FilePath | FileText | TextIOBase
77
+ type FileSourceBytes = FilePath | FileData | BufferedIOBase
76
78
 
77
79
 
78
- def get_path(path: str | None = None) -> str:
80
+ def format_path(path: str | None = None) -> str:
79
81
  """
80
- resolve relative path and replace to forward slash `/`.
82
+ Resolve relative path and replace to forward slash `/`.
81
83
 
82
84
  Parameters
83
85
  ----------
@@ -86,13 +88,13 @@ def get_path(path: str | None = None) -> str:
86
88
 
87
89
  Returns
88
90
  -------
89
- Handled path.
91
+ Formatted path.
90
92
  """
91
93
 
92
94
  # Handle parameter.
93
95
  path = path or ''
94
96
 
95
- # Handle.
97
+ # Format.
96
98
  path_obj = Path(path)
97
99
  path_obj = path_obj.resolve()
98
100
  path = path_obj.as_posix()
@@ -100,6 +102,28 @@ def get_path(path: str | None = None) -> str:
100
102
  return path
101
103
 
102
104
 
105
+ def join_path(*paths: str) -> str:
106
+ """
107
+ Join path and resolve relative path and replace to forward slash `/`.
108
+
109
+ Parameters
110
+ ----------
111
+ paths : Paths.
112
+
113
+ Returns
114
+ -------
115
+ Joined and formatted path.
116
+ """
117
+
118
+ # Join.
119
+ path = os_join(*paths)
120
+
121
+ # Format.
122
+ path = format_path(path)
123
+
124
+ return path
125
+
126
+
103
127
  def get_md5(data: str | bytes) -> str:
104
128
  """
105
129
  Get MD5 value.
@@ -183,14 +207,14 @@ def find_relpath(abspath: str, relpath: str) -> str:
183
207
  for _ in range(level):
184
208
  folder_path, _ = os_split(folder_path)
185
209
  relpath = relpath[level + strip_n:]
186
- path = os_join(folder_path, relpath)
210
+ path = join_path(folder_path, relpath)
187
211
 
188
212
  return path
189
213
 
190
214
 
191
- def get_file_str(source: FileStr) -> str:
215
+ def read_file_str(source: FileSourceStr) -> str:
192
216
  """
193
- Get file string data.
217
+ Read file string data.
194
218
 
195
219
  Parameters
196
220
  ----------
@@ -231,9 +255,9 @@ def get_file_str(source: FileStr) -> str:
231
255
  return file_str
232
256
 
233
257
 
234
- def get_file_bytes(source: FileBytes) -> bytes:
258
+ def read_file_bytes(source: FileSourceBytes) -> bytes:
235
259
  """
236
- Get file bytes data.
260
+ Read file bytes data.
237
261
 
238
262
  Parameters
239
263
  ----------
@@ -324,7 +348,7 @@ class File(Base):
324
348
  """
325
349
 
326
350
  # Set attribute.
327
- self.path = get_path(path)
351
+ self.path = format_path(path)
328
352
 
329
353
 
330
354
  @overload
@@ -512,7 +536,7 @@ class File(Base):
512
536
  """
513
537
 
514
538
  # Get parameter.
515
- move_path = os_join(self.dir, name)
539
+ move_path = join_path(self.dir, name)
516
540
 
517
541
  # Move.
518
542
  self.move(move_path)
@@ -525,7 +549,7 @@ class File(Base):
525
549
  Remove file.
526
550
  """
527
551
 
528
- # Copy.
552
+ # Remove.
529
553
  try:
530
554
  os_remove(self.path)
531
555
 
@@ -854,7 +878,7 @@ class Folder(Base):
854
878
  """
855
879
 
856
880
  # Set attribute.
857
- self.path = get_path(path)
881
+ self.path = format_path(path)
858
882
 
859
883
 
860
884
  def paths(
@@ -887,21 +911,21 @@ class Folder(Base):
887
911
  match target:
888
912
  case 'all':
889
913
  targets_path = [
890
- os_join(path, file_name)
914
+ join_path(path, file_name)
891
915
  for path, folders_name, files_name in obj_walk
892
916
  for file_name in files_name + folders_name
893
917
  ]
894
918
  paths.extend(targets_path)
895
919
  case 'file':
896
920
  targets_path = [
897
- os_join(path, file_name)
921
+ join_path(path, file_name)
898
922
  for path, _, files_name in obj_walk
899
923
  for file_name in files_name
900
924
  ]
901
925
  paths.extend(targets_path)
902
- case 'all' | 'folder':
926
+ case 'folder':
903
927
  targets_path = [
904
- os_join(path, folder_name)
928
+ join_path(path, folder_name)
905
929
  for path, folders_name, _ in obj_walk
906
930
  for folder_name in folders_name
907
931
  ]
@@ -913,17 +937,17 @@ class Folder(Base):
913
937
  match target:
914
938
  case 'all':
915
939
  for name in names:
916
- target_path = os_join(self.path, name)
940
+ target_path = join_path(self.path, name)
917
941
  paths.append(target_path)
918
942
  case 'file':
919
943
  for name in names:
920
- target_path = os_join(self.path, name)
944
+ target_path = join_path(self.path, name)
921
945
  is_file = os_isfile(target_path)
922
946
  if is_file:
923
947
  paths.append(target_path)
924
948
  case 'folder':
925
949
  for name in names:
926
- target_path = os_join(self.path, name)
950
+ target_path = join_path(self.path, name)
927
951
  is_dir = os_isdir(target_path)
928
952
  if is_dir:
929
953
  paths.append(target_path)
@@ -934,7 +958,7 @@ class Folder(Base):
934
958
  @overload
935
959
  def search(
936
960
  self,
937
- pattern: str,
961
+ pattern: str = '',
938
962
  target: Literal['all', 'file', 'folder'] = 'all',
939
963
  recursion: bool = False
940
964
  ) -> str | None: ...
@@ -942,7 +966,7 @@ class Folder(Base):
942
966
  @overload
943
967
  def search(
944
968
  self,
945
- pattern: str,
969
+ pattern: str = '',
946
970
  target: Literal['all', 'file', 'folder'] = 'all',
947
971
  recursion: bool = False,
948
972
  *,
@@ -951,7 +975,7 @@ class Folder(Base):
951
975
 
952
976
  def search(
953
977
  self,
954
- pattern: str,
978
+ pattern: str = '',
955
979
  target: Literal['all', 'file', 'folder'] = 'all',
956
980
  recursion: bool = False,
957
981
  first: bool = True
@@ -1010,9 +1034,9 @@ class Folder(Base):
1010
1034
  """
1011
1035
 
1012
1036
  # Join.
1013
- join_path = os_join(self.path, path)
1037
+ path = join_path(self.path, path)
1014
1038
 
1015
- return join_path
1039
+ return path
1016
1040
 
1017
1041
 
1018
1042
  def make(self, report: bool = False) -> None:
@@ -1069,7 +1093,7 @@ class Folder(Base):
1069
1093
  """
1070
1094
 
1071
1095
  # Get parameter.
1072
- move_path = os_join(self.dir, name)
1096
+ move_path = join_path(self.dir, name)
1073
1097
 
1074
1098
  # Move.
1075
1099
  self.move(move_path)
@@ -1286,7 +1310,7 @@ class TempFile(Base):
1286
1310
  suffix=suffix,
1287
1311
  dir=dir_
1288
1312
  )
1289
- self.path = get_path(self.file.name)
1313
+ self.path = format_path(self.file.name)
1290
1314
 
1291
1315
 
1292
1316
  def read(self) -> bytes | str:
@@ -1563,7 +1587,7 @@ class TempFolder(Base):
1563
1587
 
1564
1588
  # Set attribute.
1565
1589
  self.folder = TemporaryDirectory(dir=dir_)
1566
- self.path = get_path(self.folder.name)
1590
+ self.path = format_path(self.folder.name)
1567
1591
 
1568
1592
 
1569
1593
  def paths(
@@ -1596,21 +1620,21 @@ class TempFolder(Base):
1596
1620
  match target:
1597
1621
  case 'all':
1598
1622
  targets_path = [
1599
- os_join(path, file_name)
1623
+ join_path(path, file_name)
1600
1624
  for path, folders_name, files_name in obj_walk
1601
1625
  for file_name in files_name + folders_name
1602
1626
  ]
1603
1627
  paths.extend(targets_path)
1604
1628
  case 'file':
1605
1629
  targets_path = [
1606
- os_join(path, file_name)
1630
+ join_path(path, file_name)
1607
1631
  for path, _, files_name in obj_walk
1608
1632
  for file_name in files_name
1609
1633
  ]
1610
1634
  paths.extend(targets_path)
1611
1635
  case 'all' | 'folder':
1612
1636
  targets_path = [
1613
- os_join(path, folder_name)
1637
+ join_path(path, folder_name)
1614
1638
  for path, folders_name, _ in obj_walk
1615
1639
  for folder_name in folders_name
1616
1640
  ]
@@ -1622,17 +1646,17 @@ class TempFolder(Base):
1622
1646
  match target:
1623
1647
  case 'all':
1624
1648
  for name in names:
1625
- target_path = os_join(self.path, name)
1649
+ target_path = join_path(self.path, name)
1626
1650
  paths.append(target_path)
1627
1651
  case 'file':
1628
1652
  for name in names:
1629
- target_path = os_join(self.path, name)
1653
+ target_path = join_path(self.path, name)
1630
1654
  is_file = os_isfile(target_path)
1631
1655
  if is_file:
1632
1656
  paths.append(target_path)
1633
1657
  case 'folder':
1634
1658
  for name in names:
1635
- target_path = os_join(self.path, name)
1659
+ target_path = join_path(self.path, name)
1636
1660
  is_dir = os_isdir(target_path)
1637
1661
  if is_dir:
1638
1662
  paths.append(target_path)
@@ -1643,7 +1667,7 @@ class TempFolder(Base):
1643
1667
  @overload
1644
1668
  def search(
1645
1669
  self,
1646
- pattern: str,
1670
+ pattern: str = '',
1647
1671
  target: Literal['all', 'file', 'folder'] = 'all',
1648
1672
  recursion: bool = False
1649
1673
  ) -> str | None: ...
@@ -1651,7 +1675,7 @@ class TempFolder(Base):
1651
1675
  @overload
1652
1676
  def search(
1653
1677
  self,
1654
- pattern: str,
1678
+ pattern: str = '',
1655
1679
  target: Literal['all', 'file', 'folder'] = 'all',
1656
1680
  recursion: bool = False,
1657
1681
  *,
@@ -1660,7 +1684,7 @@ class TempFolder(Base):
1660
1684
 
1661
1685
  def search(
1662
1686
  self,
1663
- pattern: str,
1687
+ pattern: str = '',
1664
1688
  target: Literal['all', 'file', 'folder'] = 'all',
1665
1689
  recursion: bool = False,
1666
1690
  first: bool = True
@@ -1719,7 +1743,7 @@ class TempFolder(Base):
1719
1743
  """
1720
1744
 
1721
1745
  # Join.
1722
- join_path = os_join(self.path, path)
1746
+ join_path = join_path(self.path, path)
1723
1747
 
1724
1748
  return join_path
1725
1749
 
@@ -1906,6 +1930,156 @@ class TempFolder(Base):
1906
1930
  __add__ = __radd__ = join
1907
1931
 
1908
1932
 
1933
+ class FileCache(Base):
1934
+ """
1935
+ File cache type.
1936
+ """
1937
+
1938
+
1939
+ def __init__(self, path: str = 'cache') -> None:
1940
+ """
1941
+ Build instance attributes.
1942
+
1943
+ Parameters
1944
+ ----------
1945
+ path : Root directory path.
1946
+ """
1947
+
1948
+ # Set attribute.
1949
+ self.folder = Folder(path)
1950
+
1951
+ # Make directory.
1952
+ self.__make_dir()
1953
+
1954
+
1955
+ def __make_dir(self) -> None:
1956
+ """
1957
+ Make cache directory and subdirectories.
1958
+ """
1959
+
1960
+ # Make.
1961
+ chars = '0123456789abcdef'
1962
+
1963
+ ## Root.
1964
+ paths = [self.folder.path]
1965
+
1966
+ ## Second layer.
1967
+ paths.extend(
1968
+ [
1969
+ self.folder + char
1970
+ for char in chars
1971
+ ]
1972
+ )
1973
+
1974
+ ## Third layer.
1975
+ paths.extend(
1976
+ [
1977
+ self.folder + f'{char}/{char_sub}'
1978
+ for char in chars
1979
+ for char_sub in chars
1980
+ ]
1981
+ )
1982
+
1983
+ make_dir(*paths)
1984
+
1985
+
1986
+ def index(self, md5: str, name: str | None = None, copy: bool = False) -> str | None:
1987
+ """
1988
+ Index file from cache directory.
1989
+
1990
+ Parameters
1991
+ ----------
1992
+ md5 : File md5 value.
1993
+ name : File name.
1994
+ - `None`: Use md5 value.
1995
+ copy : Do you want to copy file when exist md5 value file and not exist file name.
1996
+
1997
+ Returns
1998
+ -------
1999
+ File path or not exist.
2000
+ """
2001
+
2002
+ # Handle parameter.
2003
+ if name is None:
2004
+ name = md5
2005
+
2006
+ # Not exist md5.
2007
+ md5_relpath = f'{md5[0]}/{md5[1]}/{md5}'
2008
+ if md5_relpath not in self.folder:
2009
+ return
2010
+
2011
+ # Exist md5.
2012
+ file_relpath = f'{md5_relpath}/{name}'
2013
+ file_path = self.folder + file_relpath
2014
+
2015
+ ## Exist file.
2016
+ if file_path in self.folder:
2017
+ return file_path
2018
+
2019
+ ## Copy file.
2020
+ elif copy:
2021
+ md5_path = self.folder + md5_relpath
2022
+ md5_folder = Folder(md5_path)
2023
+ md5_file_path = md5_folder.search(target='file')
2024
+ file = File(md5_file_path)
2025
+ file.copy(file_path)
2026
+ return file_path
2027
+
2028
+
2029
+ def store(self, source: FileSourceBytes, name: str | None = None, delete: bool = False) -> str:
2030
+ """
2031
+ Store file to cache directory.
2032
+
2033
+ Parameters
2034
+ ----------
2035
+ source : Source file path or file data.
2036
+ name : File name.
2037
+ - `None`: Use md5 value.
2038
+ delete : When source is file path, whether delete original file.
2039
+
2040
+ Returns
2041
+ -------
2042
+ Store file path.
2043
+ """
2044
+
2045
+ # Handle parameter.
2046
+ file_bytes = read_file_bytes(source)
2047
+ file_md5 = get_md5(file_bytes)
2048
+ if name is None:
2049
+ name = file_md5
2050
+ delete = delete and type(source) == str
2051
+
2052
+ # Exist.
2053
+ path = self.index(file_md5, name)
2054
+ if path is not None:
2055
+
2056
+ ## Delete.
2057
+ if delete:
2058
+ file = File(source)
2059
+ file.remove()
2060
+
2061
+ return path
2062
+
2063
+ # Store.
2064
+ md5_relpath = f'{file_md5[0]}/{file_md5[1]}/{file_md5}'
2065
+ md5_path = self.folder + md5_relpath
2066
+ folder = Folder(md5_path)
2067
+ folder.make()
2068
+ path = folder + name
2069
+
2070
+ ## Delete.
2071
+ if delete:
2072
+ file = File(source)
2073
+ file.move(path)
2074
+
2075
+ ## Make.
2076
+ else:
2077
+ file = File(path)
2078
+ file(file_bytes)
2079
+
2080
+ return path
2081
+
2082
+
1909
2083
  def doc_to_docx(path: str, save_path: str | None = None) -> str:
1910
2084
  """
1911
2085
  Convert `DOC` file to `DOCX` file.
reykit/rzip.py CHANGED
@@ -11,9 +11,9 @@
11
11
 
12
12
  from zipfile import ZipFile, is_zipfile, ZIP_DEFLATED
13
13
  from os import getcwd as os_getcwd, walk as os_walk
14
- from os.path import join as os_join, isfile as os_isfile
14
+ from os.path import isfile as os_isfile
15
15
 
16
- from .ros import File, Folder
16
+ from .ros import File, Folder, join_path
17
17
 
18
18
 
19
19
  __all__ = (
@@ -54,7 +54,7 @@ def compress(
54
54
  folder = Folder(path)
55
55
  obj_name = folder.name
56
56
  build_name = obj_name + '.zip'
57
- build_path = os_join(build_dir, build_name)
57
+ build_path = join_path(build_dir, build_name)
58
58
 
59
59
  # Compress.
60
60
  with ZipFile(build_path, mode, ZIP_DEFLATED) as zip_file:
@@ -69,11 +69,11 @@ def compress(
69
69
  dirs = os_walk(folder.path)
70
70
  for folder_name, sub_folders_name, files_name in dirs:
71
71
  for sub_folder_name in sub_folders_name:
72
- sub_folder_path = os_join(folder_name, sub_folder_name)
72
+ sub_folder_path = join_path(folder_name, sub_folder_name)
73
73
  zip_path = sub_folder_path[dir_path_len:]
74
74
  zip_file.write(sub_folder_path, zip_path)
75
75
  for file_name in files_name:
76
- file_path = os_join(folder_name, file_name)
76
+ file_path = join_path(folder_name, file_name)
77
77
  zip_path = file_path[dir_path_len:]
78
78
  zip_file.write(file_path, zip_path)
79
79
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reykit
3
- Version: 1.1.52
3
+ Version: 1.1.54
4
4
  Summary: Kit method set.
5
5
  Project-URL: homepage, https://github.com/reyxbo/reykit/
6
6
  Author-email: Rey <reyxbo@163.com>
@@ -2,13 +2,13 @@ reykit/__init__.py,sha256=V86CHqPAAVkooVx3_QIOKpDIFVneQCTTSwfJ-uWgBno,788
2
2
  reykit/rall.py,sha256=7Hip02YOkIDm3_xkoSDjvvYV2LhdBV2r4UKzWWnIfIo,628
3
3
  reykit/rbase.py,sha256=KPSMPMenmzsA50Q84r0DOXv4Ei-hbp06HXnCB46dsP4,22121
4
4
  reykit/rdata.py,sha256=DqxoWkbN3WqGZ5FC9VRlhXAwpTGebv1M5VSeOeR2YnQ,10308
5
- reykit/remail.py,sha256=s7TXbLgEWEqNoeM42c6FpPufB2LajHgQuahfZri3urQ,6706
5
+ reykit/remail.py,sha256=9r4UEBhd43MzHPtGVQe3QyxLjGO7BINt9WtHvWhSLTs,6708
6
6
  reykit/rimage.py,sha256=Dj2ZK0Qprmu0WGLjaMnJgjbT39o1YxqyD8e9pAe3kl0,6151
7
7
  reykit/rlog.py,sha256=jgnI8jFSGw0WcD8SSVmUCkomLXY8uoXdwJMUyB2ED4U,25587
8
8
  reykit/rmonkey.py,sha256=9-NvBM4phThKTHpqTSPlPGfJWcoDSp4EVl8x3xHJacg,7951
9
9
  reykit/rnet.py,sha256=15yrZTMET4cdimbslMk9O8HO9ofMtvfo1dZgLd4Bafw,16938
10
10
  reykit/rnum.py,sha256=PhG4V_BkVfCJUsbpMDN1umGZly1Hsus80TW8bpyBtyY,3653
11
- reykit/ros.py,sha256=vrzs2biU6qZhNqvwV4iJn7MvJF1vdeblJ6pbjIh12dc,42955
11
+ reykit/ros.py,sha256=mhlwA8fmVURNH5eJbSnE9AN_9c44nH04GQaVBMigp-U,47033
12
12
  reykit/rrand.py,sha256=imysGSoQH4O0yq45EILYYdow_280LDqYioE4Sm-L4_U,8938
13
13
  reykit/rre.py,sha256=4DVxy28dl5zn6_II8-cgr7E2nVPH5QJIJVB4o7Vsf1A,6078
14
14
  reykit/rschedule.py,sha256=_nrfrXYxlFAKCDbM8ibTTb60zNDlHxyE310cv-A19Kw,5799
@@ -19,10 +19,10 @@ reykit/rtask.py,sha256=d3Fs-_ZB-uHtzz7zyI2aAmiQv3NcIvWrco6x10jFuzc,22842
19
19
  reykit/rtext.py,sha256=gkmA849MBHjchvY4apUTQpkFs13vcmyK_hIwucH2A84,12849
20
20
  reykit/rtime.py,sha256=xBpXItHRSmftec1ZzqVRTkMNb6gmFx0A8TaUd5nmiy8,16974
21
21
  reykit/rwrap.py,sha256=x4CzSndSdSv_e8lLbLifvC_v2ogWHD42-tDhwsq_DzQ,15317
22
- reykit/rzip.py,sha256=TU18pEpbr2T7zWFzxkcZPjN5gudw-FArusf55qeNDCo,3453
22
+ reykit/rzip.py,sha256=cG1PbY5dlMRNEIBzOytxF2crjr1yWLMmswR_klh_4Ek,3453
23
23
  reykit/rdll/__init__.py,sha256=WrJ_8jp_hbn2nl1osrR3buZMsmAGRVY6HfQdhDoJpSM,698
24
24
  reykit/rdll/rdll_core.py,sha256=o6-rKcTQgxZQe0kD3GnwyNb3KL9IogzgCQNOmYLMm7A,5086
25
- reykit-1.1.52.dist-info/METADATA,sha256=FaLppu0Wz58YqO4tAD2RzT_acfSws0pUXYq4GD7FC0I,1872
26
- reykit-1.1.52.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
- reykit-1.1.52.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
28
- reykit-1.1.52.dist-info/RECORD,,
25
+ reykit-1.1.54.dist-info/METADATA,sha256=KnsGv5u0b7ZUBwEkGsieQ6yTp6tkPukiX_rurAkxoVk,1872
26
+ reykit-1.1.54.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
+ reykit-1.1.54.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
28
+ reykit-1.1.54.dist-info/RECORD,,