-
-
Notifications
You must be signed in to change notification settings - Fork 3
Query objects.inv from homepage url #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5ad1f2f
767f4d7
857bacf
29674f8
623f82f
c62fe91
4e5ad61
6e1429f
6763c54
7dc9e8e
739a018
49b93a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,13 +33,14 @@ | |
# stdlib | ||
import functools | ||
import json | ||
import os.path | ||
import re | ||
from typing import Dict, Optional, Tuple, Union | ||
from typing import Dict, List, Optional, Tuple, Union | ||
from urllib.parse import urlparse | ||
|
||
# 3rd party | ||
import dist_meta | ||
import requests | ||
from dist_meta.metadata_mapping import MetadataMapping | ||
from domdf_python_tools.compat import importlib_resources | ||
from domdf_python_tools.utils import stderr_writer | ||
from packaging.requirements import Requirement | ||
|
@@ -60,7 +61,7 @@ | |
_DOCUMENTATION_RE = re.compile(r"^[dD]oc(s|umentation)") | ||
|
||
|
||
def _get_project_links(project_name: str) -> MetadataMapping: | ||
def _get_project_links(project_name: str) -> List[str]: | ||
""" | ||
Returns the web links for the given project. | ||
|
||
|
@@ -69,29 +70,36 @@ def _get_project_links(project_name: str) -> MetadataMapping: | |
:param project_name: | ||
""" | ||
|
||
urls = MetadataMapping() | ||
urls = [] | ||
|
||
# Try a local package first | ||
try: | ||
dist = dist_meta.distributions.get_distribution(project_name) | ||
raw_urls = dist.get_metadata().get_all("Project-URL", default=()) | ||
metadata = dist.get_metadata() | ||
raw_urls = metadata.get_all("Project-URL", default=()) | ||
|
||
for url in raw_urls: | ||
label, url, *_ = map(str.strip, url.split(',')) | ||
label, url = url.split(',', 1) | ||
if _DOCUMENTATION_RE.match(label): | ||
urls[label] = url | ||
urls.append(url) | ||
|
||
urls.append(metadata.get("Home-Page", '')) | ||
|
||
except dist_meta.distributions.DistributionNotFoundError: | ||
# Fall back to PyPI | ||
|
||
with PyPIJSON() as client: | ||
metadata = client.get_metadata(project_name).info | ||
pypi_metadata = client.get_metadata(project_name).info | ||
|
||
if "project_urls" in pypi_metadata and pypi_metadata["project_urls"]: | ||
|
||
for label, url in pypi_metadata["project_urls"].items(): | ||
if _DOCUMENTATION_RE.match(label): | ||
urls.append(url) | ||
|
||
if "project_urls" in metadata and metadata["project_urls"]: | ||
for label, url in metadata["project_urls"].items(): | ||
if _DOCUMENTATION_RE.match(label): | ||
urls[label] = url | ||
urls.append(pypi_metadata["home_page"]) | ||
|
||
urls = [url.strip() for url in filter(None, urls)] | ||
return urls | ||
|
||
|
||
|
@@ -127,25 +135,24 @@ def get_sphinx_doc_url(pypi_name: str) -> str: | |
:exc:`apeye.slumber_url.exceptions.HttpNotFoundError` if the project could not be found on PyPI. | ||
""" | ||
|
||
for key, value in _get_project_links(pypi_name).items(): | ||
|
||
docs_urls = [] | ||
for value in _get_project_links(pypi_name): | ||
# Follow redirects to get actual URL | ||
r = requests.head(value, allow_redirects=True, timeout=10) | ||
if r.status_code != 200: # pragma: no cover | ||
raise ValueError(f"Documentation URL not found: HTTP Status {r.status_code}.") | ||
|
||
docs_url = r.url | ||
if r.status_code == 200: | ||
has_extension = os.path.splitext(urlparse(r.url).path)[-1] | ||
url = os.path.dirname(r.url) if has_extension else r.url | ||
docs_urls.append(url) | ||
|
||
if docs_url.endswith('/'): | ||
objects_inv_url = f"{docs_url}objects.inv" | ||
else: # pragma: no cover | ||
objects_inv_url = f"{docs_url}/objects.inv" | ||
for docs_url in docs_urls: | ||
objects_inv_url = f"{docs_url.rstrip('/')}/objects.inv" | ||
|
||
r = requests.head(objects_inv_url, allow_redirects=True, timeout=10) | ||
if r.status_code != 200: | ||
raise ValueError(f"objects.inv not found at url {objects_inv_url}: HTTP Status {r.status_code}.") | ||
|
||
return docs_url | ||
stderr_writer(f"WARNING: objects.inv not found at url {objects_inv_url}: HTTP Status {r.status_code}.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm reluctant to accept this change as If you're wanting to make the warning on line 197 more specific -- to say why the documentation URL couldn't be obtained -- how about including the exception message text? E.g.:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your point, removing the |
||
else: | ||
return docs_url | ||
|
||
raise ValueError("Documentation URL not found in data from PyPI.") | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.