Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keewenaw
GitHub Repository: keewenaw/ethereum-wallet-cracker
Path: blob/main/test/lib/python3.9/site-packages/setuptools/_distutils/command/register.py
4804 views
1
"""distutils.command.register
2
3
Implements the Distutils 'register' command (register with the repository).
4
"""
5
6
# created 2002/10/21, Richard Jones
7
8
import getpass
9
import io
10
import urllib.parse, urllib.request
11
from warnings import warn
12
13
from distutils.core import PyPIRCCommand
14
from distutils.errors import *
15
from distutils import log
16
17
class register(PyPIRCCommand):
18
19
description = ("register the distribution with the Python package index")
20
user_options = PyPIRCCommand.user_options + [
21
('list-classifiers', None,
22
'list the valid Trove classifiers'),
23
('strict', None ,
24
'Will stop the registering if the meta-data are not fully compliant')
25
]
26
boolean_options = PyPIRCCommand.boolean_options + [
27
'verify', 'list-classifiers', 'strict']
28
29
sub_commands = [('check', lambda self: True)]
30
31
def initialize_options(self):
32
PyPIRCCommand.initialize_options(self)
33
self.list_classifiers = 0
34
self.strict = 0
35
36
def finalize_options(self):
37
PyPIRCCommand.finalize_options(self)
38
# setting options for the `check` subcommand
39
check_options = {'strict': ('register', self.strict),
40
'restructuredtext': ('register', 1)}
41
self.distribution.command_options['check'] = check_options
42
43
def run(self):
44
self.finalize_options()
45
self._set_config()
46
47
# Run sub commands
48
for cmd_name in self.get_sub_commands():
49
self.run_command(cmd_name)
50
51
if self.dry_run:
52
self.verify_metadata()
53
elif self.list_classifiers:
54
self.classifiers()
55
else:
56
self.send_metadata()
57
58
def check_metadata(self):
59
"""Deprecated API."""
60
warn("distutils.command.register.check_metadata is deprecated, \
61
use the check command instead", PendingDeprecationWarning)
62
check = self.distribution.get_command_obj('check')
63
check.ensure_finalized()
64
check.strict = self.strict
65
check.restructuredtext = 1
66
check.run()
67
68
def _set_config(self):
69
''' Reads the configuration file and set attributes.
70
'''
71
config = self._read_pypirc()
72
if config != {}:
73
self.username = config['username']
74
self.password = config['password']
75
self.repository = config['repository']
76
self.realm = config['realm']
77
self.has_config = True
78
else:
79
if self.repository not in ('pypi', self.DEFAULT_REPOSITORY):
80
raise ValueError('%s not found in .pypirc' % self.repository)
81
if self.repository == 'pypi':
82
self.repository = self.DEFAULT_REPOSITORY
83
self.has_config = False
84
85
def classifiers(self):
86
''' Fetch the list of classifiers from the server.
87
'''
88
url = self.repository+'?:action=list_classifiers'
89
response = urllib.request.urlopen(url)
90
log.info(self._read_pypi_response(response))
91
92
def verify_metadata(self):
93
''' Send the metadata to the package index server to be checked.
94
'''
95
# send the info to the server and report the result
96
(code, result) = self.post_to_server(self.build_post_data('verify'))
97
log.info('Server response (%s): %s', code, result)
98
99
def send_metadata(self):
100
''' Send the metadata to the package index server.
101
102
Well, do the following:
103
1. figure who the user is, and then
104
2. send the data as a Basic auth'ed POST.
105
106
First we try to read the username/password from $HOME/.pypirc,
107
which is a ConfigParser-formatted file with a section
108
[distutils] containing username and password entries (both
109
in clear text). Eg:
110
111
[distutils]
112
index-servers =
113
pypi
114
115
[pypi]
116
username: fred
117
password: sekrit
118
119
Otherwise, to figure who the user is, we offer the user three
120
choices:
121
122
1. use existing login,
123
2. register as a new user, or
124
3. set the password to a random string and email the user.
125
126
'''
127
# see if we can short-cut and get the username/password from the
128
# config
129
if self.has_config:
130
choice = '1'
131
username = self.username
132
password = self.password
133
else:
134
choice = 'x'
135
username = password = ''
136
137
# get the user's login info
138
choices = '1 2 3 4'.split()
139
while choice not in choices:
140
self.announce('''\
141
We need to know who you are, so please choose either:
142
1. use your existing login,
143
2. register as a new user,
144
3. have the server generate a new password for you (and email it to you), or
145
4. quit
146
Your selection [default 1]: ''', log.INFO)
147
choice = input()
148
if not choice:
149
choice = '1'
150
elif choice not in choices:
151
print('Please choose one of the four options!')
152
153
if choice == '1':
154
# get the username and password
155
while not username:
156
username = input('Username: ')
157
while not password:
158
password = getpass.getpass('Password: ')
159
160
# set up the authentication
161
auth = urllib.request.HTTPPasswordMgr()
162
host = urllib.parse.urlparse(self.repository)[1]
163
auth.add_password(self.realm, host, username, password)
164
# send the info to the server and report the result
165
code, result = self.post_to_server(self.build_post_data('submit'),
166
auth)
167
self.announce('Server response (%s): %s' % (code, result),
168
log.INFO)
169
170
# possibly save the login
171
if code == 200:
172
if self.has_config:
173
# sharing the password in the distribution instance
174
# so the upload command can reuse it
175
self.distribution.password = password
176
else:
177
self.announce(('I can store your PyPI login so future '
178
'submissions will be faster.'), log.INFO)
179
self.announce('(the login will be stored in %s)' % \
180
self._get_rc_file(), log.INFO)
181
choice = 'X'
182
while choice.lower() not in 'yn':
183
choice = input('Save your login (y/N)?')
184
if not choice:
185
choice = 'n'
186
if choice.lower() == 'y':
187
self._store_pypirc(username, password)
188
189
elif choice == '2':
190
data = {':action': 'user'}
191
data['name'] = data['password'] = data['email'] = ''
192
data['confirm'] = None
193
while not data['name']:
194
data['name'] = input('Username: ')
195
while data['password'] != data['confirm']:
196
while not data['password']:
197
data['password'] = getpass.getpass('Password: ')
198
while not data['confirm']:
199
data['confirm'] = getpass.getpass(' Confirm: ')
200
if data['password'] != data['confirm']:
201
data['password'] = ''
202
data['confirm'] = None
203
print("Password and confirm don't match!")
204
while not data['email']:
205
data['email'] = input(' EMail: ')
206
code, result = self.post_to_server(data)
207
if code != 200:
208
log.info('Server response (%s): %s', code, result)
209
else:
210
log.info('You will receive an email shortly.')
211
log.info(('Follow the instructions in it to '
212
'complete registration.'))
213
elif choice == '3':
214
data = {':action': 'password_reset'}
215
data['email'] = ''
216
while not data['email']:
217
data['email'] = input('Your email address: ')
218
code, result = self.post_to_server(data)
219
log.info('Server response (%s): %s', code, result)
220
221
def build_post_data(self, action):
222
# figure the data to send - the metadata plus some additional
223
# information used by the package server
224
meta = self.distribution.metadata
225
data = {
226
':action': action,
227
'metadata_version' : '1.0',
228
'name': meta.get_name(),
229
'version': meta.get_version(),
230
'summary': meta.get_description(),
231
'home_page': meta.get_url(),
232
'author': meta.get_contact(),
233
'author_email': meta.get_contact_email(),
234
'license': meta.get_licence(),
235
'description': meta.get_long_description(),
236
'keywords': meta.get_keywords(),
237
'platform': meta.get_platforms(),
238
'classifiers': meta.get_classifiers(),
239
'download_url': meta.get_download_url(),
240
# PEP 314
241
'provides': meta.get_provides(),
242
'requires': meta.get_requires(),
243
'obsoletes': meta.get_obsoletes(),
244
}
245
if data['provides'] or data['requires'] or data['obsoletes']:
246
data['metadata_version'] = '1.1'
247
return data
248
249
def post_to_server(self, data, auth=None):
250
''' Post a query to the server, and return a string response.
251
'''
252
if 'name' in data:
253
self.announce('Registering %s to %s' % (data['name'],
254
self.repository),
255
log.INFO)
256
# Build up the MIME payload for the urllib2 POST data
257
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
258
sep_boundary = '\n--' + boundary
259
end_boundary = sep_boundary + '--'
260
body = io.StringIO()
261
for key, value in data.items():
262
# handle multiple entries for the same name
263
if type(value) not in (type([]), type( () )):
264
value = [value]
265
for value in value:
266
value = str(value)
267
body.write(sep_boundary)
268
body.write('\nContent-Disposition: form-data; name="%s"'%key)
269
body.write("\n\n")
270
body.write(value)
271
if value and value[-1] == '\r':
272
body.write('\n') # write an extra newline (lurve Macs)
273
body.write(end_boundary)
274
body.write("\n")
275
body = body.getvalue().encode("utf-8")
276
277
# build the Request
278
headers = {
279
'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
280
'Content-length': str(len(body))
281
}
282
req = urllib.request.Request(self.repository, body, headers)
283
284
# handle HTTP and include the Basic Auth handler
285
opener = urllib.request.build_opener(
286
urllib.request.HTTPBasicAuthHandler(password_mgr=auth)
287
)
288
data = ''
289
try:
290
result = opener.open(req)
291
except urllib.error.HTTPError as e:
292
if self.show_response:
293
data = e.fp.read()
294
result = e.code, e.msg
295
except urllib.error.URLError as e:
296
result = 500, str(e)
297
else:
298
if self.show_response:
299
data = self._read_pypi_response(result)
300
result = 200, 'OK'
301
if self.show_response:
302
msg = '\n'.join(('-' * 75, data, '-' * 75))
303
self.announce(msg, log.INFO)
304
return result
305
306