|
15 | 15 | HttpResponse, |
16 | 16 | HttpResponseBadRequest, |
17 | 17 | HttpResponseForbidden, |
| 18 | + HttpResponseNotFound, |
18 | 19 | StreamingHttpResponse, |
19 | 20 | ) |
20 | 21 | from django.shortcuts import redirect |
@@ -255,52 +256,53 @@ def parse_package(release_package): |
255 | 256 |
|
256 | 257 | rfilter = get_remote_package_filter(remote) |
257 | 258 | if not rfilter.filter_project(package): |
258 | | - raise Http404(f"{package} does not exist.") |
| 259 | + return {} |
259 | 260 |
|
260 | 261 | url = remote.get_remote_artifact_url(f"simple/{package}/") |
261 | 262 | remote.headers = remote.headers or [] |
262 | 263 | remote.headers.append({"Accept": ACCEPT_JSON_PREFERRED}) |
263 | 264 | downloader = remote.get_downloader(url=url, max_retries=1) |
264 | 265 | try: |
265 | 266 | d = downloader.fetch() |
266 | | - except ClientError: |
267 | | - return HttpResponse(f"Failed to fetch {package} from {remote.url}.", status=502) |
268 | | - except TimeoutException: |
269 | | - return HttpResponse(f"{remote.url} timed out while fetching {package}.", status=504) |
| 267 | + except (ClientError, TimeoutException): |
| 268 | + log.info(f"Failed to fetch {package} simple page from {remote.url}") |
| 269 | + return {} |
270 | 270 |
|
271 | 271 | if d.headers["content-type"] == "application/vnd.pypi.simple.v1+json": |
272 | 272 | page = ProjectPage.from_json_data(json.load(open(d.path, "rb")), base_url=url) |
273 | 273 | else: |
274 | 274 | page = ProjectPage.from_html(package, open(d.path, "rb").read(), base_url=url) |
275 | | - packages = [ |
276 | | - parse_package(p) for p in page.packages if rfilter.filter_release(package, p.version) |
277 | | - ] |
278 | | - return HttpResponse(write_simple_detail(package, packages)) |
| 275 | + return { |
| 276 | + p.filename: parse_package(p) |
| 277 | + for p in page.packages |
| 278 | + if rfilter.filter_release(package, p.version) |
| 279 | + } |
279 | 280 |
|
280 | 281 | @extend_schema(operation_id="pypi_simple_package_read", summary="Get package simple page") |
281 | 282 | def retrieve(self, request, path, package): |
282 | 283 | """Retrieves the simple api html page for a package.""" |
283 | 284 | repo_ver, content = self.get_rvc() |
284 | 285 | # Should I redirect if the normalized name is different? |
285 | 286 | normalized = canonicalize_name(package) |
| 287 | + releases = {} |
286 | 288 | if self.distribution.remote: |
287 | | - return self.pull_through_package_simple(normalized, path, self.distribution.remote) |
288 | | - if self.should_redirect(repo_version=repo_ver): |
| 289 | + releases = self.pull_through_package_simple(normalized, path, self.distribution.remote) |
| 290 | + elif self.should_redirect(repo_version=repo_ver): |
289 | 291 | return redirect(urljoin(self.base_content_url, f"{path}/simple/{normalized}/")) |
290 | | - packages = ( |
291 | | - content.filter(name__normalize=normalized) |
292 | | - .values_list("filename", "sha256", "name") |
293 | | - .iterator() |
294 | | - ) |
295 | | - try: |
296 | | - present = next(packages) |
297 | | - except StopIteration: |
298 | | - raise Http404(f"{normalized} does not exist.") |
299 | | - else: |
300 | | - packages = chain([present], packages) |
301 | | - name = present[2] |
302 | | - releases = ((f, urljoin(self.base_content_url, f"{path}/{f}"), d) for f, d, _ in packages) |
303 | | - return StreamingHttpResponse(write_simple_detail(name, releases, streamed=True)) |
| 292 | + if content: |
| 293 | + packages = content.filter(name__normalize=normalized).values("filename", "sha256") |
| 294 | + local_releases = { |
| 295 | + p["filename"]: ( |
| 296 | + p["filename"], |
| 297 | + urljoin(self.base_content_url, f"{path}/{p['filename']}"), |
| 298 | + p["sha256"], |
| 299 | + ) |
| 300 | + for p in packages |
| 301 | + } |
| 302 | + releases.update(local_releases) |
| 303 | + if not releases: |
| 304 | + return HttpResponseNotFound(f"{normalized} does not exist.") |
| 305 | + return HttpResponse(write_simple_detail(normalized, releases.values())) |
304 | 306 |
|
305 | 307 | @extend_schema( |
306 | 308 | request=PackageUploadSerializer, |
|
0 commit comments