atomicshop 2.10.0__py3-none-any.whl → 2.10.1__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.10.0'
4
+ __version__ = '2.10.1'
@@ -3,7 +3,7 @@ import zipfile
3
3
  from io import BytesIO
4
4
  from typing import Union
5
5
 
6
- from . import zip, sevenz
6
+ from . import zips, sevenzs
7
7
  from .. import file_types
8
8
 
9
9
  import py7zr
@@ -37,12 +37,12 @@ def _get_unique_filename(directory, filename):
37
37
 
38
38
  def _is_zip_file(file, zip_obj):
39
39
  with zip_obj.open(file) as file_data:
40
- return zip.is_zip_zipfile(file_data.read())
40
+ return zips.is_zip_zipfile(file_data.read())
41
41
 
42
42
 
43
43
  def _is_7z_file(file, sevenz_obj):
44
44
  with sevenz_obj.open(file) as file_data:
45
- return sevenz.is_7z(file_data.read())
45
+ return sevenzs.is_7z(file_data.read())
46
46
 
47
47
 
48
48
  def _match_file_name(target, current, case_sensitive):
@@ -158,9 +158,9 @@ def _get_archive_type(file_object) -> Union[str, None]:
158
158
  if file_mime not in SUPPORTED_ARCHIVE_MIMES:
159
159
  return None
160
160
 
161
- if zip.is_zip_zipfile(file_object):
161
+ if zips.is_zip_zipfile(file_object):
162
162
  return 'zip'
163
- elif sevenz.is_7z(file_object):
163
+ elif sevenzs.is_7z(file_object):
164
164
  return '7z'
165
165
  else:
166
166
  raise UnknownArchiveType(f"{file_object[:10]} is not a known archive type.")
@@ -244,6 +244,58 @@ def convert_object_with_attributes_to_dict(
244
244
  return obj_dict
245
245
 
246
246
 
247
+ def convert_complex_object_to_dict(data):
248
+ """ Function that converts complex objects to dict recursively """
249
+
250
+ # 1. Extracts only the first level of objects. No byte decoding.
251
+ # new_dict = dict()
252
+ # for key, value in vars(obj).items():
253
+ # new_dict.update({key: str(value)})
254
+ # return new_dict
255
+
256
+ # 2. Extracts only the first level of objects. Tries to decode bytes, if exception rises stores string as is.
257
+ # new_dict = dict()
258
+ # for key, value in vars(obj).items():
259
+ # try:
260
+ # new_dict.update({key: value.decode('utf-8')})
261
+ # except Exception:
262
+ # new_dict.update({key: str(value)})
263
+ # return new_dict
264
+
265
+ # 3. Decompress all the objects, save objects as is (no byte decoding).
266
+ if hasattr(data, "__dict__"):
267
+ # 'vars' return a dictionary of all the variables in a class / object.
268
+ # 'map' iterates through function 'dict_converter' all the values of the second argument and returns a list
269
+ # of all iterations of the function result.
270
+ function_return = dict(map(convert_complex_object_to_dict, vars(data).items()))
271
+ # If 'data' type is 'bytes'
272
+ elif isinstance(data, dict):
273
+ function_return = dict(map(convert_complex_object_to_dict, data.items()))
274
+ elif isinstance(data, tuple):
275
+ function_return = tuple(map(convert_complex_object_to_dict, data))
276
+ elif isinstance(data, list):
277
+ function_return = list(map(convert_complex_object_to_dict, data))
278
+ # One value objects.
279
+ elif isinstance(data, datetime.datetime):
280
+ function_return = data.strftime('%Y-%m-%d-%H:%M:%S')
281
+ elif isinstance(data, bytes) or isinstance(data, bytearray):
282
+ function_return = str(data)
283
+
284
+ # Don't want to use the next method, since there will be different formatted strings / messages. And we don't
285
+ # want that, since we can't manipulate it easily later.
286
+ # # Try to decode, if fails, return string.
287
+ # try:
288
+ # function_return = data.decode(encoding='utf-8')
289
+ # except Exception:
290
+ # function_return = str(data)
291
+ # pass
292
+ # Any other type will return as is (something that 'dict()' function can handle), like strings and integers.
293
+ else:
294
+ function_return = data
295
+
296
+ return function_return
297
+
298
+
247
299
  def convert_tuples_to_lists(obj):
248
300
  """
249
301
  Convert all tuples in object to lists. The first input 'obj' can be a dictionary, list or tuple.
@@ -1,11 +1,9 @@
1
- # v1.0.2 - 21.03.2023 13:50
2
1
  import json
3
- # Needed to convert datetime objects inside 'dict_converter' function.
4
- import datetime
5
2
  # Needed to get the function caller module.
6
3
  import inspect
7
4
 
8
5
  from ..wrappers.loggingw import loggingw
6
+ from ..basics import dicts
9
7
 
10
8
 
11
9
  # If the string has several dot characters (".") - return the most right string after the last dot.
@@ -40,59 +38,7 @@ def create_custom_logger():
40
38
  return loggingw.get_logger_with_level(logger_name)
41
39
 
42
40
 
43
- def dict_converter(data):
44
- """ Function that converts complex objects to dict recursively """
45
-
46
- # 1. Extracts only the first level of objects. No byte decoding.
47
- # new_dict = dict()
48
- # for key, value in vars(obj).items():
49
- # new_dict.update({key: str(value)})
50
- # return new_dict
51
-
52
- # 2. Extracts only the first level of objects. Tries to decode bytes, if exception rises stores string as is.
53
- # new_dict = dict()
54
- # for key, value in vars(obj).items():
55
- # try:
56
- # new_dict.update({key: value.decode('utf-8')})
57
- # except Exception:
58
- # new_dict.update({key: str(value)})
59
- # return new_dict
60
-
61
- # 3. Decompress all the objects, save objects as is (no byte decoding).
62
- if hasattr(data, "__dict__"):
63
- # 'vars' return a dictionary of all the variables in a class / object.
64
- # 'map' iterates through function 'dict_converter' all the values of the second argument and returns a list
65
- # of all iterations of the function result.
66
- function_return = dict(map(dict_converter, vars(data).items()))
67
- # If 'data' type is 'bytes'
68
- elif isinstance(data, dict):
69
- function_return = dict(map(dict_converter, data.items()))
70
- elif isinstance(data, tuple):
71
- function_return = tuple(map(dict_converter, data))
72
- elif isinstance(data, list):
73
- function_return = list(map(dict_converter, data))
74
- # One value objects.
75
- elif isinstance(data, datetime.datetime):
76
- function_return = data.strftime('%Y-%m-%d-%H:%M:%S')
77
- elif isinstance(data, bytes) or isinstance(data, bytearray):
78
- function_return = str(data)
79
-
80
- # Don't want to use the next method, since there will be different formatted strings / messages. And we don't
81
- # want that, since we can't manipulate it easily later.
82
- # # Try to decode, if fails, return string.
83
- # try:
84
- # function_return = data.decode(encoding='utf-8')
85
- # except Exception:
86
- # function_return = str(data)
87
- # pass
88
- # Any other type will return as is (something that 'dict()' function can handle), like strings and integers.
89
- else:
90
- function_return = data
91
-
92
- return function_return
93
-
94
-
95
41
  def get_json(obj):
96
42
  """ Convert any nested object to json / dict and values to string as is """
97
43
 
98
- return json.dumps(obj, default=dict_converter)
44
+ return json.dumps(obj, default=dicts.convert_complex_object_to_dict)
atomicshop/web.py CHANGED
@@ -2,7 +2,7 @@ import os
2
2
  import urllib.request
3
3
 
4
4
  from .print_api import print_api
5
- from .archiver import zip
5
+ from .archiver import zips
6
6
  from .urls import url_parser
7
7
  from .file_io import file_io
8
8
  from .wrappers.playwrightw import scenarios
@@ -239,7 +239,7 @@ def download_and_extract_file(
239
239
  file_url=file_url, target_directory=target_directory, file_name=file_name, **kwargs)
240
240
 
241
241
  # Extract the archive and remove the first directory.
242
- zip.extract_archive_with_zipfile(
242
+ zips.extract_archive_with_zipfile(
243
243
  archive_path=f'{file_path}', extract_directory=target_directory,
244
244
  remove_first_directory=archive_remove_first_directory, **kwargs)
245
245
 
@@ -3,13 +3,19 @@ from pathlib import Path
3
3
  import sys
4
4
 
5
5
  from .... import permissions, filesystem
6
+ from ....archiver import zips
6
7
  from ....print_api import print_api
7
- from ... import githubw, ubuntu_terminal
8
+ from ... import githubw
8
9
  from ...dockerw import install_docker
9
10
  from .. import config_install
10
11
 
11
12
 
12
- def install_before_restart(installation_directory: str, remove_existing_installation_directory: bool = True):
13
+ def install_before_restart(
14
+ installation_directory: str,
15
+ remove_existing_installation_directory: bool = True,
16
+ fact_source_archive_path: str = None,
17
+ print_kwargs: dict = None
18
+ ):
13
19
  """
14
20
  This function will install the FACT_core before the restart of the computer.
15
21
  :param installation_directory: string, the directory to install the FACT_core to.
@@ -17,6 +23,13 @@ def install_before_restart(installation_directory: str, remove_existing_installa
17
23
  if True, the existing installation directory will be removed.
18
24
  if False, the existing installation directory will not be removed and FACT installation scripts will do their
19
25
  best to install the FACT_core to the existing installation directory.
26
+ :param fact_source_archive_path: string, the path to the FACT_core source archive.
27
+ This is used when the FACT_core source archive is already downloaded, and you want to use the specific archive
28
+ instead of downloading it again. Or you want to use a specific version of the FACT_core.
29
+ This is optional, if not provided, the latest version of the FACT_core will be downloaded.
30
+ The archive should be an exact copy of the FACT_core repository of the master branch as you download it from
31
+ GitHub.
32
+ :param print_kwargs: dict, the print kwargs for the print_api function.
20
33
  :return:
21
34
  """
22
35
 
@@ -36,20 +49,27 @@ def install_before_restart(installation_directory: str, remove_existing_installa
36
49
  if remove_existing_installation_directory:
37
50
  filesystem.remove_directory(installation_directory)
38
51
 
52
+ # Since you run the script with sudo, we need to change the permissions to the current user.
39
53
  with permissions.temporary_regular_permissions():
40
54
  # Create the FACT_core directory.
41
55
  filesystem.create_directory(installation_directory)
42
56
 
43
- # Download the FACT_core repo.
44
- if not filesystem.get_file_paths_from_directory(installation_directory):
45
- git_wrapper = githubw.GitHubWrapper(repo_url=config_install.FACT_CORE_GITHUB_URL)
46
- git_wrapper.build_links_from_repo_url()
47
- git_wrapper.download_and_extract_branch(
48
- target_directory=installation_directory,
49
- archive_remove_first_directory=True)
57
+ if not fact_source_archive_path:
58
+ # Download the FACT_core repo.
59
+ if not filesystem.get_file_paths_from_directory(installation_directory):
60
+ git_wrapper = githubw.GitHubWrapper(repo_url=config_install.FACT_CORE_GITHUB_URL)
61
+ git_wrapper.build_links_from_repo_url()
62
+ git_wrapper.download_and_extract_branch(
63
+ target_directory=installation_directory,
64
+ archive_remove_first_directory=True)
65
+ else:
66
+ # Extract the archive and remove the first directory.
67
+ zips.extract_archive_with_zipfile(
68
+ archive_path=fact_source_archive_path, extract_directory=installation_directory,
69
+ remove_first_directory=True, **(print_kwargs or {}))
50
70
 
51
- # Set the executable permission on the pre-install file.
52
- permissions.set_executable_permission(fact_core_pre_install_file_path)
71
+ # Set the executable permission on the pre-install file.
72
+ permissions.set_executable_permission(fact_core_pre_install_file_path)
53
73
 
54
74
  # Run the shell script
55
75
  subprocess.run(['bash', fact_core_pre_install_file_path])
@@ -95,6 +95,8 @@ def install_nodejs_ubuntu(
95
95
  if not force_install:
96
96
  return
97
97
 
98
+ # NodeSource is listed as source under official Node.js GitHub repository:
99
+ # https://github.com/nodejs/node?tab=readme-ov-file#current-and-lts-releases
98
100
  print_api("Adding NodeSource repository...")
99
101
 
100
102
  # Fetch and execute the NodeSource repository setup script.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.10.0
3
+ Version: 2.10.1
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=Vb-OirUUuTpKZXUvWHYjzscN4SeetO7oxaKph1XstLw,123
1
+ atomicshop/__init__.py,sha256=ukl6aqshNmALeGqIPGLVnag3oMdx9rXTGHupAsgJhXk,123
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
@@ -44,7 +44,7 @@ atomicshop/timer.py,sha256=KxBBgVM8po6pUJDW8TgY1UXj0iiDmRmL5XDCq0VHAfU,1670
44
44
  atomicshop/urls.py,sha256=CQl1j1kjEVDlAuYJqYD9XxPF1SUSgrmG8PjlcXNEKsQ,597
45
45
  atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
46
46
  atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
47
- atomicshop/web.py,sha256=K3UndqJqHO9bTogZUWDz-IEZN776KNhpk28m3Ct_pbc,11069
47
+ atomicshop/web.py,sha256=7WPV6Q4xZX7bByEeCl2VAfPlyMY42BpR_byVX0Gu7Js,11071
48
48
  atomicshop/addons/PlayWrightCodegen.cmd,sha256=Z5cnllsyXD4F1W2h-WLEnyFkg5nZy0-hTGHRWXVOuW4,173
49
49
  atomicshop/addons/ScriptExecution.cmd,sha256=8iC-uHs9MX9qUD_C2M7n9Xw4MZvwOfxT8H5v3hluVps,93
50
50
  atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh,sha256=lM7LkXQ2AxfFzDGyzSOfIS_zpg9bAD1k3JJ-qu5CdH8,81
@@ -67,16 +67,16 @@ atomicshop/addons/process_list/compiled/Win10x64/process_list.lib,sha256=n9c2MVP
67
67
  atomicshop/archiver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
68
  atomicshop/archiver/_search_in_zip.py,sha256=dd8qFSvIhcKmtnPj_uYNJFPmMwZp4tZys0kKgTw_ACw,8385
69
69
  atomicshop/archiver/archiver.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
70
- atomicshop/archiver/search_in_archive.py,sha256=mEngDfULXBd3Oio8a2SUtynfJASVLsH74XIYJOWVkH0,10467
71
- atomicshop/archiver/sevenz.py,sha256=5i_C50-deC1Cz_GQdMGofV2jeMPbbGWAvih-QnA72cg,1370
72
- atomicshop/archiver/zip.py,sha256=k742K1bEDtc_4N44j_Waebi-uOkxxavqltvV6q-BLW4,14402
70
+ atomicshop/archiver/search_in_archive.py,sha256=kui33oobL2F3VLgAE8L037rHR8Ud3HpXz_E0tbuiDD4,10473
71
+ atomicshop/archiver/sevenzs.py,sha256=5i_C50-deC1Cz_GQdMGofV2jeMPbbGWAvih-QnA72cg,1370
72
+ atomicshop/archiver/zips.py,sha256=k742K1bEDtc_4N44j_Waebi-uOkxxavqltvV6q-BLW4,14402
73
73
  atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX98jcBMpJE,3140
75
75
  atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
76
76
  atomicshop/basics/booleans.py,sha256=va3LYIaSOhjdifW4ZEesnIQxBICNHyQjUAkYelzchhE,2047
77
77
  atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
78
78
  atomicshop/basics/classes.py,sha256=EijW_g4EhdNBnKPMG3nT3HjFspTchtM7to6zm9Ad_Mk,9771
79
- atomicshop/basics/dicts.py,sha256=N696f-vamrCcLpLOvtRpHrEmLfyOqkCyW8JDZnwYLpg,11295
79
+ atomicshop/basics/dicts.py,sha256=JevEkLsQdH4Tqn8rspSey40jW6h8pJ2SP5fcuFBR4dU,13651
80
80
  atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
81
81
  atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
82
82
  atomicshop/basics/enums.py,sha256=CeV8MfqWHihK7vvV6Mbzq7rD9JykeQfrJeFdLVzfHI4,3547
@@ -111,7 +111,7 @@ atomicshop/mitm/import_config.py,sha256=_V-IVJ7a1L6E-VOR4CDfZj-S1odbsIlBe13ij0Nl
111
111
  atomicshop/mitm/initialize_engines.py,sha256=UGdT5DKYNri3MNOxESP7oeSxYiUDrVilJ4jic_nwdew,8055
112
112
  atomicshop/mitm/initialize_mitm_server.py,sha256=aXNZlRu1_RGjC7lagvs2Q8rjQiygxYucy-U4C_SBnsk,13871
113
113
  atomicshop/mitm/message.py,sha256=u2U2f2SOHdBNU-6r1Ik2W14ai2EOwxUV4wVfGZA098k,1732
114
- atomicshop/mitm/shared_functions.py,sha256=NeHABBlY-tmQRooWGVl2jZQx1wSTKJtEqG7mMvF2Jqo,4268
114
+ atomicshop/mitm/shared_functions.py,sha256=PaK_sbnEA5zo9k2ktEOKLmvo-6wRUunxzSNRr41uXIQ,1924
115
115
  atomicshop/mitm/statistic_analyzer.py,sha256=1g5l6X-NbnHvh_TREJRumTDWgE4ixUNJ8pKGneKcf4Y,23524
116
116
  atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
117
  atomicshop/mitm/engines/create_module_template.py,sha256=tRjVSm1sD6FzML71Qbuwvita0qsusdFGm8NZLsZ-XMs,4853
@@ -177,7 +177,7 @@ atomicshop/wrappers/factw/fact_extractor/docker_image.py,sha256=jJAoJNQ4aoATjn3x
177
177
  atomicshop/wrappers/factw/fact_extractor/get_extractor.py,sha256=2mfOAftHIlCcGt1s7MWdq7DsDCuI6wX3MtvcEZ4SK-0,756
178
178
  atomicshop/wrappers/factw/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  atomicshop/wrappers/factw/install/install_after_restart.py,sha256=roM1W2hkDynpEKda55xd7AsZxodsFj8i4wmFGt_HHzA,1558
180
- atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=xPMYgXoyA7y1MHyG5paoqKTWuklhsSGym2ObPcex75M,3036
180
+ atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=fAH53sJgWoXOOhjeAmME2SHYm-5YQAgEi1neaok82Lk,4246
181
181
  atomicshop/wrappers/factw/postgresql/__init__.py,sha256=xMBn2d3Exo23IPP2F_9-SXmOlhFbwWDgS9KwozSTjA0,162
182
182
  atomicshop/wrappers/factw/postgresql/analysis.py,sha256=2Rxzy2jyq3zEKIo53z8VkjuslKE_i5mq2ZpmJAvyd6U,716
183
183
  atomicshop/wrappers/factw/postgresql/file_object.py,sha256=VRiCXnsd6yDbnsE-TEKYPC-gkAgFVkE6rygRrJLQShI,713
@@ -199,7 +199,7 @@ atomicshop/wrappers/loggingw/loggers.py,sha256=DHOOTAtqkwn1xgvLHSkOiBm6yFGNuQy1k
199
199
  atomicshop/wrappers/loggingw/loggingw.py,sha256=v9WAseZXB50LluT9rIUcRvvevg2nLVKPgz3dbGejfV0,12151
200
200
  atomicshop/wrappers/loggingw/reading.py,sha256=xs7L6Jo-vedrhCVP7m-cJo0VhWmoSoK86avR4Tm0kG4,3675
201
201
  atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
- atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=tHJQHpnK-QVrdbbUN3gz_6gklX5c6w1ERRgZ8efn4Bo,4794
202
+ atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=VZvefvdeSzoyetCx1y8zg_liX3_GtFtpOpjw7P5iMLk,4956
203
203
  atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
204
204
  atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
205
205
  atomicshop/wrappers/playwrightw/base.py,sha256=WeRpx8otdXuKSr-BjY-uCJTze21kbPpfitoOjKQz5-g,9818
@@ -232,8 +232,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
232
232
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
233
233
  atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
234
234
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
235
- atomicshop-2.10.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
236
- atomicshop-2.10.0.dist-info/METADATA,sha256=FI-w5jz9h06C_vDlRS0qjGL9g7eA8xhcjhugwE74Da4,10423
237
- atomicshop-2.10.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
238
- atomicshop-2.10.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
239
- atomicshop-2.10.0.dist-info/RECORD,,
235
+ atomicshop-2.10.1.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
236
+ atomicshop-2.10.1.dist-info/METADATA,sha256=Bhbu_I_0laKqCOs51DFk4MH4r7BgeHumK5kATL_9cwM,10423
237
+ atomicshop-2.10.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
238
+ atomicshop-2.10.1.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
239
+ atomicshop-2.10.1.dist-info/RECORD,,
File without changes
File without changes