atomicshop 2.12.16__py3-none-any.whl → 2.12.17__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/diff_check.py +95 -49
- atomicshop/monitor/change_monitor.py +77 -134
- atomicshop/monitor/checks/dns.py +100 -82
- atomicshop/monitor/checks/hash.py +39 -28
- atomicshop/monitor/checks/hash_checks/file.py +34 -35
- atomicshop/monitor/checks/hash_checks/url.py +41 -39
- atomicshop/monitor/checks/network.py +30 -28
- atomicshop/monitor/checks/process_running.py +7 -7
- atomicshop/timer.py +30 -11
- {atomicshop-2.12.16.dist-info → atomicshop-2.12.17.dist-info}/METADATA +1 -1
- {atomicshop-2.12.16.dist-info → atomicshop-2.12.17.dist-info}/RECORD +15 -15
- {atomicshop-2.12.16.dist-info → atomicshop-2.12.17.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.12.16.dist-info → atomicshop-2.12.17.dist-info}/WHEEL +0 -0
- {atomicshop-2.12.16.dist-info → atomicshop-2.12.17.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/diff_check.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Union, Literal
|
|
|
4
4
|
import json
|
|
5
5
|
import queue
|
|
6
6
|
|
|
7
|
-
from . import filesystem,
|
|
7
|
+
from . import filesystem, timer
|
|
8
8
|
from .file_io import file_io, jsons
|
|
9
9
|
from .print_api import print_api
|
|
10
10
|
from .basics import list_of_dicts, dicts
|
|
@@ -29,7 +29,6 @@ class DiffChecker:
|
|
|
29
29
|
self,
|
|
30
30
|
check_object: any = None,
|
|
31
31
|
check_object_display_name: str = None,
|
|
32
|
-
aggregation: bool = False,
|
|
33
32
|
input_file_path: str = None,
|
|
34
33
|
input_file_write_only: bool = True,
|
|
35
34
|
return_first_cycle: bool = True,
|
|
@@ -38,11 +37,13 @@ class DiffChecker:
|
|
|
38
37
|
'hit_statistics',
|
|
39
38
|
'all_objects',
|
|
40
39
|
'single_object'] = None,
|
|
41
|
-
|
|
40
|
+
hit_statistics_input_file_rotation_cycle_hours: Union[
|
|
42
41
|
float,
|
|
43
42
|
Literal['midnight'],
|
|
44
43
|
None] = None,
|
|
45
|
-
|
|
44
|
+
hit_statistics_enable_queue: bool = False,
|
|
45
|
+
new_objects_hours_then_difference: float = None
|
|
46
|
+
|
|
46
47
|
):
|
|
47
48
|
"""
|
|
48
49
|
:param check_object: any, object to check if it changed.
|
|
@@ -85,11 +86,11 @@ class DiffChecker:
|
|
|
85
86
|
'single_object': will store the object as is, without any comparison. Meaning, that the object will be
|
|
86
87
|
compared only to itself, and if it changes, it will be updated.
|
|
87
88
|
None: Nothing will be done, you will get an exception.
|
|
88
|
-
:param
|
|
89
|
+
:param hit_statistics_input_file_rotation_cycle_hours:
|
|
89
90
|
float, the amount of hours the input file will be rotated in the 'hit_statistics' operation type.
|
|
90
91
|
str, (only 'midnight' is valid), the input file will be rotated daily at midnight.
|
|
91
92
|
This is valid only for the 'hit_statistics' operation type.
|
|
92
|
-
:param
|
|
93
|
+
:param hit_statistics_enable_queue: boolean, if True, the statistics queue will be enabled for the 'hit_statistics'
|
|
93
94
|
operation type. You can use this queue to process the statistics in another thread.
|
|
94
95
|
|
|
95
96
|
Example:
|
|
@@ -99,8 +100,8 @@ class DiffChecker:
|
|
|
99
100
|
input_file_write_only=True,
|
|
100
101
|
return_first_cycle=True,
|
|
101
102
|
operation_type='hit_statistics',
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
hit_statistics_input_file_rotation_cycle_hours='midnight',
|
|
104
|
+
hit_statistics_enable_queue=True)
|
|
104
105
|
|
|
105
106
|
def process_statistics_queue():
|
|
106
107
|
while True:
|
|
@@ -110,6 +111,12 @@ class DiffChecker:
|
|
|
110
111
|
threading.Thread(target=process_statistics_queue).start()
|
|
111
112
|
|
|
112
113
|
<... Your checking operation for the object ...>
|
|
114
|
+
:param new_objects_hours_then_difference: float, This is only for the 'new_objects' operation type.
|
|
115
|
+
If the object is not in the list of objects, it will be added to the list.
|
|
116
|
+
If the object is in the list of objects, it will be ignored.
|
|
117
|
+
After the specified amount of hours, new objects will not be added to the input file list, so each new
|
|
118
|
+
object will be outputted from the function. This is useful for checking new objects that are not
|
|
119
|
+
supposed to be in the list of objects, but you want to know about them.
|
|
113
120
|
|
|
114
121
|
--------------------------------------------------
|
|
115
122
|
|
|
@@ -180,61 +187,87 @@ class DiffChecker:
|
|
|
180
187
|
print(message)
|
|
181
188
|
"""
|
|
182
189
|
|
|
190
|
+
self.check_object = check_object
|
|
191
|
+
self.check_object_display_name = check_object_display_name
|
|
192
|
+
self.input_file_path: str = input_file_path
|
|
193
|
+
self.input_file_write_only: bool = input_file_write_only
|
|
194
|
+
self.return_first_cycle: bool = return_first_cycle
|
|
195
|
+
self.operation_type = operation_type
|
|
196
|
+
self.hit_statistics_input_file_rotation_cycle_hours = hit_statistics_input_file_rotation_cycle_hours
|
|
197
|
+
self.hit_statistics_enable_queue = hit_statistics_enable_queue
|
|
198
|
+
self.new_objects_hours_then_difference: float = new_objects_hours_then_difference
|
|
199
|
+
|
|
200
|
+
# Previous content.
|
|
201
|
+
self.previous_content: Union['list', 'str', None] = None
|
|
202
|
+
# The format the file will be saved as (not used as extension): txt, json.
|
|
203
|
+
self.save_as: str = str()
|
|
204
|
+
|
|
205
|
+
self.statistics_queue = None
|
|
206
|
+
self.previous_day = None
|
|
207
|
+
self.new_objects_seconds_then_difference: Union[float, None] = None
|
|
208
|
+
self.timer = None
|
|
209
|
+
|
|
210
|
+
def _static_pre_process(self):
|
|
211
|
+
"""
|
|
212
|
+
This function will be called before the actual checking of the object.
|
|
213
|
+
If you change any attribute of the class, you will need to call this function again.
|
|
214
|
+
"""
|
|
183
215
|
# 'check_object' can be none, so checking if it not equals empty string.
|
|
184
|
-
if check_object == "":
|
|
216
|
+
if self.check_object == "":
|
|
185
217
|
raise ValueError("[check_object] option can't be empty string.")
|
|
186
218
|
|
|
187
|
-
if operation_type and operation_type not in
|
|
219
|
+
if (self.operation_type and self.operation_type not in
|
|
220
|
+
['new_objects', 'hit_statistics', 'all_objects', 'single_object']):
|
|
188
221
|
raise ValueError(f"[operation_type] must be one of the following: "
|
|
189
222
|
f"'new_objects', 'hit_statistics', 'all_objects', 'single_object'.")
|
|
190
223
|
|
|
191
|
-
if
|
|
224
|
+
if self.hit_statistics_input_file_rotation_cycle_hours and self.operation_type != 'hit_statistics':
|
|
192
225
|
raise ValueError("[input_file_rotation_cycle] can be specified only for 'hit_statistics' operation type.")
|
|
193
226
|
|
|
194
|
-
if
|
|
195
|
-
raise ValueError("[
|
|
227
|
+
if self.hit_statistics_enable_queue and self.operation_type != 'hit_statistics':
|
|
228
|
+
raise ValueError("[hit_statistics_enable_queue] can be specified only for 'hit_statistics' operation type.")
|
|
196
229
|
|
|
197
|
-
if
|
|
198
|
-
not isinstance(
|
|
199
|
-
|
|
230
|
+
if (self.hit_statistics_input_file_rotation_cycle_hours and
|
|
231
|
+
not isinstance(self.hit_statistics_input_file_rotation_cycle_hours, float) and
|
|
232
|
+
not isinstance(self.hit_statistics_input_file_rotation_cycle_hours, int) and
|
|
233
|
+
self.hit_statistics_input_file_rotation_cycle_hours != 'midnight'):
|
|
200
234
|
raise ValueError("[input_file_rotation_cycle] must be float, int or 'midnight' str.")
|
|
201
235
|
|
|
202
|
-
self.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
self.input_file_path: str = input_file_path
|
|
206
|
-
self.input_file_write_only: bool = input_file_write_only
|
|
207
|
-
self.return_first_cycle: bool = return_first_cycle
|
|
208
|
-
self.operation_type = operation_type
|
|
209
|
-
self.input_file_rotation_cycle = input_file_rotation_cycle_hours
|
|
210
|
-
self.enable_statistics_queue = enable_statistics_queue
|
|
236
|
+
if self.new_objects_hours_then_difference and self.operation_type != 'new_objects':
|
|
237
|
+
raise ValueError(
|
|
238
|
+
"[new_objects_hours_then_difference] can be specified only for 'new_objects' operation type.")
|
|
211
239
|
|
|
212
240
|
if not self.check_object_display_name:
|
|
213
241
|
self.check_object_display_name = self.check_object
|
|
214
242
|
|
|
215
|
-
# Previous content.
|
|
216
|
-
self.previous_content: Union['list', 'str', None] = None
|
|
217
|
-
# The format the file will be saved as (not used as extension): txt, json.
|
|
218
|
-
self.save_as: str = str()
|
|
219
|
-
|
|
220
243
|
# If the input file rotation cycle is set and the statistics queue is enabled, we will create the queue.
|
|
221
|
-
if self.
|
|
244
|
+
if self.hit_statistics_input_file_rotation_cycle_hours and self.hit_statistics_enable_queue:
|
|
222
245
|
# You can use this queue to process the statistics in another thread.
|
|
223
246
|
self.statistics_queue = queue.Queue()
|
|
224
247
|
else:
|
|
225
248
|
self.statistics_queue = None
|
|
226
249
|
|
|
227
250
|
# If the input file rotation cycle is set to midnight, we will store the previous day as today.
|
|
228
|
-
if self.
|
|
251
|
+
if self.hit_statistics_input_file_rotation_cycle_hours == 'midnight':
|
|
229
252
|
self.previous_day = datetime.datetime.now().strftime('%d')
|
|
230
253
|
else:
|
|
231
254
|
self.previous_day = None
|
|
232
255
|
|
|
256
|
+
if self.new_objects_hours_then_difference and self.operation_type != 'new_objects':
|
|
257
|
+
raise ValueError("The 'new_objects_hours_then_difference' variable must be set for 'new_objects' operation type.")
|
|
258
|
+
|
|
259
|
+
if self.new_objects_hours_then_difference:
|
|
260
|
+
self.new_objects_seconds_then_difference = self.new_objects_hours_then_difference * 60 * 60
|
|
261
|
+
self.timer = timer.Timer()
|
|
262
|
+
self.timer.start()
|
|
263
|
+
|
|
233
264
|
def check_string(self, print_kwargs: dict = None):
|
|
234
265
|
"""
|
|
235
266
|
The function will check file content for change by hashing it and comparing the hash.
|
|
236
267
|
"""
|
|
237
268
|
|
|
269
|
+
self._static_pre_process()
|
|
270
|
+
|
|
238
271
|
if not isinstance(self.check_object, str):
|
|
239
272
|
raise TypeError(f"[check_object] must be string, not {type(self.check_object)}.")
|
|
240
273
|
|
|
@@ -254,6 +287,8 @@ class DiffChecker:
|
|
|
254
287
|
:param print_kwargs: dict, of kwargs to pass to 'print_api' function.
|
|
255
288
|
"""
|
|
256
289
|
|
|
290
|
+
self._static_pre_process()
|
|
291
|
+
|
|
257
292
|
if not isinstance(self.check_object, list):
|
|
258
293
|
raise TypeError(f'[check_object] must be list, not {type(self.check_object)}.')
|
|
259
294
|
|
|
@@ -343,7 +378,7 @@ class DiffChecker:
|
|
|
343
378
|
return result, message
|
|
344
379
|
|
|
345
380
|
def _hit_statistics_only_handling(self, current_content, result, message, sort_by_keys, print_kwargs: dict = None):
|
|
346
|
-
if self.
|
|
381
|
+
if self.hit_statistics_input_file_rotation_cycle_hours == 'midnight':
|
|
347
382
|
# If the current time is midnight, we will rotate the file.
|
|
348
383
|
# Get current date.
|
|
349
384
|
current_date = datetime.datetime.now().strftime('%d')
|
|
@@ -417,29 +452,40 @@ class DiffChecker:
|
|
|
417
452
|
'object': self.check_object_display_name,
|
|
418
453
|
'old': list(self.previous_content),
|
|
419
454
|
'updated': current_content
|
|
420
|
-
# 'type': self.object_type
|
|
421
455
|
}
|
|
422
456
|
|
|
423
457
|
# f"Type: {result['type']} | "
|
|
424
458
|
message = f"Object: {result['object']} | Old: {result['old']} | Updated: {result['updated']}"
|
|
425
459
|
|
|
426
|
-
#
|
|
427
|
-
self.
|
|
460
|
+
# If the time has passed, we will stop updating the input file.
|
|
461
|
+
if ((self.new_objects_seconds_then_difference and
|
|
462
|
+
self.new_objects_seconds_then_difference > self.timer.measure())
|
|
463
|
+
or not self.new_objects_hours_then_difference):
|
|
428
464
|
|
|
429
|
-
|
|
430
|
-
if sort_by_keys:
|
|
431
|
-
self.previous_content = list_of_dicts.sort_by_keys(
|
|
432
|
-
self.previous_content, sort_by_keys, case_insensitive=True)
|
|
465
|
+
result['time_passed'] = False
|
|
433
466
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
467
|
+
# Make known content the current, since it is updated.
|
|
468
|
+
self.previous_content.extend(current_content)
|
|
469
|
+
|
|
470
|
+
# Sort list of dicts by specified list of keys.
|
|
471
|
+
if sort_by_keys:
|
|
472
|
+
self.previous_content = list_of_dicts.sort_by_keys(
|
|
473
|
+
self.previous_content, sort_by_keys, case_insensitive=True)
|
|
474
|
+
|
|
475
|
+
# If 'input_file_path' was specified by the user, it means that we will use the input file to save
|
|
476
|
+
# our known content there for next iterations to compare.
|
|
477
|
+
if self.input_file_path:
|
|
478
|
+
if self.save_as == 'txt':
|
|
479
|
+
# noinspection PyTypeChecker
|
|
480
|
+
file_io.write_file(self.previous_content, self.input_file_path, **(print_kwargs or {}))
|
|
481
|
+
elif self.save_as == 'json':
|
|
482
|
+
jsons.write_json_file(
|
|
483
|
+
self.previous_content, self.input_file_path, use_default_indent=True, **(print_kwargs or {}))
|
|
484
|
+
else:
|
|
485
|
+
result['time_passed'] = True
|
|
486
|
+
# We will stop the timer, since the time has passed, the 'measure' method will return the last measure
|
|
487
|
+
# when the timer was running.
|
|
488
|
+
self.timer.stop()
|
|
443
489
|
else:
|
|
444
490
|
message = f"Object didn't change: {self.check_object_display_name}"
|
|
445
491
|
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
from typing import Literal, Union
|
|
2
|
-
import
|
|
2
|
+
from pathlib import Path
|
|
3
3
|
|
|
4
4
|
from .checks import dns, network, hash, process_running
|
|
5
5
|
from .. import filesystem, scheduling
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
DNS__DEFAULT_SETTINGS = {
|
|
9
|
+
'learning_mode_create_unique_entries_list': True,
|
|
10
|
+
'learning_hours': 24, # 0 - the learning will never stop.
|
|
11
|
+
'alert_about_missing_entries_after_learning': False,
|
|
12
|
+
'alert_about_missing_entries_always': True,
|
|
13
|
+
'create_alert_statistics': True,
|
|
14
|
+
'statistics_rotation_hours': 'midnight' # 'midnight' or float of hours
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
FILE__URL__DEFAULT_SETTINGS = {
|
|
18
|
+
'store_original_object': False
|
|
19
|
+
}
|
|
7
20
|
|
|
8
21
|
|
|
9
22
|
class ChangeMonitor:
|
|
@@ -12,6 +25,11 @@ class ChangeMonitor:
|
|
|
12
25
|
"""
|
|
13
26
|
def __init__(
|
|
14
27
|
self,
|
|
28
|
+
check_object: any = None,
|
|
29
|
+
input_file_name: str = None,
|
|
30
|
+
input_statistics_file_name: str = None,
|
|
31
|
+
input_directory: str = None,
|
|
32
|
+
input_file_write_only: bool = True,
|
|
15
33
|
object_type: Union[
|
|
16
34
|
Literal[
|
|
17
35
|
'file',
|
|
@@ -24,20 +42,7 @@ class ChangeMonitor:
|
|
|
24
42
|
'url_playwright_png',
|
|
25
43
|
'url_playwright_jpeg'],
|
|
26
44
|
None] = None,
|
|
27
|
-
|
|
28
|
-
input_file_directory: str = None,
|
|
29
|
-
input_file_name: str = None,
|
|
30
|
-
generate_input_file_name: bool = False,
|
|
31
|
-
input_file_write_only: bool = True,
|
|
32
|
-
store_original_object: bool = False,
|
|
33
|
-
operation_type: Literal[
|
|
34
|
-
'hit_statistics',
|
|
35
|
-
'all_objects'] = None,
|
|
36
|
-
input_file_rotation_cycle_hours: Union[
|
|
37
|
-
float,
|
|
38
|
-
Literal['midnight'],
|
|
39
|
-
None] = None,
|
|
40
|
-
enable_statistics_queue: bool = False
|
|
45
|
+
object_type_settings: dict = None
|
|
41
46
|
):
|
|
42
47
|
"""
|
|
43
48
|
:param object_type: string, type of object to check. The type must be one of the following:
|
|
@@ -57,10 +62,15 @@ class ChangeMonitor:
|
|
|
57
62
|
be downloaded using 'playwright' library in PNG.
|
|
58
63
|
'url_playwright_jpeg': 'check_object_list' must contain strings of full URL to a web page. The page will
|
|
59
64
|
be downloaded using 'playwright' library in JPEG.
|
|
60
|
-
:param
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
:param object_type_settings: dict, specific settings for the object type.
|
|
66
|
+
'dns': Check the default settings example in 'DNS__DEFAULT_SETTINGS'.
|
|
67
|
+
:param check_object: The object to check if changed.
|
|
68
|
+
'dns': empty.
|
|
69
|
+
'network': empty.
|
|
70
|
+
'process_running': list of strings, process names to check if they are running.
|
|
71
|
+
'file': string, full path to the file.
|
|
72
|
+
'url_*': string, full URL to a web page.
|
|
73
|
+
:param input_directory: string, full directory path for storing input files for current state of objects,
|
|
64
74
|
to check later if this state isn't updated. If this variable is left empty, all the content will be saved
|
|
65
75
|
in memory and input file will not be used.
|
|
66
76
|
If the file is not specified, the update of an object will be checked
|
|
@@ -77,116 +87,71 @@ class ChangeMonitor:
|
|
|
77
87
|
False: write to input file each time there is an update, and read each check cycle from the file and not
|
|
78
88
|
from the memory.
|
|
79
89
|
:param store_original_object: boolean, if True, the original object will be stored on the disk inside
|
|
80
|
-
'Original' folder, inside '
|
|
90
|
+
'Original' folder, inside 'input_directory'.
|
|
81
91
|
:param operation_type: string, type of operation to perform. The type must be one of the following:
|
|
82
92
|
'hit_statistics': will only store the statistics of the entries in the input file.
|
|
83
93
|
'all_objects': disable the DiffChecker features, meaning any new entries will be emitted as is.
|
|
84
94
|
None: will use the default operation type, based on the object type.
|
|
85
|
-
:param
|
|
95
|
+
:param hit_statistics_input_file_rotation_cycle_hours:
|
|
86
96
|
float, the amount of hours the input file will be rotated in the 'hit_statistics' operation type.
|
|
87
97
|
str, (only 'midnight' is valid), the input file will be rotated daily at midnight.
|
|
88
98
|
This is valid only for the 'hit_statistics' operation type.
|
|
89
|
-
:param
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
:param hit_statistics_enable_queue: boolean, if True, the statistics queue will be enabled.
|
|
100
|
+
:param new_objects_hours_then_difference: float, currently works only for the 'dns' object_type.
|
|
101
|
+
This is only for the 'new_objects' operation type.
|
|
102
|
+
If the object is not in the list of objects, it will be added to the list.
|
|
103
|
+
If the object is in the list of objects, it will be ignored.
|
|
104
|
+
After the specified amount of hours, new objects will not be added to the input file list, so each new
|
|
105
|
+
object will be outputted from the function. This is useful for checking new objects that are not
|
|
106
|
+
supposed to be in the list of objects, but you want to know about them.
|
|
107
|
+
|
|
108
|
+
If 'input_directory' is not specified, the 'input_file_name' is not specified, and
|
|
92
109
|
'generate_input_file_name' is False, then the input file will not be used and the object will be stored
|
|
93
110
|
in memory. This means that the object will be checked only during the time that the script is running.
|
|
94
111
|
"""
|
|
95
112
|
|
|
96
|
-
# =================== Exception section ============================
|
|
97
|
-
if not input_file_directory and store_original_object:
|
|
98
|
-
raise ValueError('ERROR: [input_file_directory] must be specified if [store_original_object] is True.')
|
|
99
|
-
|
|
100
|
-
if not input_file_directory and generate_input_file_name:
|
|
101
|
-
raise ValueError('ERROR: [input_file_directory] must be specified if [generate_input_file_name] is True.')
|
|
102
|
-
|
|
103
|
-
if not input_file_directory and input_file_name:
|
|
104
|
-
raise ValueError('ERROR: [input_file_directory] must be specified if [input_file_name] is specified.')
|
|
105
|
-
|
|
106
|
-
if input_file_name and generate_input_file_name:
|
|
107
|
-
raise ValueError(
|
|
108
|
-
'ERROR: [input_file_name] and [generate_input_file_name] cannot be both specified and True.')
|
|
109
|
-
|
|
110
|
-
if operation_type:
|
|
111
|
-
if operation_type not in ['hit_statistics', 'all_objects']:
|
|
112
|
-
raise ValueError(
|
|
113
|
-
'ERROR: [operation_type] must be one of the following: "hit_statistics", "all_objects".')
|
|
114
|
-
|
|
115
|
-
if input_file_rotation_cycle_hours and operation_type != 'hit_statistics':
|
|
116
|
-
raise ValueError("[input_file_rotation_cycle] can be specified only for 'hit_statistics' operation type.")
|
|
117
|
-
|
|
118
|
-
# === EOF Exception section ========================================
|
|
119
113
|
# === Initialize Main variables ====================================
|
|
120
114
|
|
|
121
|
-
|
|
122
|
-
check_object_list = list()
|
|
123
|
-
|
|
124
|
-
self.object_type = object_type
|
|
125
|
-
self.check_object_list: list = check_object_list
|
|
126
|
-
self.input_file_directory: str = input_file_directory
|
|
115
|
+
self.check_object: any = check_object
|
|
127
116
|
self.input_file_name: str = input_file_name
|
|
128
|
-
self.
|
|
117
|
+
self.input_statistics_file_name: str = input_statistics_file_name
|
|
118
|
+
self.input_directory: str = input_directory
|
|
129
119
|
self.input_file_write_only: bool = input_file_write_only
|
|
130
|
-
self.
|
|
131
|
-
self.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
# The 'diff_check' will store the list of DiffChecker classes.
|
|
139
|
-
self.diff_check_list: list = list()
|
|
140
|
-
|
|
141
|
-
# If 'check_object_list' is a list, loop through it and create a DiffChecker object for each object.
|
|
142
|
-
if self.check_object_list:
|
|
143
|
-
for index in range(len(self.check_object_list)):
|
|
144
|
-
self.diff_check_list.append(
|
|
145
|
-
DiffChecker(
|
|
146
|
-
input_file_write_only=self.input_file_write_only,
|
|
147
|
-
operation_type=self.operation_type,
|
|
148
|
-
input_file_rotation_cycle_hours=self.input_file_rotation_cycle_hours,
|
|
149
|
-
enable_statistics_queue=self.enable_statistics_queue
|
|
150
|
-
)
|
|
151
|
-
)
|
|
152
|
-
# Else, if 'check_object_list' is None, create a DiffChecker object only once.
|
|
153
|
-
else:
|
|
154
|
-
self.diff_check_list.append(
|
|
155
|
-
DiffChecker(
|
|
156
|
-
input_file_write_only=self.input_file_write_only,
|
|
157
|
-
operation_type=self.operation_type,
|
|
158
|
-
input_file_rotation_cycle_hours=self.input_file_rotation_cycle_hours,
|
|
159
|
-
enable_statistics_queue=self.enable_statistics_queue
|
|
160
|
-
)
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
self.input_file_path = None
|
|
164
|
-
self.original_object_directory = None
|
|
165
|
-
self.original_object_file_path = None
|
|
166
|
-
|
|
167
|
-
# If 'store_original_object' is True, create directory for original object.
|
|
168
|
-
if self.store_original_object:
|
|
169
|
-
# Make path for original object.
|
|
170
|
-
self.original_object_directory = filesystem.add_object_to_path(
|
|
171
|
-
self.input_file_directory, 'Original')
|
|
172
|
-
# Create directory if it doesn't exist.
|
|
173
|
-
filesystem.create_directory(self.original_object_directory)
|
|
174
|
-
|
|
175
|
-
self.first_cycle = True
|
|
120
|
+
self.object_type = object_type
|
|
121
|
+
self.object_type_settings: dict = object_type_settings
|
|
122
|
+
|
|
123
|
+
# === Additional variables ========================================
|
|
124
|
+
|
|
125
|
+
# self.original_object_directory = None
|
|
126
|
+
# self.original_object_file_path = None
|
|
176
127
|
|
|
128
|
+
# # If 'store_original_object' is True, create directory for original object.
|
|
129
|
+
# if self.store_original_object:
|
|
130
|
+
# # Make path for original object.
|
|
131
|
+
# self.original_object_directory = filesystem.add_object_to_path(
|
|
132
|
+
# self.input_directory, 'Original')
|
|
133
|
+
# # Create directory if it doesn't exist.
|
|
134
|
+
# filesystem.create_directory(self.original_object_directory)
|
|
135
|
+
#
|
|
177
136
|
# Initialize objects for DNS and Network monitoring.
|
|
178
|
-
self.fetch_engine = None
|
|
179
|
-
self.thread_looper = scheduling.ThreadLooper()
|
|
180
137
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
138
|
+
self.checks_instance = None
|
|
139
|
+
self._setup_object()
|
|
140
|
+
|
|
141
|
+
def _setup_object(self):
|
|
142
|
+
if self.object_type == 'file' or 'url_' in self.object_type:
|
|
143
|
+
self.checks_instance = hash
|
|
144
|
+
if self.object_type == 'dns':
|
|
145
|
+
self.checks_instance = dns
|
|
146
|
+
|
|
147
|
+
if not self.object_type_settings:
|
|
148
|
+
self.object_type_settings = DNS__DEFAULT_SETTINGS
|
|
149
|
+
elif self.object_type == 'network':
|
|
150
|
+
self.checks_instance = network
|
|
151
|
+
elif self.object_type == 'process_running':
|
|
152
|
+
self.checks_instance = process_running
|
|
187
153
|
|
|
188
|
-
|
|
189
|
-
self.diff_check_list[check_object_index].input_file_path = self.input_file_path
|
|
154
|
+
self.checks_instance.setup_check(self)
|
|
190
155
|
|
|
191
156
|
def check_cycle(self, print_kwargs: dict = None):
|
|
192
157
|
"""
|
|
@@ -195,28 +160,6 @@ class ChangeMonitor:
|
|
|
195
160
|
:return: None
|
|
196
161
|
"""
|
|
197
162
|
|
|
198
|
-
return_list =
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
self.object_type == 'file' or
|
|
202
|
-
'url_' in self.object_type):
|
|
203
|
-
return_list = hash._execute_cycle(self, print_kwargs=print_kwargs)
|
|
204
|
-
if self.object_type == 'dns':
|
|
205
|
-
return_list = dns._execute_cycle(self, print_kwargs=print_kwargs)
|
|
206
|
-
elif self.object_type == 'network':
|
|
207
|
-
return_list = network._execute_cycle(self, print_kwargs=print_kwargs)
|
|
208
|
-
elif self.object_type == 'process_running':
|
|
209
|
-
return_list = process_running._execute_cycle(self, print_kwargs=print_kwargs)
|
|
210
|
-
|
|
211
|
-
# Set 'first_cycle' to False, since the first cycle is finished.
|
|
212
|
-
if self.first_cycle:
|
|
213
|
-
self.first_cycle = False
|
|
163
|
+
return_list = self.checks_instance.execute_cycle(print_kwargs=print_kwargs)
|
|
214
164
|
|
|
215
165
|
return return_list
|
|
216
|
-
|
|
217
|
-
def run_loop(self, interval_seconds=0, print_kwargs: dict = None):
|
|
218
|
-
self.thread_looper.run_loop(
|
|
219
|
-
self.check_cycle, kwargs={'print_kwargs': print_kwargs}, interval_seconds=interval_seconds)
|
|
220
|
-
|
|
221
|
-
def emit_from_loop(self):
|
|
222
|
-
return self.thread_looper.emit_from_loop()
|