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 CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.12.9'
4
+ __version__ = '2.12.10'
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['new_objects', 'hit_statistics', 'all_objects', 'single_object'] = None
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['hit_statistics', 'all_objects'] = None
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.12.9
3
+ Version: 2.12.10
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=-vfpVbmmEp5MJjeiy8KXfc5AiYWei228hKs92EJDabk,123
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=U7eshTajImlsL6aB0O2yiRsGCQCwumiCvGoFcJ2iAfs,19226
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=JVWoOSkm-lfh11nBMlrP0w_YnrTFnJ5noYLtoN5Nf5o,48809
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=5LNBcVodxeZMXsDvhzdhb67ipUau__Kh6v6Znj9QjyY,10858
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.9.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
255
- atomicshop-2.12.9.dist-info/METADATA,sha256=p5kxZx91i1n0Os02yyC3ce6mvSZARM6G-jl2qFh8e_0,10478
256
- atomicshop-2.12.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
257
- atomicshop-2.12.9.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
258
- atomicshop-2.12.9.dist-info/RECORD,,
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,,