mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-14 23:16:48 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b031e7e05 | ||
|
|
70831c27b3 |
@@ -982,12 +982,35 @@ class Settings(BaseSettings, ConfigModel, LogConfigModel):
|
||||
)
|
||||
|
||||
@property
|
||||
def PROXY(self):
|
||||
def PROXY(self) -> Optional[Dict[str, str]]:
|
||||
"""
|
||||
获取 requests 兼容的系统代理配置。
|
||||
"""
|
||||
if self.PROXY_HOST and self.PROXY_HOST.strip():
|
||||
proxy_host = self.PROXY_HOST.strip()
|
||||
return {
|
||||
"http": self.PROXY_HOST,
|
||||
"https": self.PROXY_HOST,
|
||||
"http": proxy_host,
|
||||
"https": proxy_host,
|
||||
}
|
||||
https_proxy = self._get_env_proxy("HTTPS_PROXY", "https_proxy")
|
||||
http_proxy = self._get_env_proxy("HTTP_PROXY", "http_proxy")
|
||||
proxy_host = https_proxy or http_proxy
|
||||
if proxy_host:
|
||||
return {
|
||||
"http": http_proxy or proxy_host,
|
||||
"https": https_proxy or proxy_host,
|
||||
}
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _get_env_proxy(*names: str) -> Optional[str]:
|
||||
"""
|
||||
按顺序读取非空代理环境变量。
|
||||
"""
|
||||
for name in names:
|
||||
proxy_host = os.environ.get(name)
|
||||
if proxy_host and proxy_host.strip():
|
||||
return proxy_host.strip()
|
||||
return None
|
||||
|
||||
@property
|
||||
|
||||
@@ -278,9 +278,15 @@ class Transmission:
|
||||
except Exception as err:
|
||||
logger.error(f"获取种子文件列表出错:{str(err)}")
|
||||
return None
|
||||
if torrent:
|
||||
if not torrent:
|
||||
return None
|
||||
try:
|
||||
get_files = getattr(torrent, "get_files", None)
|
||||
if callable(get_files):
|
||||
return get_files()
|
||||
return torrent.files()
|
||||
else:
|
||||
except Exception as err:
|
||||
logger.error(f"获取种子文件列表出错:{str(err)}")
|
||||
return None
|
||||
|
||||
def set_files(self, tid: str, file_ids: list) -> bool:
|
||||
|
||||
75
tests/test_proxy_config.py
Normal file
75
tests/test_proxy_config.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from app.core.config import Settings
|
||||
|
||||
|
||||
PROXY_ENV_NAMES = (
|
||||
"PROXY_HOST",
|
||||
"HTTP_PROXY",
|
||||
"HTTPS_PROXY",
|
||||
"http_proxy",
|
||||
"https_proxy",
|
||||
)
|
||||
|
||||
|
||||
def clear_proxy_env(monkeypatch) -> None:
|
||||
"""
|
||||
清理测试进程中的代理环境变量。
|
||||
"""
|
||||
for name in PROXY_ENV_NAMES:
|
||||
monkeypatch.delenv(name, raising=False)
|
||||
|
||||
|
||||
def test_proxy_prefers_proxy_host_over_standard_env(monkeypatch) -> None:
|
||||
"""
|
||||
PROXY_HOST 应优先于标准代理环境变量。
|
||||
"""
|
||||
clear_proxy_env(monkeypatch)
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://env-proxy.example.com:7890")
|
||||
|
||||
settings = Settings(PROXY_HOST=" http://custom-proxy.example.com:7890 ")
|
||||
|
||||
assert settings.PROXY == {
|
||||
"http": "http://custom-proxy.example.com:7890",
|
||||
"https": "http://custom-proxy.example.com:7890",
|
||||
}
|
||||
|
||||
|
||||
def test_proxy_falls_back_to_standard_proxy_env(monkeypatch) -> None:
|
||||
"""
|
||||
未配置 PROXY_HOST 时应读取 HTTP_PROXY 和 HTTPS_PROXY。
|
||||
"""
|
||||
clear_proxy_env(monkeypatch)
|
||||
monkeypatch.setenv("HTTP_PROXY", "http://http-proxy.example.com:7890")
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://https-proxy.example.com:7890")
|
||||
|
||||
settings = Settings(PROXY_HOST=None)
|
||||
|
||||
assert settings.PROXY == {
|
||||
"http": "http://http-proxy.example.com:7890",
|
||||
"https": "http://https-proxy.example.com:7890",
|
||||
}
|
||||
|
||||
|
||||
def test_proxy_reuses_single_standard_env_for_both_schemes(monkeypatch) -> None:
|
||||
"""
|
||||
只配置单个标准代理环境变量时应同时用于 http 和 https。
|
||||
"""
|
||||
clear_proxy_env(monkeypatch)
|
||||
monkeypatch.setenv("HTTP_PROXY", "http://http-proxy.example.com:7890")
|
||||
|
||||
settings = Settings(PROXY_HOST=None)
|
||||
|
||||
assert settings.PROXY == {
|
||||
"http": "http://http-proxy.example.com:7890",
|
||||
"https": "http://http-proxy.example.com:7890",
|
||||
}
|
||||
|
||||
|
||||
def test_proxy_returns_none_without_any_proxy(monkeypatch) -> None:
|
||||
"""
|
||||
未配置任何代理时应返回 None。
|
||||
"""
|
||||
clear_proxy_env(monkeypatch)
|
||||
|
||||
settings = Settings(PROXY_HOST=None)
|
||||
|
||||
assert settings.PROXY is None
|
||||
@@ -132,3 +132,35 @@ def test_login_skips_incomplete_file_suffix_when_already_matches():
|
||||
|
||||
assert downloader.trc is fake_client
|
||||
fake_client.set_session.assert_not_called()
|
||||
|
||||
|
||||
def test_get_files_uses_transmission_rpc_v7_get_files():
|
||||
"""
|
||||
transmission-rpc v7 任务对象应使用 get_files 获取文件列表。
|
||||
"""
|
||||
downloader = Transmission.__new__(Transmission)
|
||||
torrent_files = [object()]
|
||||
torrent = types.SimpleNamespace(get_files=MagicMock(return_value=torrent_files))
|
||||
fake_client = MagicMock()
|
||||
fake_client.get_torrent.return_value = torrent
|
||||
downloader.trc = fake_client
|
||||
|
||||
assert downloader.get_files("1") == torrent_files
|
||||
fake_client.get_torrent.assert_called_once_with("1")
|
||||
torrent.get_files.assert_called_once_with()
|
||||
|
||||
|
||||
def test_get_files_falls_back_to_legacy_files_method():
|
||||
"""
|
||||
旧版 transmission-rpc 任务对象仍应通过 files 获取文件列表。
|
||||
"""
|
||||
downloader = Transmission.__new__(Transmission)
|
||||
torrent_files = [object()]
|
||||
torrent = types.SimpleNamespace(files=MagicMock(return_value=torrent_files))
|
||||
fake_client = MagicMock()
|
||||
fake_client.get_torrent.return_value = torrent
|
||||
downloader.trc = fake_client
|
||||
|
||||
assert downloader.get_files("1") == torrent_files
|
||||
fake_client.get_torrent.assert_called_once_with("1")
|
||||
torrent.files.assert_called_once_with()
|
||||
|
||||
Reference in New Issue
Block a user