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