atomicshop 2.16.30__py3-none-any.whl → 2.16.32__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/basics/booleans.py +28 -40
- atomicshop/config_init.py +4 -4
- atomicshop/file_io/csvs.py +2 -3
- atomicshop/file_io/file_io.py +5 -3
- atomicshop/mitm/engines/__parent/recorder___parent.py +2 -18
- atomicshop/mitm/import_config.py +10 -9
- atomicshop/mitm/mitm_main.py +7 -0
- atomicshop/mitm/recs_files.py +4 -2
- atomicshop/mitm/shared_functions.py +0 -6
- atomicshop/mitm/statistic_analyzer.py +15 -3
- atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +74 -46
- atomicshop/print_api.py +1 -2
- atomicshop/system_resource_monitor.py +41 -40
- atomicshop/wrappers/ctyping/win_console.py +39 -0
- atomicshop/wrappers/loggingw/loggingw.py +1 -1
- atomicshop/wrappers/loggingw/reading.py +28 -11
- atomicshop/wrappers/mongodbw/mongodbw.py +50 -31
- atomicshop/wrappers/nodejsw/install_nodejs.py +7 -4
- atomicshop/wrappers/socketw/dns_server.py +8 -5
- atomicshop/wrappers/socketw/sender.py +18 -25
- atomicshop/wrappers/socketw/socket_wrapper.py +9 -5
- {atomicshop-2.16.30.dist-info → atomicshop-2.16.32.dist-info}/METADATA +1 -1
- {atomicshop-2.16.30.dist-info → atomicshop-2.16.32.dist-info}/RECORD +27 -26
- {atomicshop-2.16.30.dist-info → atomicshop-2.16.32.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.30.dist-info → atomicshop-2.16.32.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.30.dist-info → atomicshop-2.16.32.dist-info}/top_level.txt +0 -0
|
@@ -118,51 +118,12 @@ class SystemResourceMonitor:
|
|
|
118
118
|
:return:
|
|
119
119
|
"""
|
|
120
120
|
|
|
121
|
-
def run_check_system_resources(
|
|
122
|
-
interval, get_cpu, get_memory, get_disk_io_bytes, get_disk_files_count, get_disk_busy_time,
|
|
123
|
-
get_disk_used_percent, calculate_maximum_changed_disk_io, maximum_disk_io, queue_list, manager_dict):
|
|
124
|
-
"""
|
|
125
|
-
Continuously update the system resources in the shared results dictionary.
|
|
126
|
-
This function runs in a separate process.
|
|
127
|
-
"""
|
|
128
|
-
|
|
129
|
-
while self.running:
|
|
130
|
-
# Get the results of the system resources check function and store them in
|
|
131
|
-
# temporary results' dictionary.
|
|
132
|
-
results = system_resources.check_system_resources(
|
|
133
|
-
interval=interval, get_cpu=get_cpu, get_memory=get_memory,
|
|
134
|
-
get_disk_io_bytes=get_disk_io_bytes, get_disk_files_count=get_disk_files_count,
|
|
135
|
-
get_disk_busy_time=get_disk_busy_time, get_disk_used_percent=get_disk_used_percent)
|
|
136
|
-
|
|
137
|
-
if calculate_maximum_changed_disk_io:
|
|
138
|
-
if results['disk_io_read'] > maximum_disk_io['read_bytes_per_sec']:
|
|
139
|
-
maximum_disk_io['read_bytes_per_sec'] = results['disk_io_read']
|
|
140
|
-
if results['disk_io_write'] > maximum_disk_io['write_bytes_per_sec']:
|
|
141
|
-
maximum_disk_io['write_bytes_per_sec'] = results['disk_io_write']
|
|
142
|
-
if results['disk_files_count_read'] > maximum_disk_io['read_files_count_per_sec']:
|
|
143
|
-
maximum_disk_io['read_files_count_per_sec'] = results['disk_files_count_read']
|
|
144
|
-
if results['disk_files_count_write'] > maximum_disk_io['write_files_count_per_sec']:
|
|
145
|
-
maximum_disk_io['write_files_count_per_sec'] = results['disk_files_count_write']
|
|
146
|
-
results['maximum_disk_io'] = maximum_disk_io
|
|
147
|
-
|
|
148
|
-
if queue_list is not None:
|
|
149
|
-
for queue in queue_list:
|
|
150
|
-
queue.put(results)
|
|
151
|
-
|
|
152
|
-
# Update the shared results dictionary with the temporary results' dictionary.
|
|
153
|
-
# This is done in separate steps to avoid overwriting the special 'multiprocessing.Manager.dict' object.
|
|
154
|
-
# So we update the shared results dictionary with the temporary results' dictionary.
|
|
155
|
-
if manager_dict is not None:
|
|
156
|
-
manager_dict.update(results)
|
|
157
|
-
|
|
158
|
-
self.results = results
|
|
159
|
-
|
|
160
121
|
if print_kwargs is None:
|
|
161
122
|
print_kwargs = {}
|
|
162
123
|
|
|
163
124
|
if self.thread is None:
|
|
164
125
|
self.running = True
|
|
165
|
-
self.thread = threading.Thread(target=run_check_system_resources, args=(
|
|
126
|
+
self.thread = threading.Thread(target=self.run_check_system_resources, args=(
|
|
166
127
|
self.interval, self.get_cpu, self.get_memory, self.get_disk_io_bytes, self.get_disk_files_count,
|
|
167
128
|
self.get_disk_busy_time, self.get_disk_used_percent, self.calculate_maximum_changed_disk_io,
|
|
168
129
|
self.maximum_disk_io, self.queue_list, self.manager_dict))
|
|
@@ -171,6 +132,46 @@ class SystemResourceMonitor:
|
|
|
171
132
|
else:
|
|
172
133
|
print_api.print_api("Monitoring is already running.", color='yellow', **print_kwargs)
|
|
173
134
|
|
|
135
|
+
def run_check_system_resources(
|
|
136
|
+
self,
|
|
137
|
+
interval, get_cpu, get_memory, get_disk_io_bytes, get_disk_files_count, get_disk_busy_time,
|
|
138
|
+
get_disk_used_percent, calculate_maximum_changed_disk_io, maximum_disk_io, queue_list, manager_dict):
|
|
139
|
+
"""
|
|
140
|
+
Continuously update the system resources in the shared results dictionary.
|
|
141
|
+
This function runs in a separate process.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
while self.running:
|
|
145
|
+
# Get the results of the system resources check function and store them in
|
|
146
|
+
# temporary results' dictionary.
|
|
147
|
+
results = system_resources.check_system_resources(
|
|
148
|
+
interval=interval, get_cpu=get_cpu, get_memory=get_memory,
|
|
149
|
+
get_disk_io_bytes=get_disk_io_bytes, get_disk_files_count=get_disk_files_count,
|
|
150
|
+
get_disk_busy_time=get_disk_busy_time, get_disk_used_percent=get_disk_used_percent)
|
|
151
|
+
|
|
152
|
+
if calculate_maximum_changed_disk_io:
|
|
153
|
+
if results['disk_io_read'] > maximum_disk_io['read_bytes_per_sec']:
|
|
154
|
+
maximum_disk_io['read_bytes_per_sec'] = results['disk_io_read']
|
|
155
|
+
if results['disk_io_write'] > maximum_disk_io['write_bytes_per_sec']:
|
|
156
|
+
maximum_disk_io['write_bytes_per_sec'] = results['disk_io_write']
|
|
157
|
+
if results['disk_files_count_read'] > maximum_disk_io['read_files_count_per_sec']:
|
|
158
|
+
maximum_disk_io['read_files_count_per_sec'] = results['disk_files_count_read']
|
|
159
|
+
if results['disk_files_count_write'] > maximum_disk_io['write_files_count_per_sec']:
|
|
160
|
+
maximum_disk_io['write_files_count_per_sec'] = results['disk_files_count_write']
|
|
161
|
+
results['maximum_disk_io'] = maximum_disk_io
|
|
162
|
+
|
|
163
|
+
if queue_list is not None:
|
|
164
|
+
for queue in queue_list:
|
|
165
|
+
queue.put(results)
|
|
166
|
+
|
|
167
|
+
# Update the shared results dictionary with the temporary results' dictionary.
|
|
168
|
+
# This is done in separate steps to avoid overwriting the special 'multiprocessing.Manager.dict' object.
|
|
169
|
+
# So we update the shared results dictionary with the temporary results' dictionary.
|
|
170
|
+
if manager_dict is not None:
|
|
171
|
+
manager_dict.update(results)
|
|
172
|
+
|
|
173
|
+
self.results = results
|
|
174
|
+
|
|
174
175
|
def get_results(self) -> dict:
|
|
175
176
|
"""
|
|
176
177
|
Retrieve the latest results.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class NotWindowsConsoleError(Exception):
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Define QuickEdit mode bit (0x0040)
|
|
9
|
+
ENABLE_QUICK_EDIT = 0x0040
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def disable_quick_edit():
|
|
13
|
+
"""
|
|
14
|
+
Disables QuickEdit mode in the Windows Command Prompt.
|
|
15
|
+
This prevents the console from being paused when the user selects text.
|
|
16
|
+
NO ADMIN REQUIRED
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
kernel32 = ctypes.windll.kernel32
|
|
20
|
+
h_stdin = kernel32.GetStdHandle(-10) # -10 is STD_INPUT_HANDLE
|
|
21
|
+
|
|
22
|
+
# Get current console mode
|
|
23
|
+
mode = ctypes.c_uint()
|
|
24
|
+
if kernel32.GetConsoleMode(h_stdin, ctypes.byref(mode)) == 0:
|
|
25
|
+
try:
|
|
26
|
+
raise ctypes.WinError()
|
|
27
|
+
except OSError as e:
|
|
28
|
+
# This means that the code is not running in console window.
|
|
29
|
+
if e.errno == 9 and e.winerror == 6:
|
|
30
|
+
raise NotWindowsConsoleError("This code is not running in a Windows console.")
|
|
31
|
+
else:
|
|
32
|
+
raise e
|
|
33
|
+
|
|
34
|
+
# Disable QuickEdit Mode by clearing the corresponding bit
|
|
35
|
+
mode.value &= ~ENABLE_QUICK_EDIT
|
|
36
|
+
|
|
37
|
+
# Set the new console mode
|
|
38
|
+
if kernel32.SetConsoleMode(h_stdin, mode) == 0:
|
|
39
|
+
raise ctypes.WinError()
|
|
@@ -13,6 +13,7 @@ def get_logs_paths(
|
|
|
13
13
|
date_format: str = None,
|
|
14
14
|
latest_only: bool = False,
|
|
15
15
|
previous_day_only: bool = False,
|
|
16
|
+
yesterday_only: bool = False,
|
|
16
17
|
specific_date: str = None
|
|
17
18
|
) -> list[filesystem.AtomicPath]:
|
|
18
19
|
"""
|
|
@@ -37,24 +38,37 @@ def get_logs_paths(
|
|
|
37
38
|
date_format = '%Y-%m-%d'
|
|
38
39
|
:param latest_only: Boolean, if True, only the latest log file path will be returned.
|
|
39
40
|
:param previous_day_only: Boolean, if True, only the log file path from the previous day will be returned.
|
|
41
|
+
:param yesterday_only: Boolean, if True, only the log file path from yesterday will be returned.
|
|
42
|
+
There's a difference between 'previous_day_only' and 'yesterday_only'.
|
|
43
|
+
'previous_day_only' will get the log file from the previous day in the list of files that were found.
|
|
44
|
+
Since that doesn't guarantee that the log file from the previous day is yesterday, we have 'yesterday_only'.
|
|
40
45
|
:param specific_date: Specific date to get the log file path.
|
|
41
46
|
If specified, the function will get the log file by the specific date.
|
|
42
47
|
Meaning that 'date_format' must be specified.
|
|
43
|
-
|
|
44
48
|
"""
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
booleans.is_only_1_true_in_list(
|
|
51
|
+
booleans_list_of_tuples=[
|
|
52
|
+
(latest_only, 'latest_only'),
|
|
53
|
+
(previous_day_only, 'previous_day_only'),
|
|
54
|
+
(yesterday_only, 'yesterday_only'),
|
|
55
|
+
(specific_date, 'specific_date'),
|
|
56
|
+
],
|
|
57
|
+
raise_if_all_false=False
|
|
58
|
+
)
|
|
51
59
|
|
|
52
60
|
if not date_format and specific_date:
|
|
53
61
|
raise ValueError('If "specific_date" is specified, "date_format" must be specified.')
|
|
54
62
|
|
|
55
63
|
# Get the file_name_pattern from the file name. Build the file_name_pattern.
|
|
64
|
+
# For some reason if the file name will be '.zip', then the file stem will be '.zip' and the extension will be ''.
|
|
56
65
|
log_file_name: str = Path(log_file_path).stem
|
|
57
66
|
log_file_extension: str = Path(log_file_path).suffix
|
|
67
|
+
|
|
68
|
+
if not log_file_extension and '.' in log_file_name:
|
|
69
|
+
log_file_name, log_file_extension = log_file_name.rsplit('.')
|
|
70
|
+
log_file_extension = f'.{log_file_extension}'
|
|
71
|
+
|
|
58
72
|
file_name_pattern: str = f'{log_file_name}*{log_file_extension}'
|
|
59
73
|
|
|
60
74
|
# Get the directory path from the file path.
|
|
@@ -111,15 +125,18 @@ def get_logs_paths(
|
|
|
111
125
|
if logs_files:
|
|
112
126
|
if latest_only:
|
|
113
127
|
logs_files = [logs_files[-1]]
|
|
114
|
-
|
|
115
|
-
if previous_day_only:
|
|
116
|
-
# Check if there is a previous day log file.
|
|
128
|
+
elif previous_day_only:
|
|
117
129
|
if len(logs_files) == 1:
|
|
118
130
|
logs_files = []
|
|
119
131
|
else:
|
|
120
132
|
logs_files = [logs_files[-2]]
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
elif yesterday_only:
|
|
134
|
+
# Get yesterday's date.
|
|
135
|
+
yesterday_date_string = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime(date_format)
|
|
136
|
+
# Check if there is a yesterday log file.
|
|
137
|
+
logs_files = [single_file
|
|
138
|
+
for single_file in logs_files if single_file.datetime_string == yesterday_date_string]
|
|
139
|
+
elif specific_date:
|
|
123
140
|
# Check if there is a specific date log file.
|
|
124
141
|
logs_files = [single_file for single_file in logs_files if single_file.datetime_string == specific_date]
|
|
125
142
|
|
|
@@ -394,9 +394,14 @@ def find(
|
|
|
394
394
|
query: dict = None,
|
|
395
395
|
page: int = None,
|
|
396
396
|
items: int = None,
|
|
397
|
-
sorting:
|
|
398
|
-
|
|
399
|
-
|
|
397
|
+
sorting: Union[
|
|
398
|
+
dict[str, Literal[
|
|
399
|
+
'asc', 'desc',
|
|
400
|
+
'ASC', 'DESC',
|
|
401
|
+
1, -1]],
|
|
402
|
+
list[tuple[
|
|
403
|
+
str, Literal[1, -1]]],
|
|
404
|
+
None] = None,
|
|
400
405
|
convert_object_id_to_str: bool = False,
|
|
401
406
|
key_convert_to_dict: list[str] = None,
|
|
402
407
|
mongo_client: pymongo.MongoClient = None,
|
|
@@ -445,29 +450,40 @@ def find(
|
|
|
445
450
|
$nin: Will search for a value not in a list of values.
|
|
446
451
|
Example for searching for a value that is not in a list of values:
|
|
447
452
|
query = {'field_name': {'$nin': ['value1', 'value2', 'value3']}}
|
|
448
|
-
|
|
453
|
+
$exists: Will search for entries where the field exists or not.
|
|
454
|
+
Example for searching for entries where the field exists:
|
|
455
|
+
query = {'field_name': {'$exists': True}}
|
|
456
|
+
Example for searching for entries where the field does not exist:
|
|
457
|
+
query = {'field_name': {'$exists': False}}
|
|
458
|
+
$ne: Will search for entries where the field is not equal to the value.
|
|
459
|
+
Example for searching for entries where the field is not equal to the value:
|
|
460
|
+
query = {'field_name': {'$ne': 'value'}}
|
|
449
461
|
|
|
450
462
|
:param page: int, the page number (Optional).
|
|
451
463
|
:param items: int, the number of results per page (Optional).
|
|
452
|
-
:param sorting: dict
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
464
|
+
:param sorting: dict or list of tuples:
|
|
465
|
+
dict, the name of the field and the order to sort the containers by.
|
|
466
|
+
You can use several fields to sort the containers by several fields.
|
|
467
|
+
In this case the containers will be sorted by the first field, then by the second field, etc.
|
|
468
|
+
You can also use only singular field to sort the containers by only one field.
|
|
469
|
+
Usage:
|
|
470
|
+
{
|
|
471
|
+
field_name: order
|
|
472
|
+
}
|
|
473
|
+
Example:
|
|
474
|
+
{
|
|
475
|
+
'vendor': 'asc',
|
|
476
|
+
'model': 'desc'
|
|
477
|
+
}
|
|
465
478
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
479
|
+
Or example using integers:
|
|
480
|
+
{
|
|
481
|
+
'vendor': 1,
|
|
482
|
+
'model': -1
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
list of tuples, each tuple will contain [0] string of the field name and [1] the integer value of the order
|
|
486
|
+
to sort by, this is pymongo default, 1 for ascending and -1 for descending.
|
|
471
487
|
:param convert_object_id_to_str: bool, if True, the '_id' field will be converted to a string.
|
|
472
488
|
The '_id' field is an ObjectId type, which is a complex object, it can be converted to a string for simpler
|
|
473
489
|
processing.
|
|
@@ -486,9 +502,9 @@ def find(
|
|
|
486
502
|
elif items and not page:
|
|
487
503
|
page = 1
|
|
488
504
|
|
|
489
|
-
if sorting:
|
|
505
|
+
if sorting and isinstance(sorting, dict):
|
|
490
506
|
for key_to_sort_by, order in sorting.items():
|
|
491
|
-
if order not in ['asc', 'desc', 1, -1]:
|
|
507
|
+
if order.lower() not in ['asc', 'desc', 1, -1]:
|
|
492
508
|
raise ValueError("The order must be 'asc', 'desc', 1 or -1.")
|
|
493
509
|
|
|
494
510
|
if not mongo_client:
|
|
@@ -510,13 +526,16 @@ def find(
|
|
|
510
526
|
|
|
511
527
|
if sorting:
|
|
512
528
|
sorting_list_of_tuples: list[tuple[str, int]] = []
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
order
|
|
516
|
-
|
|
517
|
-
order
|
|
518
|
-
|
|
519
|
-
|
|
529
|
+
if isinstance(sorting, dict):
|
|
530
|
+
for key_to_sort_by, order in sorting.items():
|
|
531
|
+
if order.lower() == 'asc':
|
|
532
|
+
order = pymongo.ASCENDING
|
|
533
|
+
elif order.lower() == 'desc':
|
|
534
|
+
order = pymongo.DESCENDING
|
|
535
|
+
|
|
536
|
+
sorting_list_of_tuples.append((key_to_sort_by, order))
|
|
537
|
+
elif sorting and isinstance(sorting, list):
|
|
538
|
+
sorting_list_of_tuples = sorting
|
|
520
539
|
|
|
521
540
|
collection_items = collection_items.sort(sorting_list_of_tuples)
|
|
522
541
|
|
|
@@ -84,10 +84,13 @@ def install_nodejs_ubuntu(
|
|
|
84
84
|
:return:
|
|
85
85
|
"""
|
|
86
86
|
|
|
87
|
-
booleans.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
booleans.is_only_1_true_in_list(
|
|
88
|
+
booleans_list_of_tuples=[
|
|
89
|
+
(install_latest_version, 'install_latest_version'),
|
|
90
|
+
(install_lts, 'install_lts'),
|
|
91
|
+
(install_by_version_number, 'install_by_version_number')
|
|
92
|
+
],
|
|
93
|
+
raise_if_all_false=True
|
|
91
94
|
)
|
|
92
95
|
|
|
93
96
|
# Check if Node.js is already installed.
|
|
@@ -261,11 +261,14 @@ class DnsServer:
|
|
|
261
261
|
|
|
262
262
|
def test_config(self):
|
|
263
263
|
try:
|
|
264
|
-
booleans.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
264
|
+
booleans.is_only_1_true_in_list(
|
|
265
|
+
booleans_list_of_tuples=[
|
|
266
|
+
(self.resolve_to_tcp_server_only_tcp_resolve_domains,
|
|
267
|
+
'resolve_to_tcp_server_only_tcp_resolve_domains'),
|
|
268
|
+
(self.resolve_to_tcp_server_all_domains, 'resolve_to_tcp_server_all_domains'),
|
|
269
|
+
(self.resolve_regular, 'resolve_regular')
|
|
270
|
+
],
|
|
271
|
+
raise_if_all_false=True
|
|
269
272
|
)
|
|
270
273
|
except ValueError as e:
|
|
271
274
|
raise DnsConfigurationValuesError(e)
|
|
@@ -68,39 +68,32 @@ class Sender:
|
|
|
68
68
|
|
|
69
69
|
# At this point the sending loop finished successfully
|
|
70
70
|
self.logger.info(f"Sent the message to destination.")
|
|
71
|
-
except ConnectionResetError as e:
|
|
72
|
-
destination_address, destination_port = base.get_destination_address_from_socket(self.ssl_socket)
|
|
73
|
-
if self.ssl_socket.server_hostname:
|
|
74
|
-
destination_address = self.ssl_socket.server_hostname
|
|
75
|
-
destination: str = f'{destination_address}:{destination_port}'
|
|
76
|
-
|
|
77
|
-
error_class_type = str(type(e)).replace("<class '", '').replace("'>", '')
|
|
78
|
-
exception_error = tracebacks.get_as_string(one_line=True)
|
|
79
|
-
error_message = (f"Socket Send: {destination}: Error, Couldn't reach the server - Connection was reset | "
|
|
80
|
-
f"{error_class_type}: {exception_error}")
|
|
81
|
-
except (ssl.SSLEOFError, ssl.SSLZeroReturnError, ssl.SSLWantWriteError, TimeoutError) as e:
|
|
82
|
-
destination_address, destination_port = base.get_destination_address_from_socket(self.ssl_socket)
|
|
83
|
-
if self.ssl_socket.server_hostname:
|
|
84
|
-
destination_address = self.ssl_socket.server_hostname
|
|
85
|
-
destination: str = f'{destination_address}:{destination_port}'
|
|
86
|
-
|
|
87
|
-
error_class_type = str(type(e)).replace("<class '", '').replace("'>", '')
|
|
88
|
-
exception_error = tracebacks.get_as_string(one_line=True)
|
|
89
|
-
error_message = f"Socket Send: {destination}: {error_class_type}: {exception_error}"
|
|
90
71
|
except Exception as e:
|
|
91
|
-
|
|
72
|
+
source_tuple, destination_tuple = base.get_source_destination(self.ssl_socket)
|
|
73
|
+
source_address, source_port = source_tuple
|
|
74
|
+
destination_address, destination_port = destination_tuple
|
|
92
75
|
if self.ssl_socket.server_hostname:
|
|
93
76
|
destination_address = self.ssl_socket.server_hostname
|
|
94
|
-
destination: str = f'{destination_address}:{destination_port}'
|
|
77
|
+
destination: str = f'[{source_address}:{source_port}<->{destination_address}:{destination_port}]'
|
|
95
78
|
|
|
96
79
|
error_class_type = str(type(e)).replace("<class '", '').replace("'>", '')
|
|
97
80
|
exception_error = tracebacks.get_as_string(one_line=True)
|
|
81
|
+
|
|
98
82
|
if 'ssl' in error_class_type.lower():
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
if error_class_type in ['ssl.SSLEOFError', 'ssl.SSLZeroReturnError', 'ssl.SSLWantWriteError']:
|
|
84
|
+
error_message = f"Socket Send: {destination}: {error_class_type}: {exception_error}"
|
|
85
|
+
else:
|
|
86
|
+
error_message = (f"Socket Send: {destination}: "
|
|
87
|
+
f"SSL UNDOCUMENTED Exception: {error_class_type}{exception_error}")
|
|
101
88
|
else:
|
|
102
|
-
|
|
103
|
-
|
|
89
|
+
if error_class_type == 'ConnectionResetError':
|
|
90
|
+
error_message = (f"Socket Send: {destination}: "
|
|
91
|
+
f"Error, Couldn't reach the server - Connection was reset | "
|
|
92
|
+
f"{error_class_type}: {exception_error}")
|
|
93
|
+
elif error_class_type in ['TimeoutError']:
|
|
94
|
+
error_message = f"Socket Send: {destination}: {error_class_type}: {exception_error}"
|
|
95
|
+
else:
|
|
96
|
+
raise e
|
|
104
97
|
|
|
105
98
|
if error_message:
|
|
106
99
|
print_api(error_message, logger=self.logger, logger_method='error')
|
|
@@ -263,11 +263,15 @@ class SocketWrapper:
|
|
|
263
263
|
raise SocketWrapperConfigurationValuesError(message)
|
|
264
264
|
|
|
265
265
|
try:
|
|
266
|
-
booleans.
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
266
|
+
booleans.is_only_1_true_in_list(
|
|
267
|
+
booleans_list_of_tuples=[
|
|
268
|
+
(self.default_server_certificate_usage, 'default_server_certificate_usage'),
|
|
269
|
+
(self.sni_create_server_certificate_for_each_domain,
|
|
270
|
+
'sni_create_server_certificate_for_each_domain'),
|
|
271
|
+
(self.custom_server_certificate_usage, 'custom_server_certificate_usage')
|
|
272
|
+
],
|
|
273
|
+
raise_if_all_false=True
|
|
274
|
+
)
|
|
271
275
|
except ValueError as e:
|
|
272
276
|
raise SocketWrapperConfigurationValuesError(str(e))
|
|
273
277
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=CTcwR9Fze6eeaSRpctGxH5Awdz0-la2J3f5qJFeP0jA,124
|
|
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
|
|
5
5
|
atomicshop/appointment_management.py,sha256=BsYH_PClTGLVazcuNjt30--hpXKYjSmHp1R1iQbM4Hc,7330
|
|
6
6
|
atomicshop/certificates.py,sha256=MEGj7t3Nt2CHE7yzXrvFTLCOKZG9tJ6Ok5JC2BsFRis,7603
|
|
7
7
|
atomicshop/command_line_processing.py,sha256=u5yT9Ger_cu7ni5ID0VFlRbVD46ARHeNC9tRM-_YXrQ,1038
|
|
8
|
-
atomicshop/config_init.py,sha256=
|
|
8
|
+
atomicshop/config_init.py,sha256=50kD2lXP8sgwPekcmAbfADcY46YvXkF-6XIdA7W_638,2501
|
|
9
9
|
atomicshop/console_output.py,sha256=AOSJjrRryE97PAGtgDL03IBtWSi02aNol8noDnW3k6M,4667
|
|
10
10
|
atomicshop/console_user_response.py,sha256=31HIy9QGXa7f-GVR8MzJauQ79E_ZqAeagF3Ks4GGdDU,3234
|
|
11
11
|
atomicshop/datetimes.py,sha256=IQZ66lmta-ZqxYbyHzm_9eugbJFSilXK1e0kfMgoXGg,18371
|
|
@@ -25,7 +25,7 @@ atomicshop/ip_addresses.py,sha256=Hvi4TumEFoTEpKWaq5WNF-YzcRzt24IxmNgv-Mgax1s,11
|
|
|
25
25
|
atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,452
|
|
26
26
|
atomicshop/on_exit.py,sha256=Rpg2SaF0aginuO7JYwA49YJYnS8F6K2jUqhjH65WzuU,6889
|
|
27
27
|
atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
|
|
28
|
-
atomicshop/print_api.py,sha256=
|
|
28
|
+
atomicshop/print_api.py,sha256=REkd1W3--g1Av4_nH3M2CvQCIEDecfsT7spMXgIRUJE,11158
|
|
29
29
|
atomicshop/process.py,sha256=PeLvyixXaCfftdUF3oMbohI1L4MdLtvQVDx2V1Tz_Rk,16662
|
|
30
30
|
atomicshop/python_file_patcher.py,sha256=-uhbUX-um5k-If_XXuOfCr8wMzZ3QE6h9N8xGWw6W_o,5486
|
|
31
31
|
atomicshop/python_functions.py,sha256=zJg4ogUwECxrDD7xdDN5JikIUctITM5lsyabr_ZNsRw,4435
|
|
@@ -37,7 +37,7 @@ atomicshop/sound.py,sha256=tHiQQbFBk7EYN3pAfGNcxfF9oNsoYnZgu9z9iq8hxQE,24352
|
|
|
37
37
|
atomicshop/speech_recognize.py,sha256=55-dIjgkpF93mvJnJuxSFuft5H5eRvGNlUj9BeIOZxk,5903
|
|
38
38
|
atomicshop/ssh_remote.py,sha256=Mxixqs2-xGy1bhbcP0LKqjxKTNPz1Gmzz8PzO8aLB4c,17345
|
|
39
39
|
atomicshop/sys_functions.py,sha256=MTBxRve5bh58SPvhX3gMiGqHlSBuI_rdNN1NnnBBWqI,906
|
|
40
|
-
atomicshop/system_resource_monitor.py,sha256=
|
|
40
|
+
atomicshop/system_resource_monitor.py,sha256=5sM3Ad4IZI8ahpKM3Wu4B0a3TD-N2Y795_kSkIv94lk,13632
|
|
41
41
|
atomicshop/system_resources.py,sha256=iKUvVSaXR47inmr3cTYsgNfclT38dRia2oupnlhIpK4,9290
|
|
42
42
|
atomicshop/tempfiles.py,sha256=uq1ve2WlWehZ3NOTXJnpBBMt6HyCdBufqedF0HyzA6k,2517
|
|
43
43
|
atomicshop/timer.py,sha256=7Zw1KRV0acHCRATMnanyX2MLBb63Hc-6us3rCZ9dNlY,2345
|
|
@@ -82,7 +82,7 @@ atomicshop/archiver/zips.py,sha256=0Z_1MWs7YRiCBVpyaG8llnzRguHSO4R51KDMN3FJZt8,1
|
|
|
82
82
|
atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
83
|
atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX98jcBMpJE,3140
|
|
84
84
|
atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
|
|
85
|
-
atomicshop/basics/booleans.py,sha256=
|
|
85
|
+
atomicshop/basics/booleans.py,sha256=V36NaMf8AffhCom_ovQeOZlYcdtGyIcQwWKki6h7O0M,1745
|
|
86
86
|
atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
|
|
87
87
|
atomicshop/basics/classes.py,sha256=T0Bm13hKvkXG3med68ptL7XuoWiCi3TE-K5TMINDlrY,10655
|
|
88
88
|
atomicshop/basics/dicts.py,sha256=DeYHIh940pMMBrFhpXt4dsigFVYzTrlqWymNo4Pq_Js,14049
|
|
@@ -114,9 +114,9 @@ atomicshop/etws/traces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
114
114
|
atomicshop/etws/traces/trace_dns.py,sha256=WvOZm7KNdP4r6ofkZhUGi9WjtYlkV3mUp_yxita3Qg4,6399
|
|
115
115
|
atomicshop/etws/traces/trace_sysmon_process_creation.py,sha256=OM-bkK38uYMwWLZKNOTDa0Xdk3sO6sqsxoMUIiPvm5g,4656
|
|
116
116
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
|
-
atomicshop/file_io/csvs.py,sha256=
|
|
117
|
+
atomicshop/file_io/csvs.py,sha256=jBdm3_z5cMyvxLxJnGcybUAptHAbyL0r0tlLqY0sdTQ,9327
|
|
118
118
|
atomicshop/file_io/docxs.py,sha256=ffJhnmM_WyD8mCoq2dGdpfahdIrGTPy96QVlH5EWjeI,5754
|
|
119
|
-
atomicshop/file_io/file_io.py,sha256=
|
|
119
|
+
atomicshop/file_io/file_io.py,sha256=5Kl0P6vF4GQVdwew1lzHLb-db9qiMvDjTgccbi5P-zk,7167
|
|
120
120
|
atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
|
|
121
121
|
atomicshop/file_io/tomls.py,sha256=ol8EvQPf9sryTmZUf1v55BYSUQ6ml7HVVBHpNKbsIlA,9768
|
|
122
122
|
atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
|
|
@@ -125,19 +125,19 @@ atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
125
125
|
atomicshop/mitm/config_static.py,sha256=ROAtbibSWSsF3BraUbhu-QO3MPIFqYY5KUKgsQbiSkk,7813
|
|
126
126
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
127
127
|
atomicshop/mitm/connection_thread_worker.py,sha256=fybUBcZckgF7TC_P1z2yIYGH6ATX7jQEfsQSBuddt2s,16531
|
|
128
|
-
atomicshop/mitm/import_config.py,sha256=
|
|
128
|
+
atomicshop/mitm/import_config.py,sha256=ZKQXxbtjVqzN9fpRrMwPNQREecH06RG8F_nXZAKTUJM,8182
|
|
129
129
|
atomicshop/mitm/initialize_engines.py,sha256=VyJE8QnzlgD3QbX5inz5o6rC3zQ3is9CeTL7-B10g1w,8292
|
|
130
130
|
atomicshop/mitm/message.py,sha256=URR5JKSuAT8XmGIkyprEjlPW2GW4ef_gfUz_GgcFseE,2184
|
|
131
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
132
|
-
atomicshop/mitm/recs_files.py,sha256=
|
|
133
|
-
atomicshop/mitm/shared_functions.py,sha256=
|
|
134
|
-
atomicshop/mitm/statistic_analyzer.py,sha256=
|
|
131
|
+
atomicshop/mitm/mitm_main.py,sha256=ICQS8-4-owDhPUIQohymLShzgCZwgq7jUocZHX1J3Zo,22592
|
|
132
|
+
atomicshop/mitm/recs_files.py,sha256=mMyO1kPB-VkS_pbWCDhZHKdbWzlPbYSout61QuzHOao,3077
|
|
133
|
+
atomicshop/mitm/shared_functions.py,sha256=l6oEyv4ug5D_03V3QLADYoocbcL2Ml_dYVW2WKM21l4,1818
|
|
134
|
+
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
135
135
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
136
136
|
atomicshop/mitm/engines/create_module_template.py,sha256=tRjVSm1sD6FzML71Qbuwvita0qsusdFGm8NZLsZ-XMs,4853
|
|
137
137
|
atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
|
|
138
138
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
139
|
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=RK2wviepP0oeq7zuLpgkvqvTJtc0r0a7hDGWdV0dGc4,657
|
|
140
|
-
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=
|
|
140
|
+
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=xJ3YVa8XYwcKqCwUIEXf6_UGnCbpRsvoicUNe0WxMfs,3782
|
|
141
141
|
atomicshop/mitm/engines/__parent/responder___parent.py,sha256=7WQeR3UmMnN74bDwn-0nz2OfhXJ3-ClXpNGUFZ7wJUE,12004
|
|
142
142
|
atomicshop/mitm/engines/__reference_general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
143
|
atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=57MEPZMAjTO6xBDZ-yt6lgGJyqRrP0Do5Gk_cgCiPns,2998
|
|
@@ -145,7 +145,7 @@ atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha2
|
|
|
145
145
|
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=IUyQYMPeEhIARfALWiKPFeXagSQD6lRzAxUdi4ZIT88,7010
|
|
146
146
|
atomicshop/mitm/statistic_analyzer_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
147
147
|
atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py,sha256=pk6L1t1ea1kvlBoR9QEJptOmaX-mumhwLsP2GCKukbk,5920
|
|
148
|
-
atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=
|
|
148
|
+
atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=Fw-1lH1NOTinMsJnCbCgMHfdoH5Vav388puKm3DmdEs,19746
|
|
149
149
|
atomicshop/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
150
|
atomicshop/monitor/change_monitor.py,sha256=K5NlVp99XIDDPnQQMdru4BDmua_DtcDIhVAzkTOvD5s,7673
|
|
151
151
|
atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -194,6 +194,7 @@ atomicshop/wrappers/certauthw/certauth.py,sha256=hKedW0DOWlEigSNm8wu4SqHkCQsGJ1t
|
|
|
194
194
|
atomicshop/wrappers/certauthw/certauthw.py,sha256=4WvhjANI7Kzqrr_nKmtA8Kf7B6rute_5wfP65gwQrjw,8082
|
|
195
195
|
atomicshop/wrappers/ctyping/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
196
196
|
atomicshop/wrappers/ctyping/process_winapi.py,sha256=QcXL-ETtlSSkoT8F7pYle97ubGWsjYp8cx8HxkVMgAc,2762
|
|
197
|
+
atomicshop/wrappers/ctyping/win_console.py,sha256=uTtjkz9rY559AaV0dhyZYUSSEe9cn6Du2DgurdMtX-M,1158
|
|
197
198
|
atomicshop/wrappers/ctyping/etw_winapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
198
199
|
atomicshop/wrappers/ctyping/etw_winapi/const.py,sha256=stZHZ7tSiSAs04ikr7uH-Td_yBXxsF-bp2Q0F3K2fsM,9543
|
|
199
200
|
atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py,sha256=Iwd0wIuoxpjMaaOfZZtT1bPtDTsMO8jjItBE5bvkocM,11546
|
|
@@ -249,14 +250,14 @@ atomicshop/wrappers/loggingw/filters.py,sha256=48UVhJHemCS0agXmQP8dHvAHM8r9DFphJ
|
|
|
249
250
|
atomicshop/wrappers/loggingw/formatters.py,sha256=ZY12IokVY1G_Wzn2Zlv9qjK-e8CtIK6yUgUfPHvH2BU,5802
|
|
250
251
|
atomicshop/wrappers/loggingw/handlers.py,sha256=vxaSSnlJGs9NKJvYROKtNjaFTqePdHy0sz-GwN5aNPw,19035
|
|
251
252
|
atomicshop/wrappers/loggingw/loggers.py,sha256=mmM__XR3W4QC82wbsDRG_M4_0JYGGEP0Qn0WCOSp-go,2910
|
|
252
|
-
atomicshop/wrappers/loggingw/loggingw.py,sha256=
|
|
253
|
-
atomicshop/wrappers/loggingw/reading.py,sha256=
|
|
253
|
+
atomicshop/wrappers/loggingw/loggingw.py,sha256=64r5XZSAwJ5GfkN7JqAvuLFlJRdf79n0jr_FriaaaCw,21330
|
|
254
|
+
atomicshop/wrappers/loggingw/reading.py,sha256=sCNlgqLNH5XdKqOOjjEox7CvViMHzs6h7-hwCnx4NKk,17566
|
|
254
255
|
atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
255
256
|
atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=3ZPqrXxj3lC-PnAKGXclylLuOqsbyXYeUpb5iGjdeUU,6626
|
|
256
257
|
atomicshop/wrappers/mongodbw/mongo_infra.py,sha256=IjEF0jPzQz866MpTm7rnksnyyWQeUT_B2h2DA9ryAio,2034
|
|
257
|
-
atomicshop/wrappers/mongodbw/mongodbw.py,sha256=
|
|
258
|
+
atomicshop/wrappers/mongodbw/mongodbw.py,sha256=oM2pS-M0EI7HhewWY0ri_Ri9U5GOBo0CehPmo4Yas3o,32736
|
|
258
259
|
atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
259
|
-
atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=
|
|
260
|
+
atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=TKGa3jSlSqZTL2NA0nMkWDFtlkz7rxGGn44ywCg7MN8,5228
|
|
260
261
|
atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
261
262
|
atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
|
|
262
263
|
atomicshop/wrappers/playwrightw/base.py,sha256=WeRpx8otdXuKSr-BjY-uCJTze21kbPpfitoOjKQz5-g,9818
|
|
@@ -296,21 +297,21 @@ atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-Atq
|
|
|
296
297
|
atomicshop/wrappers/socketw/base.py,sha256=evoOIxg5Xff3THJnrVX00D5HobaOpDp6_e_gso7TJmA,2191
|
|
297
298
|
atomicshop/wrappers/socketw/certificator.py,sha256=3CpQKtcW68FSbH6LVSEZTqWBS6Yg_-3K0x4nFkId4UY,12236
|
|
298
299
|
atomicshop/wrappers/socketw/creator.py,sha256=3_OraDkw2DAWZfoSdY3svCGMOIxpjLEEY7NxWd7M5P4,9873
|
|
299
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
300
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=VHV6s7vd0zqqW3dhE6li-260YRzmEB5ZUXqYJ9p0vVA,49069
|
|
300
301
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
|
|
301
302
|
atomicshop/wrappers/socketw/get_process.py,sha256=zKEqh98cB9UDLFhtxVpperfXsCjyIMNANHilDD06p0U,6094
|
|
302
303
|
atomicshop/wrappers/socketw/receiver.py,sha256=XVvWOoeCo3vA0O5p19ryi-hcDIyx382WNG7WzMNVeYk,9322
|
|
303
|
-
atomicshop/wrappers/socketw/sender.py,sha256=
|
|
304
|
+
atomicshop/wrappers/socketw/sender.py,sha256=5HPrgTS2pA1g-jbG1TUtR7drHT1Z_8UevlRCTwW7dgY,5007
|
|
304
305
|
atomicshop/wrappers/socketw/sni.py,sha256=J1kPnQ77XwKN1pO5aOI1c_VfhuivCm95OOaQxMpPuZ0,17627
|
|
305
306
|
atomicshop/wrappers/socketw/socket_client.py,sha256=XC-YaqA1wu0rvWQ9Q99DWLxcycKPkPc72pSnflzalfo,20320
|
|
306
307
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
307
|
-
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=
|
|
308
|
+
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
|
|
308
309
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
|
|
309
310
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
|
|
310
311
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
311
312
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=bQ8Jql8bVGBJ0dt3VQ56lga_1LBOMLI3Km_otvvbU6c,7138
|
|
312
|
-
atomicshop-2.16.
|
|
313
|
-
atomicshop-2.16.
|
|
314
|
-
atomicshop-2.16.
|
|
315
|
-
atomicshop-2.16.
|
|
316
|
-
atomicshop-2.16.
|
|
313
|
+
atomicshop-2.16.32.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
314
|
+
atomicshop-2.16.32.dist-info/METADATA,sha256=9y8KcvM3GJNgsSJQ2aDxHl6YGVSkAV6KWlkAO3t9HTQ,10473
|
|
315
|
+
atomicshop-2.16.32.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
316
|
+
atomicshop-2.16.32.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
317
|
+
atomicshop-2.16.32.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|