atomicshop 2.16.16__py3-none-any.whl → 2.16.18__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/mitm/statistic_analyzer_helper/moving_average_helper.py +6 -6
- atomicshop/wrappers/loggingw/loggers.py +11 -0
- atomicshop/wrappers/loggingw/loggingw.py +10 -0
- atomicshop/wrappers/loggingw/reading.py +2 -2
- atomicshop/wrappers/mongodbw/mongo_infra.py +8 -0
- atomicshop/wrappers/mongodbw/mongodbw.py +576 -29
- {atomicshop-2.16.16.dist-info → atomicshop-2.16.18.dist-info}/METADATA +1 -1
- {atomicshop-2.16.16.dist-info → atomicshop-2.16.18.dist-info}/RECORD +12 -12
- {atomicshop-2.16.16.dist-info → atomicshop-2.16.18.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.16.dist-info → atomicshop-2.16.18.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.16.dist-info → atomicshop-2.16.18.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Literal
|
|
|
5
5
|
from ...print_api import print_api
|
|
6
6
|
from ...wrappers.loggingw import reading, consts
|
|
7
7
|
from ...file_io import csvs
|
|
8
|
-
from ... import urls
|
|
8
|
+
from ... import urls, filesystem
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def calculate_moving_average(
|
|
@@ -43,7 +43,7 @@ def calculate_moving_average(
|
|
|
43
43
|
date_format: str = consts.DEFAULT_ROTATING_SUFFIXES_FROM_WHEN['midnight']
|
|
44
44
|
|
|
45
45
|
# Get all the file paths and their midnight rotations.
|
|
46
|
-
logs_paths: list = reading.get_logs_paths(
|
|
46
|
+
logs_paths: list[filesystem.AtomicPath] = reading.get_logs_paths(
|
|
47
47
|
log_file_path=file_path,
|
|
48
48
|
date_format=date_format
|
|
49
49
|
)
|
|
@@ -54,14 +54,14 @@ def calculate_moving_average(
|
|
|
54
54
|
|
|
55
55
|
statistics_content: dict = {}
|
|
56
56
|
# Read each file to its day.
|
|
57
|
-
for
|
|
58
|
-
date_string =
|
|
57
|
+
for log_atomic_path in logs_paths:
|
|
58
|
+
date_string = log_atomic_path.datetime_string
|
|
59
59
|
statistics_content[date_string] = {}
|
|
60
60
|
|
|
61
|
-
statistics_content[date_string]['file'] =
|
|
61
|
+
statistics_content[date_string]['file'] = log_atomic_path
|
|
62
62
|
|
|
63
63
|
log_file_content, log_file_header = (
|
|
64
|
-
csvs.read_csv_to_list_of_dicts_by_header(
|
|
64
|
+
csvs.read_csv_to_list_of_dicts_by_header(log_atomic_path.path, **(print_kwargs or {})))
|
|
65
65
|
statistics_content[date_string]['content'] = log_file_content
|
|
66
66
|
statistics_content[date_string]['header'] = log_file_header
|
|
67
67
|
|
|
@@ -14,6 +14,17 @@ import logging
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
def is_logger_exists(
|
|
18
|
+
logger_name: str
|
|
19
|
+
) -> bool:
|
|
20
|
+
"""
|
|
21
|
+
Function to check if the logger exists.
|
|
22
|
+
:param logger_name: str, Name of the logger.
|
|
23
|
+
:return: bool, True if the logger exists, False otherwise.
|
|
24
|
+
"""
|
|
25
|
+
return logger_name in logging.Logger.manager.loggerDict
|
|
26
|
+
|
|
27
|
+
|
|
17
28
|
def get_logger(logger_name: str) -> logging.Logger:
|
|
18
29
|
"""
|
|
19
30
|
Function to get a logger.
|
|
@@ -8,6 +8,7 @@ from . import loggers, handlers
|
|
|
8
8
|
# noinspection PyPep8Naming
|
|
9
9
|
def create_logger(
|
|
10
10
|
logger_name: str,
|
|
11
|
+
get_existing_if_exists: bool = True,
|
|
11
12
|
file_path: str = None,
|
|
12
13
|
directory_path: str = None,
|
|
13
14
|
add_stream: bool = False,
|
|
@@ -42,6 +43,8 @@ def create_logger(
|
|
|
42
43
|
Function to get a logger and add StreamHandler and TimedRotatingFileHandler to it.
|
|
43
44
|
|
|
44
45
|
:param logger_name: Name of the logger.
|
|
46
|
+
:param get_existing_if_exists: bool, If set to True, the logger will be returned if it already exists.
|
|
47
|
+
If set to False, the new stream/file handler will be added to existing logger again.
|
|
45
48
|
:param file_path: full path to the log file. If you don't want to use the file, set it to None.
|
|
46
49
|
You can set the directory_path only and then the 'logger_name' will be used as the file name with the
|
|
47
50
|
'file_type' as the file extension.
|
|
@@ -173,8 +176,15 @@ def create_logger(
|
|
|
173
176
|
|
|
174
177
|
file_path = f"{directory_path}{os.sep}{logger_name}.{file_type}"
|
|
175
178
|
|
|
179
|
+
# Check if the logger exists before creating it/getting the existing.
|
|
180
|
+
is_logger_exists = loggers.is_logger_exists(logger_name)
|
|
181
|
+
|
|
176
182
|
logger = get_logger_with_level(logger_name, logging_level)
|
|
177
183
|
|
|
184
|
+
# If the logger already exists, and we don't want to add the handlers again, return the logger.
|
|
185
|
+
if get_existing_if_exists and is_logger_exists:
|
|
186
|
+
return logger
|
|
187
|
+
|
|
178
188
|
if add_stream:
|
|
179
189
|
handlers.add_stream_handler(
|
|
180
190
|
logger=logger, logging_level=logging_level, formatter=formatter_streamhandler,
|
|
@@ -14,7 +14,7 @@ def get_logs_paths(
|
|
|
14
14
|
latest_only: bool = False,
|
|
15
15
|
previous_day_only: bool = False,
|
|
16
16
|
specific_date: str = None
|
|
17
|
-
):
|
|
17
|
+
) -> list[filesystem.AtomicPath]:
|
|
18
18
|
"""
|
|
19
19
|
This function gets the logs file paths from the directory. Supports rotating files to get the logs by time.
|
|
20
20
|
|
|
@@ -61,7 +61,7 @@ def get_logs_paths(
|
|
|
61
61
|
log_files_directory_path: str = str(Path(log_file_path).parent)
|
|
62
62
|
|
|
63
63
|
# Get all the log file paths by the file_name_pattern and the date_format string.
|
|
64
|
-
logs_files: list = filesystem.get_paths_from_directory(
|
|
64
|
+
logs_files: list[filesystem.AtomicPath] = filesystem.get_paths_from_directory(
|
|
65
65
|
log_files_directory_path,
|
|
66
66
|
get_file=True,
|
|
67
67
|
file_name_check_pattern=file_name_pattern,
|
|
@@ -23,6 +23,14 @@ def test_connection(
|
|
|
23
23
|
uri: str = MONGODB_DEFAULT_URI,
|
|
24
24
|
raise_exception: bool = False
|
|
25
25
|
) -> bool:
|
|
26
|
+
"""
|
|
27
|
+
Test the connection to the MongoDB server.
|
|
28
|
+
|
|
29
|
+
:param uri: str, URI to the MongoDB server.
|
|
30
|
+
:param raise_exception: bool, True to raise an exception if the connection fails, False otherwise (just return
|
|
31
|
+
False).
|
|
32
|
+
:return: bool, True if the connection is successful, False otherwise.
|
|
33
|
+
"""
|
|
26
34
|
try:
|
|
27
35
|
client = MongoClient(uri)
|
|
28
36
|
client.admin.command('ping')
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
from typing import Union
|
|
1
|
+
from typing import Union, Literal
|
|
2
2
|
import datetime
|
|
3
|
+
import json
|
|
3
4
|
|
|
5
|
+
# noinspection PyPackageRequirements
|
|
4
6
|
import pymongo
|
|
7
|
+
# noinspection PyPackageRequirements
|
|
8
|
+
import pymongo.database
|
|
5
9
|
|
|
6
10
|
from ...basics import dicts
|
|
7
11
|
|
|
@@ -14,6 +18,253 @@ These are good examples to get you started, but can't really cover all the use c
|
|
|
14
18
|
"""
|
|
15
19
|
|
|
16
20
|
|
|
21
|
+
class MongoDBWrapper:
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
db_name: str,
|
|
25
|
+
uri: str = mongo_infra.MONGODB_DEFAULT_URI
|
|
26
|
+
):
|
|
27
|
+
self.db_name: str = db_name
|
|
28
|
+
self.uri: str = uri
|
|
29
|
+
|
|
30
|
+
# noinspection PyTypeChecker
|
|
31
|
+
self.client: pymongo.MongoClient = None
|
|
32
|
+
# noinspection PyTypeChecker
|
|
33
|
+
self.db: pymongo.database.Database = None
|
|
34
|
+
|
|
35
|
+
def connect(self):
|
|
36
|
+
"""
|
|
37
|
+
Connect to a MongoDB database.
|
|
38
|
+
:return: pymongo.MongoClient, the client object.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
if not self.client:
|
|
42
|
+
self.client = connect(uri=self.uri)
|
|
43
|
+
self.db = get_db(database=self.db_name, mongo_client=self.client)
|
|
44
|
+
|
|
45
|
+
def disconnect(self):
|
|
46
|
+
"""
|
|
47
|
+
Disconnect from a MongoDB database.
|
|
48
|
+
:return: None
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
if self.client:
|
|
52
|
+
self.client.close()
|
|
53
|
+
self.client = None
|
|
54
|
+
|
|
55
|
+
def index(
|
|
56
|
+
self,
|
|
57
|
+
object_instance: Union[list[dict], dict],
|
|
58
|
+
collection_name: str,
|
|
59
|
+
add_timestamp: bool = False,
|
|
60
|
+
convert_mixed_lists_to_strings: bool = False
|
|
61
|
+
):
|
|
62
|
+
"""
|
|
63
|
+
Add a dictionary or list dictionaries to a MongoDB collection.
|
|
64
|
+
:param object_instance: list of dictionaries or dictionary to add to the collection.
|
|
65
|
+
:param collection_name: str, the name of the collection.
|
|
66
|
+
:param add_timestamp: bool, if True, a current time timestamp will be added to the object.
|
|
67
|
+
:param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are
|
|
68
|
+
strings and integers, the integers will be converted to strings.
|
|
69
|
+
|
|
70
|
+
:return: None
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
self.connect()
|
|
74
|
+
|
|
75
|
+
index(
|
|
76
|
+
object_instance=object_instance,
|
|
77
|
+
database=self.db, collection_name=collection_name,
|
|
78
|
+
add_timestamp=add_timestamp, convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
|
|
79
|
+
mongo_client=self.client, close_client=False)
|
|
80
|
+
|
|
81
|
+
def delete(
|
|
82
|
+
self,
|
|
83
|
+
object_instance: Union[list[dict], dict],
|
|
84
|
+
collection_name: str
|
|
85
|
+
):
|
|
86
|
+
"""
|
|
87
|
+
Remove a list of dictionaries or a dictionary from a MongoDB collection.
|
|
88
|
+
|
|
89
|
+
:param object_instance: list of dictionaries, the list of dictionaries to remove from the collection.
|
|
90
|
+
:param collection_name: str, the name of the collection.
|
|
91
|
+
|
|
92
|
+
:return: None
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
self.connect()
|
|
96
|
+
|
|
97
|
+
delete(
|
|
98
|
+
object_instance=object_instance,
|
|
99
|
+
database=self.db, collection_name=collection_name,
|
|
100
|
+
mongo_client=self.client, close_client=False)
|
|
101
|
+
|
|
102
|
+
def find(
|
|
103
|
+
self,
|
|
104
|
+
collection_name: str,
|
|
105
|
+
query: dict = None,
|
|
106
|
+
page: int = None,
|
|
107
|
+
items: int = None,
|
|
108
|
+
sorting: dict[str, Literal[
|
|
109
|
+
'asc', 'desc',
|
|
110
|
+
1, -1]] = None,
|
|
111
|
+
convert_object_id_to_str: bool = False,
|
|
112
|
+
keys_convert_to_dict: list[str] = None
|
|
113
|
+
) -> list[dict]:
|
|
114
|
+
"""
|
|
115
|
+
Find entries in a MongoDB collection by query.
|
|
116
|
+
:param collection_name: str, the name of the collection.
|
|
117
|
+
:param query: dict, the query to search for.
|
|
118
|
+
Example, search for all entries with column name 'name' equal to 'John':
|
|
119
|
+
query = {'name': 'John'}
|
|
120
|
+
Example, return all entries from collection:
|
|
121
|
+
query = None
|
|
122
|
+
|
|
123
|
+
CHECK MORE EXAMPLES IN THE DOCSTRING OF THE FUNCTION 'find' BELOW which is not in this class.
|
|
124
|
+
:param page: int, the page number (Optional).
|
|
125
|
+
The results are filtered after results are fetched from db.
|
|
126
|
+
:param items: int, the number of results per page (Optional).
|
|
127
|
+
The results are filtered after results are fetched from db.
|
|
128
|
+
:param sorting: dict, the name of the field and the order to sort the containers by.
|
|
129
|
+
You can use several fields to sort the containers by several fields.
|
|
130
|
+
In this case the containers will be sorted by the first field, then by the second field, etc.
|
|
131
|
+
You can also use only singular field to sort the containers by only one field.
|
|
132
|
+
Usage:
|
|
133
|
+
{
|
|
134
|
+
field_name: order
|
|
135
|
+
}
|
|
136
|
+
Example:
|
|
137
|
+
{
|
|
138
|
+
'vendor': 'asc',
|
|
139
|
+
'model': 'desc'
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Or example using integers:
|
|
143
|
+
{
|
|
144
|
+
'vendor': 1,
|
|
145
|
+
'model': -1
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:param convert_object_id_to_str: bool, if True, the '_id' field will be converted to a string.
|
|
149
|
+
The '_id' field is an ObjectId type, which is a complex object, it can be converted to a string for simpler
|
|
150
|
+
processing.
|
|
151
|
+
:param keys_convert_to_dict: list, the keys of the documents that should be converted from string to dict.
|
|
152
|
+
Recursively searches for keys in specified list in a nested dictionary in result entries list,
|
|
153
|
+
and converts their values using 'json.loads' if found.
|
|
154
|
+
:return: list of dictionaries, the list of entries that match the query.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
self.connect()
|
|
158
|
+
|
|
159
|
+
entries: list[dict] = find(
|
|
160
|
+
database=self.db, collection_name=collection_name,
|
|
161
|
+
query=query, page=page, items=items, sorting=sorting,
|
|
162
|
+
convert_object_id_to_str=convert_object_id_to_str, key_convert_to_dict=keys_convert_to_dict,
|
|
163
|
+
mongo_client=self.client, close_client=False)
|
|
164
|
+
|
|
165
|
+
return entries
|
|
166
|
+
|
|
167
|
+
def distinct(
|
|
168
|
+
self,
|
|
169
|
+
collection_name: str,
|
|
170
|
+
field_name: str,
|
|
171
|
+
query: dict = None
|
|
172
|
+
) -> list:
|
|
173
|
+
"""
|
|
174
|
+
Get distinct values of a field from a MongoDB collection.
|
|
175
|
+
Example:
|
|
176
|
+
Example database:
|
|
177
|
+
{
|
|
178
|
+
'users': [
|
|
179
|
+
{'name': 'John', 'age': 25},
|
|
180
|
+
{'name': 'John', 'age': 30},
|
|
181
|
+
{'name': 'Alice', 'age': 25}
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
Get distinct values of the field 'name' from the collection 'users':
|
|
186
|
+
distinct('users', 'name')
|
|
187
|
+
|
|
188
|
+
Output:
|
|
189
|
+
['John', 'Alice']
|
|
190
|
+
|
|
191
|
+
:param collection_name: str, the name of the collection.
|
|
192
|
+
:param field_name: str, the name of the field.
|
|
193
|
+
:param query: dict, the query to search for. If None, the query will not be executed.
|
|
194
|
+
|
|
195
|
+
:return: list, the list of distinct values.
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
self.connect()
|
|
199
|
+
|
|
200
|
+
distinct_values = distinct(
|
|
201
|
+
database=self.db, collection_name=collection_name,
|
|
202
|
+
field_name=field_name, query=query, mongo_client=self.client, close_client=False)
|
|
203
|
+
|
|
204
|
+
return distinct_values
|
|
205
|
+
|
|
206
|
+
def count_entries_in_collection(
|
|
207
|
+
self,
|
|
208
|
+
collection_name: str,
|
|
209
|
+
query: dict = None
|
|
210
|
+
) -> int:
|
|
211
|
+
"""
|
|
212
|
+
Count entries in a MongoDB collection by query.
|
|
213
|
+
|
|
214
|
+
:param collection_name: str, the name of the collection.
|
|
215
|
+
:param query: dict, the query to search for.
|
|
216
|
+
Example, search for all entries with column name 'name' equal to 'John':
|
|
217
|
+
query = {'name': 'John'}
|
|
218
|
+
Example, return all entries from collection:
|
|
219
|
+
query = None
|
|
220
|
+
|
|
221
|
+
:return: int, the number of entries that match the query.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
self.connect()
|
|
225
|
+
|
|
226
|
+
count = count_entries_in_collection(
|
|
227
|
+
database=self.db, collection_name=collection_name,
|
|
228
|
+
query=query, mongo_client=self.client, close_client=False)
|
|
229
|
+
|
|
230
|
+
return count
|
|
231
|
+
|
|
232
|
+
def get_client(self):
|
|
233
|
+
return self.client
|
|
234
|
+
|
|
235
|
+
def get_stats_db(
|
|
236
|
+
self
|
|
237
|
+
):
|
|
238
|
+
"""
|
|
239
|
+
Get the stats of a MongoDB database.
|
|
240
|
+
|
|
241
|
+
:return: dict, the stats of the collection.
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
self.connect()
|
|
245
|
+
|
|
246
|
+
stats = get_stats_db(
|
|
247
|
+
database=self.db, mongo_client=self.client, close_client=False)
|
|
248
|
+
|
|
249
|
+
return stats
|
|
250
|
+
|
|
251
|
+
def get_stats_db_size(
|
|
252
|
+
self
|
|
253
|
+
):
|
|
254
|
+
"""
|
|
255
|
+
Get the size of a MongoDB database in bytes.
|
|
256
|
+
|
|
257
|
+
:return: int, the size of the database in bytes.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
self.connect()
|
|
261
|
+
|
|
262
|
+
size = get_stats_db_size(
|
|
263
|
+
database=self.db, mongo_client=self.client, close_client=False)
|
|
264
|
+
|
|
265
|
+
return size
|
|
266
|
+
|
|
267
|
+
|
|
17
268
|
def connect(uri: str = mongo_infra.MONGODB_DEFAULT_URI):
|
|
18
269
|
"""
|
|
19
270
|
Connect to a MongoDB database.
|
|
@@ -23,9 +274,27 @@ def connect(uri: str = mongo_infra.MONGODB_DEFAULT_URI):
|
|
|
23
274
|
return pymongo.MongoClient(uri)
|
|
24
275
|
|
|
25
276
|
|
|
277
|
+
def get_db(
|
|
278
|
+
database: str,
|
|
279
|
+
mongo_client: pymongo.MongoClient = None
|
|
280
|
+
) -> pymongo.database.Database:
|
|
281
|
+
"""
|
|
282
|
+
Get a MongoDB database object.
|
|
283
|
+
:param database: String, the name of the database.
|
|
284
|
+
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
285
|
+
If None, a new connection will be created to default URI.
|
|
286
|
+
:return: pymongo.database.Database, the database object.
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
if not mongo_client:
|
|
290
|
+
mongo_client = connect()
|
|
291
|
+
|
|
292
|
+
return mongo_client[database]
|
|
293
|
+
|
|
294
|
+
|
|
26
295
|
def index(
|
|
27
296
|
object_instance: Union[list[dict], dict],
|
|
28
|
-
|
|
297
|
+
database: Union[str, pymongo.database.Database],
|
|
29
298
|
collection_name: str,
|
|
30
299
|
add_timestamp: bool = False,
|
|
31
300
|
convert_mixed_lists_to_strings: bool = False,
|
|
@@ -35,7 +304,9 @@ def index(
|
|
|
35
304
|
"""
|
|
36
305
|
Add a dictionary or list dictionaries to a MongoDB collection.
|
|
37
306
|
:param object_instance: list of dictionaries or dictionary to add to the collection.
|
|
38
|
-
:param
|
|
307
|
+
:param database: String or the database object.
|
|
308
|
+
str - the name of the database. In this case the database object will be created.
|
|
309
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
39
310
|
:param collection_name: str, the name of the collection.
|
|
40
311
|
:param add_timestamp: bool, if True, a current time timestamp will be added to the object.
|
|
41
312
|
:param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are strings and integers,
|
|
@@ -53,7 +324,7 @@ def index(
|
|
|
53
324
|
mongo_client = connect()
|
|
54
325
|
close_client = True
|
|
55
326
|
|
|
56
|
-
db = mongo_client
|
|
327
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
57
328
|
collection = db[collection_name]
|
|
58
329
|
|
|
59
330
|
if convert_mixed_lists_to_strings:
|
|
@@ -78,7 +349,7 @@ def index(
|
|
|
78
349
|
|
|
79
350
|
def delete(
|
|
80
351
|
object_instance: Union[list[dict], dict],
|
|
81
|
-
|
|
352
|
+
database: Union[str, pymongo.database.Database],
|
|
82
353
|
collection_name: str,
|
|
83
354
|
mongo_client: pymongo.MongoClient = None,
|
|
84
355
|
close_client: bool = False
|
|
@@ -87,7 +358,9 @@ def delete(
|
|
|
87
358
|
Remove a list of dictionaries or a dictionary from a MongoDB collection.
|
|
88
359
|
|
|
89
360
|
:param object_instance: list of dictionaries, the list of dictionaries to remove from the collection.
|
|
90
|
-
:param
|
|
361
|
+
:param database: String or the database object.
|
|
362
|
+
str - the name of the database. In this case the database object will be created.
|
|
363
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
91
364
|
:param collection_name: str, the name of the collection.
|
|
92
365
|
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
93
366
|
If None, a new connection will be created to default URI.
|
|
@@ -102,7 +375,7 @@ def delete(
|
|
|
102
375
|
mongo_client = connect()
|
|
103
376
|
close_client = True
|
|
104
377
|
|
|
105
|
-
db = mongo_client
|
|
378
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
106
379
|
collection = db[collection_name]
|
|
107
380
|
|
|
108
381
|
if isinstance(object_instance, dict):
|
|
@@ -116,21 +389,91 @@ def delete(
|
|
|
116
389
|
|
|
117
390
|
|
|
118
391
|
def find(
|
|
119
|
-
|
|
392
|
+
database: Union[str, pymongo.database.Database],
|
|
120
393
|
collection_name: str,
|
|
121
394
|
query: dict = None,
|
|
395
|
+
page: int = None,
|
|
396
|
+
items: int = None,
|
|
397
|
+
sorting: dict[str, Literal[
|
|
398
|
+
'asc', 'desc',
|
|
399
|
+
1, -1]] = None,
|
|
400
|
+
convert_object_id_to_str: bool = False,
|
|
401
|
+
key_convert_to_dict: list[str] = None,
|
|
122
402
|
mongo_client: pymongo.MongoClient = None,
|
|
123
403
|
close_client: bool = False
|
|
124
|
-
):
|
|
404
|
+
) -> list[dict]:
|
|
125
405
|
"""
|
|
126
406
|
Find entries in a MongoDB collection by query.
|
|
127
|
-
:param
|
|
407
|
+
:param database: String or the database object.
|
|
408
|
+
str - the name of the database. In this case the database object will be created.
|
|
409
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
128
410
|
:param collection_name: str, the name of the collection.
|
|
129
411
|
:param query: dict, the query to search for.
|
|
130
|
-
Example, search for all entries with column name 'name' equal to 'John':
|
|
131
|
-
query = {'name': 'John'}
|
|
132
412
|
Example, return all entries from collection:
|
|
133
413
|
query = None
|
|
414
|
+
Example, search for all entries with column name 'name' equal to 'John':
|
|
415
|
+
query = {'name': 'John'}
|
|
416
|
+
|
|
417
|
+
Additional parameters to use in the value of the query:
|
|
418
|
+
$regex: Will search for a regex pattern in the field.
|
|
419
|
+
Example for searching for a value that contains 'test':
|
|
420
|
+
query = {'field_name': {'$regex': 'test'}}
|
|
421
|
+
This will return all entries where the field 'field_name' contains the word 'test':
|
|
422
|
+
'test', 'test1', '2test', etc.
|
|
423
|
+
|
|
424
|
+
Example for searching for a value that starts with 'test':
|
|
425
|
+
query = {'field_name': {'$regex': '^test'}}
|
|
426
|
+
$options: The options for the regex search.
|
|
427
|
+
'i': case-insensitive search.
|
|
428
|
+
Example for case-insensitive search:
|
|
429
|
+
query = {'field_name': {'$regex': 'test', '$options': 'i'}}
|
|
430
|
+
$and: Will search for entries that match all the conditions.
|
|
431
|
+
Example for searching for entries that match all the conditions:
|
|
432
|
+
query = {'$and': [
|
|
433
|
+
{'field_name1': 'value1'},
|
|
434
|
+
{'field_name2': 'value2'}
|
|
435
|
+
]}
|
|
436
|
+
$or: Will search for entries that match at least one of the conditions.
|
|
437
|
+
Example for searching for entries that match at least one of the conditions:
|
|
438
|
+
query = {'$or': [
|
|
439
|
+
{'field_name1': 'value1'},
|
|
440
|
+
{'field_name2': 'value2'}
|
|
441
|
+
]}
|
|
442
|
+
$in: Will search for a value in a list of values.
|
|
443
|
+
Example for searching for a value that is in a list of values:
|
|
444
|
+
query = {'field_name': {'$in': ['value1', 'value2', 'value3']}}
|
|
445
|
+
$nin: Will search for a value not in a list of values.
|
|
446
|
+
Example for searching for a value that is not in a list of values:
|
|
447
|
+
query = {'field_name': {'$nin': ['value1', 'value2', 'value3']}}
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
:param page: int, the page number (Optional).
|
|
451
|
+
:param items: int, the number of results per page (Optional).
|
|
452
|
+
:param sorting: dict, the name of the field and the order to sort the containers by.
|
|
453
|
+
You can use several fields to sort the containers by several fields.
|
|
454
|
+
In this case the containers will be sorted by the first field, then by the second field, etc.
|
|
455
|
+
You can also use only singular field to sort the containers by only one field.
|
|
456
|
+
Usage:
|
|
457
|
+
{
|
|
458
|
+
field_name: order
|
|
459
|
+
}
|
|
460
|
+
Example:
|
|
461
|
+
{
|
|
462
|
+
'vendor': 'asc',
|
|
463
|
+
'model': 'desc'
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
Or example using integers:
|
|
467
|
+
{
|
|
468
|
+
'vendor': 1,
|
|
469
|
+
'model': -1
|
|
470
|
+
}
|
|
471
|
+
:param convert_object_id_to_str: bool, if True, the '_id' field will be converted to a string.
|
|
472
|
+
The '_id' field is an ObjectId type, which is a complex object, it can be converted to a string for simpler
|
|
473
|
+
processing.
|
|
474
|
+
:param key_convert_to_dict: list, the keys of the documents that should be converted from string to dict.
|
|
475
|
+
Recursively searches for keys in specified list in a nested dictionary in result entries list,
|
|
476
|
+
and converts their values using 'json.loads' if found.
|
|
134
477
|
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
135
478
|
If None, a new connection will be created to default URI.
|
|
136
479
|
:param close_client: bool, if True, the connection will be closed after the operation.
|
|
@@ -138,17 +481,58 @@ def find(
|
|
|
138
481
|
:return: list of dictionaries, the list of entries that match the query.
|
|
139
482
|
"""
|
|
140
483
|
|
|
484
|
+
if page and not items:
|
|
485
|
+
raise ValueError("If 'page' is provided, 'items' must be provided as well.")
|
|
486
|
+
elif items and not page:
|
|
487
|
+
page = 1
|
|
488
|
+
|
|
489
|
+
if sorting:
|
|
490
|
+
for key_to_sort_by, order in sorting.items():
|
|
491
|
+
if order not in ['asc', 'desc', 1, -1]:
|
|
492
|
+
raise ValueError("The order must be 'asc', 'desc', 1 or -1.")
|
|
493
|
+
|
|
141
494
|
if not mongo_client:
|
|
142
495
|
mongo_client = connect()
|
|
143
496
|
close_client = True
|
|
144
497
|
|
|
145
|
-
db = mongo_client
|
|
498
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
146
499
|
collection = db[collection_name]
|
|
147
500
|
|
|
148
501
|
if query is None:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
502
|
+
query = {}
|
|
503
|
+
|
|
504
|
+
# Calculate the number of documents to skip
|
|
505
|
+
skip_items = 0
|
|
506
|
+
if page and items:
|
|
507
|
+
skip_items = (page - 1) * items
|
|
508
|
+
|
|
509
|
+
collection_items = collection.find(query)
|
|
510
|
+
|
|
511
|
+
if sorting:
|
|
512
|
+
sorting_list_of_tuples: list[tuple[str, int]] = []
|
|
513
|
+
for key_to_sort_by, order in sorting.items():
|
|
514
|
+
if order == 'asc':
|
|
515
|
+
order = pymongo.ASCENDING
|
|
516
|
+
elif order == 'desc':
|
|
517
|
+
order = pymongo.DESCENDING
|
|
518
|
+
|
|
519
|
+
sorting_list_of_tuples.append((key_to_sort_by, order))
|
|
520
|
+
|
|
521
|
+
collection_items = collection_items.sort(sorting_list_of_tuples)
|
|
522
|
+
|
|
523
|
+
# 'skip_items' can be 0, if we ask for the first page, so we still need to cut the number of items.
|
|
524
|
+
# In this case checking if 'items' is not None is enough.
|
|
525
|
+
if items:
|
|
526
|
+
collection_items = collection_items.skip(skip_items).limit(items)
|
|
527
|
+
|
|
528
|
+
entries: list[dict] = list(collection_items)
|
|
529
|
+
|
|
530
|
+
if convert_object_id_to_str:
|
|
531
|
+
for entry_index, entry in enumerate(entries):
|
|
532
|
+
entries[entry_index]['_id'] = str(entry['_id'])
|
|
533
|
+
|
|
534
|
+
if key_convert_to_dict and entries:
|
|
535
|
+
entries = _convert_key_values_to_objects(keys_convert_to_dict=key_convert_to_dict, returned_data=entries)
|
|
152
536
|
|
|
153
537
|
if close_client:
|
|
154
538
|
mongo_client.close()
|
|
@@ -156,15 +540,116 @@ def find(
|
|
|
156
540
|
return entries
|
|
157
541
|
|
|
158
542
|
|
|
543
|
+
def distinct(
|
|
544
|
+
database: Union[str, pymongo.database.Database],
|
|
545
|
+
collection_name: str,
|
|
546
|
+
field_name: str,
|
|
547
|
+
query: dict = None,
|
|
548
|
+
mongo_client: pymongo.MongoClient = None,
|
|
549
|
+
close_client: bool = False
|
|
550
|
+
) -> list:
|
|
551
|
+
"""
|
|
552
|
+
Get distinct values of a field from a MongoDB collection.
|
|
553
|
+
Example:
|
|
554
|
+
Example database:
|
|
555
|
+
{
|
|
556
|
+
'users': [
|
|
557
|
+
{'name': 'John', 'age': 25},
|
|
558
|
+
{'name': 'John', 'age': 30},
|
|
559
|
+
{'name': 'Alice', 'age': 25}
|
|
560
|
+
]
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
Get distinct values of the field 'name' from the collection 'users':
|
|
564
|
+
distinct('my_db', 'users', 'name')
|
|
565
|
+
|
|
566
|
+
Output:
|
|
567
|
+
['John', 'Alice']
|
|
568
|
+
|
|
569
|
+
:param database: String or the database object.
|
|
570
|
+
str - the name of the database. In this case the database object will be created.
|
|
571
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
572
|
+
:param collection_name: str, the name of the collection.
|
|
573
|
+
:param field_name: str, the name of the field.
|
|
574
|
+
:param query: dict, the query to search for.
|
|
575
|
+
If None, the query will not be executed.
|
|
576
|
+
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
577
|
+
If None, a new connection will be created to default URI.
|
|
578
|
+
:param close_client: bool, if True, the connection will be closed after the operation.
|
|
579
|
+
|
|
580
|
+
:return: list, the list of distinct values.
|
|
581
|
+
"""
|
|
582
|
+
|
|
583
|
+
if not mongo_client:
|
|
584
|
+
mongo_client = connect()
|
|
585
|
+
close_client = True
|
|
586
|
+
|
|
587
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
588
|
+
collection = db[collection_name]
|
|
589
|
+
|
|
590
|
+
distinct_values = collection.distinct(field_name, query)
|
|
591
|
+
|
|
592
|
+
if close_client:
|
|
593
|
+
mongo_client.close()
|
|
594
|
+
|
|
595
|
+
return distinct_values
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
def count_entries_in_collection(
|
|
599
|
+
database: Union[str, pymongo.database.Database],
|
|
600
|
+
collection_name: str,
|
|
601
|
+
query: dict = None,
|
|
602
|
+
mongo_client: pymongo.MongoClient = None,
|
|
603
|
+
close_client: bool = False
|
|
604
|
+
) -> int:
|
|
605
|
+
"""
|
|
606
|
+
Count entries in a MongoDB collection by query.
|
|
607
|
+
|
|
608
|
+
:param database: String or the database object.
|
|
609
|
+
str - the name of the database. In this case the database object will be created.
|
|
610
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
611
|
+
:param collection_name: str, the name of the collection.
|
|
612
|
+
:param query: dict, the query to search for.
|
|
613
|
+
Example, search for all entries with column name 'name' equal to 'John':
|
|
614
|
+
query = {'name': 'John'}
|
|
615
|
+
Example, return all entries from collection:
|
|
616
|
+
query = None
|
|
617
|
+
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
618
|
+
If None, a new connection will be created to default URI.
|
|
619
|
+
:param close_client: bool, if True, the connection will be closed after the operation.
|
|
620
|
+
|
|
621
|
+
:return: int, the number of entries that match the query.
|
|
622
|
+
"""
|
|
623
|
+
|
|
624
|
+
if not mongo_client:
|
|
625
|
+
mongo_client = connect()
|
|
626
|
+
close_client = True
|
|
627
|
+
|
|
628
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
629
|
+
collection = db[collection_name]
|
|
630
|
+
|
|
631
|
+
if query is None:
|
|
632
|
+
query = {}
|
|
633
|
+
|
|
634
|
+
count = collection.count_documents(query)
|
|
635
|
+
|
|
636
|
+
if close_client:
|
|
637
|
+
mongo_client.close()
|
|
638
|
+
|
|
639
|
+
return count
|
|
640
|
+
|
|
641
|
+
|
|
159
642
|
def delete_all_entries_from_collection(
|
|
160
|
-
|
|
643
|
+
database: Union[str, pymongo.database.Database],
|
|
161
644
|
collection_name: str,
|
|
162
645
|
mongo_client: pymongo.MongoClient = None,
|
|
163
646
|
close_client: bool = False
|
|
164
647
|
):
|
|
165
648
|
"""
|
|
166
649
|
Remove all entries from a MongoDB collection.
|
|
167
|
-
:param
|
|
650
|
+
:param database: String or the database object.
|
|
651
|
+
str - the name of the database. In this case the database object will be created.
|
|
652
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
168
653
|
:param collection_name: str, the name of the collection.
|
|
169
654
|
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
170
655
|
If None, a new connection will be created to default URI.
|
|
@@ -177,7 +662,7 @@ def delete_all_entries_from_collection(
|
|
|
177
662
|
mongo_client = connect()
|
|
178
663
|
close_client = True
|
|
179
664
|
|
|
180
|
-
db = mongo_client
|
|
665
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
181
666
|
collection = db[collection_name]
|
|
182
667
|
|
|
183
668
|
collection.delete_many({})
|
|
@@ -188,7 +673,7 @@ def delete_all_entries_from_collection(
|
|
|
188
673
|
|
|
189
674
|
def overwrite_collection(
|
|
190
675
|
object_instance: list,
|
|
191
|
-
|
|
676
|
+
database: Union[str, pymongo.database.Database],
|
|
192
677
|
collection_name: str,
|
|
193
678
|
add_timestamp: bool = False,
|
|
194
679
|
convert_mixed_lists_to_strings: bool = False,
|
|
@@ -198,7 +683,9 @@ def overwrite_collection(
|
|
|
198
683
|
"""
|
|
199
684
|
Overwrite a MongoDB collection with list of dicts or a dict.
|
|
200
685
|
:param object_instance: list of dictionaries, the list of dictionaries to overwrite in the collection.
|
|
201
|
-
:param
|
|
686
|
+
:param database: String or the database object.
|
|
687
|
+
str - the name of the database. In this case the database object will be created.
|
|
688
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
202
689
|
:param collection_name: str, the name of the collection.
|
|
203
690
|
:param add_timestamp: bool, if True, a current time timestamp will be added to the object.
|
|
204
691
|
:param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are strings and integers,
|
|
@@ -217,13 +704,13 @@ def overwrite_collection(
|
|
|
217
704
|
close_client = True
|
|
218
705
|
|
|
219
706
|
delete_all_entries_from_collection(
|
|
220
|
-
|
|
707
|
+
database=database, collection_name=collection_name,
|
|
221
708
|
mongo_client=mongo_client
|
|
222
709
|
)
|
|
223
710
|
|
|
224
711
|
index(
|
|
225
712
|
object_instance=object_instance,
|
|
226
|
-
|
|
713
|
+
database=database, collection_name=collection_name,
|
|
227
714
|
add_timestamp=add_timestamp, convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
|
|
228
715
|
mongo_client=mongo_client, close_client=close_client)
|
|
229
716
|
|
|
@@ -242,15 +729,39 @@ def _is_object_list_of_dicts_or_dict(
|
|
|
242
729
|
raise ValueError("Object must be a dictionary or a list of dictionaries.")
|
|
243
730
|
|
|
244
731
|
|
|
732
|
+
def _get_pymongo_db_from_string_or_pymongo_db(
|
|
733
|
+
database: Union[str, pymongo.database.Database],
|
|
734
|
+
mongo_client: pymongo.MongoClient
|
|
735
|
+
) -> pymongo.database.Database:
|
|
736
|
+
"""
|
|
737
|
+
Get a pymongo.database.Database object from a string or a pymongo.database.Database object.
|
|
738
|
+
|
|
739
|
+
:param database: Union[str, pymongo.database.Database], the database object or the name of the database.
|
|
740
|
+
If the database is a string, the database object will be created.
|
|
741
|
+
If the database is a pymongo.database.Database object, it will be returned as is.
|
|
742
|
+
:param mongo_client: mongodb.MongoClient, the connection object.
|
|
743
|
+
:return: pymongo.database.Database, the database object.
|
|
744
|
+
"""
|
|
745
|
+
|
|
746
|
+
if isinstance(database, str):
|
|
747
|
+
return mongo_client[database]
|
|
748
|
+
elif isinstance(database, pymongo.database.Database):
|
|
749
|
+
return database
|
|
750
|
+
else:
|
|
751
|
+
raise ValueError("Database must be a string (database name) or a pymongo.database.Database object.")
|
|
752
|
+
|
|
753
|
+
|
|
245
754
|
def get_stats_db(
|
|
246
|
-
|
|
755
|
+
database: Union[str, pymongo.database.Database],
|
|
247
756
|
mongo_client: pymongo.MongoClient = None,
|
|
248
757
|
close_client: bool = False
|
|
249
758
|
):
|
|
250
759
|
"""
|
|
251
760
|
Get the stats of a MongoDB database.
|
|
252
761
|
|
|
253
|
-
:param
|
|
762
|
+
:param database: String or the database object.
|
|
763
|
+
str - the name of the database. In this case the database object will be created.
|
|
764
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
254
765
|
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
255
766
|
If None, a new connection will be created to default URI.
|
|
256
767
|
:param close_client: bool, if True, the connection will be closed after the operation.
|
|
@@ -262,7 +773,7 @@ def get_stats_db(
|
|
|
262
773
|
mongo_client = connect()
|
|
263
774
|
close_client = True
|
|
264
775
|
|
|
265
|
-
db = mongo_client
|
|
776
|
+
db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
|
|
266
777
|
|
|
267
778
|
stats = db.command("dbStats")
|
|
268
779
|
|
|
@@ -273,14 +784,16 @@ def get_stats_db(
|
|
|
273
784
|
|
|
274
785
|
|
|
275
786
|
def get_stats_db_size(
|
|
276
|
-
|
|
787
|
+
database: Union[str, pymongo.database.Database],
|
|
277
788
|
mongo_client: pymongo.MongoClient = None,
|
|
278
789
|
close_client: bool = False
|
|
279
790
|
):
|
|
280
791
|
"""
|
|
281
792
|
Get the size of a MongoDB database in bytes.
|
|
282
793
|
|
|
283
|
-
:param
|
|
794
|
+
:param database: String or the database object.
|
|
795
|
+
str - the name of the database. In this case the database object will be created.
|
|
796
|
+
pymongo.database.Database - the database object that will be used instead of creating a new one.
|
|
284
797
|
:param mongo_client: pymongo.MongoClient, the connection object.
|
|
285
798
|
If None, a new connection will be created to default URI.
|
|
286
799
|
:param close_client: bool, if True, the connection will be closed after the operation.
|
|
@@ -289,6 +802,40 @@ def get_stats_db_size(
|
|
|
289
802
|
"""
|
|
290
803
|
|
|
291
804
|
stats = get_stats_db(
|
|
292
|
-
|
|
805
|
+
database=database, mongo_client=mongo_client, close_client=close_client)
|
|
293
806
|
|
|
294
807
|
return stats['dataSize']
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
def _convert_key_values_to_objects(
|
|
811
|
+
keys_convert_to_dict: list[str],
|
|
812
|
+
returned_data: Union[dict, list]
|
|
813
|
+
) -> Union[dict, list]:
|
|
814
|
+
"""
|
|
815
|
+
Recursively searches for provided keys from the 'keys_convert_to_dict' list like 'test1' and 'test2'
|
|
816
|
+
in a nested dictionary 'returned_data' and converts their values using "json.loads" if found.
|
|
817
|
+
|
|
818
|
+
:param keys_convert_to_dict: list, the keys of the documents that should be converted from string to dict.
|
|
819
|
+
:param returned_data: The nested dictionary to search through.
|
|
820
|
+
:type returned_data: dict
|
|
821
|
+
"""
|
|
822
|
+
|
|
823
|
+
if isinstance(returned_data, dict):
|
|
824
|
+
for key, value in returned_data.items():
|
|
825
|
+
if key in keys_convert_to_dict:
|
|
826
|
+
# Can be that the value is None, so we don't need to convert it.
|
|
827
|
+
if value is None:
|
|
828
|
+
continue
|
|
829
|
+
|
|
830
|
+
try:
|
|
831
|
+
returned_data[key] = json.loads(value)
|
|
832
|
+
except (ValueError, TypeError):
|
|
833
|
+
# This is needed only to know the possible exception types.
|
|
834
|
+
raise
|
|
835
|
+
else:
|
|
836
|
+
_convert_key_values_to_objects(keys_convert_to_dict, value)
|
|
837
|
+
elif isinstance(returned_data, list):
|
|
838
|
+
for i, item in enumerate(returned_data):
|
|
839
|
+
returned_data[i] = _convert_key_values_to_objects(keys_convert_to_dict, item)
|
|
840
|
+
|
|
841
|
+
return returned_data
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=oNmVsW_-ZdNWYFu1cVLreluzXWdxRiR3VEX5qDGDz5A,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
|
|
@@ -145,7 +145,7 @@ atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha2
|
|
|
145
145
|
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=1AM49UaFTKA0AHw-k3SV3uH3QbG-o6ux0c-GoWkKNU0,6993
|
|
146
146
|
atomicshop/mitm/statistic_analyzer_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
147
147
|
atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py,sha256=pk6L1t1ea1kvlBoR9QEJptOmaX-mumhwLsP2GCKukbk,5920
|
|
148
|
-
atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=
|
|
148
|
+
atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=Wge-OfbbClfjeEWwOyksd-x9C5QZdRD3KRSjtP9VL9Q,16651
|
|
149
149
|
atomicshop/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
150
|
atomicshop/monitor/change_monitor.py,sha256=K5NlVp99XIDDPnQQMdru4BDmua_DtcDIhVAzkTOvD5s,7673
|
|
151
151
|
atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -248,13 +248,13 @@ atomicshop/wrappers/loggingw/consts.py,sha256=JWiUJEydjhwatBxtIJsGTmDUSTLbmIRidt
|
|
|
248
248
|
atomicshop/wrappers/loggingw/filters.py,sha256=CMs5PAMb68zxJgBcQobaOFDG5kLJBOVYnoBHjDgksO8,2859
|
|
249
249
|
atomicshop/wrappers/loggingw/formatters.py,sha256=7XUJvlB0CK4DCkEp8NTL0S0dkyrZD0UTADgEwkStKOY,5483
|
|
250
250
|
atomicshop/wrappers/loggingw/handlers.py,sha256=hAPFJQ-wFoNO8QzGrJRSvyuP09Q1F0Dl9_w7zzlgcW0,18155
|
|
251
|
-
atomicshop/wrappers/loggingw/loggers.py,sha256=
|
|
252
|
-
atomicshop/wrappers/loggingw/loggingw.py,sha256=
|
|
253
|
-
atomicshop/wrappers/loggingw/reading.py,sha256=
|
|
251
|
+
atomicshop/wrappers/loggingw/loggers.py,sha256=QH5QainlGLyrDpsDu4T1C8-WQQau3JW2OS5RgC-kXpM,2677
|
|
252
|
+
atomicshop/wrappers/loggingw/loggingw.py,sha256=6HUn2z4ZW8PgakPscosKx23qYwHlBQcLiZGw-VZHi-k,12374
|
|
253
|
+
atomicshop/wrappers/loggingw/reading.py,sha256=SZFE4d6IFoC1GveFf28oAuDQzHG8UnBHx3K3-dE5Mes,16528
|
|
254
254
|
atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
255
255
|
atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=3ZPqrXxj3lC-PnAKGXclylLuOqsbyXYeUpb5iGjdeUU,6626
|
|
256
|
-
atomicshop/wrappers/mongodbw/mongo_infra.py,sha256=
|
|
257
|
-
atomicshop/wrappers/mongodbw/mongodbw.py,sha256=
|
|
256
|
+
atomicshop/wrappers/mongodbw/mongo_infra.py,sha256=IjEF0jPzQz866MpTm7rnksnyyWQeUT_B2h2DA9ryAio,2034
|
|
257
|
+
atomicshop/wrappers/mongodbw/mongodbw.py,sha256=v_5YYgbgT0F-k2I-hDHQCMPhpry8OonsPclubJk2NG0,31509
|
|
258
258
|
atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
259
259
|
atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=QZg-R2iTQt7kFb8wNtnTmwraSGwvUs34JIasdbNa7ZU,5154
|
|
260
260
|
atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -309,8 +309,8 @@ atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0L
|
|
|
309
309
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=V_m1D0KpizQox3IEWp2AUcncwWy5kG25hbFrc-mBSJE,3029
|
|
310
310
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
311
311
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=bQ8Jql8bVGBJ0dt3VQ56lga_1LBOMLI3Km_otvvbU6c,7138
|
|
312
|
-
atomicshop-2.16.
|
|
313
|
-
atomicshop-2.16.
|
|
314
|
-
atomicshop-2.16.
|
|
315
|
-
atomicshop-2.16.
|
|
316
|
-
atomicshop-2.16.
|
|
312
|
+
atomicshop-2.16.18.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
313
|
+
atomicshop-2.16.18.dist-info/METADATA,sha256=b68lhNlBqxZwdV4zttZaQcCUAF18IPOHwKq4PaFIAkA,10473
|
|
314
|
+
atomicshop-2.16.18.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
315
|
+
atomicshop-2.16.18.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
316
|
+
atomicshop-2.16.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|