atomicshop 2.12.9__py3-none-any.whl → 2.12.10__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 +19 -1
- atomicshop/filesystem.py +65 -1
- atomicshop/monitor/change_monitor.py +19 -3
- {atomicshop-2.12.9.dist-info → atomicshop-2.12.10.dist-info}/METADATA +1 -1
- {atomicshop-2.12.9.dist-info → atomicshop-2.12.10.dist-info}/RECORD +9 -9
- {atomicshop-2.12.9.dist-info → atomicshop-2.12.10.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.12.9.dist-info → atomicshop-2.12.10.dist-info}/WHEEL +0 -0
- {atomicshop-2.12.9.dist-info → atomicshop-2.12.10.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/diff_check.py
CHANGED
|
@@ -31,7 +31,15 @@ class DiffChecker:
|
|
|
31
31
|
input_file_path: str = None,
|
|
32
32
|
input_file_write_only: bool = True,
|
|
33
33
|
return_first_cycle: bool = True,
|
|
34
|
-
operation_type: Literal[
|
|
34
|
+
operation_type: Literal[
|
|
35
|
+
'new_objects',
|
|
36
|
+
'hit_statistics',
|
|
37
|
+
'all_objects',
|
|
38
|
+
'single_object'] = None,
|
|
39
|
+
input_file_rotation_cycle_hours: Union[
|
|
40
|
+
float,
|
|
41
|
+
Literal['midnight'],
|
|
42
|
+
None] = None
|
|
35
43
|
):
|
|
36
44
|
"""
|
|
37
45
|
:param check_object: any, object to check if it changed.
|
|
@@ -68,10 +76,16 @@ class DiffChecker:
|
|
|
68
76
|
:param operation_type: string, type of operation to perform. The type must be one of the following:
|
|
69
77
|
'new_objects': will only store the new objects in the input file.
|
|
70
78
|
'hit_statistics': will only store the statistics of the entries in the input file.
|
|
79
|
+
The file will be rotated after the specified time in the 'input_file_rotation_cycle' variable, if
|
|
80
|
+
it is specified.
|
|
71
81
|
'all_objects': disable the DiffChecker features, meaning any new entries will be emitted as is.
|
|
72
82
|
'single_object': will store the object as is, without any comparison. Meaning, that the object will be
|
|
73
83
|
compared only to itself, and if it changes, it will be updated.
|
|
74
84
|
None: Nothing will be done, you will get an exception.
|
|
85
|
+
:param input_file_rotation_cycle_hours:
|
|
86
|
+
float, the amount of hours the input file will be rotated.
|
|
87
|
+
str, (only 'midnight' is valid), the input file will be rotated daily at midnight.
|
|
88
|
+
This is valid only for the 'hit_statistics' operation type.
|
|
75
89
|
|
|
76
90
|
--------------------------------------------------
|
|
77
91
|
|
|
@@ -150,6 +164,9 @@ class DiffChecker:
|
|
|
150
164
|
raise ValueError(f"[operation_type] must be one of the following: "
|
|
151
165
|
f"'new_objects', 'hit_statistics', 'all_objects', 'single_object'.")
|
|
152
166
|
|
|
167
|
+
if input_file_rotation_cycle_hours and operation_type != 'hit_statistics':
|
|
168
|
+
raise ValueError("[input_file_rotation_cycle] can be specified only for 'hit_statistics' operation type.")
|
|
169
|
+
|
|
153
170
|
self.check_object = check_object
|
|
154
171
|
self.check_object_display_name = check_object_display_name
|
|
155
172
|
self.aggregation: bool = aggregation
|
|
@@ -157,6 +174,7 @@ class DiffChecker:
|
|
|
157
174
|
self.input_file_write_only: bool = input_file_write_only
|
|
158
175
|
self.return_first_cycle: bool = return_first_cycle
|
|
159
176
|
self.operation_type = operation_type
|
|
177
|
+
self.input_file_rotation_cycle = input_file_rotation_cycle_hours
|
|
160
178
|
|
|
161
179
|
if not self.check_object_display_name:
|
|
162
180
|
self.check_object_display_name = self.check_object
|
atomicshop/filesystem.py
CHANGED
|
@@ -14,7 +14,7 @@ import psutil
|
|
|
14
14
|
from .print_api import print_api, print_status_of_list
|
|
15
15
|
from .basics import strings, list_of_dicts
|
|
16
16
|
from .file_io import file_io
|
|
17
|
-
from . import hashing
|
|
17
|
+
from . import hashing, datetimes
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
WINDOWS_DIRECTORY_SPECIAL_CHARACTERS = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']
|
|
@@ -446,6 +446,26 @@ def move_file(source_file_path: str, target_file_path: str, overwrite: bool = Tr
|
|
|
446
446
|
shutil.move(source_file_path, target_file_path)
|
|
447
447
|
|
|
448
448
|
|
|
449
|
+
def move_folder(source_directory: str, target_directory: str, overwrite: bool = True) -> None:
|
|
450
|
+
"""
|
|
451
|
+
The function moves folder from source to target.
|
|
452
|
+
|
|
453
|
+
:param source_directory: string, full path to source directory.
|
|
454
|
+
:param target_directory: string, full path to target directory.
|
|
455
|
+
:param overwrite: boolean, if 'False', then the function will not overwrite the directory if it exists.
|
|
456
|
+
|
|
457
|
+
:return: None
|
|
458
|
+
"""
|
|
459
|
+
|
|
460
|
+
# Check if 'overwrite' is set to 'True' and if the directory exists.
|
|
461
|
+
if not overwrite:
|
|
462
|
+
if check_directory_existence(target_directory):
|
|
463
|
+
raise FileExistsError(f'Directory already exists: {target_directory}')
|
|
464
|
+
|
|
465
|
+
# Move directory.
|
|
466
|
+
shutil.move(source_directory, target_directory)
|
|
467
|
+
|
|
468
|
+
|
|
449
469
|
def move_files_from_folder_to_folder(
|
|
450
470
|
source_directory: str,
|
|
451
471
|
target_directory: str,
|
|
@@ -1319,3 +1339,47 @@ def get_download_directory(place: Literal['temp', 'script', 'working'] = 'temp',
|
|
|
1319
1339
|
raise ValueError("Invalid place specified.")
|
|
1320
1340
|
|
|
1321
1341
|
return download_directory
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
def backup_folder(directory_path: str, backup_directory: str) -> None:
|
|
1345
|
+
"""
|
|
1346
|
+
Backup the specified directory.
|
|
1347
|
+
|
|
1348
|
+
:param directory_path: The directory path to backup.
|
|
1349
|
+
:param backup_directory: The directory to backup the directory to.
|
|
1350
|
+
|
|
1351
|
+
Example:
|
|
1352
|
+
backup_folder(directory_path='C:\\Users\\user1\\Downloads\\folder1', backup_directory='C:\\Users\\user1\\Downloads\\backup')
|
|
1353
|
+
|
|
1354
|
+
Backed up folder will be moved to 'C:\\Users\\user1\\Downloads\\backup' with timestamp in the name.
|
|
1355
|
+
Final path will look like: 'C:\\Users\\user1\\Downloads\\backup\\20231003-120000-000000_folder1'
|
|
1356
|
+
"""
|
|
1357
|
+
|
|
1358
|
+
if check_directory_existence(directory_path):
|
|
1359
|
+
timestamp: str = datetimes.TimeFormats().get_current_formatted_time_filename_stamp(True)
|
|
1360
|
+
directory_name = Path(directory_path).name
|
|
1361
|
+
backup_directory_path: str = str(Path(backup_directory) / f"{timestamp}_{directory_name}")
|
|
1362
|
+
create_directory(backup_directory_path)
|
|
1363
|
+
move_folder(directory_path, backup_directory_path)
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
def backup_file(file_path: str, backup_directory: str) -> None:
|
|
1367
|
+
"""
|
|
1368
|
+
Backup the specified file.
|
|
1369
|
+
|
|
1370
|
+
:param file_path: The file path to backup.
|
|
1371
|
+
:param backup_directory: The directory to backup the file to.
|
|
1372
|
+
|
|
1373
|
+
Example:
|
|
1374
|
+
backup_file(file_path='C:\\Users\\user1\\Downloads\\file.txt', backup_directory='C:\\Users\\user1\\Downloads\\backup')
|
|
1375
|
+
|
|
1376
|
+
Backed up file will be moved to 'C:\\Users\\user1\\Downloads\\backup' with timestamp in the name.
|
|
1377
|
+
Final path will look like: 'C:\\Users\\user1\\Downloads\\backup\\20231003-120000-000000_file.txt'
|
|
1378
|
+
"""
|
|
1379
|
+
|
|
1380
|
+
if check_file_existence(file_path):
|
|
1381
|
+
timestamp: str = datetimes.TimeFormats().get_current_formatted_time_filename_stamp(True)
|
|
1382
|
+
file_name_no_extension = Path(file_path).stem
|
|
1383
|
+
file_extension = Path(file_path).suffix
|
|
1384
|
+
backup_file_path: str = str(Path(backup_directory) / f"{file_name_no_extension}_{timestamp}{file_extension}")
|
|
1385
|
+
move_file(file_path, backup_file_path)
|
|
@@ -29,7 +29,13 @@ class ChangeMonitor:
|
|
|
29
29
|
generate_input_file_name: bool = False,
|
|
30
30
|
input_file_write_only: bool = True,
|
|
31
31
|
store_original_object: bool = False,
|
|
32
|
-
operation_type: Literal[
|
|
32
|
+
operation_type: Literal[
|
|
33
|
+
'hit_statistics',
|
|
34
|
+
'all_objects'] = None,
|
|
35
|
+
input_file_rotation_cycle_hours: Union[
|
|
36
|
+
float,
|
|
37
|
+
Literal['midnight'],
|
|
38
|
+
None] = None
|
|
33
39
|
):
|
|
34
40
|
"""
|
|
35
41
|
:param object_type: string, type of object to check. The type must be one of the following:
|
|
@@ -74,6 +80,10 @@ class ChangeMonitor:
|
|
|
74
80
|
'hit_statistics': will only store the statistics of the entries in the input file.
|
|
75
81
|
'all_objects': disable the DiffChecker features, meaning any new entries will be emitted as is.
|
|
76
82
|
None: will use the default operation type, based on the object type.
|
|
83
|
+
:param input_file_rotation_cycle_hours:
|
|
84
|
+
float, the amount of hours the input file will be rotated.
|
|
85
|
+
str, (only 'midnight' is valid), the input file will be rotated daily at midnight.
|
|
86
|
+
This is valid only for the 'hit_statistics' operation type.
|
|
77
87
|
|
|
78
88
|
If 'input_file_directory' is not specified, the 'input_file_name' is not specified, and
|
|
79
89
|
'generate_input_file_name' is False, then the input file will not be used and the object will be stored
|
|
@@ -99,6 +109,9 @@ class ChangeMonitor:
|
|
|
99
109
|
raise ValueError(
|
|
100
110
|
'ERROR: [operation_type] must be one of the following: "hit_statistics", "all_objects".')
|
|
101
111
|
|
|
112
|
+
if input_file_rotation_cycle_hours and operation_type != 'hit_statistics':
|
|
113
|
+
raise ValueError("[input_file_rotation_cycle] can be specified only for 'hit_statistics' operation type.")
|
|
114
|
+
|
|
102
115
|
# === EOF Exception section ========================================
|
|
103
116
|
# === Initialize Main variables ====================================
|
|
104
117
|
|
|
@@ -113,6 +126,7 @@ class ChangeMonitor:
|
|
|
113
126
|
self.input_file_write_only: bool = input_file_write_only
|
|
114
127
|
self.store_original_object: bool = store_original_object
|
|
115
128
|
self.operation_type = operation_type
|
|
129
|
+
self.input_file_rotation_cycle_hours = input_file_rotation_cycle_hours
|
|
116
130
|
|
|
117
131
|
# === EOF Initialize Main variables ================================
|
|
118
132
|
# === Initialize Secondary variables ===============================
|
|
@@ -126,7 +140,8 @@ class ChangeMonitor:
|
|
|
126
140
|
self.diff_check_list.append(
|
|
127
141
|
DiffChecker(
|
|
128
142
|
input_file_write_only=self.input_file_write_only,
|
|
129
|
-
operation_type=self.operation_type
|
|
143
|
+
operation_type=self.operation_type,
|
|
144
|
+
input_file_rotation_cycle_hours=self.input_file_rotation_cycle_hours
|
|
130
145
|
)
|
|
131
146
|
)
|
|
132
147
|
# Else, if 'check_object_list' is None, create a DiffChecker object only once.
|
|
@@ -134,7 +149,8 @@ class ChangeMonitor:
|
|
|
134
149
|
self.diff_check_list.append(
|
|
135
150
|
DiffChecker(
|
|
136
151
|
input_file_write_only=self.input_file_write_only,
|
|
137
|
-
operation_type=self.operation_type
|
|
152
|
+
operation_type=self.operation_type,
|
|
153
|
+
input_file_rotation_cycle_hours=self.input_file_rotation_cycle_hours
|
|
138
154
|
)
|
|
139
155
|
)
|
|
140
156
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256
|
|
1
|
+
atomicshop/__init__.py,sha256=7Vx_nxgUsmh8XnHp545Je0VoGYtduvu1AXK5YqXnoYc,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
|
|
@@ -9,12 +9,12 @@ atomicshop/config_init.py,sha256=z2RXD_mw9nQlAOpuGry1h9QT-2LhNscXgGAktN3dCVQ,249
|
|
|
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=olsL01S5tkXk4WPzucxujqgLOh198BLgJntDnGYukRU,15533
|
|
12
|
-
atomicshop/diff_check.py,sha256=
|
|
12
|
+
atomicshop/diff_check.py,sha256=aa0cJAXc643qLbAnVCnVQUEzf3V0cTsy-y9fwarIdPE,20160
|
|
13
13
|
atomicshop/dns.py,sha256=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
|
|
14
14
|
atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
|
|
15
15
|
atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
|
|
16
16
|
atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
|
|
17
|
-
atomicshop/filesystem.py,sha256=
|
|
17
|
+
atomicshop/filesystem.py,sha256=3LfLBXRwvdeK_qIBhIyGrDBO5l4OMpQ7Nev24yUfg0U,51606
|
|
18
18
|
atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
|
|
19
19
|
atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
|
|
20
20
|
atomicshop/http_parse.py,sha256=nrf2rZcprLqtW8HVrV7TCZ1iTBcWRRy-mXIlAOzcaJs,9703
|
|
@@ -132,7 +132,7 @@ 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=xLL5iLCAHSpxFqJ8EaYXo49py5k0r3qgZzbfbsgAebA,11801
|
|
136
136
|
atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
137
137
|
atomicshop/monitor/checks/dns.py,sha256=orp-TgqL6EPzXVm0MtjEceFE8LRfTP3iPR6hGc8Y3TQ,4499
|
|
138
138
|
atomicshop/monitor/checks/hash.py,sha256=A6bJ7F5Qv_brdEh3sGhOyfviab2dsnvbXUufyBk5C1U,1951
|
|
@@ -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.10.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
255
|
+
atomicshop-2.12.10.dist-info/METADATA,sha256=qeP1u3Xf--S_WBIEm2cilMZUhmBdQZMWS-COhqHhmKE,10479
|
|
256
|
+
atomicshop-2.12.10.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
257
|
+
atomicshop-2.12.10.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
258
|
+
atomicshop-2.12.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|