atomicshop 2.16.27__py3-none-any.whl → 2.16.29__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 +1 -1
- atomicshop/archiver/zips.py +5 -6
- atomicshop/basics/strings.py +2 -2
- atomicshop/dns.py +8 -6
- atomicshop/file_io/file_io.py +7 -7
- atomicshop/filesystem.py +6 -7
- atomicshop/http_parse.py +12 -18
- atomicshop/mitm/connection_thread_worker.py +183 -227
- atomicshop/mitm/engines/__parent/parser___parent.py +1 -4
- atomicshop/mitm/engines/__parent/recorder___parent.py +1 -1
- atomicshop/mitm/message.py +0 -17
- atomicshop/mitm/mitm_main.py +29 -27
- atomicshop/print_api.py +13 -49
- atomicshop/system_resource_monitor.py +8 -8
- atomicshop/system_resources.py +8 -8
- atomicshop/web.py +10 -10
- atomicshop/wrappers/loggingw/filters.py +23 -0
- atomicshop/wrappers/loggingw/formatters.py +12 -0
- atomicshop/wrappers/loggingw/handlers.py +30 -0
- atomicshop/wrappers/loggingw/loggingw.py +135 -8
- atomicshop/wrappers/playwrightw/engine.py +6 -7
- atomicshop/wrappers/playwrightw/waits.py +9 -7
- atomicshop/wrappers/socketw/dns_server.py +1 -1
- atomicshop/wrappers/socketw/sender.py +36 -27
- atomicshop/wrappers/socketw/socket_client.py +6 -5
- atomicshop/wrappers/socketw/socket_wrapper.py +45 -7
- {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/METADATA +1 -1
- {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/RECORD +31 -31
- {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.27.dist-info → atomicshop-2.16.29.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/archiver/zips.py
CHANGED
|
@@ -4,8 +4,7 @@ import zipfile
|
|
|
4
4
|
from io import BytesIO
|
|
5
5
|
from typing import Union, Literal
|
|
6
6
|
|
|
7
|
-
from .. import filesystem
|
|
8
|
-
from ..print_api import print_api
|
|
7
|
+
from .. import filesystem, print_api
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def is_zip_zipfile(file_object: Union[str, bytes]) -> bool:
|
|
@@ -42,7 +41,7 @@ def is_zip_magic_number(file_path: str) -> bool:
|
|
|
42
41
|
Each file within the ZIP archive starts with this signature.
|
|
43
42
|
50 4B 05 06: This is the end of central directory record signature.
|
|
44
43
|
It's found at the end of a ZIP file and is essential for identifying the structure of the ZIP archive,
|
|
45
|
-
especially in cases where the file is split or is a
|
|
44
|
+
especially in cases where the file is split or is a multipart archive.
|
|
46
45
|
50 4B 07 08: This signature is used for spanned ZIP archives (also known as split or multi-volume ZIP archives).
|
|
47
46
|
It's found in the end of central directory locator for ZIP files that are split across multiple volumes.
|
|
48
47
|
"""
|
|
@@ -93,7 +92,7 @@ def extract_archive_with_zipfile(
|
|
|
93
92
|
filesystem.get_file_directory(archive_path) + os.sep +
|
|
94
93
|
filesystem.get_file_name_without_extension(archive_path))
|
|
95
94
|
|
|
96
|
-
print_api(f'Extracting to directory: {extract_directory}', **print_kwargs)
|
|
95
|
+
print_api.print_api(f'Extracting to directory: {extract_directory}', **print_kwargs)
|
|
97
96
|
|
|
98
97
|
# initiating the archived file path as 'zipfile.ZipFile' object.
|
|
99
98
|
with zipfile.ZipFile(archive_path) as zip_object:
|
|
@@ -113,7 +112,7 @@ def extract_archive_with_zipfile(
|
|
|
113
112
|
# Cut the first directory from the filename.
|
|
114
113
|
zip_info.filename = zip_info.filename.split('/', maxsplit=1)[1]
|
|
115
114
|
|
|
116
|
-
print_api(f'Extracting: {zip_info.filename}', **print_kwargs)
|
|
115
|
+
print_api.print_api(f'Extracting: {zip_info.filename}', **print_kwargs)
|
|
117
116
|
|
|
118
117
|
# Extract current file from the archive using 'zip_info' of the current file with 'filename' that we
|
|
119
118
|
# updated under specified parameters to specified directory.
|
|
@@ -126,7 +125,7 @@ def extract_archive_with_zipfile(
|
|
|
126
125
|
date_time = time.mktime(zip_info.date_time + (0, 0, -1))
|
|
127
126
|
# Using 'os' library, changed the datetime of the file to the object created in previous step.
|
|
128
127
|
os.utime(extracted_file_path, (date_time, date_time))
|
|
129
|
-
print_api('Extraction done.', color="green", **print_kwargs)
|
|
128
|
+
print_api.print_api('Extraction done.', color="green", **print_kwargs)
|
|
130
129
|
|
|
131
130
|
return extract_directory
|
|
132
131
|
|
atomicshop/basics/strings.py
CHANGED
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
import argparse
|
|
5
5
|
|
|
6
6
|
from . import lists
|
|
7
|
-
from ..
|
|
7
|
+
from .. import print_api
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def get_nth_character_from_start(input_string: str, nth: int):
|
|
@@ -537,7 +537,7 @@ def replace_string_in_file(
|
|
|
537
537
|
file.writelines(lines)
|
|
538
538
|
|
|
539
539
|
# Output the relevant line numbers
|
|
540
|
-
print_api(f"Target string found on the following lines: {changed_lines}", **(print_kwargs or {}))
|
|
540
|
+
print_api.print_api(f"Target string found on the following lines: {changed_lines}", **(print_kwargs or {}))
|
|
541
541
|
return changed_lines
|
|
542
542
|
|
|
543
543
|
|
atomicshop/dns.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
|
|
3
|
+
# noinspection PyPackageRequirements
|
|
3
4
|
import dns.resolver
|
|
4
5
|
|
|
5
|
-
from .
|
|
6
|
+
from . import print_api
|
|
6
7
|
from .permissions import permissions
|
|
7
8
|
from .wrappers.pywin32w.wmis import win32networkadapter
|
|
8
9
|
from .wrappers.winregw import winreg_network
|
|
@@ -57,10 +58,10 @@ def resolve_dns_localhost(domain_name: str, dns_servers_list: list = None, print
|
|
|
57
58
|
# Get only the first entry of the list of IPs [0]
|
|
58
59
|
connection_ip = function_server_address[0].to_text()
|
|
59
60
|
message = f"Resolved to [{connection_ip}]"
|
|
60
|
-
print_api(message, **print_kwargs)
|
|
61
|
+
print_api.print_api(message, **print_kwargs)
|
|
61
62
|
except dns.resolver.NXDOMAIN:
|
|
62
63
|
message = f"Domain {domain_name} doesn't exist - Couldn't resolve with {dns_servers_list}."
|
|
63
|
-
print_api(message, **print_kwargs, error_type=True, logger_method='error')
|
|
64
|
+
print_api.print_api(message, **print_kwargs, error_type=True, logger_method='error')
|
|
64
65
|
pass
|
|
65
66
|
|
|
66
67
|
return connection_ip
|
|
@@ -137,12 +138,13 @@ def default_dns_gateway_main() -> int:
|
|
|
137
138
|
args = argparse_obj.parse_args()
|
|
138
139
|
|
|
139
140
|
if (args.set or args.dynamic) and not (args.connection_name or args.connection_default):
|
|
140
|
-
print_api(
|
|
141
|
+
print_api.print_api(
|
|
142
|
+
"Please provide the connection name [-cn] or use the default connection [-cd].", color='red')
|
|
141
143
|
return 1
|
|
142
144
|
|
|
143
145
|
if args.set or args.dynamic:
|
|
144
146
|
if not permissions.is_admin():
|
|
145
|
-
print_api("You need to run this script as an administrator", color='red')
|
|
147
|
+
print_api.print_api("You need to run this script as an administrator", color='red')
|
|
146
148
|
return 1
|
|
147
149
|
|
|
148
150
|
if args.get:
|
|
@@ -152,7 +154,7 @@ def default_dns_gateway_main() -> int:
|
|
|
152
154
|
is_dynamic_string = 'Dynamic'
|
|
153
155
|
else:
|
|
154
156
|
is_dynamic_string = 'Static'
|
|
155
|
-
print_api(f'DNS Gateway: {is_dynamic_string} - {dns_servers}', color='blue')
|
|
157
|
+
print_api.print_api(f'DNS Gateway: {is_dynamic_string} - {dns_servers}', color='blue')
|
|
156
158
|
elif args.set:
|
|
157
159
|
# dns_servers_list: list = args.dns_servers.split(',')
|
|
158
160
|
set_connection_dns_gateway_static(
|
atomicshop/file_io/file_io.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Union
|
|
2
2
|
import functools
|
|
3
3
|
|
|
4
|
-
from ..
|
|
4
|
+
from .. import print_api
|
|
5
5
|
from ..inspect_wrapper import get_target_function_default_args_and_combine_with_current
|
|
6
6
|
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ def write_file_decorator(function_name):
|
|
|
19
19
|
# args, kwargs = put_args_to_kwargs(function_name, *args, **kwargs)
|
|
20
20
|
args, kwargs = get_target_function_default_args_and_combine_with_current(function_name, *args, **kwargs)
|
|
21
21
|
|
|
22
|
-
print_api(message=f"Writing file: {kwargs['file_path']}", **kwargs)
|
|
22
|
+
print_api.print_api(message=f"Writing file: {kwargs['file_path']}", **kwargs)
|
|
23
23
|
|
|
24
24
|
enable_long_file_path = kwargs.get('enable_long_file_path', False)
|
|
25
25
|
if enable_long_file_path:
|
|
@@ -41,7 +41,7 @@ def write_file_decorator(function_name):
|
|
|
41
41
|
except FileExistsError:
|
|
42
42
|
message = f"Can't write file: {kwargs['file_path']}\n" \
|
|
43
43
|
f"File exists, you should enable force/overwrite mode."
|
|
44
|
-
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
44
|
+
print_api.print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
45
45
|
|
|
46
46
|
return wrapper_write_file_decorator
|
|
47
47
|
|
|
@@ -56,7 +56,7 @@ def read_file_decorator(function_name):
|
|
|
56
56
|
continue_loop: bool = True
|
|
57
57
|
while continue_loop:
|
|
58
58
|
try:
|
|
59
|
-
print_api(message=f"Reading file: {kwargs['file_path']}", **kwargs)
|
|
59
|
+
print_api.print_api(message=f"Reading file: {kwargs['file_path']}", **kwargs)
|
|
60
60
|
with open(kwargs['file_path'], kwargs['file_mode'], encoding=kwargs['encoding']) as input_file:
|
|
61
61
|
# Pass the 'output_file' object to kwargs that will pass the object to the executing function.
|
|
62
62
|
kwargs['file_object'] = input_file
|
|
@@ -64,19 +64,19 @@ def read_file_decorator(function_name):
|
|
|
64
64
|
return function_name(**kwargs)
|
|
65
65
|
except FileNotFoundError:
|
|
66
66
|
message = f"File doesn't exist: {kwargs['file_path']}"
|
|
67
|
-
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
67
|
+
print_api.print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
68
68
|
raise
|
|
69
69
|
except UnicodeDecodeError as exception_object:
|
|
70
70
|
if kwargs["encoding"] != 'utf-8':
|
|
71
71
|
message = f'File decode error, current encoding: {kwargs["encoding"]}. Will try "utf-8".'
|
|
72
|
-
print_api(message, logger_method='error', **kwargs)
|
|
72
|
+
print_api.print_api(message, logger_method='error', **kwargs)
|
|
73
73
|
kwargs["encoding"] = 'utf-8'
|
|
74
74
|
pass
|
|
75
75
|
continue
|
|
76
76
|
else:
|
|
77
77
|
message = f'File decode error.\n' \
|
|
78
78
|
f'{exception_object}'
|
|
79
|
-
print_api(message, merror_type=True, logger_method='critical', **kwargs)
|
|
79
|
+
print_api.print_api(message, merror_type=True, logger_method='critical', **kwargs)
|
|
80
80
|
continue_loop = False
|
|
81
81
|
|
|
82
82
|
return wrapper_read_file_decorator
|
atomicshop/filesystem.py
CHANGED
|
@@ -12,10 +12,9 @@ import tempfile
|
|
|
12
12
|
# noinspection PyPackageRequirements
|
|
13
13
|
import psutil
|
|
14
14
|
|
|
15
|
-
from .print_api import print_api, print_status_of_list
|
|
16
15
|
from .basics import strings, list_of_dicts, list_of_classes
|
|
17
16
|
from .file_io import file_io
|
|
18
|
-
from . import hashing, datetimes
|
|
17
|
+
from . import hashing, datetimes, print_api
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
WINDOWS_DIRECTORY_SPECIAL_CHARACTERS = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']
|
|
@@ -280,12 +279,12 @@ def remove_file(file_path: str, **kwargs) -> bool:
|
|
|
280
279
|
|
|
281
280
|
try:
|
|
282
281
|
os.remove(file_path)
|
|
283
|
-
print_api(f'File Removed: {file_path}')
|
|
282
|
+
print_api.print_api(f'File Removed: {file_path}')
|
|
284
283
|
return True
|
|
285
284
|
# Since the file doesn't exist, we actually don't care, since we want to remove it anyway.
|
|
286
285
|
except FileNotFoundError:
|
|
287
286
|
message = f'File Removal Failed, File non-existent: {file_path}'
|
|
288
|
-
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
287
|
+
print_api.print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
289
288
|
return False
|
|
290
289
|
|
|
291
290
|
|
|
@@ -321,12 +320,12 @@ def remove_directory(directory_path: str, force_readonly: bool = False, print_kw
|
|
|
321
320
|
shutil.rmtree(directory_path, onerror=remove_readonly)
|
|
322
321
|
else:
|
|
323
322
|
shutil.rmtree(directory_path)
|
|
324
|
-
print_api(f'Directory Removed: {directory_path}', **print_kwargs)
|
|
323
|
+
print_api.print_api(f'Directory Removed: {directory_path}', **print_kwargs)
|
|
325
324
|
return True
|
|
326
325
|
# Since the directory doesn't exist, we actually don't care, since we want to remove it anyway.
|
|
327
326
|
except FileNotFoundError:
|
|
328
327
|
message = f'Directory Removal Failed, Directory non-existent: {directory_path}'
|
|
329
|
-
print_api(message, error_type=True, logger_method='critical', **print_kwargs)
|
|
328
|
+
print_api.print_api(message, error_type=True, logger_method='critical', **print_kwargs)
|
|
330
329
|
return False
|
|
331
330
|
|
|
332
331
|
|
|
@@ -878,7 +877,7 @@ def get_paths_from_directory(
|
|
|
878
877
|
prefix_string = 'Reading File: '
|
|
879
878
|
|
|
880
879
|
for file_index, file_path in enumerate(object_list):
|
|
881
|
-
print_status_of_list(
|
|
880
|
+
print_api.print_status_of_list(
|
|
882
881
|
list_instance=object_list, prefix_string=prefix_string, current_state=(file_index + 1))
|
|
883
882
|
|
|
884
883
|
# If 'add_binary' was passed.
|
atomicshop/http_parse.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# v1.0.1 - 26.03.2023 23:40
|
|
2
1
|
from http.server import BaseHTTPRequestHandler
|
|
3
2
|
from http.client import HTTPResponse
|
|
4
3
|
import http
|
|
@@ -49,6 +48,7 @@ class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
|
49
48
|
client_message.request_raw_decoded = request_decoded
|
|
50
49
|
"""
|
|
51
50
|
|
|
51
|
+
# noinspection PyMissingConstructor
|
|
52
52
|
def __init__(self, request_text):
|
|
53
53
|
self.rfile = BytesIO(request_text)
|
|
54
54
|
self.raw_requestline = self.rfile.readline()
|
|
@@ -57,28 +57,26 @@ class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
|
57
57
|
|
|
58
58
|
# Check if ".path" attribute exists after HTTP request parsing
|
|
59
59
|
if not hasattr(self, 'path'):
|
|
60
|
+
# noinspection PyTypeChecker
|
|
60
61
|
self.path = None
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
self.content_length = None
|
|
64
|
+
self.body = None
|
|
65
|
+
|
|
66
|
+
# Before checking for body, we need to make sure that ".headers" property exists, if not, return empty values.
|
|
67
|
+
if hasattr(self, 'headers'):
|
|
64
68
|
# The "body" of request is in the 'Content-Length' key. If it exists in "headers" - get the body
|
|
65
69
|
if 'Content-Length' in self.headers.keys():
|
|
66
70
|
# "self.headers.get('Content-Length')" returns number in string format, "int" converts it to integer
|
|
67
71
|
self.content_length = int(self.headers.get('Content-Length'))
|
|
68
72
|
self.body = self.rfile.read(self.content_length)
|
|
69
|
-
else:
|
|
70
|
-
self.content_length = None
|
|
71
|
-
self.body = None
|
|
72
|
-
except Exception:
|
|
73
|
-
self.content_length = None
|
|
74
|
-
self.body = None
|
|
75
|
-
pass
|
|
76
73
|
|
|
77
74
|
# Examples:
|
|
78
75
|
# Getting path: self.path
|
|
79
76
|
# Getting Request Version: self.request_version
|
|
80
77
|
# Getting specific header: self.headers['host']
|
|
81
78
|
|
|
79
|
+
# noinspection PyMethodOverriding
|
|
82
80
|
def send_error(self, code, message):
|
|
83
81
|
self.error_code = code
|
|
84
82
|
self.error_message = message
|
|
@@ -117,9 +115,7 @@ class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
|
117
115
|
|
|
118
116
|
client_message.request_raw_decoded = request_decoded
|
|
119
117
|
"""
|
|
120
|
-
|
|
121
|
-
reason = None
|
|
122
|
-
function_result: bool = True
|
|
118
|
+
|
|
123
119
|
error: bool = False
|
|
124
120
|
|
|
125
121
|
# If there's any error in HTTP parsing
|
|
@@ -185,7 +181,9 @@ class HTTPResponseParse:
|
|
|
185
181
|
pass
|
|
186
182
|
|
|
187
183
|
# Before checking for body, we need to make sure that ".headers" property exists, if not, return empty values
|
|
188
|
-
|
|
184
|
+
self.response_raw_decoded.content_length = None
|
|
185
|
+
self.response_raw_decoded.body = None
|
|
186
|
+
if hasattr(self.response_raw_decoded, 'headers') and self.response_raw_decoded is not None:
|
|
189
187
|
# The "body" of response is in the 'Content-Length' key. If it exists in "headers" - get the body.
|
|
190
188
|
if 'Content-Length' in self.response_raw_decoded.headers.keys():
|
|
191
189
|
# "self.response_raw_decoded.headers.get('Content-Length')" returns number in string format,
|
|
@@ -198,7 +196,3 @@ class HTTPResponseParse:
|
|
|
198
196
|
else:
|
|
199
197
|
self.response_raw_decoded.content_length = None
|
|
200
198
|
self.response_raw_decoded.body = None
|
|
201
|
-
except Exception:
|
|
202
|
-
self.response_raw_decoded.content_length = None
|
|
203
|
-
self.response_raw_decoded.body = None
|
|
204
|
-
pass
|