atomicshop 2.16.26__py3-none-any.whl → 2.16.28__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/file_io/csvs.py +20 -0
- atomicshop/mitm/mitm_main.py +21 -19
- atomicshop/mitm/recs_files.py +2 -1
- atomicshop/on_exit.py +38 -9
- atomicshop/print_api.py +40 -12
- atomicshop/wrappers/loggingw/formatters.py +12 -0
- atomicshop/wrappers/loggingw/handlers.py +10 -0
- atomicshop/wrappers/loggingw/loggingw.py +98 -0
- {atomicshop-2.16.26.dist-info → atomicshop-2.16.28.dist-info}/METADATA +1 -1
- {atomicshop-2.16.26.dist-info → atomicshop-2.16.28.dist-info}/RECORD +14 -14
- {atomicshop-2.16.26.dist-info → atomicshop-2.16.28.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.26.dist-info → atomicshop-2.16.28.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.26.dist-info → atomicshop-2.16.28.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/file_io/csvs.py
CHANGED
|
@@ -254,3 +254,23 @@ def escape_csv_line_to_list(csv_line: list) -> list:
|
|
|
254
254
|
result_csv_entries.append(escape_csv_value(entry))
|
|
255
255
|
|
|
256
256
|
return result_csv_entries
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def get_number_of_cells_in_string_line(line: str) -> int:
|
|
260
|
+
"""
|
|
261
|
+
Function to get number of cells in CSV line.
|
|
262
|
+
|
|
263
|
+
:param line: String, line of CSV file.
|
|
264
|
+
:return: int, number of cells in the line.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
# Create CSV reader from 'input_file'. By default, the first row will be the header if 'fieldnames' is None.
|
|
268
|
+
csv_reader = csv.reader([line])
|
|
269
|
+
|
|
270
|
+
# Get the first row of the CSV file.
|
|
271
|
+
csv_list = list(csv_reader)
|
|
272
|
+
|
|
273
|
+
# Get the number of cells in the first row.
|
|
274
|
+
number_of_cells = len(csv_list[0])
|
|
275
|
+
|
|
276
|
+
return number_of_cells
|
atomicshop/mitm/mitm_main.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import threading
|
|
3
|
+
import multiprocessing
|
|
3
4
|
import time
|
|
4
5
|
import datetime
|
|
5
6
|
|
|
6
7
|
import atomicshop # Importing atomicshop package to get the version of the package.
|
|
7
8
|
|
|
8
9
|
from .. import filesystem, queues, dns, on_exit
|
|
9
|
-
from ..basics import tracebacks
|
|
10
|
-
from ..file_io import csvs
|
|
11
10
|
from ..permissions import permissions
|
|
12
11
|
from ..python_functions import get_current_python_version_string, check_python_version_compliance
|
|
13
12
|
from ..wrappers.socketw import socket_wrapper, dns_server, base
|
|
@@ -21,12 +20,14 @@ from . import config_static, recs_files
|
|
|
21
20
|
|
|
22
21
|
NETWORK_INTERFACE_IS_DYNAMIC: bool = bool()
|
|
23
22
|
NETWORK_INTERFACE_IPV4_ADDRESS_LIST: list[str] = list()
|
|
23
|
+
# noinspection PyTypeChecker
|
|
24
|
+
RECS_PROCESS_INSTANCE: multiprocessing.Process = None
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
EXCEPTIONS_CSV_LOGGER_NAME: str = 'exceptions'
|
|
27
28
|
EXCEPTIONS_CSV_LOGGER_HEADER: str = 'time,exception'
|
|
28
29
|
# noinspection PyTypeChecker
|
|
29
|
-
MITM_ERROR_LOGGER:
|
|
30
|
+
MITM_ERROR_LOGGER: loggingw.ExceptionCsvLogger = None
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def exit_cleanup():
|
|
@@ -39,9 +40,13 @@ def exit_cleanup():
|
|
|
39
40
|
dns.set_connection_dns_gateway_dynamic(use_default_connection=True)
|
|
40
41
|
print_api("Returned default DNS gateway...", color='blue')
|
|
41
42
|
|
|
43
|
+
print_api(RECS_PROCESS_INSTANCE.is_alive())
|
|
44
|
+
RECS_PROCESS_INSTANCE.terminate()
|
|
45
|
+
RECS_PROCESS_INSTANCE.join()
|
|
46
|
+
|
|
42
47
|
|
|
43
48
|
def mitm_server(config_file_path: str):
|
|
44
|
-
on_exit.register_exit_handler(exit_cleanup)
|
|
49
|
+
on_exit.register_exit_handler(exit_cleanup, at_exit=False)
|
|
45
50
|
|
|
46
51
|
# Main function should return integer with error code, 0 is successful.
|
|
47
52
|
# Since listening server is infinite, this will not be reached.
|
|
@@ -54,14 +59,7 @@ def mitm_server(config_file_path: str):
|
|
|
54
59
|
return result
|
|
55
60
|
|
|
56
61
|
global MITM_ERROR_LOGGER
|
|
57
|
-
MITM_ERROR_LOGGER = loggingw.
|
|
58
|
-
logger_name=EXCEPTIONS_CSV_LOGGER_NAME,
|
|
59
|
-
directory_path=config_static.LogRec.logs_path,
|
|
60
|
-
file_type="csv",
|
|
61
|
-
add_timedfile=True,
|
|
62
|
-
formatter_filehandler='MESSAGE',
|
|
63
|
-
header=EXCEPTIONS_CSV_LOGGER_HEADER
|
|
64
|
-
)
|
|
62
|
+
MITM_ERROR_LOGGER = loggingw.ExceptionCsvLogger(EXCEPTIONS_CSV_LOGGER_NAME, config_static.LogRec.logs_path)
|
|
65
63
|
|
|
66
64
|
# Create folders.
|
|
67
65
|
filesystem.create_directory(config_static.LogRec.logs_path)
|
|
@@ -69,7 +67,8 @@ def mitm_server(config_file_path: str):
|
|
|
69
67
|
if config_static.LogRec.enable_request_response_recordings_in_logs:
|
|
70
68
|
filesystem.create_directory(config_static.LogRec.recordings_path)
|
|
71
69
|
# Compress recordings of the previous days if there are any.
|
|
72
|
-
|
|
70
|
+
global RECS_PROCESS_INSTANCE
|
|
71
|
+
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(config_static.LogRec.recordings_path)
|
|
73
72
|
|
|
74
73
|
if config_static.Certificates.sni_get_server_certificate_from_server_socket:
|
|
75
74
|
filesystem.create_directory(
|
|
@@ -335,7 +334,7 @@ def mitm_server(config_file_path: str):
|
|
|
335
334
|
global NETWORK_INTERFACE_IS_DYNAMIC, NETWORK_INTERFACE_IPV4_ADDRESS_LIST
|
|
336
335
|
NETWORK_INTERFACE_IS_DYNAMIC, NETWORK_INTERFACE_IPV4_ADDRESS_LIST = dns.get_default_dns_gateway()
|
|
337
336
|
if set_dns_gateway:
|
|
338
|
-
# Set the DNS gateway to the specified one only if the DNS gateway is dynamic or it is static but different
|
|
337
|
+
# Set the DNS gateway to the specified one only if the DNS gateway is dynamic, or it is static but different
|
|
339
338
|
# from the one specified in the configuration file.
|
|
340
339
|
if (NETWORK_INTERFACE_IS_DYNAMIC or (not NETWORK_INTERFACE_IS_DYNAMIC and
|
|
341
340
|
NETWORK_INTERFACE_IPV4_ADDRESS_LIST != dns_gateway_server_list)):
|
|
@@ -374,7 +373,8 @@ def _loop_at_midnight_recs_archive():
|
|
|
374
373
|
# If it's midnight, start the archiving process.
|
|
375
374
|
if current_date != previous_date:
|
|
376
375
|
if config_static.LogRec.enable_request_response_recordings_in_logs:
|
|
377
|
-
|
|
376
|
+
global RECS_PROCESS_INSTANCE
|
|
377
|
+
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(config_static.LogRec.recordings_path)
|
|
378
378
|
# Update the previous date.
|
|
379
379
|
previous_date = current_date
|
|
380
380
|
# Sleep for 1 minute.
|
|
@@ -387,9 +387,11 @@ def mitm_server_main(config_file_path: str):
|
|
|
387
387
|
return mitm_server(config_file_path)
|
|
388
388
|
except KeyboardInterrupt:
|
|
389
389
|
print_api("Server Stopped by [KeyboardInterrupt].", color='blue')
|
|
390
|
+
exit_cleanup()
|
|
390
391
|
return 0
|
|
391
392
|
except Exception as e:
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
MITM_ERROR_LOGGER.
|
|
395
|
-
|
|
393
|
+
RECS_PROCESS_INSTANCE.terminate()
|
|
394
|
+
|
|
395
|
+
MITM_ERROR_LOGGER.write(e)
|
|
396
|
+
exit_cleanup()
|
|
397
|
+
return 1
|
atomicshop/mitm/recs_files.py
CHANGED
|
@@ -64,10 +64,11 @@ def recs_archiver(recs_directory: str) -> list:
|
|
|
64
64
|
return archived_files
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
def recs_archiver_in_process(recs_directory: str):
|
|
67
|
+
def recs_archiver_in_process(recs_directory: str) -> multiprocessing.Process:
|
|
68
68
|
"""
|
|
69
69
|
Archive recs files in a directory for each day in a separate process.
|
|
70
70
|
"""
|
|
71
71
|
|
|
72
72
|
process = multiprocessing.Process(target=recs_archiver, args=(recs_directory,))
|
|
73
73
|
process.start()
|
|
74
|
+
return process
|
atomicshop/on_exit.py
CHANGED
|
@@ -91,25 +91,54 @@ class ExitHandler:
|
|
|
91
91
|
# Exit the process gracefully
|
|
92
92
|
raise SystemExit(0)
|
|
93
93
|
|
|
94
|
-
def register_handlers(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
def register_handlers(
|
|
95
|
+
self,
|
|
96
|
+
at_exit: bool = True,
|
|
97
|
+
console_close: bool = True,
|
|
98
|
+
kill_signal: bool = True
|
|
99
|
+
):
|
|
100
|
+
"""
|
|
101
|
+
Register the exit handlers.
|
|
102
|
+
|
|
103
|
+
:param at_exit: Register the atexit handler.
|
|
104
|
+
Just remember that the atexit handler will be called right away on [Ctrl+C], meaning if you want to do
|
|
105
|
+
something specifically on KeyboardInterrupt, you should handle it separately and set this parameter to False.
|
|
106
|
+
Same goes for all the exceptions.
|
|
107
|
+
:param console_close: Register the console close handler.
|
|
108
|
+
:param kill_signal: Register the kill signal handler.
|
|
109
|
+
"""
|
|
110
|
+
if at_exit:
|
|
111
|
+
atexit.register(self.atexit_handler)
|
|
112
|
+
if console_close:
|
|
113
|
+
win32api.SetConsoleCtrlHandler(self.console_handler, True)
|
|
114
|
+
if kill_signal:
|
|
115
|
+
signal.signal(signal.SIGINT, self.signal_handler)
|
|
116
|
+
signal.signal(signal.SIGTERM, self.signal_handler)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def register_exit_handler(
|
|
120
|
+
clean_up_function,
|
|
121
|
+
at_exit: bool = True,
|
|
122
|
+
console_close: bool = True,
|
|
123
|
+
kill_signal: bool = True,
|
|
124
|
+
*args, **kwargs):
|
|
102
125
|
"""
|
|
103
126
|
This function will register the exit handler to handle exit events: Closing the console, pressing 'CTRL+C',
|
|
104
127
|
Killing the process.
|
|
105
128
|
|
|
106
129
|
:param clean_up_function: The action to run when one of exit types is triggered.
|
|
130
|
+
:param at_exit: Register the atexit handler.
|
|
131
|
+
Just remember that the atexit handler will be called right away on [Ctrl+C], meaning if you want to do something
|
|
132
|
+
specifically on KeyboardInterrupt, you should handle it separately and set this parameter to False.
|
|
133
|
+
Same goes for all the exceptions.
|
|
134
|
+
:param console_close: Register the console close handler.
|
|
135
|
+
:param kill_signal: Register the kill signal handler.
|
|
107
136
|
:param args: The arguments to pass to the cleanup action.
|
|
108
137
|
:param kwargs: The keyword arguments to pass to the cleanup action.
|
|
109
138
|
"""
|
|
110
139
|
global EXIT_HANDLER_INSTANCE
|
|
111
140
|
EXIT_HANDLER_INSTANCE = ExitHandler(clean_up_function, args, kwargs)
|
|
112
|
-
EXIT_HANDLER_INSTANCE.register_handlers()
|
|
141
|
+
EXIT_HANDLER_INSTANCE.register_handlers(at_exit=at_exit, console_close=console_close, kill_signal=kill_signal)
|
|
113
142
|
|
|
114
143
|
|
|
115
144
|
def restart_function(callable_function, *args, **kwargs):
|
atomicshop/print_api.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import sys
|
|
2
|
+
import logging
|
|
2
3
|
|
|
3
4
|
from .basics.ansi_escape_codes import ColorsBasic, get_colors_basic_dict
|
|
5
|
+
from .wrappers.loggingw import handlers
|
|
4
6
|
from .basics import tracebacks
|
|
5
7
|
|
|
6
8
|
|
|
@@ -94,6 +96,20 @@ def print_api(
|
|
|
94
96
|
from bidi.algorithm import get_display
|
|
95
97
|
message = get_display(message)
|
|
96
98
|
|
|
99
|
+
if logger_method == 'error' or logger_method == 'critical':
|
|
100
|
+
error_type = True
|
|
101
|
+
|
|
102
|
+
# If exception was raised and 'stderr=True'.
|
|
103
|
+
if sys.exc_info()[0] is not None and stderr and traceback_string:
|
|
104
|
+
# If 'traceback' is set to 'True', we'll output traceback of exception.
|
|
105
|
+
if traceback_string:
|
|
106
|
+
if message:
|
|
107
|
+
message = f'{message}\n{tracebacks.get_as_string()}{message}'
|
|
108
|
+
else:
|
|
109
|
+
message = tracebacks.get_as_string()
|
|
110
|
+
|
|
111
|
+
color = 'red'
|
|
112
|
+
|
|
97
113
|
# If 'stdcolor' is 'True', the console output will be colored.
|
|
98
114
|
if stdcolor:
|
|
99
115
|
# If 'logger.error' should be outputted to console, and 'color' wasn't selected, then set color to 'yellow'.
|
|
@@ -103,19 +119,24 @@ def print_api(
|
|
|
103
119
|
elif logger_method == 'critical' and not color:
|
|
104
120
|
color = 'red'
|
|
105
121
|
|
|
106
|
-
if color:
|
|
122
|
+
if color and not logger:
|
|
107
123
|
message = get_colors_basic_dict(color) + message + ColorsBasic.END
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
elif color and logger:
|
|
125
|
+
# Save the original formatter
|
|
126
|
+
original_formatter = None
|
|
127
|
+
|
|
128
|
+
# Find the stream handler and change its formatter
|
|
129
|
+
# noinspection PyUnresolvedReferences
|
|
130
|
+
for handler in logger.handlers:
|
|
131
|
+
if isinstance(handler, logging.StreamHandler):
|
|
132
|
+
# Save the original formatter
|
|
133
|
+
original_formatter = handler.formatter
|
|
134
|
+
original_formatter_string = handlers.get_formatter_string(handler)
|
|
135
|
+
|
|
136
|
+
# Create a colored formatter for errors
|
|
137
|
+
color_formatter = logging.Formatter(
|
|
138
|
+
get_colors_basic_dict(color) + original_formatter_string + ColorsBasic.END)
|
|
139
|
+
handler.setFormatter(color_formatter)
|
|
119
140
|
|
|
120
141
|
# If 'online' is set to 'True', we'll output message as oneline.
|
|
121
142
|
if oneline:
|
|
@@ -130,6 +151,13 @@ def print_api(
|
|
|
130
151
|
if print_end == '\n':
|
|
131
152
|
# Use logger to output message.
|
|
132
153
|
getattr(logger, logger_method)(message)
|
|
154
|
+
|
|
155
|
+
if stdcolor:
|
|
156
|
+
# Restore the original formatter after logging
|
|
157
|
+
# noinspection PyUnresolvedReferences
|
|
158
|
+
for handler in logger.handlers:
|
|
159
|
+
if isinstance(handler, logging.StreamHandler):
|
|
160
|
+
handler.setFormatter(original_formatter)
|
|
133
161
|
# If logger wasn't passed.
|
|
134
162
|
else:
|
|
135
163
|
# Use print to output the message.
|
|
@@ -155,3 +155,15 @@ def get_logging_formatter_from_string(
|
|
|
155
155
|
return NanosecondsFormatter(formatter, style=style, datefmt=datefmt, use_nanoseconds=use_nanoseconds)
|
|
156
156
|
else:
|
|
157
157
|
return logging.Formatter(formatter, style=style, datefmt=datefmt)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def get_formatter_string(formatter) -> str:
|
|
161
|
+
"""
|
|
162
|
+
Function to get the formatter string from the 'logging.Formatter'.
|
|
163
|
+
|
|
164
|
+
:param formatter: logging.Formatter, formatter to convert to string.
|
|
165
|
+
:return: str, formatter string.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
# noinspection PyProtectedMember
|
|
169
|
+
return formatter._fmt
|
|
@@ -472,3 +472,13 @@ def add_filter_to_handler(handler: logging.Handler, filter_object: logging.Filte
|
|
|
472
472
|
"""
|
|
473
473
|
|
|
474
474
|
handler.addFilter(filter_object)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def get_formatter_string(handler: logging.Handler) -> str:
|
|
478
|
+
"""
|
|
479
|
+
Function to get the formatter string from the handler.
|
|
480
|
+
:param handler: Handler to get the formatter from.
|
|
481
|
+
:return: Formatter string.
|
|
482
|
+
"""
|
|
483
|
+
|
|
484
|
+
return formatters.get_formatter_string(handler.formatter)
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
from typing import Literal, Union
|
|
4
|
+
import datetime
|
|
4
5
|
|
|
5
6
|
from . import loggers, handlers
|
|
7
|
+
from ...file_io import csvs
|
|
8
|
+
from ...basics import tracebacks
|
|
9
|
+
from ...print_api import print_api
|
|
6
10
|
|
|
7
11
|
|
|
8
12
|
class LoggingwLoggerAlreadyExistsError(Exception):
|
|
@@ -258,3 +262,97 @@ def get_datetime_format_string_from_logger_file_handlers(logger: logging.Logger)
|
|
|
258
262
|
datetime_format_strings.append(date_time_format_string)
|
|
259
263
|
|
|
260
264
|
return datetime_format_strings
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def is_logger_exists(logger_name: str) -> bool:
|
|
268
|
+
"""
|
|
269
|
+
Function to check if the logger exists.
|
|
270
|
+
:param logger_name: Name of the logger.
|
|
271
|
+
:return: True if the logger exists, False if it doesn't.
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
return loggers.is_logger_exists(logger_name)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class ExceptionCsvLogger:
|
|
278
|
+
def __init__(
|
|
279
|
+
self,
|
|
280
|
+
logger_name: str,
|
|
281
|
+
custom_header: str = None,
|
|
282
|
+
directory_path: str = None
|
|
283
|
+
):
|
|
284
|
+
"""
|
|
285
|
+
Initialize the ExceptionCsvLogger object.
|
|
286
|
+
|
|
287
|
+
:param logger_name: Name of the logger.
|
|
288
|
+
:param custom_header: Custom header to write to the log file.
|
|
289
|
+
If None, the default header will be used: "timestamp,exception", since that what is written to the log file.
|
|
290
|
+
If you want to add more columns to the csv file, you can provide a custom header:
|
|
291
|
+
"custom1,custom2,custom3".
|
|
292
|
+
These will be added to the default header as:
|
|
293
|
+
"timestamp,custom1,custom2,custom3,exception".
|
|
294
|
+
:param directory_path: Directory path where the log file will be saved.
|
|
295
|
+
You can leave it as None, but if the logger doesn't exist, you will get an exception.
|
|
296
|
+
"""
|
|
297
|
+
|
|
298
|
+
if custom_header:
|
|
299
|
+
self.header = f"timestamp,{custom_header},exception"
|
|
300
|
+
else:
|
|
301
|
+
self.header = "timestamp,exception"
|
|
302
|
+
|
|
303
|
+
if is_logger_exists(logger_name):
|
|
304
|
+
self.logger = get_logger_with_level(logger_name)
|
|
305
|
+
else:
|
|
306
|
+
if directory_path is None:
|
|
307
|
+
raise ValueError("You need to provide 'directory_path' if the logger doesn't exist.")
|
|
308
|
+
|
|
309
|
+
self.logger = create_logger(
|
|
310
|
+
logger_name=logger_name,
|
|
311
|
+
directory_path=directory_path,
|
|
312
|
+
file_type="csv",
|
|
313
|
+
add_timedfile=True,
|
|
314
|
+
formatter_filehandler='MESSAGE',
|
|
315
|
+
header=self.header)
|
|
316
|
+
|
|
317
|
+
def write(
|
|
318
|
+
self,
|
|
319
|
+
message: Union[str, Exception] = None,
|
|
320
|
+
custom_csv_string: str = None,
|
|
321
|
+
stdout: bool = True
|
|
322
|
+
):
|
|
323
|
+
"""
|
|
324
|
+
Write the message to the log file.
|
|
325
|
+
|
|
326
|
+
:param message: The message to write to the log file.
|
|
327
|
+
If None, the message will be retrieved from current traceback frame.
|
|
328
|
+
:param custom_csv_string: Custom CSV string to add between the timestamp and the exception.
|
|
329
|
+
Currently, without the 'custom_csv_string', the csv line written as "timestamp,exception" as the header.
|
|
330
|
+
If you add a 'custom_csv_string', the csv line will be written as "timestamp,custom_csv_string,exception".
|
|
331
|
+
Meaning, that you need to provide the 'custom_header' during the initialization of the object.
|
|
332
|
+
Off course, you can use as many commas as you need in the 'custom_csv_string': "custom1,custom2,custom3".
|
|
333
|
+
This need to be mirrored in the 'custom_header' as well: "custom1,custom2,custom3".
|
|
334
|
+
:param stdout: If set to True, the exception will be printed to the console.
|
|
335
|
+
"""
|
|
336
|
+
|
|
337
|
+
if message is None or isinstance(message, Exception):
|
|
338
|
+
message = tracebacks.get_as_string()
|
|
339
|
+
|
|
340
|
+
if custom_csv_string:
|
|
341
|
+
output_csv_line: str = csvs.escape_csv_line_to_string([datetime.datetime.now(), custom_csv_string, message])
|
|
342
|
+
else:
|
|
343
|
+
output_csv_line: str = csvs.escape_csv_line_to_string([datetime.datetime.now(), message])
|
|
344
|
+
|
|
345
|
+
# If the number of cells in the 'output_csv_line' doesn't match the number of cells in the 'header',
|
|
346
|
+
# raise an exception.
|
|
347
|
+
if (csvs.get_number_of_cells_in_string_line(output_csv_line) !=
|
|
348
|
+
csvs.get_number_of_cells_in_string_line(self.header)):
|
|
349
|
+
raise ValueError(
|
|
350
|
+
"Number of cells in the 'output_csv_line' doesn't match the number of cells in the 'header'.")
|
|
351
|
+
|
|
352
|
+
self.logger.info(output_csv_line)
|
|
353
|
+
|
|
354
|
+
if stdout:
|
|
355
|
+
print_api('', error_type=True, color="red", traceback_string=True)
|
|
356
|
+
|
|
357
|
+
def get_logger(self):
|
|
358
|
+
return self.logger
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=RKrFOzhIp5E7tjs7oJStRgnGRfLQJGazFO71-p0tK_o,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
|
|
@@ -23,9 +23,9 @@ atomicshop/http_parse.py,sha256=nrf2rZcprLqtW8HVrV7TCZ1iTBcWRRy-mXIlAOzcaJs,9703
|
|
|
23
23
|
atomicshop/inspect_wrapper.py,sha256=sGRVQhrJovNygHTydqJj0hxES-aB2Eg9KbIk3G31apw,11429
|
|
24
24
|
atomicshop/ip_addresses.py,sha256=Hvi4TumEFoTEpKWaq5WNF-YzcRzt24IxmNgv-Mgax1s,1190
|
|
25
25
|
atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,452
|
|
26
|
-
atomicshop/on_exit.py,sha256=
|
|
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=Bny4BpkD9dwa8FRTKAibTLMWJp38M9BsVrOpJNFSWTw,13010
|
|
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
|
|
@@ -114,7 +114,7 @@ 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=XFZ-kvg2nWLXUpFh_FyPwOXB_TYLFRrHpS5hWMblTi8,9353
|
|
118
118
|
atomicshop/file_io/docxs.py,sha256=ffJhnmM_WyD8mCoq2dGdpfahdIrGTPy96QVlH5EWjeI,5754
|
|
119
119
|
atomicshop/file_io/file_io.py,sha256=IVqs0Kd7PV8O-NH9321hK_IvPqWx2z_45zdDtqgw4II,7113
|
|
120
120
|
atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
|
|
@@ -128,8 +128,8 @@ atomicshop/mitm/connection_thread_worker.py,sha256=rfullUfMRR5YUEI45KJdGXlbOGYF8
|
|
|
128
128
|
atomicshop/mitm/import_config.py,sha256=_nu8mgA-M4s6dZ8_QWx3x0aVb75upvsCuX_PIUg4X2w,8345
|
|
129
129
|
atomicshop/mitm/initialize_engines.py,sha256=VyJE8QnzlgD3QbX5inz5o6rC3zQ3is9CeTL7-B10g1w,8292
|
|
130
130
|
atomicshop/mitm/message.py,sha256=d_sm3O_aoZf87dDQP44xOMNEG-uZBN1ZecQgMCacbZs,1814
|
|
131
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
132
|
-
atomicshop/mitm/recs_files.py,sha256=
|
|
131
|
+
atomicshop/mitm/mitm_main.py,sha256=L8fcFNU_azIJepymb3JZRnfvvRIsUf1gWNcFQKeQTcs,21876
|
|
132
|
+
atomicshop/mitm/recs_files.py,sha256=VjgtJF7vy365mBjctwB2bpDYoLMkEeogzF8kbb01dAk,2977
|
|
133
133
|
atomicshop/mitm/shared_functions.py,sha256=jjCDZVQCwQ8hf9QNMe3T8W3ISkfZo4Mm2HtXOJLZYgI,1999
|
|
134
134
|
atomicshop/mitm/statistic_analyzer.py,sha256=mBmwEe68WAjnIskGndQTRldnsAsDHuaOW0O7UXlM3Pc,26702
|
|
135
135
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -246,10 +246,10 @@ atomicshop/wrappers/fibratusw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
246
246
|
atomicshop/wrappers/fibratusw/install.py,sha256=PLVymDe0HuOvU0r2lje8BkQAgtiOWEeRO7n-1zKuL7A,3287
|
|
247
247
|
atomicshop/wrappers/loggingw/consts.py,sha256=JWiUJEydjhwatBxtIJsGTmDUSTLbmIRidtR6qRLMaIY,1608
|
|
248
248
|
atomicshop/wrappers/loggingw/filters.py,sha256=CMs5PAMb68zxJgBcQobaOFDG5kLJBOVYnoBHjDgksO8,2859
|
|
249
|
-
atomicshop/wrappers/loggingw/formatters.py,sha256=
|
|
250
|
-
atomicshop/wrappers/loggingw/handlers.py,sha256=
|
|
249
|
+
atomicshop/wrappers/loggingw/formatters.py,sha256=ZY12IokVY1G_Wzn2Zlv9qjK-e8CtIK6yUgUfPHvH2BU,5802
|
|
250
|
+
atomicshop/wrappers/loggingw/handlers.py,sha256=AsltQH17cAhgexVaR2TJtSaD2Xlw8QNiv_hKIo6ZF7s,18450
|
|
251
251
|
atomicshop/wrappers/loggingw/loggers.py,sha256=mmM__XR3W4QC82wbsDRG_M4_0JYGGEP0Qn0WCOSp-go,2910
|
|
252
|
-
atomicshop/wrappers/loggingw/loggingw.py,sha256=
|
|
252
|
+
atomicshop/wrappers/loggingw/loggingw.py,sha256=OTar1pwc-qxPal2yMjMvK1rzvtpcQzVwTxSckt-90_Q,16289
|
|
253
253
|
atomicshop/wrappers/loggingw/reading.py,sha256=ERBSiQbEksySKpXpu2E_6k9dZ6MPH95ZIsmdjWW9MUE,16436
|
|
254
254
|
atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
255
255
|
atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=3ZPqrXxj3lC-PnAKGXclylLuOqsbyXYeUpb5iGjdeUU,6626
|
|
@@ -309,8 +309,8 @@ atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0L
|
|
|
309
309
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
|
|
310
310
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
311
311
|
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.
|
|
312
|
+
atomicshop-2.16.28.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
313
|
+
atomicshop-2.16.28.dist-info/METADATA,sha256=dd_ZbiMXylLwEVatyDQXjaRPx_RJRFbOtELFjVKRYzk,10473
|
|
314
|
+
atomicshop-2.16.28.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
315
|
+
atomicshop-2.16.28.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
316
|
+
atomicshop-2.16.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|