]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/command/upload.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / command / upload.py
CommitLineData
4710c53d 1"""distutils.command.upload\r
2\r
3Implements the Distutils 'upload' subcommand (upload package to PyPI)."""\r
4import os\r
5import socket\r
6import platform\r
7from urllib2 import urlopen, Request, HTTPError\r
8from base64 import standard_b64encode\r
9import urlparse\r
10import cStringIO as StringIO\r
11from hashlib import md5\r
12\r
13from distutils.errors import DistutilsOptionError\r
14from distutils.core import PyPIRCCommand\r
15from distutils.spawn import spawn\r
16from distutils import log\r
17\r
18class upload(PyPIRCCommand):\r
19\r
20 description = "upload binary package to PyPI"\r
21\r
22 user_options = PyPIRCCommand.user_options + [\r
23 ('sign', 's',\r
24 'sign files to upload using gpg'),\r
25 ('identity=', 'i', 'GPG identity used to sign files'),\r
26 ]\r
27\r
28 boolean_options = PyPIRCCommand.boolean_options + ['sign']\r
29\r
30 def initialize_options(self):\r
31 PyPIRCCommand.initialize_options(self)\r
32 self.username = ''\r
33 self.password = ''\r
34 self.show_response = 0\r
35 self.sign = False\r
36 self.identity = None\r
37\r
38 def finalize_options(self):\r
39 PyPIRCCommand.finalize_options(self)\r
40 if self.identity and not self.sign:\r
41 raise DistutilsOptionError(\r
42 "Must use --sign for --identity to have meaning"\r
43 )\r
44 config = self._read_pypirc()\r
45 if config != {}:\r
46 self.username = config['username']\r
47 self.password = config['password']\r
48 self.repository = config['repository']\r
49 self.realm = config['realm']\r
50\r
51 # getting the password from the distribution\r
52 # if previously set by the register command\r
53 if not self.password and self.distribution.password:\r
54 self.password = self.distribution.password\r
55\r
56 def run(self):\r
57 if not self.distribution.dist_files:\r
58 raise DistutilsOptionError("No dist file created in earlier command")\r
59 for command, pyversion, filename in self.distribution.dist_files:\r
60 self.upload_file(command, pyversion, filename)\r
61\r
62 def upload_file(self, command, pyversion, filename):\r
63 # Makes sure the repository URL is compliant\r
64 schema, netloc, url, params, query, fragments = \\r
65 urlparse.urlparse(self.repository)\r
66 if params or query or fragments:\r
67 raise AssertionError("Incompatible url %s" % self.repository)\r
68\r
69 if schema not in ('http', 'https'):\r
70 raise AssertionError("unsupported schema " + schema)\r
71\r
72 # Sign if requested\r
73 if self.sign:\r
74 gpg_args = ["gpg", "--detach-sign", "-a", filename]\r
75 if self.identity:\r
76 gpg_args[2:2] = ["--local-user", self.identity]\r
77 spawn(gpg_args,\r
78 dry_run=self.dry_run)\r
79\r
80 # Fill in the data - send all the meta-data in case we need to\r
81 # register a new release\r
82 f = open(filename,'rb')\r
83 try:\r
84 content = f.read()\r
85 finally:\r
86 f.close()\r
87 meta = self.distribution.metadata\r
88 data = {\r
89 # action\r
90 ':action': 'file_upload',\r
91 'protcol_version': '1',\r
92\r
93 # identify release\r
94 'name': meta.get_name(),\r
95 'version': meta.get_version(),\r
96\r
97 # file content\r
98 'content': (os.path.basename(filename),content),\r
99 'filetype': command,\r
100 'pyversion': pyversion,\r
101 'md5_digest': md5(content).hexdigest(),\r
102\r
103 # additional meta-data\r
104 'metadata_version' : '1.0',\r
105 'summary': meta.get_description(),\r
106 'home_page': meta.get_url(),\r
107 'author': meta.get_contact(),\r
108 'author_email': meta.get_contact_email(),\r
109 'license': meta.get_licence(),\r
110 'description': meta.get_long_description(),\r
111 'keywords': meta.get_keywords(),\r
112 'platform': meta.get_platforms(),\r
113 'classifiers': meta.get_classifiers(),\r
114 'download_url': meta.get_download_url(),\r
115 # PEP 314\r
116 'provides': meta.get_provides(),\r
117 'requires': meta.get_requires(),\r
118 'obsoletes': meta.get_obsoletes(),\r
119 }\r
120 comment = ''\r
121 if command == 'bdist_rpm':\r
122 dist, version, id = platform.dist()\r
123 if dist:\r
124 comment = 'built for %s %s' % (dist, version)\r
125 elif command == 'bdist_dumb':\r
126 comment = 'built for %s' % platform.platform(terse=1)\r
127 data['comment'] = comment\r
128\r
129 if self.sign:\r
130 data['gpg_signature'] = (os.path.basename(filename) + ".asc",\r
131 open(filename+".asc").read())\r
132\r
133 # set up the authentication\r
134 auth = "Basic " + standard_b64encode(self.username + ":" +\r
135 self.password)\r
136\r
137 # Build up the MIME payload for the POST data\r
138 boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'\r
139 sep_boundary = '\n--' + boundary\r
140 end_boundary = sep_boundary + '--'\r
141 body = StringIO.StringIO()\r
142 for key, value in data.items():\r
143 # handle multiple entries for the same name\r
144 if not isinstance(value, list):\r
145 value = [value]\r
146 for value in value:\r
147 if isinstance(value, tuple):\r
148 fn = ';filename="%s"' % value[0]\r
149 value = value[1]\r
150 else:\r
151 fn = ""\r
152\r
153 body.write(sep_boundary)\r
154 body.write('\nContent-Disposition: form-data; name="%s"'%key)\r
155 body.write(fn)\r
156 body.write("\n\n")\r
157 body.write(value)\r
158 if value and value[-1] == '\r':\r
159 body.write('\n') # write an extra newline (lurve Macs)\r
160 body.write(end_boundary)\r
161 body.write("\n")\r
162 body = body.getvalue()\r
163\r
164 self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)\r
165\r
166 # build the Request\r
167 headers = {'Content-type':\r
168 'multipart/form-data; boundary=%s' % boundary,\r
169 'Content-length': str(len(body)),\r
170 'Authorization': auth}\r
171\r
172 request = Request(self.repository, data=body,\r
173 headers=headers)\r
174 # send the data\r
175 try:\r
176 result = urlopen(request)\r
177 status = result.getcode()\r
178 reason = result.msg\r
179 if self.show_response:\r
180 msg = '\n'.join(('-' * 75, r.read(), '-' * 75))\r
181 self.announce(msg, log.INFO)\r
182 except socket.error, e:\r
183 self.announce(str(e), log.ERROR)\r
184 return\r
185 except HTTPError, e:\r
186 status = e.code\r
187 reason = e.msg\r
188\r
189 if status == 200:\r
190 self.announce('Server response (%s): %s' % (status, reason),\r
191 log.INFO)\r
192 else:\r
193 self.announce('Upload failed (%s): %s' % (status, reason),\r
194 log.ERROR)\r