atomicshop 3.4.2__py3-none-any.whl → 3.5.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 atomicshop might be problematic. Click here for more details.

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__ = '3.4.2'
4
+ __version__ = '3.5.0'
@@ -2,8 +2,9 @@ import datetime
2
2
  import os
3
3
  import multiprocessing
4
4
  import logging
5
+ import zipfile
6
+ import shutil
5
7
 
6
- from ..archiver import zips
7
8
  from .. import filesystem, print_api
8
9
  from .. wrappers.loggingw import consts, loggingw
9
10
 
@@ -13,6 +14,43 @@ REC_FILE_DATE_TIME_FORMAT: str = f'{consts.DEFAULT_ROTATING_SUFFIXES_FROM_WHEN["
13
14
  REC_FILE_DATE_FORMAT: str = REC_FILE_DATE_TIME_FORMAT.split('_')[0]
14
15
 
15
16
 
17
+ def archive(
18
+ directory_path: str,
19
+ include_root_directory: bool = True,
20
+ ) -> str:
21
+ """
22
+ Function archives the directory.
23
+ :param directory_path: string, full path to the directory.
24
+ :param include_root_directory: boolean, default is 'True'.
25
+ 'True': The root directory will be included in the archive.
26
+ 'False': The root directory will not be included in the archive.
27
+ True is usually the case in most archiving utilities.
28
+ :return: string, full path to the archived file.
29
+ """
30
+
31
+ # This is commonly used and supported by most ZIP utilities.
32
+ compression_method = zipfile.ZIP_DEFLATED
33
+
34
+ archive_path: str = directory_path + '.zip'
35
+ with zipfile.ZipFile(archive_path, 'w', compression_method) as zip_object:
36
+ for root, _, files in os.walk(directory_path):
37
+ for file in files:
38
+ file_path = os.path.join(root, file)
39
+
40
+ # If including the root directory, use the relative path from the parent directory of the root
41
+ if include_root_directory:
42
+ arcname = os.path.relpath(file_path, os.path.dirname(directory_path))
43
+ else:
44
+ arcname = os.path.relpath(file_path, directory_path)
45
+
46
+ zip_object.write(file_path, arcname)
47
+
48
+ # Remove the original directory after archiving.
49
+ shutil.rmtree(directory_path, ignore_errors=True)
50
+
51
+ return archive_path
52
+
53
+
16
54
  def recs_archiver(
17
55
  recs_directory: str,
18
56
  logging_queue: multiprocessing.Queue,
@@ -83,8 +121,7 @@ def recs_archiver(
83
121
  archive_directories: list = filesystem.get_paths_from_directory(
84
122
  directory_path.path, get_directory=True, recursive=False)
85
123
  for archive_directory in archive_directories:
86
- archived_file: str = zips.archive_directory(
87
- archive_directory.path, remove_original=True, include_root_directory=True)
124
+ archived_file: str = archive(archive_directory.path, include_root_directory=True)
88
125
  archived_files.append(archived_file)
89
126
 
90
127
  finalize_output_queue.put(None)
atomicshop/print_api.py CHANGED
@@ -1,13 +1,14 @@
1
1
  import sys
2
2
  import logging
3
+ from typing import Any
3
4
 
4
5
  from .basics import ansi_escape_codes
5
6
  from .basics import tracebacks
6
7
 
7
8
 
8
9
  def print_api(
9
- message: any,
10
- color: any = None,
10
+ message: Any,
11
+ color: Any = None,
11
12
  print_end: str = '\n',
12
13
  rtl: bool = False,
13
14
  error_type: bool = False,
@@ -73,7 +74,6 @@ def print_api(
73
74
 
74
75
  # Inner functions already get all the local variables of the main function.
75
76
  def print_or_logger():
76
- from .wrappers.loggingw import loggingw
77
77
  nonlocal message
78
78
  nonlocal color
79
79
  nonlocal traceback_string
@@ -83,8 +83,6 @@ def print_api(
83
83
 
84
84
  # If 'rtl' is set to 'True', we'll add Right-To-Left text conversion to 'message'.
85
85
  if rtl:
86
- # Lazy importing of 'bidi' library. It's not a problem since python caches the library after first import.
87
- # Off-course, it will be imported from the cache each time this section is triggered.
88
86
  # pip install python-bidi
89
87
  from bidi.algorithm import get_display
90
88
  message = get_display(message)
atomicshop/web.py CHANGED
@@ -7,8 +7,8 @@ import http.client
7
7
 
8
8
  # noinspection PyPackageRequirements
9
9
  import certifi
10
+ from dkarchiver.arch_wrappers import zips
10
11
 
11
- from .archiver import zips
12
12
  from .urls import url_parser
13
13
  from .file_io import file_io
14
14
  from .wrappers.playwrightw import scenarios
@@ -301,7 +301,7 @@ def download_and_extract_file(
301
301
  Default is empty. If it is empty, then the filename will be extracted from 'file_url'.
302
302
  :param target_directory: string, target directory where to save the file.
303
303
  :param archive_remove_first_directory: boolean, sets if archive extract function will extract the archive without
304
- first directory in the archive. Check reference in the 'extract_archive_with_zipfile' function.
304
+ first directory in the archive. Check reference in the 'dkarchiver.arch_wrappers.zips.extract_archive_with_zipfile' function.
305
305
  :param headers: dictionary, HTTP headers to use when downloading the file.
306
306
  :return:
307
307
  """
@@ -313,7 +313,7 @@ def download_and_extract_file(
313
313
  # Extract the archive and remove the first directory.
314
314
  zips.extract_archive_with_zipfile(
315
315
  archive_path=f'{file_path}', extract_directory=target_directory,
316
- remove_first_directory=archive_remove_first_directory, **kwargs)
316
+ remove_first_directory=archive_remove_first_directory)
317
317
 
318
318
  # Remove the archive file.
319
319
  filesystem.remove_file(file_path=f'{file_path}', **kwargs)
@@ -1,8 +1,9 @@
1
1
  import os
2
2
  from pathlib import Path
3
3
 
4
+ from dkarchiver.arch_wrappers import sevenz_app_w
5
+
4
6
  from . import tables
5
- from ....archiver import sevenz_app_w
6
7
 
7
8
 
8
9
  def resolve_directory_path(directory_info, directory_key):
@@ -1,11 +1,12 @@
1
1
  import os
2
2
  import argparse
3
3
 
4
+ from dkarchiver.arch_wrappers import sevenz_app_w
5
+
4
6
  from .base import msi
5
7
  from . import base, tables, cabs
6
8
  from ... import olefilew
7
9
  from ....print_api import print_api
8
- from ....archiver import sevenz_app_w
9
10
 
10
11
 
11
12
  # Directory names.
@@ -1,10 +1,10 @@
1
- import sys
2
1
  import subprocess
3
2
  from pathlib import Path
4
3
 
4
+ from dkarchiver.arch_wrappers import zips
5
+
5
6
  from .... import filesystem
6
7
  from ....permissions import ubuntu_permissions
7
- from ....archiver import zips
8
8
  from ....print_api import print_api
9
9
  from ... import githubw, pipw, ubuntu_terminal
10
10
  from ...dockerw import install_docker
@@ -276,7 +276,7 @@ class GitHubWrapper:
276
276
  :param archive_remove_first_directory: boolean, available only if 'path' was not specified during the initialization
277
277
  Sets if archive extract function will extract the archive
278
278
  without first directory in the archive. Check reference in the
279
- 'archiver.zip.extract_archive_with_zipfile' function.
279
+ 'dkarchiver.arch_wrappers.zips.extract_archive_with_zipfile' function.
280
280
  :param download_each_file: bool, available only if 'path' was specified during the initialization of the class.
281
281
  Sets if each file will be downloaded separately.
282
282
 
@@ -521,7 +521,7 @@ class GitHubWrapper:
521
521
  :param exclude_string: str, the string to exclude from the search. No wildcards can be used.
522
522
  :param archive_remove_first_directory: bool, sets if archive extract function will extract the archive
523
523
  without first directory in the archive. Check reference in the
524
- 'archiver.zip.extract_archive_with_zipfile' function.
524
+ 'dkarchiver.arch_wrappers.zips.extract_archive_with_zipfile' function.
525
525
  :param kwargs: dict, the print arguments for the 'print_api' function.
526
526
  :return:
527
527
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomicshop
3
- Version: 3.4.2
3
+ Version: 3.5.0
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License-Expression: MIT
@@ -12,8 +12,9 @@ Requires-Python: <3.13,>=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE.txt
14
14
  Requires-Dist: wheel
15
- Requires-Dist: beautifulsoup4
15
+ Requires-Dist: setuptools
16
16
  Requires-Dist: cryptography
17
+ Requires-Dist: dkarchiver
17
18
  Requires-Dist: dkinst
18
19
  Requires-Dist: dnslib
19
20
  Requires-Dist: dnspython
@@ -31,16 +32,10 @@ Requires-Dist: pefile
31
32
  Requires-Dist: playwright
32
33
  Requires-Dist: protobuf
33
34
  Requires-Dist: psutil
34
- Requires-Dist: py7zr==0.22.0
35
- Requires-Dist: pyautogui
36
35
  Requires-Dist: pymongo
37
36
  Requires-Dist: pyopenssl
38
- Requires-Dist: python-bidi
39
37
  Requires-Dist: python-docx
40
- Requires-Dist: python-magic
41
38
  Requires-Dist: pywin32; platform_system == "Windows"
42
- Requires-Dist: reportlab
43
- Requires-Dist: setuptools
44
39
  Requires-Dist: SoundCard
45
40
  Requires-Dist: soundfile
46
41
  Requires-Dist: SpeechRecognition
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=z6B8jy3rF9-QI0t-bMD5Kjc5FyXhKQba4P5WtIQrHhk,122
1
+ atomicshop/__init__.py,sha256=Ym5LqQ0nxVmRpNT7f4YPuHzfVf7bivikNbri8tJsWYU,122
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
4
4
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
@@ -14,7 +14,6 @@ atomicshop/diff_check.py,sha256=vxTDccVbGZHEge6Ja9_ArLWwslOUgIoJAdYPylh4cZg,2717
14
14
  atomicshop/dns.py,sha256=XB0tijVi1bxWLWKV9hPzpt75jK4SrGbZCV5VJbiiQ74,7185
15
15
  atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
16
16
  atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
17
- atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
18
17
  atomicshop/filesystem.py,sha256=tCPRA6SQiJJkFL3BnPCoVhPCkvrkI2C4RyuSKzuxo1w,68060
19
18
  atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
20
19
  atomicshop/get_process_list.py,sha256=8cxb7gKe9sl4R6H2yMi8J6oe-RkonTvCdKjRFqi-Fs4,6075
@@ -27,7 +26,7 @@ atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,
27
26
  atomicshop/networks.py,sha256=IfhEgI0rJHPgkbIDEC6lsPVZm-fyylpacKSo5HrIEic,26403
28
27
  atomicshop/on_exit.py,sha256=9XlOnzoAG8zlI8wBF4AB8hyrC6Q1b84gkhqpAhhdN9g,6977
29
28
  atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
30
- atomicshop/print_api.py,sha256=SJNQIMqSLlYaPtjHnALySAI-jQYuYHOCGgfP7oe96fU,10957
29
+ atomicshop/print_api.py,sha256=RDEokUczRhfiZ13PROdD90jppB-y37alkmU9-gWaOEI,10713
31
30
  atomicshop/process.py,sha256=e8u7jvq5HDKqna7xmeqNTKFY4BQNKX6NtAUGPwur6zE,17288
32
31
  atomicshop/python_file_patcher.py,sha256=-uhbUX-um5k-If_XXuOfCr8wMzZ3QE6h9N8xGWw6W_o,5486
33
32
  atomicshop/python_functions.py,sha256=BPZ3sv5DgQs6Xrl3nIMdPABRpgrau3XSrsnDIz-LEwY,6175
@@ -48,7 +47,7 @@ atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
48
47
  atomicshop/venvs.py,sha256=D9lwOoObkYoRx-weuoAmbvN-RdSHhVm4DE9TVl-utAs,903
49
48
  atomicshop/versioning.py,sha256=e5W6m9AF3__M5nntqI9CqNAeHqkwY9JhlnpYeZ1CEus,970
50
49
  atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
51
- atomicshop/web.py,sha256=mHWrHb-zl0NRg7oHBZr-0k66aTBmKLvanBzoCZ63Xks,14340
50
+ atomicshop/web.py,sha256=xwERN-IBGAtux_KGhfRBrETpJqEcw5hcZyamLA1KupQ,14375
52
51
  atomicshop/websocket_parse.py,sha256=aLHWyKqaYqEn_MRBWm2L6rIl6QPmqbVrjEXE_rBzwCw,16711
53
52
  atomicshop/a_installs/ubuntu/docker_rootless.py,sha256=9IPNtGZYjfy1_n6ZRt7gWz9KZgR6XCgevjqq02xk-o0,281
54
53
  atomicshop/a_installs/ubuntu/docker_sudo.py,sha256=JzayxeyKDtiuT4Icp2L2LyFRbx4wvpyN_bHLfZ-yX5E,281
@@ -72,13 +71,6 @@ atomicshop/addons/process_list/process_list.cpp,sha256=kcrltiJhzRc2HmKy2Yxdbj7mF
72
71
  atomicshop/addons/process_list/compiled/Win10x64/process_list.dll,sha256=rl74P7oh4UZyo3cILmtDFznurcHNRMrZ56tOTv5pJqk,276992
73
72
  atomicshop/addons/process_list/compiled/Win10x64/process_list.exp,sha256=cbvukITcmtGm5uwOIuq8bKCE_LXIHvkMfLJQpBrJk64,842
74
73
  atomicshop/addons/process_list/compiled/Win10x64/process_list.lib,sha256=T2Ncs0MwKlAaCq8UKFMvfQAfcJdDx-nWiHVBfglrLIU,2112
75
- atomicshop/archiver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- atomicshop/archiver/_search_in_zip.py,sha256=dd8qFSvIhcKmtnPj_uYNJFPmMwZp4tZys0kKgTw_ACw,8385
77
- atomicshop/archiver/search_in_archive.py,sha256=iDIWS9G2pdz6QxGawGQJ1RSl33gdIRjpYrnP0brIDgU,12450
78
- atomicshop/archiver/sevenz_app_w.py,sha256=BWcJb4f7jZEiETDBKyNLE0f5YLFPQx6B91_ObEIXWf8,3007
79
- atomicshop/archiver/sevenzs.py,sha256=b9rI-nF36ZNawwKsPWOgsnm0p-jYDfD1NYV3eA8LoQ0,2491
80
- atomicshop/archiver/shutils.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
81
- atomicshop/archiver/zips.py,sha256=0Z_1MWs7YRiCBVpyaG8llnzRguHSO4R51KDMN3FJZt8,16984
82
74
  atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
75
  atomicshop/basics/ansi_escape_codes.py,sha256=uGVRW01v2O052701sOfAdCaM_GLF_cu_jrssuYiPbzA,3216
84
76
  atomicshop/basics/argparse_template.py,sha256=NRz63v2jr4tHcAGvqW1okYsGRt6n0u8FXuMQQT3dHPw,6071
@@ -131,7 +123,7 @@ atomicshop/mitm/import_config.py,sha256=7aLfKqflc3ZnzKc2_Y4T0eenzQpKG94M0r-PaVwF
131
123
  atomicshop/mitm/initialize_engines.py,sha256=qzz5jzh_lKC03bI1w5ebngVXo1K-RV3poAyW-nObyqo,11042
132
124
  atomicshop/mitm/message.py,sha256=CDhhm4BTuZE7oNZCjvIZ4BuPOW4MuIzQLOg91hJaxDI,3065
133
125
  atomicshop/mitm/mitm_main.py,sha256=i0YcLDKAYH1aUS_Rf7IbwXiSQzndsdOY_JuYTvTiTN8,40453
134
- atomicshop/mitm/recs_files.py,sha256=tv8XFhYZMkBv4DauvpiAdPgvSo0Bcm1CghnmwO7dx8M,5018
126
+ atomicshop/mitm/recs_files.py,sha256=TyaMWV0fRmKV7MTGoP_DYDcr-MpS18FFfshq-KTQVBc,6438
135
127
  atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
136
128
  atomicshop/mitm/statistic_analyzer.py,sha256=EC9g21ocOsFzNfntV-nZHSGtrS1-Kxb0QDSGWS5FuNA,28942
137
129
  atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -187,7 +179,7 @@ atomicshop/wrappers/astw.py,sha256=VkYfkfyc_PJLIOxByT6L7B8uUmKY6-I8XGZl4t_z828,4
187
179
  atomicshop/wrappers/configparserw.py,sha256=JwDTPjZoSrv44YKwIRcjyUnpN-FjgXVfMqMK_tJuSgU,22800
188
180
  atomicshop/wrappers/cryptographyw.py,sha256=QEUpDn8vUvMg3ADz6-4oC2kbDNC_woDlw7C0zU7qFVM,14233
189
181
  atomicshop/wrappers/ffmpegw.py,sha256=wcq0ZnAe0yajBOuTKZCCaKI7CDBjkq7FAgdW5IsKcVE,6031
190
- atomicshop/wrappers/githubw.py,sha256=95RAbxomp4GA9-7B1pk6q3aYOmrCO0vkHyhSPgr3n3Q,31924
182
+ atomicshop/wrappers/githubw.py,sha256=d4-IdNEu-HfGMZq75c6EBuhhLYn7ulyuOCjM_4HnC20,31958
191
183
  atomicshop/wrappers/netshw.py,sha256=8WE_576XiiHykwFuE-VkCx5CydMpFlztX4frlEteCtI,6350
192
184
  atomicshop/wrappers/numpyw.py,sha256=sBV4gSKyr23kXTalqAb1oqttzE_2XxBooCui66jbAqc,1025
193
185
  atomicshop/wrappers/olefilew.py,sha256=biD5m58rogifCYmYhJBrAFb9O_Bn_spLek_9HofLeYE,2051
@@ -208,8 +200,8 @@ atomicshop/wrappers/ctyping/etw_winapi/const.py,sha256=W-NMYlJ8RrMxLRjKcatEHe6wJ
208
200
  atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py,sha256=EMdCjGd3x6aRcHkY2NRNTlrOuC7TY4rhfqfRtTWkbYU,17225
209
201
  atomicshop/wrappers/ctyping/msi_windows_installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
210
202
  atomicshop/wrappers/ctyping/msi_windows_installer/base.py,sha256=Uu9SlWLsQQ6mjE-ek-ptHcmgiI3Ruah9bdZus70EaVY,4884
211
- atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py,sha256=htzwb2ROYI8yyc82xApStckPS2yCcoyaw32yC15KROs,3285
212
- atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py,sha256=AEkjnqEhfCbCUcYaulv3uba5hZjTB03xm-puAINsZGM,5488
203
+ atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py,sha256=LbAkEKNQtN4jWmLb_0VTsUya2CWe5thPagNDhYSHjYc,3299
204
+ atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py,sha256=sO6ZKHMOAMMArIyhmMFen3FJnRHJeXoep22964O9Is8,5502
213
205
  atomicshop/wrappers/ctyping/msi_windows_installer/tables.py,sha256=tHsu0YfBgzuIk9L-PyqLgU_IzyVbCfy8L1EqelNnvWk,17674
214
206
  atomicshop/wrappers/dockerw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
207
  atomicshop/wrappers/dockerw/dockerw.py,sha256=GgPSvXxJj15kZ-LPiaHLl8aekof53sSP_U-vUMUe7_8,10639
@@ -235,7 +227,7 @@ atomicshop/wrappers/factw/fact_extractor/docker_image.py,sha256=2FyYjnw8gxFNwISQ
235
227
  atomicshop/wrappers/factw/fact_extractor/get_extractor.py,sha256=2mfOAftHIlCcGt1s7MWdq7DsDCuI6wX3MtvcEZ4SK-0,756
236
228
  atomicshop/wrappers/factw/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
229
  atomicshop/wrappers/factw/install/install_after_restart.py,sha256=4dHn2XMbYaPJlhRCmZqqwsgHQBlG2mT7aW50pQCPtp4,4345
238
- atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=Xnb1-NGAR-jjzfgkSbJ8JTkGNWb9R4-N36zsLO245n0,6193
230
+ atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=D4W5hfRbC2fe9eFUIF5zLhTlb2f9oVEm6FqPPopnXoo,6195
239
231
  atomicshop/wrappers/factw/postgresql/__init__.py,sha256=xMBn2d3Exo23IPP2F_9-SXmOlhFbwWDgS9KwozSTjA0,162
240
232
  atomicshop/wrappers/factw/postgresql/analysis.py,sha256=2Rxzy2jyq3zEKIo53z8VkjuslKE_i5mq2ZpmJAvyd6U,716
241
233
  atomicshop/wrappers/factw/postgresql/file_object.py,sha256=VRiCXnsd6yDbnsE-TEKYPC-gkAgFVkE6rygRrJLQShI,713
@@ -314,8 +306,8 @@ atomicshop/wrappers/socketw/statistics_csv.py,sha256=_gA8bMX6Sw_UCXKi2y9wNAwlqif
314
306
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
315
307
  atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
316
308
  atomicshop/wrappers/winregw/winreg_network.py,sha256=ih0BVNwByLvf9F_Lac4EdmDYYJA3PzMvmG0PieDZrsE,9905
317
- atomicshop-3.4.2.dist-info/licenses/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
318
- atomicshop-3.4.2.dist-info/METADATA,sha256=LSck6xzVp4t5nFs5mLWlM5-6NvidcN44oDJueNqU7sQ,9317
319
- atomicshop-3.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
320
- atomicshop-3.4.2.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
321
- atomicshop-3.4.2.dist-info/RECORD,,
309
+ atomicshop-3.5.0.dist-info/licenses/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
310
+ atomicshop-3.5.0.dist-info/METADATA,sha256=rok0mkiAeQkcqbznZGMuOhaf9SdVcrpH25WfzE6GjNM,9174
311
+ atomicshop-3.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
312
+ atomicshop-3.5.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
313
+ atomicshop-3.5.0.dist-info/RECORD,,
File without changes
@@ -1,189 +0,0 @@
1
- # This was written before 'search_in_archive', currently search_in_archive is in test mode.
2
- # So probably this will go away eventually.
3
- import os
4
- import zipfile
5
- from io import BytesIO
6
-
7
-
8
- def _get_unique_filename(directory, filename):
9
- """
10
- Generates a unique filename by appending a number if the file already exists.
11
- """
12
- name, ext = os.path.splitext(filename)
13
- counter = 1
14
- unique_filename = filename
15
- while os.path.exists(os.path.join(directory, unique_filename)):
16
- unique_filename = f"{name}_{counter}{ext}"
17
- counter += 1
18
- return unique_filename
19
-
20
-
21
- def _is_zip_file(file, zip_obj):
22
- try:
23
- with zip_obj.open(file) as file_data:
24
- with zipfile.ZipFile(BytesIO(file_data.read())) as zip_file:
25
- if zip_file.testzip() is None: # No errors found
26
- return True
27
- except zipfile.BadZipFile:
28
- return False
29
- return False
30
-
31
-
32
- def _match_file_name(target, current, case_sensitive):
33
- if case_sensitive:
34
- return current.endswith(target)
35
- else:
36
- return current.lower().endswith(target.lower())
37
-
38
-
39
- def _handle_nested_zip(
40
- zip_obj, item, archived_file_bytes, file_names, results, found_set, recursive, return_first_only,
41
- case_sensitive, callback_functions, extract_file_to_path):
42
-
43
- if recursive and _is_zip_file(item.filename, zip_obj):
44
- nested_zip_bytes = BytesIO(archived_file_bytes)
45
- with zipfile.ZipFile(nested_zip_bytes) as nested_zip:
46
- _search_in_zip(
47
- nested_zip, file_names, results, found_set, case_sensitive, return_first_only, recursive,
48
- callback_functions, extract_file_to_path)
49
-
50
-
51
- def _handle_file_extraction(item, extract_file_to_path, archived_file_bytes):
52
- if extract_file_to_path:
53
- unique_filename = _get_unique_filename(extract_file_to_path, os.path.basename(item.filename))
54
- with open(os.path.join(extract_file_to_path, unique_filename), 'wb') as f:
55
- f.write(archived_file_bytes)
56
-
57
-
58
- def _handle_callback_matching(item, archived_file_bytes, callback_functions, results, found_set, return_first_only):
59
- for callback in callback_functions:
60
- callback_result = callback(archived_file_bytes)
61
- if callback_result:
62
- # Initialize key for callback function name if not present
63
- if callback.__name__ not in results:
64
- results[callback.__name__] = []
65
- file_info = {
66
- 'bytes': archived_file_bytes,
67
- 'name': item.filename,
68
- 'size': item.file_size,
69
- 'modified_time': item.date_time
70
- }
71
- results[callback.__name__].append(file_info)
72
- if return_first_only:
73
- found_set.add(item.filename)
74
- return True
75
- return False
76
-
77
-
78
- def _handle_name_matching(item, archived_file_bytes, file_names, case_sensitive, results, found_set, return_first_only):
79
- if any(_match_file_name(file_name, item.filename, case_sensitive) for file_name in file_names):
80
- if item.filename not in results:
81
- results[item.filename] = []
82
- file_info = {
83
- 'bytes': archived_file_bytes,
84
- 'name': item.filename,
85
- 'size': item.file_size,
86
- 'modified_time': item.date_time
87
- }
88
- results[item.filename].append(file_info)
89
- if return_first_only:
90
- found_set.add(item.filename)
91
-
92
-
93
- def _search_in_zip(
94
- zip_obj, file_names, results, found_set, case_sensitive, return_first_only, recursive, callback_functions,
95
- extract_file_to_path):
96
-
97
- for item in zip_obj.infolist():
98
- if item.filename.endswith('/'): # Skip directories
99
- continue
100
-
101
- with zip_obj.open(item) as file_data:
102
- archived_file_bytes = file_data.read()
103
-
104
- callback_matched = False
105
- if callback_functions:
106
- callback_matched = _handle_callback_matching(
107
- item, archived_file_bytes, callback_functions, results, found_set, return_first_only)
108
-
109
- if callback_matched:
110
- _handle_file_extraction(item, extract_file_to_path, archived_file_bytes)
111
- else:
112
- _handle_nested_zip(
113
- zip_obj, item, archived_file_bytes, file_names, results, found_set, recursive, return_first_only,
114
- case_sensitive, callback_functions, extract_file_to_path)
115
- if file_names and not callback_matched:
116
- _handle_name_matching(
117
- item, archived_file_bytes, file_names, case_sensitive, results, found_set, return_first_only)
118
-
119
- if file_names is not None and len(found_set) == len(file_names):
120
- break # All files found, stop searching
121
-
122
-
123
- def _initialize_results(callback_functions):
124
- if callback_functions:
125
- return {callback.__name__: [] for callback in callback_functions}
126
- else:
127
- return {}
128
-
129
-
130
- def _search_zip_content(
131
- file_path, file_bytes, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
132
- callback_functions, extract_file_to_path):
133
- if file_bytes is not None:
134
- with zipfile.ZipFile(BytesIO(file_bytes), 'r') as zip_ref:
135
- _search_in_zip(zip_ref, file_names_to_search, results, found_set, case_sensitive, return_first_only,
136
- recursive, callback_functions, extract_file_to_path)
137
- elif file_path is not None:
138
- with zipfile.ZipFile(file_path, 'r') as zip_ref:
139
- _search_in_zip(zip_ref, file_names_to_search, results, found_set, case_sensitive, return_first_only,
140
- recursive, callback_functions, extract_file_to_path)
141
- else:
142
- raise ValueError("Either file_path or file_bytes must be provided.")
143
-
144
-
145
- def search_file_in_zip(
146
- file_path: str = None,
147
- file_bytes: bytes = None,
148
- file_names_to_search: list[str] = None,
149
- case_sensitive: bool = True,
150
- return_first_only: bool = False,
151
- return_empty_list_per_file_name: bool = False,
152
- recursive: bool = False,
153
- callback_functions: list = None,
154
- extract_file_to_path: str = None
155
- ) -> dict[str, list[bytes]]:
156
- """
157
- Function searches for the file names inside the zip file and returns a dictionary where the keys are the
158
- names of the callback functions and the values are lists of found file bytes.
159
- :param file_path: string, full path to the zip file.
160
- :param file_bytes: bytes, the bytes of the zip file.
161
- :param file_names_to_search: list of strings, the names of the files to search.
162
- :param case_sensitive: boolean, default is 'True'. Determines if file name search should be case sensitive.
163
- :param return_first_only: boolean, default is 'False'. Return only the first found file for each file name.
164
- :param return_empty_list_per_file_name: boolean, default is 'False'.
165
- True: Return empty list for each file name that wasn't found.
166
- False: Don't return empty list for each file name that wasn't found.
167
- :param recursive: boolean, default is 'False'. If True, search for file names recursively in nested zip files.
168
- :param callback_functions: list of callables, default is None. Each function takes a file name and should return a
169
- boolean that will tell the main function if this file is 'found' or not.
170
- :param extract_file_to_path: string, full path to the directory where the found files should be extracted.
171
- :return: dictionary of lists of bytes.
172
- """
173
-
174
- if file_names_to_search is None and callback_functions is None:
175
- raise ValueError("Either file_names_to_search or callback_functions must be provided.")
176
-
177
- # Initialize results dictionary.
178
- results = _initialize_results(callback_functions)
179
- found_set = set()
180
-
181
- _search_zip_content(
182
- file_path, file_bytes, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
183
- callback_functions, extract_file_to_path)
184
-
185
- if not return_empty_list_per_file_name:
186
- # Filter out keys with empty lists.
187
- results = {key: value for key, value in results.items() if value}
188
-
189
- return results