atomicshop 3.2.5__py3-none-any.whl → 3.2.7__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/basics/tracebacks.py +13 -3
- atomicshop/mitm/mitm_main.py +45 -15
- atomicshop/mitm/recs_files.py +74 -23
- atomicshop/wrappers/socketw/dns_server.py +1 -0
- {atomicshop-3.2.5.dist-info → atomicshop-3.2.7.dist-info}/METADATA +1 -1
- {atomicshop-3.2.5.dist-info → atomicshop-3.2.7.dist-info}/RECORD +10 -10
- {atomicshop-3.2.5.dist-info → atomicshop-3.2.7.dist-info}/LICENSE.txt +0 -0
- {atomicshop-3.2.5.dist-info → atomicshop-3.2.7.dist-info}/WHEEL +0 -0
- {atomicshop-3.2.5.dist-info → atomicshop-3.2.7.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/basics/tracebacks.py
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import traceback
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def get_as_string(
|
|
4
|
+
def get_as_string(
|
|
5
|
+
exc: BaseException = None,
|
|
6
|
+
one_line: bool = False,
|
|
7
|
+
replace_end: str = str()
|
|
8
|
+
) -> str:
|
|
5
9
|
"""
|
|
6
10
|
Returns traceback as string.
|
|
7
11
|
|
|
12
|
+
:param exc: Exception to get traceback from. If 'None', current exception will be used.
|
|
8
13
|
:param one_line: If 'True', traceback will be returned as one line.
|
|
9
14
|
:param replace_end: If 'one_line' is 'True', this string will be used to replace '\n' in traceback.
|
|
10
15
|
:return: Traceback as string.
|
|
11
16
|
"""
|
|
12
17
|
|
|
18
|
+
if exc is None:
|
|
19
|
+
stringed_exception: str = traceback.format_exc()
|
|
20
|
+
else:
|
|
21
|
+
stringed_exception: str = ''.join(traceback.TracebackException.from_exception(exc).format())
|
|
22
|
+
|
|
13
23
|
if not one_line:
|
|
14
|
-
return
|
|
24
|
+
return stringed_exception
|
|
15
25
|
else:
|
|
16
|
-
return
|
|
26
|
+
return stringed_exception.replace('\n', replace_end)
|
atomicshop/mitm/mitm_main.py
CHANGED
|
@@ -3,6 +3,7 @@ import multiprocessing
|
|
|
3
3
|
import time
|
|
4
4
|
import datetime
|
|
5
5
|
import os
|
|
6
|
+
import logging
|
|
6
7
|
|
|
7
8
|
import atomicshop # Importing atomicshop package to get the version of the package.
|
|
8
9
|
|
|
@@ -71,6 +72,9 @@ MITM_ERROR_LOGGER: loggingw.ExceptionCsvLogger = None
|
|
|
71
72
|
# Create logger's queue.
|
|
72
73
|
NETWORK_LOGGER_QUEUE: multiprocessing.Queue = multiprocessing.Queue()
|
|
73
74
|
|
|
75
|
+
# Create finalization queue for the rec archiving process.
|
|
76
|
+
FINALIZE_RECS_ARCHIVE_QUEUE: multiprocessing.Queue = multiprocessing.Queue()
|
|
77
|
+
|
|
74
78
|
|
|
75
79
|
try:
|
|
76
80
|
win_console.disable_quick_edit()
|
|
@@ -115,7 +119,7 @@ def exit_cleanup():
|
|
|
115
119
|
|
|
116
120
|
# The process will not be executed if there was an exception in the beginning.
|
|
117
121
|
if RECS_PROCESS_INSTANCE is not None:
|
|
118
|
-
print_api.print_api(RECS_PROCESS_INSTANCE.is_alive())
|
|
122
|
+
print_api.print_api(f'Recs archive process alive: {RECS_PROCESS_INSTANCE.is_alive()}')
|
|
119
123
|
RECS_PROCESS_INSTANCE.terminate()
|
|
120
124
|
RECS_PROCESS_INSTANCE.join()
|
|
121
125
|
|
|
@@ -324,12 +328,6 @@ def mitm_server(config_file_path: str, script_version: str):
|
|
|
324
328
|
# Create folders.
|
|
325
329
|
filesystem.create_directory(config_static.LogRec.logs_path)
|
|
326
330
|
|
|
327
|
-
if config_static.LogRec.enable_request_response_recordings_in_logs:
|
|
328
|
-
filesystem.create_directory(config_static.LogRec.recordings_path)
|
|
329
|
-
# Compress recordings of the previous days if there are any.
|
|
330
|
-
global RECS_PROCESS_INSTANCE
|
|
331
|
-
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(config_static.LogRec.recordings_path)
|
|
332
|
-
|
|
333
331
|
if config_static.Certificates.sni_get_server_certificate_from_server_socket:
|
|
334
332
|
filesystem.create_directory(
|
|
335
333
|
config_static.Certificates.sni_server_certificate_from_server_socket_download_directory)
|
|
@@ -347,14 +345,35 @@ def mitm_server(config_file_path: str, script_version: str):
|
|
|
347
345
|
formatter_filehandler='DEFAULT',
|
|
348
346
|
backupCount=config_static.LogRec.store_logs_for_x_days)
|
|
349
347
|
|
|
350
|
-
network_logger_with_queue_handler = loggingw.create_logger(
|
|
348
|
+
network_logger_with_queue_handler: logging.Logger = loggingw.create_logger(
|
|
351
349
|
logger_name=network_logger_name,
|
|
352
350
|
add_queue_handler=True,
|
|
353
351
|
log_queue=NETWORK_LOGGER_QUEUE)
|
|
354
352
|
|
|
355
353
|
# Initiate Listener logger, which is a child of network logger, so he uses the same settings and handlers
|
|
356
|
-
listener_logger = loggingw.get_logger_with_level(f'{network_logger_name}.listener')
|
|
357
|
-
system_logger = loggingw.get_logger_with_level(f'{network_logger_name}.system')
|
|
354
|
+
listener_logger: logging.Logger = loggingw.get_logger_with_level(f'{network_logger_name}.listener')
|
|
355
|
+
system_logger: logging.Logger = loggingw.get_logger_with_level(f'{network_logger_name}.system')
|
|
356
|
+
|
|
357
|
+
if config_static.LogRec.enable_request_response_recordings_in_logs:
|
|
358
|
+
filesystem.create_directory(config_static.LogRec.recordings_path)
|
|
359
|
+
# Compress recordings of the previous days if there are any.
|
|
360
|
+
global RECS_PROCESS_INSTANCE
|
|
361
|
+
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(
|
|
362
|
+
config_static.LogRec.recordings_path,
|
|
363
|
+
logging_queue=NETWORK_LOGGER_QUEUE,
|
|
364
|
+
logger_name=network_logger_name,
|
|
365
|
+
finalize_output_queue=FINALIZE_RECS_ARCHIVE_QUEUE
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
archiver_result = FINALIZE_RECS_ARCHIVE_QUEUE.get()
|
|
369
|
+
if isinstance(archiver_result, Exception):
|
|
370
|
+
print_api.print_api(
|
|
371
|
+
f"Error while archiving recordings: {archiver_result}",
|
|
372
|
+
error_type=True, color="red", logger=system_logger, logger_method='critical')
|
|
373
|
+
# Wait for the message to be printed and saved to file.
|
|
374
|
+
time.sleep(1)
|
|
375
|
+
network_logger_queue_listener.stop()
|
|
376
|
+
return 1
|
|
358
377
|
|
|
359
378
|
# Logging Startup information.
|
|
360
379
|
startup_output(system_logger, script_version)
|
|
@@ -528,7 +547,9 @@ def mitm_server(config_file_path: str, script_version: str):
|
|
|
528
547
|
|
|
529
548
|
socket_wrapper_instance.start_listening_sockets(
|
|
530
549
|
reference_function_name=thread_worker_main,
|
|
531
|
-
reference_function_args=(
|
|
550
|
+
reference_function_args=(
|
|
551
|
+
network_logger_with_queue_handler, statistics_writer, config_static.ENGINES_LIST,
|
|
552
|
+
config_static.REFERENCE_MODULE)
|
|
532
553
|
)
|
|
533
554
|
|
|
534
555
|
# socket_thread = threading.Thread(
|
|
@@ -544,8 +565,7 @@ def mitm_server(config_file_path: str, script_version: str):
|
|
|
544
565
|
# socket_thread.start()
|
|
545
566
|
|
|
546
567
|
# Compress recordings each day in a separate process.
|
|
547
|
-
recs_archiver_thread = threading.Thread(target=_loop_at_midnight_recs_archive)
|
|
548
|
-
recs_archiver_thread.daemon = True
|
|
568
|
+
recs_archiver_thread = threading.Thread(target=_loop_at_midnight_recs_archive, args=(network_logger_name,), daemon=True)
|
|
549
569
|
recs_archiver_thread.start()
|
|
550
570
|
|
|
551
571
|
if config_static.DNSServer.enable or config_static.TCPServer.enable:
|
|
@@ -554,7 +574,7 @@ def mitm_server(config_file_path: str, script_version: str):
|
|
|
554
574
|
time.sleep(1)
|
|
555
575
|
|
|
556
576
|
|
|
557
|
-
def _loop_at_midnight_recs_archive():
|
|
577
|
+
def _loop_at_midnight_recs_archive(network_logger_name):
|
|
558
578
|
previous_date = datetime.datetime.now().strftime('%d')
|
|
559
579
|
while True:
|
|
560
580
|
# Get current time.
|
|
@@ -563,7 +583,17 @@ def _loop_at_midnight_recs_archive():
|
|
|
563
583
|
if current_date != previous_date:
|
|
564
584
|
if config_static.LogRec.enable_request_response_recordings_in_logs:
|
|
565
585
|
global RECS_PROCESS_INSTANCE
|
|
566
|
-
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(
|
|
586
|
+
RECS_PROCESS_INSTANCE = recs_files.recs_archiver_in_process(
|
|
587
|
+
config_static.LogRec.recordings_path,
|
|
588
|
+
logging_queue=NETWORK_LOGGER_QUEUE,
|
|
589
|
+
logger_name=network_logger_name,
|
|
590
|
+
finalize_output_queue=FINALIZE_RECS_ARCHIVE_QUEUE
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
archiver_result = FINALIZE_RECS_ARCHIVE_QUEUE.get()
|
|
594
|
+
if isinstance(archiver_result, Exception):
|
|
595
|
+
MITM_ERROR_LOGGER.write(archiver_result)
|
|
596
|
+
|
|
567
597
|
# Update the previous date.
|
|
568
598
|
previous_date = current_date
|
|
569
599
|
# Sleep for 1 minute.
|
atomicshop/mitm/recs_files.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import os
|
|
3
3
|
import multiprocessing
|
|
4
|
+
import logging
|
|
4
5
|
|
|
5
6
|
from ..archiver import zips
|
|
6
|
-
from .. import filesystem
|
|
7
|
-
from .. wrappers.loggingw import consts
|
|
7
|
+
from .. import filesystem, print_api
|
|
8
|
+
from .. wrappers.loggingw import consts, loggingw
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
REC_FILE_DATE_TIME_MILLISECONDS_FORMAT: str = f'{consts.DEFAULT_ROTATING_SUFFIXES_FROM_WHEN["S"]}_%f'
|
|
@@ -12,14 +13,35 @@ REC_FILE_DATE_TIME_FORMAT: str = f'{consts.DEFAULT_ROTATING_SUFFIXES_FROM_WHEN["
|
|
|
12
13
|
REC_FILE_DATE_FORMAT: str = REC_FILE_DATE_TIME_FORMAT.split('_')[0]
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
def recs_archiver(
|
|
16
|
+
def recs_archiver(
|
|
17
|
+
recs_directory: str,
|
|
18
|
+
logging_queue: multiprocessing.Queue,
|
|
19
|
+
logger_name: str,
|
|
20
|
+
finalize_output_queue: multiprocessing.Queue
|
|
21
|
+
) -> list | None:
|
|
16
22
|
"""
|
|
17
23
|
Find recs files in a directory for each day.
|
|
18
24
|
Each day of recordings will have separate archive.
|
|
19
25
|
|
|
20
26
|
:param recs_directory: The directory where recordings are stored.
|
|
27
|
+
:param logging_queue: The queue for logging messages.
|
|
28
|
+
:param logger_name: The name of the logger to use for logging.
|
|
29
|
+
This is the base name that '.rec_packer' will be added to it.
|
|
30
|
+
:param finalize_output_queue: output queue for results/exceptions.
|
|
21
31
|
"""
|
|
22
32
|
|
|
33
|
+
logger_name = f"{logger_name}.rec_packer"
|
|
34
|
+
|
|
35
|
+
rec_packer_logger_with_queue_handler: logging.Logger = loggingw.create_logger(
|
|
36
|
+
logger_name=logger_name,
|
|
37
|
+
add_queue_handler=True,
|
|
38
|
+
log_queue=logging_queue)
|
|
39
|
+
|
|
40
|
+
print_api.print_api(
|
|
41
|
+
'Starting recs archiver process.', color='blue',
|
|
42
|
+
logger=rec_packer_logger_with_queue_handler
|
|
43
|
+
)
|
|
44
|
+
|
|
23
45
|
today_date_string = datetime.datetime.now().strftime(REC_FILE_DATE_FORMAT)
|
|
24
46
|
|
|
25
47
|
# There should not be recording json files in recs root.
|
|
@@ -43,34 +65,63 @@ def recs_archiver(recs_directory: str) -> list:
|
|
|
43
65
|
)
|
|
44
66
|
file_list_per_directory.append((directory_path, all_recs_files))
|
|
45
67
|
|
|
46
|
-
archived_files: list = list()
|
|
47
|
-
for directory_path, all_recs_files in file_list_per_directory:
|
|
48
|
-
for recs_atomic_path in all_recs_files:
|
|
49
|
-
# We don't need to archive today's files.
|
|
50
|
-
if today_date_string == recs_atomic_path.datetime_string:
|
|
51
|
-
continue
|
|
52
68
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
try:
|
|
70
|
+
archived_files: list = list()
|
|
71
|
+
for directory_path, all_recs_files in file_list_per_directory:
|
|
72
|
+
for recs_atomic_path in all_recs_files:
|
|
73
|
+
# We don't need to archive today's files.
|
|
74
|
+
if today_date_string == recs_atomic_path.datetime_string:
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
target_directory_path: str = f"{directory_path.path}{os.sep}{recs_atomic_path.datetime_string}"
|
|
78
|
+
filesystem.create_directory(target_directory_path)
|
|
79
|
+
filesystem.move_file(
|
|
80
|
+
recs_atomic_path.path, target_directory_path)
|
|
81
|
+
|
|
82
|
+
# Archive directories.
|
|
83
|
+
archive_directories: list = filesystem.get_paths_from_directory(
|
|
84
|
+
directory_path.path, get_directory=True, recursive=False)
|
|
85
|
+
for archive_directory in archive_directories:
|
|
86
|
+
archived_file: str = zips.archive_directory(
|
|
87
|
+
archive_directory.path, remove_original=True, include_root_directory=True)
|
|
88
|
+
archived_files.append(archived_file)
|
|
89
|
+
|
|
90
|
+
finalize_output_queue.put(None)
|
|
91
|
+
|
|
92
|
+
print_api.print_api(
|
|
93
|
+
'Finished recs archiver process.', color='blue',
|
|
94
|
+
logger=rec_packer_logger_with_queue_handler
|
|
95
|
+
)
|
|
57
96
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
97
|
+
return archived_files
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print_api.print_api(
|
|
100
|
+
f"Error while archiving recs files: {e}",
|
|
101
|
+
color='red',
|
|
102
|
+
logger=rec_packer_logger_with_queue_handler
|
|
103
|
+
)
|
|
65
104
|
|
|
66
|
-
|
|
105
|
+
finalize_output_queue.put(e)
|
|
106
|
+
return None
|
|
67
107
|
|
|
68
108
|
|
|
69
|
-
def recs_archiver_in_process(
|
|
109
|
+
def recs_archiver_in_process(
|
|
110
|
+
recs_directory: str,
|
|
111
|
+
logging_queue: multiprocessing.Queue,
|
|
112
|
+
logger_name: str,
|
|
113
|
+
finalize_output_queue: multiprocessing.Queue
|
|
114
|
+
) -> multiprocessing.Process:
|
|
70
115
|
"""
|
|
71
116
|
Archive recs files in a directory for each day in a separate process.
|
|
117
|
+
|
|
118
|
+
:param recs_directory: The directory where recordings are stored.
|
|
119
|
+
:param logging_queue: The queue for logging messages.
|
|
120
|
+
:param logger_name: The name of the logger to use for logging.
|
|
121
|
+
:param finalize_output_queue: output queue for results/exceptions.
|
|
72
122
|
"""
|
|
73
123
|
|
|
74
|
-
process = multiprocessing.Process(
|
|
124
|
+
process = multiprocessing.Process(
|
|
125
|
+
target=recs_archiver, args=(recs_directory, logging_queue, logger_name, finalize_output_queue))
|
|
75
126
|
process.start()
|
|
76
127
|
return process
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=sG7TcY0alK20P2ZsB4W-k6VOCCAYaqRHUjArVbqR-I8,122
|
|
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
|
|
@@ -114,7 +114,7 @@ atomicshop/basics/randoms.py,sha256=DmYLtnIhDK29tAQrGP1Nt-A-v8WC7WIEB8Edi-nk3N4,
|
|
|
114
114
|
atomicshop/basics/strings.py,sha256=mT31UXrn4dgfLtNC6PeBwrkuQHtjdPEiP38VaWgpv3w,21217
|
|
115
115
|
atomicshop/basics/threads.py,sha256=LDJiprLqdWU4JnPpCOiIC_tEnyssmCqh-6J3gfrO4QA,3195
|
|
116
116
|
atomicshop/basics/timeit_template.py,sha256=fYLrk-X_dhdVtnPU22tarrhhvlggeW6FdKCXM8zkX68,405
|
|
117
|
-
atomicshop/basics/tracebacks.py,sha256=
|
|
117
|
+
atomicshop/basics/tracebacks.py,sha256=Q10VnbWqcA1tL0tJsq0q1PxQtRehPT_F69DQzRMNdks,842
|
|
118
118
|
atomicshop/etws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
119
|
atomicshop/etws/_pywintrace_fix.py,sha256=nHrtnAb796eOZ6FlCqcsuRh_TSqSPp6JXLN6TBIz-Us,418
|
|
120
120
|
atomicshop/etws/const.py,sha256=v3x_IdCYeSKbCGywiZFOZln80ldpwKW5nuMDuUe51Jg,1257
|
|
@@ -140,8 +140,8 @@ atomicshop/mitm/connection_thread_worker.py,sha256=zo9YVliRtanmt3BDnxlePOuZLYk8H
|
|
|
140
140
|
atomicshop/mitm/import_config.py,sha256=_RJPxoVEEsJQwQY-K_8qPw2PbzsDcV23_sEJEWSKqXY,17831
|
|
141
141
|
atomicshop/mitm/initialize_engines.py,sha256=EYGW6gEYVETmmh9uNdsFT89YAdzeducFTIkdF-as33s,10534
|
|
142
142
|
atomicshop/mitm/message.py,sha256=CDhhm4BTuZE7oNZCjvIZ4BuPOW4MuIzQLOg91hJaxDI,3065
|
|
143
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
144
|
-
atomicshop/mitm/recs_files.py,sha256=
|
|
143
|
+
atomicshop/mitm/mitm_main.py,sha256=StOAvsswTx325kVIXjHiH97QP2Syxq5o0mnoeiPsy_4,32149
|
|
144
|
+
atomicshop/mitm/recs_files.py,sha256=tv8XFhYZMkBv4DauvpiAdPgvSo0Bcm1CghnmwO7dx8M,5018
|
|
145
145
|
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
146
146
|
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
147
147
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -323,7 +323,7 @@ atomicshop/wrappers/socketw/accepter.py,sha256=4I9ORugRDvwaqSzm_gWSjZnRwQGY8hDTl
|
|
|
323
323
|
atomicshop/wrappers/socketw/base.py,sha256=EcosGkD8VzgBY3GeIHDSG29ThQfXwg3-GQPmBTAqTdw,3048
|
|
324
324
|
atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
|
|
325
325
|
atomicshop/wrappers/socketw/creator.py,sha256=LGI4gcgJ47thx6f96rjwjPz3CsTAIv6VxWFY4EyUF2E,13667
|
|
326
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
326
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=6dtZT3foDy4tKGQKC7JL1eN4kWfUYCepVm8nUA4lpoo,54026
|
|
327
327
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=qW_1CKyPgGlsIt7_jusKkMV4A4hih4bX324u0PLnoO8,7382
|
|
328
328
|
atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
|
|
329
329
|
atomicshop/wrappers/socketw/receiver.py,sha256=9B3MvcDqr4C3x2fsnjG5SQognd1wRqsBgikxZa0wXG8,8243
|
|
@@ -337,8 +337,8 @@ atomicshop/wrappers/socketw/statistics_csv.py,sha256=WcNyaqEZ82S5-f3kzqi1nllNT2N
|
|
|
337
337
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
338
338
|
atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
|
|
339
339
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=ih0BVNwByLvf9F_Lac4EdmDYYJA3PzMvmG0PieDZrsE,9905
|
|
340
|
-
atomicshop-3.2.
|
|
341
|
-
atomicshop-3.2.
|
|
342
|
-
atomicshop-3.2.
|
|
343
|
-
atomicshop-3.2.
|
|
344
|
-
atomicshop-3.2.
|
|
340
|
+
atomicshop-3.2.7.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
341
|
+
atomicshop-3.2.7.dist-info/METADATA,sha256=hKbsS8KlBcIbX6dTG7pDOCtn9y_Do92GHr_LVnsf2ps,10670
|
|
342
|
+
atomicshop-3.2.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
343
|
+
atomicshop-3.2.7.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
344
|
+
atomicshop-3.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|