This repository has been archived by the owner on Aug 27, 2023. It is now read-only.
/
locator.py
88 lines (73 loc) · 2.97 KB
/
locator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
""" Simple replacement for distlib SimpleScrapingLocator """
import logging
import distlib.locators
import requests
from distlib.locators import SimpleScrapingLocator
from .util import TimedCache
LOG = logging.getLogger(__name__)
class SimpleJsonLocator(object):
"""Simple replacement for distlib SimpleScrapingLocator"""
def __init__(self, base_index):
self.base_index = base_index
# 16m cache
self._cache = TimedCache(1000, self._get_releases)
def get_releases(self, project_name):
return self._cache[project_name]
def _get_releases(self, project_name):
url = "%s/pypi/%s/json" % (self.base_index, project_name)
try:
response = requests.get(url)
response.raise_for_status()
except requests.RequestException as e:
LOG.warning("Error fetching '%s' from upstream: %s", project_name, e)
return []
data = response.json()
items = []
summary = data["info"].get("summary")
for version, releases in data["releases"].items():
for release in releases:
try:
item = {
"name": project_name,
"version": version,
"summary": summary,
"url": release["url"],
"digests": release.get("digests", {}),
"requires_python": release["requires_python"],
}
except KeyError:
continue
items.append(item)
return items
class FormattedScrapingLocator(SimpleScrapingLocator):
def get_releases(self, project_name):
projects = self.get_project(project_name)
items = []
for version, urls in projects["urls"].items():
for url in urls:
dist = projects[version]
digest = projects["digests"].get(url)
digest_dict = {}
if digest is not None:
digest_dict[digest[0]] = digest[1]
items.append(
{
"name": dist.name,
"version": dist.version,
"summary": dist.metadata.dictionary.get("summary"),
"url": url,
"digests": digest_dict,
"requires_python": dist.metadata.dictionary.get(
"requires_python"
),
}
)
return items
# Distlib checks if wheels are compatible before returning them.
# This is useful if you are attempting to install on the system running
# distlib, but we actually want ALL wheels so we can display them to the
# clients. So we have to monkey patch the method. I'm sorry.
def is_compatible(wheel, tags=None):
"""Hacked function to monkey patch into distlib"""
return True
distlib.locators.is_compatible = is_compatible