atomicshop 2.12.15__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/timer.py CHANGED
@@ -7,7 +7,10 @@ class TimerError(Exception):
7
7
 
8
8
  class Timer:
9
9
  """ Custom timer class to measure elapsed time. Returns time in seconds (float) or nanoseconds with setting. """
10
- def __init__(self, nanoseconds: bool = False):
10
+ def __init__(
11
+ self,
12
+ nanoseconds: bool = False
13
+ ):
11
14
  """
12
15
  Set up timer in seconds or nanoseconds
13
16
  Seconds are returned as float, nanoseconds as int.
@@ -17,6 +20,9 @@ class Timer:
17
20
  self._start_time = None
18
21
  self._nanoseconds: bool = nanoseconds
19
22
 
23
+ self.running: bool = False
24
+ self.last_measure = None
25
+
20
26
  def start(self):
21
27
  """Start a new timer"""
22
28
 
@@ -28,6 +34,8 @@ class Timer:
28
34
  else:
29
35
  self._start_time = time.perf_counter()
30
36
 
37
+ self.running = True
38
+
31
39
  def restart(self):
32
40
  """Reset the timer"""
33
41
 
@@ -37,20 +45,31 @@ class Timer:
37
45
  def measure(self):
38
46
  """Measure the elapsed time"""
39
47
 
40
- if self._start_time is None:
41
- raise TimerError(f"Timer is not running. Use .start() to start it")
48
+ # if self._start_time is None and self.last_measure is None:
49
+ # raise TimerError(f"Timer is not running. Use .start() to start it")
42
50
 
43
- if self._nanoseconds:
44
- elapsed_time = time.perf_counter_ns() - self._start_time
45
- else:
46
- elapsed_time = time.perf_counter() - self._start_time
51
+ # If the timer is running, measure the elapsed time. If not, return the last measured time.
52
+ if self.running:
53
+ if self._nanoseconds:
54
+ self.last_measure = time.perf_counter_ns() - self._start_time
55
+ else:
56
+ self.last_measure = time.perf_counter() - self._start_time
47
57
 
48
- return elapsed_time
58
+ return self.last_measure
59
+
60
+ def stop(self, measure: bool = True):
61
+ """
62
+ Stop the timer, and report the elapsed time
63
+
64
+ :param measure: True to measure the elapsed time, False to stop the timer without measuring.
65
+ Measuring, means that the timer will return the elapsed time and 'self.last_measure' will be updated.
66
+ """
49
67
 
50
- def stop(self):
51
- """Stop the timer, and report the elapsed time"""
68
+ elapsed_time = None
69
+ if measure:
70
+ elapsed_time = self.measure()
52
71
 
53
- elapsed_time = self.measure()
54
72
  self._start_time = None
73
+ self.running = False
55
74
 
56
75
  return elapsed_time
@@ -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(current_file_name, date_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:
@@ -249,6 +251,31 @@ def get_latest_lines(
249
251
  time.sleep(1)
250
252
  """
251
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
+
252
279
  if log_type != 'csv':
253
280
  raise ValueError('Only "csv" log type is supported.')
254
281
 
@@ -262,9 +289,6 @@ def get_latest_lines(
262
289
  latest_only=True
263
290
  )
264
291
 
265
- if not latest_statistics_file_path_object:
266
- return [], [], [], []
267
-
268
292
  latest_statistics_file_path: str = latest_statistics_file_path_object[0]['file_path']
269
293
 
270
294
  # Get the previous day statistics file path.
@@ -279,33 +303,36 @@ def get_latest_lines(
279
303
  except KeyError:
280
304
  pass
281
305
 
282
- current_lines, header = csvs.read_csv_to_list_of_dicts_by_header(
283
- latest_statistics_file_path, header=header, stdout=False)
284
- if len(current_lines) > len(READING_EXISTING_LINES):
285
- # return current_lines
286
- pass
287
- elif len(current_lines) == len(READING_EXISTING_LINES):
288
- # return None
289
- pass
290
- elif len(current_lines) < len(READING_EXISTING_LINES):
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:
291
316
  current_lines, header = csvs.read_csv_to_list_of_dicts_by_header(
292
317
  previous_day_statistics_file_path, header=header, stdout=False)
293
- # Handle case where source CSV is empty (rotation period)
294
- READING_EXISTING_LINES.clear() # Clear existing lines to start fresh after rotation
295
318
 
296
319
  if get_previous_file:
297
320
  previous_file_lines = current_lines
298
321
 
299
- # return current_lines
322
+ EXISTING_LOGS_FILE_COUNT = current_log_files_count
300
323
 
301
- new_lines: list = []
302
- if current_lines:
303
- for row in current_lines:
304
- # If the row is not in the existing lines, then add it to the new lines.
305
- if row not in READING_EXISTING_LINES:
306
- new_lines.append(row)
324
+ new_lines_from_previous_file = extract_new_lines_only(current_lines)
307
325
 
308
- if new_lines:
309
- READING_EXISTING_LINES.extend(new_lines)
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
310
337
 
311
- return new_lines, current_lines, READING_EXISTING_LINES, previous_file_lines, header
338
+ return new_lines, previous_file_lines, header
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.12.15
3
+ Version: 2.12.17
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=irfB8lK9cOngD6YC1kQbNIWYjaADA5biLnI9LD1TntY,124
1
+ atomicshop/__init__.py,sha256=Y0i9YbX4w6RHv1MhMq0Dp3xhWzkgeDIA2V8gJkAoNbw,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,7 +9,7 @@ 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=nT67QKIz6Kjx4lUhER_3OAafasp_K8ZpT3tIKwcHr44,24298
12
+ atomicshop/diff_check.py,sha256=BJIhnAgTyJ-nyw3UBKwobvF0lJuhXQ2rPu12NiYETkI,27088
13
13
  atomicshop/dns.py,sha256=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
14
14
  atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
15
15
  atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
@@ -40,7 +40,7 @@ atomicshop/sys_functions.py,sha256=MTBxRve5bh58SPvhX3gMiGqHlSBuI_rdNN1NnnBBWqI,9
40
40
  atomicshop/system_resource_monitor.py,sha256=ilA3wEUJfBjQhRsHDXGH7Q05mYr5KarPjRWP8S6pCTw,13681
41
41
  atomicshop/system_resources.py,sha256=0mhDZBEcMzToCOw5ArJhtqYjktOW6iJGdyRkJ01Cpwk,9272
42
42
  atomicshop/tempfiles.py,sha256=uq1ve2WlWehZ3NOTXJnpBBMt6HyCdBufqedF0HyzA6k,2517
43
- atomicshop/timer.py,sha256=KxBBgVM8po6pUJDW8TgY1UXj0iiDmRmL5XDCq0VHAfU,1670
43
+ atomicshop/timer.py,sha256=7Zw1KRV0acHCRATMnanyX2MLBb63Hc-6us3rCZ9dNlY,2345
44
44
  atomicshop/urls.py,sha256=CQl1j1kjEVDlAuYJqYD9XxPF1SUSgrmG8PjlcXNEKsQ,597
45
45
  atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
46
46
  atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
@@ -132,15 +132,15 @@ 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=FUAolHTWVFfC14K2cTMK1NE6ORp37A0fCrfwNbxmbIs,12221
135
+ atomicshop/monitor/change_monitor.py,sha256=ySfFCtsCFG3irV6gKr43DbbyQgmTwzG5m3FkCWDa8UI,9246
136
136
  atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- atomicshop/monitor/checks/dns.py,sha256=wX53eGX2F5_lBDLL5D6dFb3XThdt3iwoYKnP05WZKfc,4870
138
- atomicshop/monitor/checks/hash.py,sha256=A6bJ7F5Qv_brdEh3sGhOyfviab2dsnvbXUufyBk5C1U,1951
139
- atomicshop/monitor/checks/network.py,sha256=I9f3KyNnlx97E8igGZXpVJl4MlUp9iU6aSbILCKqbA0,3820
140
- atomicshop/monitor/checks/process_running.py,sha256=948Sify4P2KFTE1ZrLHKLwd1B1HOgWmC11x3b6MCvz0,1892
137
+ atomicshop/monitor/checks/dns.py,sha256=XOMVhf2A2A8zEvQxBszL5z_DItJC0pomg_mkiMKMrug,5741
138
+ atomicshop/monitor/checks/hash.py,sha256=f719jU1A_rJi1ixGEHzWIZEoqpHJq4znabZnq4in9IM,2202
139
+ atomicshop/monitor/checks/network.py,sha256=i2jc5LRKeQJRNtOrSbkZQQCMy33No_X-SjMcXDmIh1E,3753
140
+ atomicshop/monitor/checks/process_running.py,sha256=pvSTa3nHDy1YH-35QkFxBUsqnCnfU5PBA_NNjp9iUNg,1889
141
141
  atomicshop/monitor/checks/hash_checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
- atomicshop/monitor/checks/hash_checks/file.py,sha256=UDHrUphYSKeH4KJR5pC3ilPAGxX0oXTu3UD8ndnR5WU,2733
143
- atomicshop/monitor/checks/hash_checks/url.py,sha256=aNAL1bIeks6xsRDk-5arGy4rhzrJkJ4ZRCqCQTi4n3U,3237
142
+ atomicshop/monitor/checks/hash_checks/file.py,sha256=o80UpjPNx9-AF5fYkZaP-ASHcBCE2zwGKUVRtDYKQyI,2402
143
+ atomicshop/monitor/checks/hash_checks/url.py,sha256=XxBNjhQZO_JlicgadqBblvt6sIRizerwM-LVCOgMCQU,3020
144
144
  atomicshop/ssh_scripts/process_from_ipv4.py,sha256=uDBKZ2Ds20614JW1xMLr4IPB-z1LzIwy6QH5-SJ4j0s,1681
145
145
  atomicshop/ssh_scripts/process_from_port.py,sha256=uDTkVh4zc3HOTTGv1Et3IxM3PonDJCPuFRL6rnZDQZ4,1389
146
146
  atomicshop/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -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=k5XAnklLs97HQYkmF72-RzfNgBGsIx6mgogLugBpd7c,13992
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.15.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
255
- atomicshop-2.12.15.dist-info/METADATA,sha256=LvzJt1ZpIyBFDgSjWVcopOaMbDsSgRJTYMKuohIXP0o,10479
256
- atomicshop-2.12.15.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
257
- atomicshop-2.12.15.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
258
- atomicshop-2.12.15.dist-info/RECORD,,
254
+ atomicshop-2.12.17.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
255
+ atomicshop-2.12.17.dist-info/METADATA,sha256=eRzyeiQbRlaJQ62ckcewFJ7JdMmcSNBZKaVuhM4-GS8,10479
256
+ atomicshop-2.12.17.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
257
+ atomicshop-2.12.17.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
258
+ atomicshop-2.12.17.dist-info/RECORD,,