atomicshop 2.12.14__py3-none-any.whl → 2.12.16__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 +4 -2
- atomicshop/monitor/change_monitor.py +1 -2
- atomicshop/monitor/checks/dns.py +2 -2
- atomicshop/wrappers/loggingw/reading.py +61 -27
- {atomicshop-2.12.14.dist-info → atomicshop-2.12.16.dist-info}/METADATA +1 -1
- {atomicshop-2.12.14.dist-info → atomicshop-2.12.16.dist-info}/RECORD +10 -10
- {atomicshop-2.12.14.dist-info → atomicshop-2.12.16.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.12.14.dist-info → atomicshop-2.12.16.dist-info}/WHEEL +0 -0
- {atomicshop-2.12.14.dist-info → atomicshop-2.12.16.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/file_io/csvs.py
CHANGED
|
@@ -30,8 +30,10 @@ def read_csv_to_list_of_dicts_by_header(
|
|
|
30
30
|
:param file_mode: string, file reading mode. Examples: 'r', 'rb'. Default is 'r'.
|
|
31
31
|
:param encoding: string, encoding of the file. Default is 'None'.
|
|
32
32
|
:param header: list, list of strings that will be the header of the CSV file. Default is 'None'.
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
None: the header from the CSV file will be used. The first row of the CSV file will be the header.
|
|
34
|
+
Meaning, that the first line will be skipped and the second line will be the first row of the content.
|
|
35
|
+
List: the list will be used as header.
|
|
36
|
+
All the lines of the CSV file will be considered as content.
|
|
35
37
|
:param file_object: file object of the 'open()' function in the decorator. Decorator executes the 'with open()'
|
|
36
38
|
statement and passes to this function. That's why the default is 'None', since we get it from the decorator.
|
|
37
39
|
:return: list.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from typing import Literal, Union
|
|
2
|
+
import queue
|
|
2
3
|
|
|
3
4
|
from .checks import dns, network, hash, process_running
|
|
4
5
|
from .. import filesystem, scheduling
|
|
@@ -177,8 +178,6 @@ class ChangeMonitor:
|
|
|
177
178
|
self.fetch_engine = None
|
|
178
179
|
self.thread_looper = scheduling.ThreadLooper()
|
|
179
180
|
|
|
180
|
-
self.statistics_queue = None
|
|
181
|
-
|
|
182
181
|
def _set_input_file_path(self, check_object_index: int = 0):
|
|
183
182
|
if self.first_cycle:
|
|
184
183
|
# If 'input_file_directory' and 'input_file_name' are specified, we'll use a filename to store.
|
atomicshop/monitor/checks/dns.py
CHANGED
|
@@ -32,8 +32,8 @@ def _execute_cycle(change_monitor_instance, print_kwargs: dict = None):
|
|
|
32
32
|
|
|
33
33
|
# Since the 'operation_type' is 'hit_statistics', we'll set the 'statistics_queue' to the 'statistics_queue' of
|
|
34
34
|
# the 'diff_check_list[0]'.
|
|
35
|
-
if change_monitor_instance.diff_check_list[0].operation_type == 'hit_statistics':
|
|
36
|
-
|
|
35
|
+
# if change_monitor_instance.diff_check_list[0].operation_type == 'hit_statistics':
|
|
36
|
+
# change_monitor_instance.statistics_queue = change_monitor_instance.diff_check_list[0].statistics_queue
|
|
37
37
|
|
|
38
38
|
if change_monitor_instance.generate_input_file_name:
|
|
39
39
|
original_name = 'known_domains'
|
|
@@ -7,6 +7,7 @@ from ...file_io import csvs
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
READING_EXISTING_LINES: list = []
|
|
10
|
+
EXISTING_LOGS_FILE_COUNT: int = 0
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def get_logs_paths(
|
|
@@ -80,7 +81,8 @@ def get_logs_paths(
|
|
|
80
81
|
current_file_name: str = Path(single_file['file_path']).name
|
|
81
82
|
# Get the datetime object from the file name by the date pattern.
|
|
82
83
|
try:
|
|
83
|
-
datetime_object = datetimes.get_datetime_from_complex_string_by_pattern(
|
|
84
|
+
datetime_object = datetimes.get_datetime_from_complex_string_by_pattern(
|
|
85
|
+
current_file_name, date_pattern)
|
|
84
86
|
timestamp_float = datetime_object.timestamp()
|
|
85
87
|
# ValueError will be raised if the date pattern does not match the file name.
|
|
86
88
|
except ValueError:
|
|
@@ -210,7 +212,8 @@ def get_latest_lines(
|
|
|
210
212
|
log_file_path: str,
|
|
211
213
|
date_pattern: str = None,
|
|
212
214
|
log_type: Literal['csv'] = 'csv',
|
|
213
|
-
get_previous_file: bool = False
|
|
215
|
+
get_previous_file: bool = False,
|
|
216
|
+
header: list = None
|
|
214
217
|
) -> tuple:
|
|
215
218
|
"""
|
|
216
219
|
This function gets the latest lines from the log file.
|
|
@@ -225,6 +228,11 @@ def get_latest_lines(
|
|
|
225
228
|
Meaning, once the day will change, the function will get the log file from the previous day in the third entry
|
|
226
229
|
of the return tuple. This happens only once each 24 hours. Not from the time the function was called, but from
|
|
227
230
|
the time the day changed.
|
|
231
|
+
:param header: List of strings that will be the header of the CSV file. Default is 'None'.
|
|
232
|
+
None: the header from the CSV file will be used. The first row of the CSV file will be the header.
|
|
233
|
+
Meaning, that the first line will be skipped and the second line will be the first row of the content.
|
|
234
|
+
List: the list will be used as header.
|
|
235
|
+
All the lines of the CSV file will be considered as content.
|
|
228
236
|
return: List of new lines.
|
|
229
237
|
|
|
230
238
|
Usage:
|
|
@@ -243,6 +251,31 @@ def get_latest_lines(
|
|
|
243
251
|
time.sleep(1)
|
|
244
252
|
"""
|
|
245
253
|
|
|
254
|
+
def extract_new_lines_only(content_lines: list):
|
|
255
|
+
new_lines: list = []
|
|
256
|
+
for row in content_lines:
|
|
257
|
+
# If the row is not in the existing lines, then add it to the new lines.
|
|
258
|
+
if row not in READING_EXISTING_LINES:
|
|
259
|
+
new_lines.append(row)
|
|
260
|
+
|
|
261
|
+
if new_lines:
|
|
262
|
+
READING_EXISTING_LINES.extend(new_lines)
|
|
263
|
+
|
|
264
|
+
return new_lines
|
|
265
|
+
|
|
266
|
+
global EXISTING_LOGS_FILE_COUNT
|
|
267
|
+
|
|
268
|
+
# If the existing logs file count is 0, it means that this is the first check. We need to get the current count.
|
|
269
|
+
if EXISTING_LOGS_FILE_COUNT == 0:
|
|
270
|
+
EXISTING_LOGS_FILE_COUNT = len(get_logs_paths(
|
|
271
|
+
log_file_path=log_file_path,
|
|
272
|
+
log_type='csv'
|
|
273
|
+
))
|
|
274
|
+
|
|
275
|
+
# If the count is still 0, then there are no logs to read.
|
|
276
|
+
if EXISTING_LOGS_FILE_COUNT == 0:
|
|
277
|
+
return [], [], header
|
|
278
|
+
|
|
246
279
|
if log_type != 'csv':
|
|
247
280
|
raise ValueError('Only "csv" log type is supported.')
|
|
248
281
|
|
|
@@ -256,9 +289,6 @@ def get_latest_lines(
|
|
|
256
289
|
latest_only=True
|
|
257
290
|
)
|
|
258
291
|
|
|
259
|
-
if not latest_statistics_file_path_object:
|
|
260
|
-
return [], [], [], []
|
|
261
|
-
|
|
262
292
|
latest_statistics_file_path: str = latest_statistics_file_path_object[0]['file_path']
|
|
263
293
|
|
|
264
294
|
# Get the previous day statistics file path.
|
|
@@ -273,32 +303,36 @@ def get_latest_lines(
|
|
|
273
303
|
except KeyError:
|
|
274
304
|
pass
|
|
275
305
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
306
|
+
# Count all the rotated files.
|
|
307
|
+
current_log_files_count: int = len(get_logs_paths(
|
|
308
|
+
log_file_path=log_file_path,
|
|
309
|
+
log_type='csv'
|
|
310
|
+
))
|
|
311
|
+
|
|
312
|
+
# If the count of the log files is greater than the existing logs file count, it means that the rotation happened.
|
|
313
|
+
# We will read the previous day statistics file.
|
|
314
|
+
new_lines_from_previous_file: list = []
|
|
315
|
+
if current_log_files_count > EXISTING_LOGS_FILE_COUNT:
|
|
316
|
+
current_lines, header = csvs.read_csv_to_list_of_dicts_by_header(
|
|
317
|
+
previous_day_statistics_file_path, header=header, stdout=False)
|
|
288
318
|
|
|
289
319
|
if get_previous_file:
|
|
290
320
|
previous_file_lines = current_lines
|
|
291
321
|
|
|
292
|
-
|
|
322
|
+
EXISTING_LOGS_FILE_COUNT = current_log_files_count
|
|
293
323
|
|
|
294
|
-
|
|
295
|
-
if current_lines:
|
|
296
|
-
for row in current_lines:
|
|
297
|
-
# If the row is not in the existing lines, then add it to the new lines.
|
|
298
|
-
if row not in READING_EXISTING_LINES:
|
|
299
|
-
new_lines.append(row)
|
|
324
|
+
new_lines_from_previous_file = extract_new_lines_only(current_lines)
|
|
300
325
|
|
|
301
|
-
|
|
302
|
-
|
|
326
|
+
# empty the previous file lines, since the file is rotated.
|
|
327
|
+
READING_EXISTING_LINES.clear()
|
|
328
|
+
|
|
329
|
+
current_lines, header = csvs.read_csv_to_list_of_dicts_by_header(
|
|
330
|
+
latest_statistics_file_path, header=header, stdout=False)
|
|
331
|
+
|
|
332
|
+
new_lines = extract_new_lines_only(current_lines)
|
|
333
|
+
|
|
334
|
+
# If we have new lines from the previous file, we will add the new lines from the latest file.
|
|
335
|
+
if new_lines_from_previous_file:
|
|
336
|
+
new_lines = new_lines_from_previous_file + new_lines
|
|
303
337
|
|
|
304
|
-
return new_lines,
|
|
338
|
+
return new_lines, previous_file_lines, header
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=Z-gJW-h7oTdZn_6KXbNYPQPfdC6kDWJvf5xxT1uoArA,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
|
|
@@ -104,7 +104,7 @@ atomicshop/etw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
104
104
|
atomicshop/etw/dns_trace.py,sha256=I4OZsiZUDyj7B4fKTOqsB1tcX1DUMw9uh4CwXlcmHfY,5571
|
|
105
105
|
atomicshop/etw/etw.py,sha256=xVJNbfCq4KgRfsDnul6CrIdAMl9xRBixZ-hUyqiB2g4,2403
|
|
106
106
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
107
|
-
atomicshop/file_io/csvs.py,sha256=
|
|
107
|
+
atomicshop/file_io/csvs.py,sha256=WOtDyVFhhA1RD3yrU9P33kDY1EKFEz8UmVCUkqYKuog,5503
|
|
108
108
|
atomicshop/file_io/docxs.py,sha256=6tcYFGp0vRsHR47VwcRqwhdt2DQOwrAUYhrwN996n9U,5117
|
|
109
109
|
atomicshop/file_io/file_io.py,sha256=FR84ihjGlr7Eqejo-_js4nBICVst31axD0bwX19S2eM,6385
|
|
110
110
|
atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
|
|
@@ -132,9 +132,9 @@ atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256
|
|
|
132
132
|
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=KENDVf9OwXD9gwSh4B1XxACCe7iHYjrvnW1t6F64wdE,695
|
|
133
133
|
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=1AM49UaFTKA0AHw-k3SV3uH3QbG-o6ux0c-GoWkKNU0,6993
|
|
134
134
|
atomicshop/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
135
|
-
atomicshop/monitor/change_monitor.py,sha256=
|
|
135
|
+
atomicshop/monitor/change_monitor.py,sha256=FUAolHTWVFfC14K2cTMK1NE6ORp37A0fCrfwNbxmbIs,12221
|
|
136
136
|
atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
137
|
-
atomicshop/monitor/checks/dns.py,sha256=
|
|
137
|
+
atomicshop/monitor/checks/dns.py,sha256=wX53eGX2F5_lBDLL5D6dFb3XThdt3iwoYKnP05WZKfc,4870
|
|
138
138
|
atomicshop/monitor/checks/hash.py,sha256=A6bJ7F5Qv_brdEh3sGhOyfviab2dsnvbXUufyBk5C1U,1951
|
|
139
139
|
atomicshop/monitor/checks/network.py,sha256=I9f3KyNnlx97E8igGZXpVJl4MlUp9iU6aSbILCKqbA0,3820
|
|
140
140
|
atomicshop/monitor/checks/process_running.py,sha256=948Sify4P2KFTE1ZrLHKLwd1B1HOgWmC11x3b6MCvz0,1892
|
|
@@ -216,7 +216,7 @@ atomicshop/wrappers/loggingw/formatters.py,sha256=mUtcJJfmhLNrwUVYShXTmdu40dBaJu
|
|
|
216
216
|
atomicshop/wrappers/loggingw/handlers.py,sha256=qm5Fbu8eDmlstMduUe5nKUlJU5IazFkSnQizz8Qt2os,5479
|
|
217
217
|
atomicshop/wrappers/loggingw/loggers.py,sha256=DHOOTAtqkwn1xgvLHSkOiBm6yFGNuQy1kvbhG-TDog8,2374
|
|
218
218
|
atomicshop/wrappers/loggingw/loggingw.py,sha256=v9WAseZXB50LluT9rIUcRvvevg2nLVKPgz3dbGejfV0,12151
|
|
219
|
-
atomicshop/wrappers/loggingw/reading.py,sha256=
|
|
219
|
+
atomicshop/wrappers/loggingw/reading.py,sha256=CtYOwOLFHj_hqYyZx-dKUo5ZDrn3cO-f7vU4EX515xI,14980
|
|
220
220
|
atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
221
221
|
atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=QZg-R2iTQt7kFb8wNtnTmwraSGwvUs34JIasdbNa7ZU,5154
|
|
222
222
|
atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -251,8 +251,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
251
251
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
252
252
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
253
253
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
254
|
-
atomicshop-2.12.
|
|
255
|
-
atomicshop-2.12.
|
|
256
|
-
atomicshop-2.12.
|
|
257
|
-
atomicshop-2.12.
|
|
258
|
-
atomicshop-2.12.
|
|
254
|
+
atomicshop-2.12.16.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
255
|
+
atomicshop-2.12.16.dist-info/METADATA,sha256=Sxe0EOSeHGX8jfjldfji7N3m_tORqIzRpxLiy7npPCY,10479
|
|
256
|
+
atomicshop-2.12.16.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
257
|
+
atomicshop-2.12.16.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
258
|
+
atomicshop-2.12.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|