atomicshop 2.6.11__py3-none-any.whl → 2.6.12__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.
atomicshop/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.6.11'
4
+ __version__ = '2.6.12'
@@ -1,12 +1,19 @@
1
1
  import os
2
2
  import zipfile
3
3
  from io import BytesIO
4
+ from typing import Union
4
5
 
5
6
  from . import zip, sevenz
7
+ from ..print_api import print_api
6
8
 
7
9
  import py7zr
8
10
 
9
11
 
12
+ # Custom exception if the file is not known archive type.
13
+ class UnknownArchiveType(Exception):
14
+ pass
15
+
16
+
10
17
  def _get_unique_filename(directory, filename):
11
18
  """
12
19
  Generates a unique filename by appending a number if the file already exists.
@@ -21,14 +28,15 @@ def _get_unique_filename(directory, filename):
21
28
 
22
29
 
23
30
  def _is_zip_file(file, zip_obj):
24
- try:
25
- with zip_obj.open(file) as file_data:
26
- with zipfile.ZipFile(BytesIO(file_data.read())) as zip_file:
27
- if zip_file.testzip() is None: # No errors found
28
- return True
29
- except zipfile.BadZipFile:
30
- return False
31
- return False
31
+ with zip_obj.open(file) as file_data:
32
+ with BytesIO(file_data.read()) as file_data_bytes_io:
33
+ return zip.is_zip_zipfile(file_data_bytes_io)
34
+
35
+
36
+ def _is_7z_file(file, sevenz_obj):
37
+ with sevenz_obj.open(file) as file_data:
38
+ with BytesIO(file_data.read()) as file_data_bytes_io:
39
+ return sevenz.is_7z(file_data_bytes_io)
32
40
 
33
41
 
34
42
  def _match_file_name(target, current, case_sensitive):
@@ -38,18 +46,6 @@ def _match_file_name(target, current, case_sensitive):
38
46
  return current.lower().endswith(target.lower())
39
47
 
40
48
 
41
- def _handle_nested_zip(
42
- zip_obj, item, archived_file_bytes, file_names, results, found_set, recursive, return_first_only,
43
- case_sensitive, callback_functions, extract_file_to_path):
44
-
45
- if recursive and _is_zip_file(item.filename, zip_obj):
46
- nested_zip_bytes = BytesIO(archived_file_bytes)
47
- with zipfile.ZipFile(nested_zip_bytes) as nested_zip:
48
- _search_in_archive(
49
- nested_zip, file_names, results, found_set, case_sensitive, return_first_only, recursive,
50
- callback_functions, extract_file_to_path)
51
-
52
-
53
49
  def _handle_file_extraction(item, extract_file_to_path, archived_file_bytes):
54
50
  if extract_file_to_path:
55
51
  unique_filename = _get_unique_filename(extract_file_to_path, os.path.basename(item.filename))
@@ -113,7 +109,9 @@ def _search_in_archive(
113
109
  elif archive_type == '7z':
114
110
  file_info_list = arch_obj.list()
115
111
 
116
- for item in file_info_list:
112
+ for item_index, item in enumerate(file_info_list):
113
+ if item_index == 16:
114
+ pass
117
115
  if item.filename.endswith('/'): # Skip directories
118
116
  continue
119
117
 
@@ -133,9 +131,10 @@ def _search_in_archive(
133
131
  if callback_matched:
134
132
  _handle_file_extraction(item, extract_file_to_path, archived_file_bytes)
135
133
  else:
136
- _handle_nested_zip(
137
- arch_obj, item, archived_file_bytes, file_names, results, found_set, recursive, return_first_only,
138
- case_sensitive, callback_functions, extract_file_to_path)
134
+ if recursive and (_is_zip_file(item.filename, arch_obj) or _is_7z_file(item.filename, arch_obj)):
135
+ _search_archive_content(
136
+ archived_file_bytes, file_names, results, found_set, case_sensitive, return_first_only,
137
+ recursive, callback_functions, extract_file_to_path)
139
138
  if file_names and not callback_matched:
140
139
  _handle_name_matching(
141
140
  item, archived_file_bytes, file_names, case_sensitive, results, found_set, return_first_only)
@@ -151,45 +150,51 @@ def _initialize_results(callback_functions):
151
150
  return {}
152
151
 
153
152
 
154
- def _open_archive(archive_type, file_like_object):
155
- if archive_type == 'zip':
156
- return zipfile.ZipFile(file_like_object, 'r')
157
- elif archive_type == '7z':
158
- return py7zr.SevenZipFile(file_like_object, 'r')
153
+ def _get_archive_type(file_object) -> Union[str, None]:
154
+ if zip.is_zip_zipfile(file_object):
155
+ return 'zip'
156
+ elif sevenz.is_7z(file_object):
157
+ return '7z'
159
158
  else:
160
- raise ValueError("Unsupported archive format.")
161
-
162
-
163
- def _get_archive_type(file_path, file_bytes) -> tuple:
164
- if file_bytes is not None:
165
- file_like_object = BytesIO(file_bytes)
166
- elif file_path is not None:
167
- file_like_object = file_path
168
- else:
169
- raise ValueError("Either file_path or file_bytes must be provided.")
170
-
171
- if zip.is_zip_zipfile(file_path=file_like_object):
172
- return 'zip', file_like_object
173
- elif sevenz.is_7z(file_path=file_like_object):
174
- return '7z', file_like_object
175
- else:
176
- raise ValueError("Unsupported archive format.")
159
+ raise UnknownArchiveType(f"{file_object[:10]} is not a known archive type.")
160
+ # print_api(f"{file_object[:10]} is not a known archive type.", color='yellow')
161
+ # return None
177
162
 
178
163
 
179
164
  def _search_archive_content(
180
- file_path, file_bytes, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
165
+ file_object, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
181
166
  callback_functions, extract_file_to_path):
182
167
 
183
- archive_type, file_like_object = _get_archive_type(file_path, file_bytes)
168
+ archive_type = _get_archive_type(file_object)
184
169
 
185
- with _open_archive(archive_type, file_like_object) as archive_ref:
186
- _search_in_archive(archive_ref, archive_type, file_names_to_search, results, found_set, case_sensitive, return_first_only,
187
- recursive, callback_functions, extract_file_to_path)
170
+ if isinstance(file_object, str):
171
+ if archive_type == 'zip':
172
+ with zipfile.ZipFile(file_object, 'r') as archive_ref:
173
+ _search_in_archive(
174
+ archive_ref, archive_type, file_names_to_search, results, found_set, case_sensitive,
175
+ return_first_only, recursive, callback_functions, extract_file_to_path)
176
+ elif archive_type == '7z':
177
+ with py7zr.SevenZipFile(file_object, 'r') as archive_ref:
178
+ _search_in_archive(
179
+ archive_ref, archive_type, file_names_to_search, results, found_set, case_sensitive,
180
+ return_first_only, recursive, callback_functions, extract_file_to_path)
181
+ elif isinstance(file_object, bytes):
182
+ if archive_type == 'zip':
183
+ with BytesIO(file_object) as file_like_object:
184
+ with zipfile.ZipFile(file_like_object, 'r') as archive_ref:
185
+ _search_in_archive(
186
+ archive_ref, archive_type, file_names_to_search, results, found_set, case_sensitive,
187
+ return_first_only, recursive, callback_functions, extract_file_to_path)
188
+ elif archive_type == '7z':
189
+ with BytesIO(file_object) as file_like_object:
190
+ with py7zr.SevenZipFile(file_like_object, 'r') as archive_ref:
191
+ _search_in_archive(
192
+ archive_ref, archive_type, file_names_to_search, results, found_set, case_sensitive,
193
+ return_first_only, recursive, callback_functions, extract_file_to_path)
188
194
 
189
195
 
190
196
  def search_file_in_archive(
191
- file_path: str = None,
192
- file_bytes: bytes = None,
197
+ file_object: Union[str, bytes] = None,
193
198
  file_names_to_search: list[str] = None,
194
199
  case_sensitive: bool = True,
195
200
  return_first_only: bool = False,
@@ -201,8 +206,9 @@ def search_file_in_archive(
201
206
  """
202
207
  Function searches for the file names inside the zip file and returns a dictionary where the keys are the
203
208
  names of the callback functions and the values are lists of found file bytes.
204
- :param file_path: string, full path to the zip file.
205
- :param file_bytes: bytes, the bytes of the zip file.
209
+ :param file_object: it can be two types:
210
+ string, full path to the zip file.
211
+ bytes, the bytes of the zip file.
206
212
  :param file_names_to_search: list of strings, the names of the files to search.
207
213
  :param case_sensitive: boolean, default is 'True'. Determines if file name search should be case sensitive.
208
214
  :param return_first_only: boolean, default is 'False'. Return only the first found file for each file name.
@@ -224,7 +230,7 @@ def search_file_in_archive(
224
230
  found_set = set()
225
231
 
226
232
  _search_archive_content(
227
- file_path, file_bytes, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
233
+ file_object, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
228
234
  callback_functions, extract_file_to_path)
229
235
 
230
236
  if not return_empty_list_per_file_name:
@@ -1,16 +1,37 @@
1
+ from io import BytesIO
2
+ from typing import Union
3
+
1
4
  import py7zr
2
5
 
3
6
 
4
- def is_7z(file_path: str) -> bool:
7
+ def is_7z(file_object: Union[str, Union[bytes, BytesIO]]) -> bool:
5
8
  """
6
9
  Function checks if the file is a 7z file.
7
- :param file_path: string, full path to the file.
10
+ :param file_object: can be two types:
11
+ string, full path to the file.
12
+ bytes or BytesIO, the bytes of the file.
8
13
  :return: boolean.
9
14
  """
10
15
 
11
- try:
12
- with py7zr.SevenZipFile(file_path) as archive:
13
- archive.testzip()
14
- return True
15
- except py7zr.Bad7zFile:
16
+ if isinstance(file_object, (str, BytesIO)):
17
+ try:
18
+ with py7zr.SevenZipFile(file_object) as archive:
19
+ archive.testzip()
20
+ return True
21
+ except py7zr.Bad7zFile:
22
+ return False
23
+ elif isinstance(file_object, bytes):
24
+ return is_7z(BytesIO(file_object))
25
+
26
+
27
+ def is_7z_magic_number(data):
28
+ # Check if the data is at least 6 bytes long
29
+ if len(data) < 6:
16
30
  return False
31
+
32
+ # 7z file signature (magic number)
33
+ # The signature is '7z' followed by 'BCAF271C'
34
+ seven_z_signature = b'7z\xBC\xAF\x27\x1C'
35
+
36
+ # Compare the first 6 bytes of the data with the 7z signature
37
+ return data.startswith(seven_z_signature)
@@ -1,20 +1,27 @@
1
1
  import os
2
2
  import time
3
3
  import zipfile
4
+ from io import BytesIO
5
+ from typing import Union
4
6
 
5
7
  from .. import filesystem
6
8
  from ..print_api import print_api
7
9
 
8
10
 
9
- def is_zip_zipfile(file_path: str) -> bool:
11
+ def is_zip_zipfile(file_object: Union[str, Union[bytes, BytesIO]]) -> bool:
10
12
  """
11
13
  Function checks if the file is a zip file.
12
- :param file_path: string, full path to the file.
14
+ :param file_object: can be two types:
15
+ string, full path to the file.
16
+ bytes or BytesIO, the bytes of the file.
13
17
  :return: boolean.
14
18
  """
15
19
 
20
+ if isinstance(file_object, bytes):
21
+ file_object = BytesIO(file_object)
22
+
16
23
  try:
17
- with zipfile.ZipFile(file_path) as zip_object:
24
+ with zipfile.ZipFile(file_object) as zip_object:
18
25
  zip_object.testzip()
19
26
  return True
20
27
  except zipfile.BadZipFile:
@@ -25,7 +25,7 @@ def create_empty_class():
25
25
  return dynamic_class
26
26
 
27
27
 
28
- def get_module_name_from_file_path(file_directory_path: str, file_path: str) -> str:
28
+ def get_module_name_from_file_path(working_directory_path: str, file_path: str) -> str:
29
29
  """
30
30
  Function that extracts module name string from file path.
31
31
 
@@ -43,16 +43,18 @@ def get_module_name_from_file_path(file_directory_path: str, file_path: str) ->
43
43
  Returns:
44
44
  'modules.classes.filesystem'
45
45
 
46
- :param file_directory_path: string, of file full path to working directory of the main script that need
46
+ :param working_directory_path: string, of file full path to working directory of the main script that need
47
47
  to call the import.
48
48
  :param file_path: string, of full file path to the module that needs ot be imported.
49
49
  :return: string, of module name.
50
50
  """
51
51
 
52
52
  # Removing suffix.
53
- file_path_no_suffix = Path(file_path).stem
53
+ file_name_no_suffix = Path(file_path).stem
54
+ file_directory = str(Path(file_path).parent)
55
+ file_path_no_suffix = file_directory + os.sep + file_name_no_suffix
54
56
  # Removing the script directory.
55
- path_without_script_directory = file_path_no_suffix.replace(file_directory_path + os.sep, '')
57
+ path_without_script_directory = file_path_no_suffix.replace(working_directory_path + os.sep, '')
56
58
  # Changing slashes to dots.
57
59
  module_name_string = path_without_script_directory.replace(os.sep, '.')
58
60
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.6.11
3
+ Version: 2.6.12
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=gP8qJqxJnpV4oYVnhjnF7B9Nskus6wWy0__6kb3YrHQ,123
1
+ atomicshop/__init__.py,sha256=dE2EYYltz4iQcAdxQMIKwlWoWucAUIC128o-pjsvjVo,123
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
4
4
  atomicshop/appointment_management.py,sha256=N3wVGJgrqJfsj_lqiRfaL3FxMEe57by5Stzanh189mk,7263
@@ -62,15 +62,15 @@ atomicshop/addons/process_list/compiled/Win10x64/process_list.exp,sha256=VTph513
62
62
  atomicshop/addons/process_list/compiled/Win10x64/process_list.lib,sha256=n9c2MVPs3GBNoOQjMesAwzNpv5aFZsW8c-ADS7GYRhA,1886
63
63
  atomicshop/archiver/_search_in_zip.py,sha256=dd8qFSvIhcKmtnPj_uYNJFPmMwZp4tZys0kKgTw_ACw,8385
64
64
  atomicshop/archiver/archiver.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
65
- atomicshop/archiver/search_in_archive.py,sha256=iciz5nbtr0m2pAbWQRR7fH1Z7q9NFxfwRv8Vy_MH6pM,9630
66
- atomicshop/archiver/sevenz.py,sha256=S90Nuc-Ay3spQBP-sZqasqoDIhJx331cPPyQ0uuylks,371
67
- atomicshop/archiver/zip.py,sha256=ZbVMEMD4xSvddQWWCf73B7wYePWt354Qk1kib5bA--4,13959
65
+ atomicshop/archiver/search_in_archive.py,sha256=o8tQVm38tXhoE-VEnpAWtTjeqksUHtYcs5UqmdfH64Y,10269
66
+ atomicshop/archiver/sevenz.py,sha256=YUxNoh3qf6NvTB2qdC0uAoFwQtJXbrnl4XNPlWAIaVw,1082
67
+ atomicshop/archiver/zip.py,sha256=_JrLb-hjlzkxqjd7maUE8WsaiHx8kibsipCSUSGvIUQ,14208
68
68
  atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX98jcBMpJE,3140
70
70
  atomicshop/basics/argparse_template.py,sha256=S-BIdKd45bmNdqO3Dj3yOxBgb0O90spZxG4OcnedBHw,5836
71
71
  atomicshop/basics/booleans.py,sha256=-4JnSQ1pSb6CNY_62wtHBW8NltjPJEKM-gYOxFujunA,1772
72
72
  atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
73
- atomicshop/basics/classes.py,sha256=-l0dqbKKDc89ABQ_wvELJub8gWl_J2MTmCEBVmAbTfk,8426
73
+ atomicshop/basics/classes.py,sha256=n5uhPOWIKBAv0xa3--n-oQYIS64s6hb6JGs_1HgW2cs,8558
74
74
  atomicshop/basics/dicts.py,sha256=sAoHvY-Rtt7QkwHzIKk1j2ZFmteIm9yFCxBGkTrpbdk,9030
75
75
  atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
76
76
  atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
@@ -208,8 +208,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
208
208
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
209
209
  atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
210
210
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
211
- atomicshop-2.6.11.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
212
- atomicshop-2.6.11.dist-info/METADATA,sha256=TTtKxMjD3QZcVKRBoIM1HzOxx368ij-6tsTmOZBtIY0,10311
213
- atomicshop-2.6.11.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
214
- atomicshop-2.6.11.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
215
- atomicshop-2.6.11.dist-info/RECORD,,
211
+ atomicshop-2.6.12.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
212
+ atomicshop-2.6.12.dist-info/METADATA,sha256=41BiQAnqpRy_lqxzEXFjFc_jwlCzxswYwqQW3QIdPy0,10311
213
+ atomicshop-2.6.12.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
214
+ atomicshop-2.6.12.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
215
+ atomicshop-2.6.12.dist-info/RECORD,,