berryworld 1.0.0.179097__py3-none-any.whl → 1.0.0.180127__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.
- berryworld/cache_data.py +3 -3
- berryworld/credentials.py +26 -3
- berryworld/email_logging.py +18 -10
- berryworld/handy_mix.py +17 -17
- berryworld/microsoft_teams.py +4 -4
- berryworld/snowflake_conn.py +77 -0
- berryworld/sql_conn.py +4 -2
- berryworld/transportation_solver.py +5 -5
- {berryworld-1.0.0.179097.dist-info → berryworld-1.0.0.180127.dist-info}/METADATA +1 -1
- {berryworld-1.0.0.179097.dist-info → berryworld-1.0.0.180127.dist-info}/RECORD +13 -12
- {berryworld-1.0.0.179097.dist-info → berryworld-1.0.0.180127.dist-info}/WHEEL +1 -1
- {berryworld-1.0.0.179097.dist-info → berryworld-1.0.0.180127.dist-info}/LICENSE +0 -0
- {berryworld-1.0.0.179097.dist-info → berryworld-1.0.0.180127.dist-info}/top_level.txt +0 -0
berryworld/cache_data.py
CHANGED
|
@@ -50,7 +50,7 @@ class CacheManagement:
|
|
|
50
50
|
def dump_pickle(df, filepath):
|
|
51
51
|
""" Save the data to a filepath
|
|
52
52
|
:param df: DataFrame gathering the data
|
|
53
|
-
:param
|
|
53
|
+
:param filepath: Path and filename to the file destination
|
|
54
54
|
"""
|
|
55
55
|
pickle_out = open(filepath, 'wb')
|
|
56
56
|
pickle.dump(df, pickle_out)
|
|
@@ -59,7 +59,7 @@ class CacheManagement:
|
|
|
59
59
|
@staticmethod
|
|
60
60
|
def retrieve_pickle(filepath):
|
|
61
61
|
""" Get the data from the indicated filepath
|
|
62
|
-
:param
|
|
62
|
+
:param filepath: Path and filename to the file destination
|
|
63
63
|
"""
|
|
64
64
|
pickle_in = open(filepath, "rb")
|
|
65
65
|
data_df = pickle.load(pickle_in)
|
|
@@ -69,7 +69,7 @@ class CacheManagement:
|
|
|
69
69
|
@staticmethod
|
|
70
70
|
def remove_pickle(filepath):
|
|
71
71
|
""" Delete a file allocated in filepath
|
|
72
|
-
:param
|
|
72
|
+
:param filepath: Path and filename to the file destination
|
|
73
73
|
"""
|
|
74
74
|
if os.path.exists(filepath):
|
|
75
75
|
os.remove(filepath)
|
berryworld/credentials.py
CHANGED
|
@@ -209,15 +209,18 @@ class WebServiceCredentials:
|
|
|
209
209
|
|
|
210
210
|
try:
|
|
211
211
|
user_name = os.environ.get(f"WEBSERVICE_USER_{self.service.upper()}")
|
|
212
|
-
except Exception:
|
|
212
|
+
except Exception as e:
|
|
213
|
+
print(e)
|
|
213
214
|
user_name = ''
|
|
214
215
|
try:
|
|
215
216
|
password = os.environ.get(f"WEBSERVICE_PASSWORD_{self.service.upper()}")
|
|
216
|
-
except Exception:
|
|
217
|
+
except Exception as e:
|
|
218
|
+
print(e)
|
|
217
219
|
password = ''
|
|
218
220
|
try:
|
|
219
221
|
access_token = os.environ.get(f"WEBSERVICE_ACCESS_TOKEN_{self.service.upper()}")
|
|
220
|
-
except Exception:
|
|
222
|
+
except Exception as e:
|
|
223
|
+
print(e)
|
|
221
224
|
access_token = ''
|
|
222
225
|
|
|
223
226
|
return {'user_name': user_name,
|
|
@@ -250,3 +253,23 @@ class MicrosoftTeamsCredentials:
|
|
|
250
253
|
|
|
251
254
|
except ValueError as e:
|
|
252
255
|
raise ValueError("Variable %s not found" % str(e))
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class SnowflakeCredentials:
|
|
259
|
+
def __init__(self, db_name):
|
|
260
|
+
if db_name is None:
|
|
261
|
+
raise ValueError("Please provide a value for db_name")
|
|
262
|
+
self.db_name = db_name
|
|
263
|
+
|
|
264
|
+
def simple_creds(self):
|
|
265
|
+
try:
|
|
266
|
+
account = os.environ.get("SNOWFLAKE_" + self.db_name.upper() + '_ACCOUNT')
|
|
267
|
+
user_name = os.environ.get("SNOWFLAKE_" + self.db_name.upper() + '_USERNAME')
|
|
268
|
+
password = os.environ.get("SNOWFLAKE_" + self.db_name.upper() + '_PASSWORD')
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
'account': account,
|
|
272
|
+
'user_name': user_name,
|
|
273
|
+
'password': password}
|
|
274
|
+
except ValueError as e:
|
|
275
|
+
raise ValueError("Variable %s not found" % str(e))
|
berryworld/email_logging.py
CHANGED
|
@@ -59,16 +59,24 @@ class EmailLogging:
|
|
|
59
59
|
:param critical: Indicate whether it should avoid sending successful logs
|
|
60
60
|
:param proposed_solution: Proposed solution to the error message
|
|
61
61
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
save_failure = True
|
|
63
|
+
if section is not None:
|
|
64
|
+
if (('prod' not in str(self.sql_con.server)) | ('prd' not in str(self.sql_con.server))) \
|
|
65
|
+
& (('connection' in str(section).lower()) & ('dw' in str(section).lower())):
|
|
66
|
+
print('Avoiding to report a connection DW error in a non-production environment')
|
|
67
|
+
save_failure = False
|
|
68
|
+
|
|
69
|
+
if save_failure:
|
|
70
|
+
unsuccessful_columns = {'Successful': 0,
|
|
71
|
+
'FinishedDate': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"),
|
|
72
|
+
'Section': section,
|
|
73
|
+
'ErrorMessage': str(error_message).replace("'", '"'),
|
|
74
|
+
'Critical': 1 if critical is True else 0}
|
|
75
|
+
self.log_df = self.log_df.assign(**unsuccessful_columns)
|
|
76
|
+
if proposed_solution is not None:
|
|
77
|
+
self.log_df = self.log_df.assign(**{'ProposedSolution': proposed_solution})
|
|
78
|
+
self.sql_con.insert(self.log_df, 'Logging', 'PythonLogs', print_sql=self.print_sql)
|
|
79
|
+
self.failure_type.append(critical)
|
|
72
80
|
|
|
73
81
|
@staticmethod
|
|
74
82
|
def register_failure(email_log, section, error_, solutions=None):
|
berryworld/handy_mix.py
CHANGED
|
@@ -65,7 +65,21 @@ class HandyMix:
|
|
|
65
65
|
return result
|
|
66
66
|
|
|
67
67
|
@staticmethod
|
|
68
|
-
def
|
|
68
|
+
def grab_n_elem(n, comp_):
|
|
69
|
+
max_list = heapq.nlargest(n, comp_)
|
|
70
|
+
like_matches = np.array([elem in max_list for elem in comp_]).sum()
|
|
71
|
+
if like_matches > n:
|
|
72
|
+
list_ = [elem in max_list for elem in comp_]
|
|
73
|
+
k = 0
|
|
74
|
+
for elem in list_:
|
|
75
|
+
if (elem is True) & (k > n - 1):
|
|
76
|
+
list_[k] = False
|
|
77
|
+
k = + 1
|
|
78
|
+
return list_
|
|
79
|
+
else:
|
|
80
|
+
return [elem in max_list for elem in comp_]
|
|
81
|
+
|
|
82
|
+
def likely_match(self, srs, match_str, n_res=1, threshold=False):
|
|
69
83
|
""" Look for the more similar element in a Series to the one provided in match_str. If there is a draw,
|
|
70
84
|
It will pick the first matching elements. Threshold only consider the elements if their likelihood is
|
|
71
85
|
greater than that threshold variable
|
|
@@ -88,29 +102,15 @@ class HandyMix:
|
|
|
88
102
|
aux = SequenceMatcher(None, element, match_str)
|
|
89
103
|
comp.append(aux.ratio())
|
|
90
104
|
|
|
91
|
-
def grab_n_elem(n, comp):
|
|
92
|
-
max_list = heapq.nlargest(n, comp)
|
|
93
|
-
like_matches = np.array([elem in max_list for elem in comp]).sum()
|
|
94
|
-
if like_matches > n:
|
|
95
|
-
list_ = [elem in max_list for elem in comp]
|
|
96
|
-
k = 0
|
|
97
|
-
for elem in list_:
|
|
98
|
-
if (elem is True) & (k > n - 1):
|
|
99
|
-
list_[k] = False
|
|
100
|
-
k = + 1
|
|
101
|
-
return list_
|
|
102
|
-
else:
|
|
103
|
-
return [elem in max_list for elem in comp]
|
|
104
|
-
|
|
105
105
|
if threshold:
|
|
106
106
|
# Return n elements above the threshold
|
|
107
107
|
if any(elem >= threshold for elem in comp):
|
|
108
|
-
return grab_n_elem(n_res, comp)
|
|
108
|
+
return self.grab_n_elem(n_res, comp)
|
|
109
109
|
else:
|
|
110
110
|
return [False] * comp.__len__()
|
|
111
111
|
else:
|
|
112
112
|
# Return n elements likely to match
|
|
113
|
-
return grab_n_elem(n_res, comp)
|
|
113
|
+
return self.grab_n_elem(n_res, comp)
|
|
114
114
|
|
|
115
115
|
@staticmethod
|
|
116
116
|
def remove_line_chars(input_text, remove_duplicate_white_spaces=False):
|
berryworld/microsoft_teams.py
CHANGED
|
@@ -254,11 +254,11 @@ class MicrosoftTeams:
|
|
|
254
254
|
vivantio_ticket_id = vivantio_ticket['Id'].values[0]
|
|
255
255
|
display_id = vivantio_ticket['DisplayId'].values[0]
|
|
256
256
|
vivantio_ticket_url = f'https://poupart.flex.vivantio.com/item/Ticket/{vivantio_ticket_id}'
|
|
257
|
-
html_message = html_message + f'<br><b>Vivantio Ticket Id:</b> {display_id}'
|
|
258
|
-
|
|
257
|
+
html_message = html_message + f'<br><b>Vivantio Ticket Id:</b> {display_id}' \
|
|
258
|
+
f'<br><b>Vivantio Ticket URL:</b> {vivantio_ticket_url}<br>'
|
|
259
259
|
|
|
260
|
-
html_message = html_message + '<br><b>Error Status:</b> ' + status + f'<br><b>Error Count:</b> {count}'
|
|
261
|
-
|
|
260
|
+
html_message = html_message + '<br><b>Error Status:</b> ' + status + f'<br><b>Error Count:</b> {count}' \
|
|
261
|
+
f'<br><b>Error Content:</b> <br>' + message
|
|
262
262
|
|
|
263
263
|
payload = {}
|
|
264
264
|
if importance:
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import snowflake.connector
|
|
3
|
+
from credentials import SnowflakeCredentials
|
|
4
|
+
|
|
5
|
+
pd.set_option('future.no_silent_downcasting', True)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SnowflakeConn:
|
|
9
|
+
def __init__(self, server_creds=None, **kwargs):
|
|
10
|
+
""" Initialize the class
|
|
11
|
+
-----------------------------
|
|
12
|
+
server_creds = {
|
|
13
|
+
"account": "",
|
|
14
|
+
"db_name": "",
|
|
15
|
+
"user_name": "",
|
|
16
|
+
"password": ""
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
-----------------------------
|
|
20
|
+
:param server_creds: Dictionary containing the info to connect to the Server
|
|
21
|
+
:param kwargs: Additional parameters to be passed to the connection
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
self.conn_str = None
|
|
25
|
+
self.conn = None
|
|
26
|
+
|
|
27
|
+
if kwargs != {}:
|
|
28
|
+
try:
|
|
29
|
+
db = kwargs['db_name']
|
|
30
|
+
server_creds = SnowflakeCredentials(db).simple_creds()
|
|
31
|
+
except KeyError:
|
|
32
|
+
raise KeyError('Please provide a valid db_name and server_type')
|
|
33
|
+
|
|
34
|
+
self.db = kwargs['db_name']
|
|
35
|
+
self.user = server_creds['user_name']
|
|
36
|
+
self.pw = server_creds['password']
|
|
37
|
+
self.account = server_creds['account']
|
|
38
|
+
|
|
39
|
+
if self.user and self.pw and self.account:
|
|
40
|
+
self.connect()
|
|
41
|
+
|
|
42
|
+
def connect(self):
|
|
43
|
+
""" Open the connection to Snowflake """
|
|
44
|
+
self.conn = snowflake.connector.connect(
|
|
45
|
+
user=self.user,
|
|
46
|
+
password=self.pw,
|
|
47
|
+
account=self.account,
|
|
48
|
+
database=self.db)
|
|
49
|
+
|
|
50
|
+
def close(self):
|
|
51
|
+
""" Close the connection to Snowflake """
|
|
52
|
+
self.conn.close()
|
|
53
|
+
|
|
54
|
+
def query(self, sql_query):
|
|
55
|
+
""" Read data from Snowflake according to the sql_query
|
|
56
|
+
-----------------------------
|
|
57
|
+
query_str = "SELECT * FROM %s" & table
|
|
58
|
+
con_.query(query_str)
|
|
59
|
+
-----------------------------
|
|
60
|
+
:param sql_query: Query to be sent to Snowflake
|
|
61
|
+
:return: DataFrame gathering the requested data
|
|
62
|
+
"""
|
|
63
|
+
cursor = None
|
|
64
|
+
self.connect()
|
|
65
|
+
try:
|
|
66
|
+
cursor = self.conn.cursor()
|
|
67
|
+
cursor.execute(sql_query)
|
|
68
|
+
rows = cursor.fetchall()
|
|
69
|
+
col_names = [desc[0] for desc in cursor.description]
|
|
70
|
+
result = pd.DataFrame(rows, columns=col_names)
|
|
71
|
+
return result
|
|
72
|
+
except Exception as e:
|
|
73
|
+
raise Exception(e)
|
|
74
|
+
finally:
|
|
75
|
+
if cursor:
|
|
76
|
+
cursor.close()
|
|
77
|
+
self.close()
|
berryworld/sql_conn.py
CHANGED
|
@@ -942,9 +942,11 @@ class SQLConn:
|
|
|
942
942
|
# Avoid converting datetime values
|
|
943
943
|
try:
|
|
944
944
|
pd.to_datetime(data[col])
|
|
945
|
-
except:
|
|
945
|
+
except Exception as e:
|
|
946
|
+
print(e)
|
|
946
947
|
data[col] = data[col].str.replace('.0', '')
|
|
947
|
-
except:
|
|
948
|
+
except Exception as e:
|
|
949
|
+
print(e)
|
|
948
950
|
continue
|
|
949
951
|
|
|
950
952
|
return data
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
|
-
from scipy.optimize import linprog
|
|
2
|
+
from scipy.optimize import linprog, _highs
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class TransportationAlgorithm:
|
|
@@ -71,13 +71,13 @@ class TransportationAlgorithm:
|
|
|
71
71
|
|
|
72
72
|
# Run the Simplex method
|
|
73
73
|
method = 'Interior-Point without constraints'
|
|
74
|
-
res = linprog(c, A_eq=a_matrix, b_eq=b, options=options, method='
|
|
74
|
+
res = linprog(c, A_eq=a_matrix, b_eq=b, options=options, method='highs-ipm')
|
|
75
75
|
res_success = res.success
|
|
76
76
|
|
|
77
77
|
# Run the Interior-Point method
|
|
78
78
|
if res_success is False:
|
|
79
79
|
method = 'Interior-Point without constraints'
|
|
80
|
-
res = linprog(c, A_eq=a_matrix, b_eq=b, options=options, method='
|
|
80
|
+
res = linprog(c, A_eq=a_matrix, b_eq=b, options=options, method='highs-ds')
|
|
81
81
|
res_success = res.success
|
|
82
82
|
|
|
83
83
|
# Run the interior-point method with constraints
|
|
@@ -89,7 +89,7 @@ class TransportationAlgorithm:
|
|
|
89
89
|
max_value = max(prod[0], sales[0])
|
|
90
90
|
b_ub = [max_value] + [max_value]
|
|
91
91
|
res = linprog(c, A_eq=a_eq, b_eq=b_eq, A_ub=a_ub, b_ub=b_ub,
|
|
92
|
-
options=options, method='
|
|
92
|
+
options=options, method='highs-ipm')
|
|
93
93
|
res_success = res.success
|
|
94
94
|
|
|
95
95
|
# Run the Revised Simplex method with constraints
|
|
@@ -101,7 +101,7 @@ class TransportationAlgorithm:
|
|
|
101
101
|
max_value = max(prod[0], sales[0])
|
|
102
102
|
b_ub = [max_value] + [max_value]
|
|
103
103
|
res = linprog(c, A_eq=a_eq, b_eq=b_eq, A_ub=a_ub, b_ub=b_ub,
|
|
104
|
-
options=options, method='
|
|
104
|
+
options=options, method='highs-ds')
|
|
105
105
|
res_success = res.success
|
|
106
106
|
|
|
107
107
|
result = self.ranking
|
|
@@ -3,23 +3,24 @@ berryworld/aks_logs.py,sha256=Gb2_cokiZbEX01Yoptd0MxpDociaug-GrXdwliyxFBo,2293
|
|
|
3
3
|
berryworld/allocation_solver.py,sha256=asFtaCAze6-eHUGWXA0kAp67UBS-Upj1KKdrVLj_ttQ,8513
|
|
4
4
|
berryworld/app_logs.py,sha256=MKzKPYd3JuPfOQNAapIgaeZeFHw1z_w2mbn9I6QCADE,4180
|
|
5
5
|
berryworld/app_logs_query.py,sha256=U94b-z3X9cuY_KFozupUcfaYciXWBn7p_RHkoRsfROU,4376
|
|
6
|
-
berryworld/cache_data.py,sha256=
|
|
7
|
-
berryworld/credentials.py,sha256=
|
|
6
|
+
berryworld/cache_data.py,sha256=AWAhV4PPkilZ4Xb1pUXuuu6UdHICAx8QqDtb9rVnjDM,2254
|
|
7
|
+
berryworld/credentials.py,sha256=L70ZzSNaS2mbHtSS8lb3iesd1XSwZNnUzGznlEKxlJY,11018
|
|
8
8
|
berryworld/devops.py,sha256=BAsVonVwCXoApUOovkt-BCzwc6KnXjxRDGff_ejSGw8,9719
|
|
9
9
|
berryworld/email_con.py,sha256=uSBzs_Ijz9pUPWt9e7U3TCB7i6q7hU1bB5vhsTB_tmw,14448
|
|
10
|
-
berryworld/email_logging.py,sha256=
|
|
10
|
+
berryworld/email_logging.py,sha256=LeSrTExhQhar49gJR2wGC1dS0lqsNpFl9pS3eYWqnuo,4936
|
|
11
11
|
berryworld/generate_env.py,sha256=Tk9Z_u7cA4Ve8YYTyLH2qwmLVAuYoTIWoFc0h8Va8lY,7842
|
|
12
|
-
berryworld/handy_mix.py,sha256=
|
|
12
|
+
berryworld/handy_mix.py,sha256=lRUes_V4jL-3ADOzwiKqi1Dukx-HWXvmf9-4s4MLwsA,9740
|
|
13
13
|
berryworld/logic_apps.py,sha256=a0uU4tNO3v2w7grdBv-OOx4hUf7VBIerJpwZ9U-29dQ,14591
|
|
14
|
-
berryworld/microsoft_teams.py,sha256=
|
|
14
|
+
berryworld/microsoft_teams.py,sha256=8uPo0yku-euBj2VdzBoZCeX3IcsCCOqISLqaVZUVxfA,16030
|
|
15
15
|
berryworld/persistent_storage.py,sha256=_lGdXa7IyxfMF3xNF9y26X_z9RDb2Ah7R0oF61HR8Gc,5764
|
|
16
16
|
berryworld/pickle_management.py,sha256=O49ojVtTqYCT510rVRTbZWWaur_-5q3HSVG03Azn8mQ,2393
|
|
17
17
|
berryworld/postgres_connection.py,sha256=whKDnchd5Feqpmxpoh2vlyn36EKHR-dVEULYq0N_4wA,8287
|
|
18
18
|
berryworld/power_automate.py,sha256=9rDuRy0v-Ttq-SThid4lOB_tD4ibkyEmobiROpa--g4,25414
|
|
19
19
|
berryworld/sharepoint_con.py,sha256=TuH-Vxk1VxjTi7x80KFssf_J8YPLRXpV27RBaFZi37U,22254
|
|
20
|
-
berryworld/
|
|
20
|
+
berryworld/snowflake_conn.py,sha256=qd7kjeGDBUtMQqSfR0rCVz1Qn6d9U3zskBvfLRNSofc,2480
|
|
21
|
+
berryworld/sql_conn.py,sha256=meDAf_92hNW5Zp5sv_PPeIUA8NDchaDtVN7zo77veIA,47491
|
|
21
22
|
berryworld/teams_logging.py,sha256=8NwXyWr4fLj7W6GzAm2nRQCGFDxibQpAHDHHD24FrP8,6997
|
|
22
|
-
berryworld/transportation_solver.py,sha256=
|
|
23
|
+
berryworld/transportation_solver.py,sha256=gdlHRgl2wlp5EV0uhKIOYtkkbAlHaFHGktnMgvuENWE,5022
|
|
23
24
|
berryworld/verify_keys.py,sha256=J2J505PcmBsQ9bj0XSRtXjpY-8qwpPU1A5LQdFRicFU,4257
|
|
24
25
|
berryworld/vivantio.py,sha256=QfZo0UKqkzVRg_LyiwivNd3aEup4TH57x4KxLZkCJwc,10627
|
|
25
26
|
berryworld/vivantio_logging.py,sha256=ciy7gA4u3FrgUIpEBnMgocbNPp6jcu9TPoy-kLcrTZU,5736
|
|
@@ -28,8 +29,8 @@ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
28
29
|
tests/test_allocation_config.py,sha256=e12l6fE9U57eSPS35g6ekJ_hol7-RHg89JV60_m1BlE,4633
|
|
29
30
|
tests/test_handy_mix_config.py,sha256=Un56mz9KJmdn4K4OwzHAHLSRzDU1Xv2nFrONNuzOG04,2594
|
|
30
31
|
tests/test_xml_parser.py,sha256=3QTlhFEd6KbK6nRFKZnc35tad6wqukTbe4QrFi8mr_8,859
|
|
31
|
-
berryworld-1.0.0.
|
|
32
|
-
berryworld-1.0.0.
|
|
33
|
-
berryworld-1.0.0.
|
|
34
|
-
berryworld-1.0.0.
|
|
35
|
-
berryworld-1.0.0.
|
|
32
|
+
berryworld-1.0.0.180127.dist-info/LICENSE,sha256=vtkVCJM6E2af2gnsi2XxKPr4WY-uIbvzVLXieFND0UU,1074
|
|
33
|
+
berryworld-1.0.0.180127.dist-info/METADATA,sha256=k_9Yaln2DC97Fes4tsW8U2GPrfZ9t2pzXDHOOCPhCcA,1091
|
|
34
|
+
berryworld-1.0.0.180127.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
35
|
+
berryworld-1.0.0.180127.dist-info/top_level.txt,sha256=GIZ5qy-P5oxfEH755vA1IMFeTVdX3-40JxMe6nOe5I8,17
|
|
36
|
+
berryworld-1.0.0.180127.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|