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 CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.6.12'
4
+ __version__ = '2.7.0'
@@ -4,11 +4,19 @@ from io import BytesIO
4
4
  from typing import Union
5
5
 
6
6
  from . import zip, sevenz
7
- from ..print_api import print_api
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
- with BytesIO(file_data.read()) as file_data_bytes_io:
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
- with BytesIO(file_data.read()) as file_data_bytes_io:
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):
@@ -4,7 +4,7 @@ from typing import Union
4
4
  import py7zr
5
5
 
6
6
 
7
- def is_7z(file_object: Union[str, Union[bytes, BytesIO]]) -> bool:
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
- if isinstance(file_object, (str, BytesIO)):
17
- try:
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
- except py7zr.Bad7zFile:
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 is_7z_magic_number(data):
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
@@ -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, Union[bytes, BytesIO]]) -> bool:
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
- with zipfile.ZipFile(file_object) as zip_object:
25
- zip_object.testzip()
26
- return True
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
 
@@ -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
@@ -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)
@@ -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()
@@ -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)
@@ -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,3 @@
1
+ DEFAULT_PORT: str = '9200'
2
+ DEFAULT_HOST: str = 'localhost'
3
+ DEFAULT_URL: str = f"http://{DEFAULT_HOST}:{DEFAULT_PORT}"
@@ -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.6.12
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=dE2EYYltz4iQcAdxQMIKwlWoWucAUIC128o-pjsvjVo,123
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=G-6jxnWooT1nJSaPxcCqIuw8S22R_0lOJcfrdovRhwE,1372
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=o8tQVm38tXhoE-VEnpAWtTjeqksUHtYcs5UqmdfH64Y,10269
66
- atomicshop/archiver/sevenz.py,sha256=YUxNoh3qf6NvTB2qdC0uAoFwQtJXbrnl4XNPlWAIaVw,1082
67
- atomicshop/archiver/zip.py,sha256=_JrLb-hjlzkxqjd7maUE8WsaiHx8kibsipCSUSGvIUQ,14208
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=sAoHvY-Rtt7QkwHzIKk1j2ZFmteIm9yFCxBGkTrpbdk,9030
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=9H-avAZ0LchdyZyTxmPZQWpvVR0-L4xM3QclI9fED2M,3637
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=uj-YiK-GxI6qCHgMbvx8t2vzWKvRarrvvqoUq8HvD3A,4416
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.6.12.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
212
- atomicshop-2.6.12.dist-info/METADATA,sha256=41BiQAnqpRy_lqxzEXFjFc_jwlCzxswYwqQW3QIdPy0,10311
213
- atomicshop-2.6.12.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
214
- atomicshop-2.6.12.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
215
- atomicshop-2.6.12.dist-info/RECORD,,
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,,