mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-11-10 12:28:27 +00:00
fix(network): apply HTTP proxy to Anna's Archive download-count lookups (#1686)
Fixes #1685 `_fetch_download_count_inline` fetches `/dyn/md5/inline_info/<md5>` for every search result (5 workers) through a module-level `requests.Session`, with no `proxies=`. `get_proxies()` reads the app config rather than the environment, so with the proxy set in Settings → Network the search page and the bypasser used it while these requests left from the host's own IP, about 50 per search. It now passes `network.get_proxies(url)` on each request, as the Libgen fast path in the same file already does. The session stays module-level for keep-alive, and proxies are resolved per request, so a settings change applies without a restart. Verification (macOS, `uv run --frozen pytest`): - New `tests/direct_download/test_download_count_proxy.py` passes. With the source change reverted it fails (`proxies` is `None`). - `tests/direct_download`: 135 passed, including `test_download_count_reuse.py`. - `ruff check` and `ruff format --check` on the changed files pass. - Not re-run live with this branch built. The behaviour before the change was observed on a running v1.6.2 container: 5 sockets from the `ThreadPoolExecutor` threads straight to the AA mirror's IP on :443, and 1 to the proxy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Bug Fixes** * Anna’s Archive download counts are now retrieved using the configured network proxies. This improves access to download-count information in environments where requests need a proxy, while preserving the existing response handling and timeout behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bb13fae0bb
commit
0d97110f01
2 files changed
+49
-1
No files matched your search
@@ -840,7 +840,12 @@ def _fetch_download_count_inline(book_id: str) -> int | None:
|
|||||||
return cached
|
return cached
|
||||||
try:
|
try:
|
||||||
url = f"{network.get_aa_base_url()}/dyn/md5/inline_info/{book_id}"
|
url = f"{network.get_aa_base_url()}/dyn/md5/inline_info/{book_id}"
|
||||||
resp = _inline_info_session.get(url, timeout=5, headers={"Accept": "application/json"})
|
resp = _inline_info_session.get(
|
||||||
|
url,
|
||||||
|
timeout=5,
|
||||||
|
headers={"Accept": "application/json"},
|
||||||
|
proxies=network.get_proxies(url),
|
||||||
|
)
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
count = data.get("downloads_total")
|
count = data.get("downloads_total")
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
"""AA download-count lookups must honor the Network proxy settings.
|
||||||
|
|
||||||
|
`_fetch_download_count_inline` runs for every search result, on its own session, so a
|
||||||
|
lookup that skips `get_proxies` sends the whole list straight from the host's IP while
|
||||||
|
the search page itself goes through the configured proxy.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from shelfmark.release_sources.direct_download import annas_archive as aa
|
||||||
|
|
||||||
|
_PROXIES = {"http": "http://10.0.80.3:8118", "https": "http://10.0.80.3:8118"}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _fresh_cache(monkeypatch):
|
||||||
|
aa._download_count_cache.clear()
|
||||||
|
monkeypatch.setattr(aa.network, "get_aa_base_url", lambda: "https://annas-archive.gl")
|
||||||
|
yield
|
||||||
|
aa._download_count_cache.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def test_download_count_lookup_passes_configured_proxies(monkeypatch):
|
||||||
|
asked_for: list[str] = []
|
||||||
|
captured: dict[str, object] = {}
|
||||||
|
|
||||||
|
def fake_get_proxies(url=""):
|
||||||
|
asked_for.append(url)
|
||||||
|
return _PROXIES
|
||||||
|
|
||||||
|
def fake_request(_self, _method, _url, *_args, **kwargs):
|
||||||
|
captured.update(kwargs)
|
||||||
|
return MagicMock(status_code=200, json=MagicMock(return_value={"downloads_total": 7}))
|
||||||
|
|
||||||
|
monkeypatch.setattr(aa.network, "get_proxies", fake_get_proxies)
|
||||||
|
monkeypatch.setattr(requests.Session, "request", fake_request)
|
||||||
|
|
||||||
|
assert aa._fetch_download_count_inline("aaa") == 7
|
||||||
|
assert captured.get("proxies") == _PROXIES
|
||||||
|
assert asked_for == ["https://annas-archive.gl/dyn/md5/inline_info/aaa"]
|
||||||
Reference in new issue
Block a user