feat(config): add proxy support and API timeout
Build and Push (dev) / build (push) Successful in 3m31s
Build and Push (dev) / build (push) Successful in 3m31s
This commit is contained in:
@@ -115,6 +115,7 @@ class Config:
|
||||
api_delay = max(
|
||||
float(os.getenv(key="API_DELAY", default=5)), 2
|
||||
) # 30r/60s для non-GET запросов, 60/30 = минимум
|
||||
api_timeout = float(os.getenv(key="API_TIMEOUT", default=15))
|
||||
max_retries = int(os.getenv(key="MAX_RETRIES", default=3))
|
||||
|
||||
enable_reply = (
|
||||
@@ -145,6 +146,133 @@ class Config:
|
||||
"ENABLE_CAPTCHA установлен, но CAPTCHA_ANSWER не задан"
|
||||
)
|
||||
|
||||
proxy_telegram = (
|
||||
os.getenv(key="PROXY_TELEGRAM", default="false")
|
||||
).lower() == "true"
|
||||
proxy_lolz = (
|
||||
os.getenv(key="PROXY_LOLZ", default="false")
|
||||
).lower() == "true"
|
||||
|
||||
proxy_protocol = None
|
||||
proxy_host = None
|
||||
proxy_port = None
|
||||
proxy_port_str = None
|
||||
proxy_username = None
|
||||
proxy_password = None
|
||||
|
||||
if proxy_telegram or proxy_lolz:
|
||||
proxy = os.getenv(key="PROXY", default=None)
|
||||
|
||||
proxy_protocol = os.getenv(key="PROXY_PROTOCOL", default="socks5")
|
||||
proxy_host = os.getenv(key="PROXY_HOST", default=None)
|
||||
proxy_port_str = os.getenv(key="PROXY_PORT", default=None)
|
||||
proxy_username = os.getenv(key="PROXY_USERNAME", default=None)
|
||||
proxy_password = os.getenv(key="PROXY_PASSWORD", default=None)
|
||||
|
||||
if proxy:
|
||||
logger.info("Парсинг прокси из переменной PROXY...")
|
||||
try:
|
||||
parts = proxy.split("://")
|
||||
if len(parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат PROXY. Ожидается: protocol://[username:password@]host:port"
|
||||
)
|
||||
|
||||
proxy_protocol = parts[0]
|
||||
main = parts[1]
|
||||
|
||||
# Проверяем наличие авторизации (username:password@host:port)
|
||||
if "@" in main:
|
||||
main_split = main.split("@")
|
||||
if len(main_split) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат авторизации в PROXY"
|
||||
)
|
||||
|
||||
authorization = main_split[0]
|
||||
server = main_split[1]
|
||||
|
||||
# Парсим username:password (используем split с limit для поддержки : в пароле)
|
||||
auth_parts = authorization.split(":", 1)
|
||||
if len(auth_parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат авторизации в PROXY. Ожидается: username:password"
|
||||
)
|
||||
proxy_username = auth_parts[0]
|
||||
proxy_password = auth_parts[1]
|
||||
else:
|
||||
server = main
|
||||
|
||||
# Парсим host:port (используем rsplit для поддержки IPv6)
|
||||
server_parts = server.rsplit(":", 1)
|
||||
if len(server_parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат сервера в PROXY. Ожидается: host:port"
|
||||
)
|
||||
proxy_host = server_parts[0]
|
||||
try:
|
||||
proxy_port = int(server_parts[1])
|
||||
except ValueError as e:
|
||||
raise ConfigError(
|
||||
f"PROXY_PORT должен быть целым числом: {server_parts[1]}"
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
"Прокси успешно распарсен: protocol=%s, host=%s, port=%s, auth=%s",
|
||||
proxy_protocol,
|
||||
proxy_host,
|
||||
proxy_port,
|
||||
"да" if proxy_username else "нет"
|
||||
)
|
||||
|
||||
except ConfigError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise ConfigError(f"Произошла ошибка при парсе PROXY: {e}") from e
|
||||
|
||||
else:
|
||||
logger.info("Загрузка прокси из отдельных переменных...")
|
||||
# Используем отдельные поля
|
||||
if not proxy_host or not proxy_port_str:
|
||||
raise ConfigError(
|
||||
"PROXY не указан, но PROXY_HOST или PROXY_PORT также отсутствуют"
|
||||
)
|
||||
|
||||
try:
|
||||
proxy_port = int(proxy_port_str)
|
||||
except (ValueError, TypeError) as e:
|
||||
raise ConfigError(
|
||||
f"PROXY_PORT должен быть целым числом: {proxy_port_str}"
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
"Прокси загружен: protocol=%s, host=%s, port=%s, auth=%s",
|
||||
proxy_protocol,
|
||||
proxy_host,
|
||||
proxy_port,
|
||||
"да" if proxy_username else "нет"
|
||||
)
|
||||
|
||||
# Валидация
|
||||
if proxy_protocol not in ["socks5", "https"]:
|
||||
raise ConfigError(
|
||||
f"Формат прокси '{proxy_protocol}' не поддерживается. Укажите socks5 или https"
|
||||
)
|
||||
|
||||
if (proxy_username and not proxy_password) or (proxy_password and not proxy_username):
|
||||
raise ConfigError(
|
||||
"PROXY_USERNAME и PROXY_PASSWORD должны быть указаны оба или не указаны вовсе"
|
||||
)
|
||||
|
||||
# Финальная проверка
|
||||
if not (proxy_protocol and proxy_host and proxy_port):
|
||||
raise ConfigError("Прокси не полностью настроены")
|
||||
|
||||
if proxy_telegram:
|
||||
logger.info("Прокси для Telegram включен")
|
||||
if proxy_lolz:
|
||||
logger.info("Прокси для Lolz API включен")
|
||||
|
||||
return {
|
||||
# Pyrogram
|
||||
"api_id": api_id,
|
||||
@@ -165,6 +293,7 @@ class Config:
|
||||
"skip_commented": skip_commented,
|
||||
# Misc
|
||||
"api_delay": api_delay,
|
||||
"api_timeout": api_timeout,
|
||||
"max_retries": max_retries,
|
||||
"default_choice": default_choice,
|
||||
# Bump
|
||||
@@ -174,13 +303,23 @@ class Config:
|
||||
"enable_captcha": enable_captcha,
|
||||
"captcha_answer": captcha_answer,
|
||||
"captcha_check_interval": captcha_check_interval,
|
||||
# Proxy
|
||||
"proxy_telegram": proxy_telegram,
|
||||
"proxy_lolz": proxy_lolz,
|
||||
"proxy_protocol": proxy_protocol,
|
||||
"proxy_host": proxy_host,
|
||||
"proxy_port": proxy_port,
|
||||
"proxy_username": proxy_username,
|
||||
"proxy_password": proxy_password,
|
||||
}
|
||||
|
||||
except ConfigError:
|
||||
raise
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
logger.error(f"Invalid configuration value: {e}")
|
||||
raise ConfigError(f"Invalid configuration value: {e}") from e
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error loading configuration: {e}")
|
||||
raise ConfigError(f"Failed to load configuration: {e}") from e
|
||||
|
||||
Reference in New Issue
Block a user