OLD | NEW |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 """Defines class Rietveld to easily access a rietveld instance. | 4 """Defines class Rietveld to easily access a rietveld instance. |
5 | 5 |
6 Security implications: | 6 Security implications: |
7 | 7 |
8 The following hypothesis are made: | 8 The following hypothesis are made: |
9 - Rietveld enforces: | 9 - Rietveld enforces: |
10 - Nobody else than issue owner can upload a patch set | 10 - Nobody else than issue owner can upload a patch set |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 Returns a useless diff for binary files. | 105 Returns a useless diff for binary files. |
106 """ | 106 """ |
107 url = '/download/issue%s_%s_%s.diff' % (issue, patchset, item) | 107 url = '/download/issue%s_%s_%s.diff' % (issue, patchset, item) |
108 return self.get(url) | 108 return self.get(url) |
109 | 109 |
110 def get_patch(self, issue, patchset): | 110 def get_patch(self, issue, patchset): |
111 """Returns a PatchSet object containing the details to apply this patch.""" | 111 """Returns a PatchSet object containing the details to apply this patch.""" |
112 props = self.get_patchset_properties(issue, patchset) or {} | 112 props = self.get_patchset_properties(issue, patchset) or {} |
113 out = [] | 113 out = [] |
114 for filename, state in props.get('files', {}).iteritems(): | 114 for filename, state in props.get('files', {}).iteritems(): |
| 115 logging.debug('%s' % filename) |
115 status = state.get('status') | 116 status = state.get('status') |
116 if status is None: | 117 if status is None: |
117 raise patch.UnsupportedPatchFormat( | 118 raise patch.UnsupportedPatchFormat( |
118 filename, 'File\'s status is None, patchset upload is incomplete') | 119 filename, 'File\'s status is None, patchset upload is incomplete.') |
119 | 120 |
120 # TODO(maruel): That's bad, it confuses property change. | 121 # TODO(maruel): That's bad, it confuses property change. |
121 status = status.strip() | 122 status = status.strip() |
122 | 123 |
123 if status == 'D': | 124 if status == 'D': |
124 # Ignore the diff. | 125 # Ignore the diff. |
125 out.append(patch.FilePatchDelete(filename, state['is_binary'])) | 126 out.append(patch.FilePatchDelete(filename, state['is_binary'])) |
126 elif status in ('A', 'M'): | 127 elif status in ('A', 'M'): |
127 # TODO(maruel): Rietveld support is still weird, add this line once it's | 128 # TODO(maruel): Rietveld support is still weird, add this line once it's |
128 # safe to use. | 129 # safe to use. |
129 # props = state.get('property_changes', '').splitlines() or [] | 130 # props = state.get('property_changes', '').splitlines() or [] |
130 props = [] | 131 props = [] |
131 if state['is_binary']: | 132 if state['is_binary']: |
132 out.append(patch.FilePatchBinary( | 133 out.append(patch.FilePatchBinary( |
133 filename, | 134 filename, |
134 self.get_file_content(issue, patchset, state['id']), | 135 self.get_file_content(issue, patchset, state['id']), |
135 props)) | 136 props)) |
136 else: | 137 else: |
137 if state['num_chunks']: | 138 if state['num_chunks']: |
138 diff = self.get_file_diff(issue, patchset, state['id']) | 139 diff = self.get_file_diff(issue, patchset, state['id']) |
139 else: | 140 else: |
140 diff = None | 141 raise patch.UnsupportedPatchFormat( |
| 142 filename, 'File doesn\'t have a diff.') |
141 out.append(patch.FilePatchDiff(filename, diff, props)) | 143 out.append(patch.FilePatchDiff(filename, diff, props)) |
142 else: | 144 else: |
143 # Line too long (N/80) | 145 # Line too long (N/80) |
144 # pylint: disable=C0301 | 146 # pylint: disable=C0301 |
145 # TODO: Add support for MM, A+, etc. Rietveld removes the svn properties | 147 # TODO: Add support for MM, A+, etc. Rietveld removes the svn properties |
146 # from the diff. | 148 # from the diff. |
147 # Example of mergeinfo across branches: | 149 # Example of mergeinfo across branches: |
148 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmlcat
alog_dummy.cc | 150 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmlcat
alog_dummy.cc |
149 # svn:eol-style property that is lost in the diff | 151 # svn:eol-style property that is lost in the diff |
150 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmllin
t_dummy.cc | 152 # http://codereview.chromium.org/202046/diff/1/third_party/libxml/xmllin
t_dummy.cc |
(...skipping 30 matching lines...) Expand all Loading... |
181 | 183 |
182 def post(self, request_path, data, **kwargs): | 184 def post(self, request_path, data, **kwargs): |
183 ctype, body = upload.EncodeMultipartFormData(data, []) | 185 ctype, body = upload.EncodeMultipartFormData(data, []) |
184 return self._send(request_path, payload=body, content_type=ctype, **kwargs) | 186 return self._send(request_path, payload=body, content_type=ctype, **kwargs) |
185 | 187 |
186 def _send(self, request_path, **kwargs): | 188 def _send(self, request_path, **kwargs): |
187 """Sends a POST/GET to Rietveld. Returns the response body.""" | 189 """Sends a POST/GET to Rietveld. Returns the response body.""" |
188 maxtries = 5 | 190 maxtries = 5 |
189 for retry in xrange(maxtries): | 191 for retry in xrange(maxtries): |
190 try: | 192 try: |
| 193 logging.debug('%s' % request_path) |
191 result = self.rpc_server.Send(request_path, **kwargs) | 194 result = self.rpc_server.Send(request_path, **kwargs) |
192 # Sometimes GAE returns a HTTP 200 but with HTTP 500 as the content. How | 195 # Sometimes GAE returns a HTTP 200 but with HTTP 500 as the content. How |
193 # nice. | 196 # nice. |
194 return result | 197 return result |
195 except urllib2.HTTPError, e: | 198 except urllib2.HTTPError, e: |
196 if retry >= (maxtries - 1): | 199 if retry >= (maxtries - 1): |
197 raise | 200 raise |
198 if e.code not in (500, 502, 503): | 201 if e.code not in (500, 502, 503): |
199 raise | 202 raise |
200 except urllib2.URLError, e: | 203 except urllib2.URLError, e: |
201 if retry >= (maxtries - 1): | 204 if retry >= (maxtries - 1): |
202 raise | 205 raise |
203 if not 'Name or service not known' in e.reason: | 206 if not 'Name or service not known' in e.reason: |
204 # Usually internal GAE flakiness. | 207 # Usually internal GAE flakiness. |
205 raise | 208 raise |
206 # If reaching this line, loop again. Uses a small backoff. | 209 # If reaching this line, loop again. Uses a small backoff. |
207 time.sleep(1+maxtries*2) | 210 time.sleep(1+maxtries*2) |
208 | 211 |
209 # DEPRECATED. | 212 # DEPRECATED. |
210 Send = get | 213 Send = get |
OLD | NEW |