atomicshop 2.6.12__py3-none-any.whl → 2.7.0__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/archiver/search_in_archive.py +16 -10
- atomicshop/archiver/sevenz.py +14 -7
- atomicshop/archiver/zip.py +10 -7
- atomicshop/basics/dicts.py +42 -0
- atomicshop/basics/lists.py +10 -0
- atomicshop/console_output.py +117 -0
- atomicshop/file_io/jsons.py +24 -0
- atomicshop/file_types.py +24 -0
- atomicshop/wrappers/elasticsearchw/__init__.py +0 -0
- atomicshop/wrappers/elasticsearchw/config_basic.py +3 -0
- atomicshop/wrappers/elasticsearchw/elasticsearchw.py +101 -0
- {atomicshop-2.6.12.dist-info → atomicshop-2.7.0.dist-info}/METADATA +3 -1
- {atomicshop-2.6.12.dist-info → atomicshop-2.7.0.dist-info}/RECORD +17 -13
- {atomicshop-2.6.12.dist-info → atomicshop-2.7.0.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.6.12.dist-info → atomicshop-2.7.0.dist-info}/WHEEL +0 -0
- {atomicshop-2.6.12.dist-info → atomicshop-2.7.0.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -4,11 +4,19 @@ from io import BytesIO
|
|
|
4
4
|
from typing import Union
|
|
5
5
|
|
|
6
6
|
from . import zip, sevenz
|
|
7
|
-
from ..
|
|
7
|
+
from .. import file_types
|
|
8
8
|
|
|
9
9
|
import py7zr
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
SUPPORTED_ARCHIVE_MIMES: list = [
|
|
13
|
+
'application/x-7z-compressed',
|
|
14
|
+
'application/zip',
|
|
15
|
+
'application/x-dosexec', # SFX zip files.
|
|
16
|
+
'application/octet-stream' # There are some non-standard zip files that are not recognized by magic.
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
12
20
|
# Custom exception if the file is not known archive type.
|
|
13
21
|
class UnknownArchiveType(Exception):
|
|
14
22
|
pass
|
|
@@ -29,14 +37,12 @@ def _get_unique_filename(directory, filename):
|
|
|
29
37
|
|
|
30
38
|
def _is_zip_file(file, zip_obj):
|
|
31
39
|
with zip_obj.open(file) as file_data:
|
|
32
|
-
|
|
33
|
-
return zip.is_zip_zipfile(file_data_bytes_io)
|
|
40
|
+
return zip.is_zip_zipfile(file_data.read())
|
|
34
41
|
|
|
35
42
|
|
|
36
43
|
def _is_7z_file(file, sevenz_obj):
|
|
37
44
|
with sevenz_obj.open(file) as file_data:
|
|
38
|
-
|
|
39
|
-
return sevenz.is_7z(file_data_bytes_io)
|
|
45
|
+
return sevenz.is_7z(file_data.read())
|
|
40
46
|
|
|
41
47
|
|
|
42
48
|
def _match_file_name(target, current, case_sensitive):
|
|
@@ -55,7 +61,6 @@ def _handle_file_extraction(item, extract_file_to_path, archived_file_bytes):
|
|
|
55
61
|
|
|
56
62
|
def _handle_callback_matching(
|
|
57
63
|
item, archive_type, archived_file_bytes, callback_functions, results, found_set, return_first_only):
|
|
58
|
-
|
|
59
64
|
for callback in callback_functions:
|
|
60
65
|
callback_result = callback(archived_file_bytes)
|
|
61
66
|
if callback_result:
|
|
@@ -102,7 +107,6 @@ def _handle_name_matching(item, archived_file_bytes, file_names, case_sensitive,
|
|
|
102
107
|
def _search_in_archive(
|
|
103
108
|
arch_obj, archive_type, file_names, results, found_set, case_sensitive, return_first_only, recursive,
|
|
104
109
|
callback_functions, extract_file_to_path):
|
|
105
|
-
|
|
106
110
|
file_info_list = None
|
|
107
111
|
if archive_type == 'zip':
|
|
108
112
|
file_info_list = arch_obj.infolist()
|
|
@@ -110,8 +114,6 @@ def _search_in_archive(
|
|
|
110
114
|
file_info_list = arch_obj.list()
|
|
111
115
|
|
|
112
116
|
for item_index, item in enumerate(file_info_list):
|
|
113
|
-
if item_index == 16:
|
|
114
|
-
pass
|
|
115
117
|
if item.filename.endswith('/'): # Skip directories
|
|
116
118
|
continue
|
|
117
119
|
|
|
@@ -151,6 +153,11 @@ def _initialize_results(callback_functions):
|
|
|
151
153
|
|
|
152
154
|
|
|
153
155
|
def _get_archive_type(file_object) -> Union[str, None]:
|
|
156
|
+
file_mime: str = file_types.get_mime_type(file_object)
|
|
157
|
+
|
|
158
|
+
if file_mime not in SUPPORTED_ARCHIVE_MIMES:
|
|
159
|
+
return None
|
|
160
|
+
|
|
154
161
|
if zip.is_zip_zipfile(file_object):
|
|
155
162
|
return 'zip'
|
|
156
163
|
elif sevenz.is_7z(file_object):
|
|
@@ -164,7 +171,6 @@ def _get_archive_type(file_object) -> Union[str, None]:
|
|
|
164
171
|
def _search_archive_content(
|
|
165
172
|
file_object, file_names_to_search, results, found_set, case_sensitive, return_first_only, recursive,
|
|
166
173
|
callback_functions, extract_file_to_path):
|
|
167
|
-
|
|
168
174
|
archive_type = _get_archive_type(file_object)
|
|
169
175
|
|
|
170
176
|
if isinstance(file_object, str):
|
atomicshop/archiver/sevenz.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Union
|
|
|
4
4
|
import py7zr
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def is_7z(file_object: Union[str,
|
|
7
|
+
def is_7z(file_object: Union[str, bytes]) -> bool:
|
|
8
8
|
"""
|
|
9
9
|
Function checks if the file is a 7z file.
|
|
10
10
|
:param file_object: can be two types:
|
|
@@ -13,18 +13,25 @@ def is_7z(file_object: Union[str, Union[bytes, BytesIO]]) -> bool:
|
|
|
13
13
|
:return: boolean.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try:
|
|
17
|
+
if isinstance(file_object, bytes):
|
|
18
|
+
with BytesIO(file_object) as file_object:
|
|
19
|
+
with py7zr.SevenZipFile(file_object) as archive:
|
|
20
|
+
archive.testzip()
|
|
21
|
+
return True
|
|
22
|
+
elif isinstance(file_object, str):
|
|
18
23
|
with py7zr.SevenZipFile(file_object) as archive:
|
|
19
24
|
archive.testzip()
|
|
20
25
|
return True
|
|
21
|
-
|
|
26
|
+
except py7zr.Bad7zFile:
|
|
27
|
+
return False
|
|
28
|
+
# For some reason there are files that return this exception instead of Bad7zFile.
|
|
29
|
+
except OSError as e:
|
|
30
|
+
if e.args[0] == 22:
|
|
22
31
|
return False
|
|
23
|
-
elif isinstance(file_object, bytes):
|
|
24
|
-
return is_7z(BytesIO(file_object))
|
|
25
32
|
|
|
26
33
|
|
|
27
|
-
def
|
|
34
|
+
def _is_7z_magic_number(data):
|
|
28
35
|
# Check if the data is at least 6 bytes long
|
|
29
36
|
if len(data) < 6:
|
|
30
37
|
return False
|
atomicshop/archiver/zip.py
CHANGED
|
@@ -8,7 +8,7 @@ from .. import filesystem
|
|
|
8
8
|
from ..print_api import print_api
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def is_zip_zipfile(file_object: Union[str,
|
|
11
|
+
def is_zip_zipfile(file_object: Union[str, bytes]) -> bool:
|
|
12
12
|
"""
|
|
13
13
|
Function checks if the file is a zip file.
|
|
14
14
|
:param file_object: can be two types:
|
|
@@ -17,13 +17,16 @@ def is_zip_zipfile(file_object: Union[str, Union[bytes, BytesIO]]) -> bool:
|
|
|
17
17
|
:return: boolean.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
if isinstance(file_object, bytes):
|
|
21
|
-
file_object = BytesIO(file_object)
|
|
22
|
-
|
|
23
20
|
try:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
if isinstance(file_object, bytes):
|
|
22
|
+
with BytesIO(file_object) as file_object:
|
|
23
|
+
with zipfile.ZipFile(file_object) as zip_object:
|
|
24
|
+
zip_object.testzip()
|
|
25
|
+
return True
|
|
26
|
+
elif isinstance(file_object, str):
|
|
27
|
+
with zipfile.ZipFile(file_object) as zip_object:
|
|
28
|
+
zip_object.testzip()
|
|
29
|
+
return True
|
|
27
30
|
except zipfile.BadZipFile:
|
|
28
31
|
return False
|
|
29
32
|
|
atomicshop/basics/dicts.py
CHANGED
|
@@ -242,3 +242,45 @@ def convert_object_with_attributes_to_dict(
|
|
|
242
242
|
obj_dict[attr_name] = attr_value
|
|
243
243
|
|
|
244
244
|
return obj_dict
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def convert_tuples_to_lists(obj):
|
|
248
|
+
"""
|
|
249
|
+
Convert all tuples in object to lists. The first input 'obj' can be a dictionary, list or tuple.
|
|
250
|
+
:param obj: dict, list, tuple, the object to convert.
|
|
251
|
+
:return:
|
|
252
|
+
"""
|
|
253
|
+
if isinstance(obj, dict):
|
|
254
|
+
return {k: convert_tuples_to_lists(v) for k, v in obj.items()}
|
|
255
|
+
elif isinstance(obj, list):
|
|
256
|
+
return [convert_tuples_to_lists(element) for element in obj]
|
|
257
|
+
elif isinstance(obj, tuple):
|
|
258
|
+
return list(obj)
|
|
259
|
+
return obj
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def convert_int_to_str_in_mixed_lists(item):
|
|
263
|
+
"""
|
|
264
|
+
Recursively traverse an item (which can be a dictionary, list, tuple, or a basic data type).
|
|
265
|
+
If a list or a tuple contains both integers and strings, convert all integers to strings.
|
|
266
|
+
This is useful when converting indexing a dictionary with mixed lists into Elasticsearch.
|
|
267
|
+
Since Elasticsearch doesn't support mixed lists, we need to convert integers to strings.
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
if isinstance(item, dict):
|
|
271
|
+
# If the item is a dictionary, apply the function to each value.
|
|
272
|
+
return {key: convert_int_to_str_in_mixed_lists(value) for key, value in item.items()}
|
|
273
|
+
elif isinstance(item, (list, tuple)):
|
|
274
|
+
# If the item is a list or a tuple, check if it contains both integers and strings.
|
|
275
|
+
contains_int = any(isinstance(elem, int) for elem in item)
|
|
276
|
+
contains_str = any(isinstance(elem, str) for elem in item)
|
|
277
|
+
|
|
278
|
+
if contains_int and contains_str:
|
|
279
|
+
# If both integers and strings are present, convert integers to strings.
|
|
280
|
+
return type(item)(str(elem) if isinstance(elem, int) else elem for elem in item)
|
|
281
|
+
else:
|
|
282
|
+
# Otherwise, apply the function to each element.
|
|
283
|
+
return type(item)(convert_int_to_str_in_mixed_lists(elem) for elem in item)
|
|
284
|
+
else:
|
|
285
|
+
# If the item is neither a dictionary, list, nor tuple, return it as is.
|
|
286
|
+
return item
|
atomicshop/basics/lists.py
CHANGED
|
@@ -99,3 +99,13 @@ def sort_list_by_another_list(list_of_strings_to_sort, list_of_strings_to_sort_b
|
|
|
99
99
|
return len(list_of_strings_to_sort_by)
|
|
100
100
|
|
|
101
101
|
return sorted(list_of_strings_to_sort, key=sort_key)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_the_most_frequent_element_from_list(list_instance: list[str]) -> str:
|
|
105
|
+
"""
|
|
106
|
+
This function will return the most frequent element from the list.
|
|
107
|
+
:param list_instance: list.
|
|
108
|
+
:return: string.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
return max(set(list_instance), key=list_instance.count)
|
atomicshop/console_output.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import sys
|
|
1
2
|
import contextlib
|
|
2
3
|
import io
|
|
4
|
+
import logging
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class TempDisableOutput:
|
|
@@ -37,3 +39,118 @@ class TempDisableOutput:
|
|
|
37
39
|
|
|
38
40
|
def __exit__(self, *args):
|
|
39
41
|
return self.redirect_stdout_object.__exit__(*args)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def capture_console_output_without_outputting(func, *args, **kwargs):
|
|
45
|
+
"""
|
|
46
|
+
Executes a function and captures its console output.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
func: The function to execute.
|
|
50
|
+
*args: Arguments to pass to the function.
|
|
51
|
+
**kwargs: Keyword arguments to pass to the function.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
A string containing the captured console output.
|
|
55
|
+
|
|
56
|
+
Usage:
|
|
57
|
+
def example_function(name):
|
|
58
|
+
print(f"Hello, {name}!")
|
|
59
|
+
|
|
60
|
+
captured_output = capture_console_output(example_function, "World")
|
|
61
|
+
print("Captured output:", captured_output)
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
output_capture = io.StringIO()
|
|
66
|
+
with contextlib.redirect_stdout(output_capture):
|
|
67
|
+
func(*args, **kwargs)
|
|
68
|
+
return output_capture.getvalue()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def capture_console_output_of_logging_without_outputting(func, *args, **kwargs):
|
|
72
|
+
"""
|
|
73
|
+
Executes a function and captures its logger output.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
func: The function to execute.
|
|
77
|
+
*args: Arguments to pass to the function.
|
|
78
|
+
**kwargs: Keyword arguments to pass to the function.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
A string containing the captured console output.
|
|
82
|
+
|
|
83
|
+
Usage:
|
|
84
|
+
def example_function():
|
|
85
|
+
logger = logging.getLogger()
|
|
86
|
+
logger.warning("This is a warning!")
|
|
87
|
+
|
|
88
|
+
captured_output = capture_logger_output(example_function)
|
|
89
|
+
print("Captured output:", captured_output)
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
log_capture_string = io.StringIO()
|
|
94
|
+
ch = logging.StreamHandler(log_capture_string)
|
|
95
|
+
ch.setLevel(logging.DEBUG)
|
|
96
|
+
|
|
97
|
+
logger = logging.getLogger()
|
|
98
|
+
old_handlers = logger.handlers
|
|
99
|
+
logger.handlers = [ch]
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
func(*args, **kwargs)
|
|
103
|
+
finally:
|
|
104
|
+
logger.handlers = old_handlers
|
|
105
|
+
ch.close()
|
|
106
|
+
|
|
107
|
+
return log_capture_string.getvalue()
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def capture_all_output(func, *args, **kwargs):
|
|
111
|
+
"""
|
|
112
|
+
Executes a function and captures its console and logger output.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
func: The function to execute.
|
|
116
|
+
*args: Arguments to pass to the function.
|
|
117
|
+
**kwargs: Keyword arguments to pass to the function.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
A string containing the captured console and logger output.
|
|
121
|
+
|
|
122
|
+
Usage:
|
|
123
|
+
def example_function():
|
|
124
|
+
print("This is a print statement.")
|
|
125
|
+
logging.warning("This is a warning from logging.")
|
|
126
|
+
sys.stderr.write("This is a direct stderr write.\n")
|
|
127
|
+
|
|
128
|
+
captured_output = capture_all_output(example_function)
|
|
129
|
+
print("Captured output:", captured_output)
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
log_capture_string = io.StringIO()
|
|
133
|
+
ch = logging.StreamHandler(log_capture_string)
|
|
134
|
+
ch.setLevel(logging.DEBUG)
|
|
135
|
+
|
|
136
|
+
logger = logging.getLogger()
|
|
137
|
+
old_handlers = logger.handlers
|
|
138
|
+
logger.handlers = [ch]
|
|
139
|
+
|
|
140
|
+
stdout_capture = io.StringIO()
|
|
141
|
+
stderr_capture = io.StringIO()
|
|
142
|
+
|
|
143
|
+
old_stdout = sys.stdout
|
|
144
|
+
old_stderr = sys.stderr
|
|
145
|
+
sys.stdout = stdout_capture
|
|
146
|
+
sys.stderr = stderr_capture
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
func(*args, **kwargs)
|
|
150
|
+
finally:
|
|
151
|
+
sys.stdout = old_stdout
|
|
152
|
+
sys.stderr = old_stderr
|
|
153
|
+
logger.handlers = old_handlers
|
|
154
|
+
ch.close()
|
|
155
|
+
|
|
156
|
+
return stdout_capture.getvalue() + stderr_capture.getvalue() + log_capture_string.getvalue()
|
atomicshop/file_io/jsons.py
CHANGED
|
@@ -107,3 +107,27 @@ def convert_json_string_to_dict(json_string: str) -> dict:
|
|
|
107
107
|
"""
|
|
108
108
|
|
|
109
109
|
return json.loads(json_string)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def is_dict_json_serializable(
|
|
113
|
+
dict_to_check: dict,
|
|
114
|
+
raise_exception: bool = False
|
|
115
|
+
) -> tuple[bool, Union[str, None]]:
|
|
116
|
+
"""
|
|
117
|
+
Check if dictionary is json serializable.
|
|
118
|
+
|
|
119
|
+
:param dict_to_check: dictionary to check.
|
|
120
|
+
:param raise_exception: boolean, if True, raise exception if dictionary is not json serializable.
|
|
121
|
+
:return:
|
|
122
|
+
boolean, True if dictionary is json serializable, False otherwise.
|
|
123
|
+
string, error message if dictionary is not json serializable, None otherwise.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
json.dumps(dict_to_check)
|
|
128
|
+
return True, None
|
|
129
|
+
except TypeError as e:
|
|
130
|
+
if raise_exception:
|
|
131
|
+
raise e
|
|
132
|
+
else:
|
|
133
|
+
return False, str(e)
|
atomicshop/file_types.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import magic
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_mime_type(file_object: Union[str, bytes]):
|
|
7
|
+
"""
|
|
8
|
+
Determine the MIME type of the given input.
|
|
9
|
+
The input can be a file path (string) or a bytes object.
|
|
10
|
+
|
|
11
|
+
:param file_object: File path as a string or bytes object.
|
|
12
|
+
:return: MIME type as a string.
|
|
13
|
+
"""
|
|
14
|
+
mime = magic.Magic(mime=True)
|
|
15
|
+
|
|
16
|
+
# Check if input is a file path (str) or bytes
|
|
17
|
+
if isinstance(file_object, str):
|
|
18
|
+
# Assuming input_data is a file path
|
|
19
|
+
return mime.from_file(file_object)
|
|
20
|
+
elif isinstance(file_object, bytes):
|
|
21
|
+
# Assuming input_data is bytes
|
|
22
|
+
return mime.from_buffer(file_object)
|
|
23
|
+
else:
|
|
24
|
+
raise TypeError("Input must be a file path (str) or bytes object.")
|
|
File without changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from elasticsearch import Elasticsearch
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
from . import config_basic
|
|
5
|
+
from ...basics import dicts
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
ELASTIC_WRAPPER = None
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_elastic_wrapper(url: str = None, overwrite: bool = False):
|
|
12
|
+
"""
|
|
13
|
+
The function initializes the Elasticsearch wrapper.
|
|
14
|
+
|
|
15
|
+
:param url: str, the url of the Elasticsearch server. If None, the default url is used: http://localhost:9200
|
|
16
|
+
:param overwrite: bool, if True, the wrapper is reinitialized even if it is already initialized.
|
|
17
|
+
:return: Elasticsearch, the Elasticsearch wrapper.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
elastic_wrapper = get_elastic_wrapper()
|
|
21
|
+
or after you initialize it once, you can use it like:
|
|
22
|
+
atomicshop.wrappers.elasticsearchw.elasticsearchw.ELASTIC_WRAPPER
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# If no url is provided, use the default url.
|
|
26
|
+
if url is None:
|
|
27
|
+
url = config_basic.DEFAULT_URL
|
|
28
|
+
|
|
29
|
+
# Get the global variable.
|
|
30
|
+
global ELASTIC_WRAPPER
|
|
31
|
+
# If the wrapper is not initialized, initialize it.
|
|
32
|
+
if ELASTIC_WRAPPER is None:
|
|
33
|
+
ELASTIC_WRAPPER = Elasticsearch([url])
|
|
34
|
+
# If the wrapper is already initialized, check if it should be overwritten.
|
|
35
|
+
else:
|
|
36
|
+
if overwrite:
|
|
37
|
+
ELASTIC_WRAPPER = Elasticsearch([url])
|
|
38
|
+
|
|
39
|
+
return ELASTIC_WRAPPER
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_connection(elastic_wrapper: Elasticsearch = None):
|
|
43
|
+
"""
|
|
44
|
+
The function tests the connection to the Elasticsearch server.
|
|
45
|
+
|
|
46
|
+
:param elastic_wrapper: Elasticsearch, the Elasticsearch wrapper.
|
|
47
|
+
:return: bool, True if the connection is successful, False otherwise.
|
|
48
|
+
|
|
49
|
+
Usage:
|
|
50
|
+
res = test_connection()
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
if elastic_wrapper is None:
|
|
54
|
+
elastic_wrapper = get_elastic_wrapper()
|
|
55
|
+
|
|
56
|
+
if elastic_wrapper.ping():
|
|
57
|
+
return True
|
|
58
|
+
else:
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def index(
|
|
63
|
+
index_name: str,
|
|
64
|
+
doc: dict,
|
|
65
|
+
doc_id: str = None,
|
|
66
|
+
use_current_timestamp: bool = False,
|
|
67
|
+
convert_mixed_lists_to_strings: bool = False,
|
|
68
|
+
elastic_wrapper: Elasticsearch = None):
|
|
69
|
+
"""
|
|
70
|
+
The function indexes a document in the Elasticsearch server.
|
|
71
|
+
|
|
72
|
+
:param index_name: str, the name of the index.
|
|
73
|
+
:param doc: dict, the document to be indexed.
|
|
74
|
+
:param doc_id: str, the id of the document. If None, a random id is generated.
|
|
75
|
+
This means that if you index the document with the same id again, the document inside DB will be overwritten.
|
|
76
|
+
:param use_current_timestamp: bool, if True, the current datetime is used as the timestamp of the document.
|
|
77
|
+
:param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are strings and integers,
|
|
78
|
+
the integers will be converted to strings.
|
|
79
|
+
:param elastic_wrapper: Elasticsearch, the Elasticsearch wrapper.
|
|
80
|
+
:return: dict, the result of the indexing operation.
|
|
81
|
+
|
|
82
|
+
Usage:
|
|
83
|
+
doc = {
|
|
84
|
+
'author': 'test_author',
|
|
85
|
+
'text': 'Some test text',
|
|
86
|
+
}
|
|
87
|
+
res = index(index_name="test_index", doc=doc)
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
if elastic_wrapper is None:
|
|
91
|
+
elastic_wrapper = get_elastic_wrapper()
|
|
92
|
+
|
|
93
|
+
if use_current_timestamp:
|
|
94
|
+
doc['timestamp'] = datetime.now()
|
|
95
|
+
|
|
96
|
+
if convert_mixed_lists_to_strings:
|
|
97
|
+
doc = dicts.convert_int_to_str_in_mixed_lists(doc)
|
|
98
|
+
|
|
99
|
+
res = elastic_wrapper.index(index=index_name, body=doc, id=doc_id)
|
|
100
|
+
|
|
101
|
+
return res
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: atomicshop
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Atomic functions and classes to make developer life easier
|
|
5
5
|
Author: Denis Kras
|
|
6
6
|
License: MIT License
|
|
@@ -37,6 +37,7 @@ Requires-Dist: cryptography
|
|
|
37
37
|
Requires-Dist: dnslib
|
|
38
38
|
Requires-Dist: dnspython
|
|
39
39
|
Requires-Dist: docker
|
|
40
|
+
Requires-Dist: elasticsearch
|
|
40
41
|
Requires-Dist: numpy
|
|
41
42
|
Requires-Dist: openpyxl
|
|
42
43
|
Requires-Dist: pandas
|
|
@@ -50,6 +51,7 @@ Requires-Dist: pyautogui
|
|
|
50
51
|
Requires-Dist: pyopenssl
|
|
51
52
|
Requires-Dist: python-bidi
|
|
52
53
|
Requires-Dist: python-docx
|
|
54
|
+
Requires-Dist: python-magic
|
|
53
55
|
Requires-Dist: SoundCard
|
|
54
56
|
Requires-Dist: soundfile
|
|
55
57
|
Requires-Dist: SpeechRecognition
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=pI9HaUaffycFBm-uxjzPkctXsfbBrHNGXNLrGiv1Pv8,122
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
|
|
4
4
|
atomicshop/appointment_management.py,sha256=N3wVGJgrqJfsj_lqiRfaL3FxMEe57by5Stzanh189mk,7263
|
|
5
5
|
atomicshop/certificates.py,sha256=J-cmd6Rpq3zZyzsOH-GcdqIXdg2UwM8_E9mg7XtUph8,3787
|
|
6
6
|
atomicshop/command_line_processing.py,sha256=u5yT9Ger_cu7ni5ID0VFlRbVD46ARHeNC9tRM-_YXrQ,1038
|
|
7
7
|
atomicshop/config_init.py,sha256=z2RXD_mw9nQlAOpuGry1h9QT-2LhNscXgGAktN3dCVQ,2497
|
|
8
|
-
atomicshop/console_output.py,sha256=
|
|
8
|
+
atomicshop/console_output.py,sha256=AOSJjrRryE97PAGtgDL03IBtWSi02aNol8noDnW3k6M,4667
|
|
9
9
|
atomicshop/console_user_response.py,sha256=31HIy9QGXa7f-GVR8MzJauQ79E_ZqAeagF3Ks4GGdDU,3234
|
|
10
10
|
atomicshop/datetimes.py,sha256=ICr0_gQqWnIw4BuNtabrHzjSlwnZkBfhyCrOILs5xpU,14623
|
|
11
11
|
atomicshop/diff_check.py,sha256=RON9cSTgy3jAnwUmAUkOyfF6bgrBKOq9Sbgyl3RYodw,12350
|
|
12
12
|
atomicshop/dns.py,sha256=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
|
|
13
13
|
atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
|
|
14
14
|
atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
|
|
15
|
+
atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
|
|
15
16
|
atomicshop/filesystem.py,sha256=ZIVmZ3Zfq4U3gJ7Bta6wPnHSNJMwpyC1CoJcgTDxKUg,32624
|
|
16
17
|
atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
|
|
17
18
|
atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
|
|
@@ -62,16 +63,16 @@ atomicshop/addons/process_list/compiled/Win10x64/process_list.exp,sha256=VTph513
|
|
|
62
63
|
atomicshop/addons/process_list/compiled/Win10x64/process_list.lib,sha256=n9c2MVPs3GBNoOQjMesAwzNpv5aFZsW8c-ADS7GYRhA,1886
|
|
63
64
|
atomicshop/archiver/_search_in_zip.py,sha256=dd8qFSvIhcKmtnPj_uYNJFPmMwZp4tZys0kKgTw_ACw,8385
|
|
64
65
|
atomicshop/archiver/archiver.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
|
|
65
|
-
atomicshop/archiver/search_in_archive.py,sha256=
|
|
66
|
-
atomicshop/archiver/sevenz.py,sha256=
|
|
67
|
-
atomicshop/archiver/zip.py,sha256=
|
|
66
|
+
atomicshop/archiver/search_in_archive.py,sha256=mEngDfULXBd3Oio8a2SUtynfJASVLsH74XIYJOWVkH0,10467
|
|
67
|
+
atomicshop/archiver/sevenz.py,sha256=5i_C50-deC1Cz_GQdMGofV2jeMPbbGWAvih-QnA72cg,1370
|
|
68
|
+
atomicshop/archiver/zip.py,sha256=k742K1bEDtc_4N44j_Waebi-uOkxxavqltvV6q-BLW4,14402
|
|
68
69
|
atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
70
|
atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX98jcBMpJE,3140
|
|
70
71
|
atomicshop/basics/argparse_template.py,sha256=S-BIdKd45bmNdqO3Dj3yOxBgb0O90spZxG4OcnedBHw,5836
|
|
71
72
|
atomicshop/basics/booleans.py,sha256=-4JnSQ1pSb6CNY_62wtHBW8NltjPJEKM-gYOxFujunA,1772
|
|
72
73
|
atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
|
|
73
74
|
atomicshop/basics/classes.py,sha256=n5uhPOWIKBAv0xa3--n-oQYIS64s6hb6JGs_1HgW2cs,8558
|
|
74
|
-
atomicshop/basics/dicts.py,sha256=
|
|
75
|
+
atomicshop/basics/dicts.py,sha256=w9_ZolDNSf2ZyoZ53zIOrFq7VZWGWYAvAvwc4qHORAo,10973
|
|
75
76
|
atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
|
|
76
77
|
atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
|
|
77
78
|
atomicshop/basics/enums.py,sha256=CeV8MfqWHihK7vvV6Mbzq7rD9JykeQfrJeFdLVzfHI4,3547
|
|
@@ -80,7 +81,7 @@ atomicshop/basics/guids.py,sha256=iRx5n18ATZWhpo748BwEjuLWLsu9y3OwF5-Adp-Dtik,40
|
|
|
80
81
|
atomicshop/basics/hexs.py,sha256=i8CTG-J0TGGa25yFSbWEvpVyHFnof_qSWUrmXY-ylKM,1054
|
|
81
82
|
atomicshop/basics/isinstancing.py,sha256=fQ35xfqbguQz2BUn-3a4KVGskhTcIn8JjRtxV2rFcRQ,876
|
|
82
83
|
atomicshop/basics/list_of_dicts.py,sha256=fu0H6dUD9uUo2kl7FYIrWzOQMwCmg7qRxGnFM5S319E,5716
|
|
83
|
-
atomicshop/basics/lists.py,sha256=
|
|
84
|
+
atomicshop/basics/lists.py,sha256=pLpYPSu0BjJIAe_Ar55XhLsH2YBhftn7b-tTAdkK1sw,3928
|
|
84
85
|
atomicshop/basics/multiprocesses.py,sha256=AczaI4TmYduNjE6_VEQhxvDQn4VLDdXYRxhPDpjH4T0,17974
|
|
85
86
|
atomicshop/basics/numbers.py,sha256=II-jP8MG0IYvmjT9_BLEai65xzDJ0LTHK2eFVSrgVqo,527
|
|
86
87
|
atomicshop/basics/randoms.py,sha256=DmYLtnIhDK29tAQrGP1Nt-A-v8WC7WIEB8Edi-nk3N4,282
|
|
@@ -95,7 +96,7 @@ atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
|
95
96
|
atomicshop/file_io/csvs.py,sha256=4R4Kij8FmxNwXFjDtlF_A0flAk0Hj5nZKlEnqC5VxgQ,3125
|
|
96
97
|
atomicshop/file_io/docxs.py,sha256=3IFtaurVhvntcuCL59bpFlzGyKxvDmVUjUQTHWluOMY,4369
|
|
97
98
|
atomicshop/file_io/file_io.py,sha256=FR84ihjGlr7Eqejo-_js4nBICVst31axD0bwX19S2eM,6385
|
|
98
|
-
atomicshop/file_io/jsons.py,sha256=
|
|
99
|
+
atomicshop/file_io/jsons.py,sha256=j-cU1w0iYhiqL5EelMhL3mDMLtaaP73Y97CXqwHcpZU,5154
|
|
99
100
|
atomicshop/file_io/tomls.py,sha256=oa0Wm8yMkPRXKN9jgBuTnKbioSOee4mABW5IMUFCYyU,3041
|
|
100
101
|
atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
|
|
101
102
|
atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
|
|
@@ -150,6 +151,9 @@ atomicshop/wrappers/ctyping/process_winapi.py,sha256=QcXL-ETtlSSkoT8F7pYle97ubGW
|
|
|
150
151
|
atomicshop/wrappers/dockerw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
151
152
|
atomicshop/wrappers/dockerw/dockerw.py,sha256=8MZCMek6L-QpawO5hn_gxXczI6ustPGcYBFWNiuQ1cw,949
|
|
152
153
|
atomicshop/wrappers/dockerw/install_docker.py,sha256=dpSOmD690oLukoLCo0u6Pzh5fRyCWBuSQEtG8VwC3jk,2765
|
|
154
|
+
atomicshop/wrappers/elasticsearchw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
155
|
+
atomicshop/wrappers/elasticsearchw/config_basic.py,sha256=nMtWYBlkQwzUMTLBaL3US8-f87bNPS_wzVxpLR1D6Hc,121
|
|
156
|
+
atomicshop/wrappers/elasticsearchw/elasticsearchw.py,sha256=utWGAc9vFPhK6typiNat8X1YPHfvwQQyDqjgnvVcInc,3382
|
|
153
157
|
atomicshop/wrappers/factw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
158
|
atomicshop/wrappers/factw/config_fact.py,sha256=J-K9Zn50WcDC7ubb-boraSZExfBk7a6M52NhRJVlsjk,895
|
|
155
159
|
atomicshop/wrappers/factw/config_install.py,sha256=QRygFnZ5r1ybJQl7ftFci3kNRmU-a-w3lMG1joElvcY,417
|
|
@@ -208,8 +212,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
208
212
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
209
213
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
210
214
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
211
|
-
atomicshop-2.
|
|
212
|
-
atomicshop-2.
|
|
213
|
-
atomicshop-2.
|
|
214
|
-
atomicshop-2.
|
|
215
|
-
atomicshop-2.
|
|
215
|
+
atomicshop-2.7.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
216
|
+
atomicshop-2.7.0.dist-info/METADATA,sha256=b3_2bHYVrfgK6JoIvpAO-kuFenRKx8bRaE_Fu9je6Wg,10369
|
|
217
|
+
atomicshop-2.7.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
218
|
+
atomicshop-2.7.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
219
|
+
atomicshop-2.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|