fix get logs

This commit is contained in:
Yuriy Yuriev
2026-05-22 00:31:11 +07:00
parent e51437f08e
commit 4feb15cc40
3 changed files with 101 additions and 18 deletions
+9 -2
View File
@@ -2163,10 +2163,17 @@ class BotInterface:
logger.info(f"▶️ Resuming: {series_size} clicks left ({elapsed:.0f}s paused)") logger.info(f"▶️ Resuming: {series_size} clicks left ({elapsed:.0f}s paused)")
else: else:
# Новая серия: задержка → рандомный размер # Новая серия: задержка → рандомный размер
await _sleep_interruptible(params.get_delay()) delay = params.get_delay()
series_size = params.get_series_size()
logger.info(
f"⏳ Next series: {series_size} clicks, "
f"delay {delay}s ({delay//60}m {delay%60}s), "
f"reading {params.min_reading}-{params.max_reading}s, "
f"done {params.successful_visits}/{max_v}"
)
await _sleep_interruptible(delay)
if params.stopped: if params.stopped:
break break
series_size = params.get_series_size()
# --- Серия кликов --- # --- Серия кликов ---
for click_num in range(series_size): for click_num in range(series_size):
+76 -9
View File
@@ -181,24 +181,35 @@ class ProxyManager:
self._load_proxies() self._load_proxies()
def _load_proxies(self) -> None: def _load_proxies(self) -> None:
"""Загружает прокси из файла.""" """Загружает прокси из файла.
Форматы строк:
socks5://ip:port:login:pass — рабочий, тип известен
!socks5://ip:port:login:pass — нерабочий, пропускается
ip:port:login:pass — тип неизвестен, будет задетектирован
"""
if not os.path.exists(self.proxy_file): if not os.path.exists(self.proxy_file):
logger.warning(f"Proxy file not found: {self.proxy_file}") logger.warning(f"Proxy file not found: {self.proxy_file}")
return return
try: try:
with open(self.proxy_file, 'r', encoding='utf-8') as f: with open(self.proxy_file, 'r', encoding='utf-8') as f:
lines = [ raw_lines = [l.rstrip('\n') for l in f]
line.strip()
for line in f
if line.strip() and not line.startswith('#')
]
loaded = [] loaded = []
_has_scheme = {"socks5://", "socks4://", "http://", "https://"} _has_scheme = {"socks5://", "socks4://", "http://", "https://"}
for line in lines: for line in raw_lines:
explicit_type = any(line.lower().startswith(s) for s in _has_scheme) stripped = line.strip()
proxy = Proxy.from_line(line, default_type=ProxyType.SOCKS5) if not stripped or stripped.startswith('#'):
continue
# Нерабочий прокси — пропускаем, не загружаем
if stripped.startswith('!'):
logger.debug(f"Skipping disabled proxy: {stripped[1:30]}...")
continue
explicit_type = any(stripped.lower().startswith(s) for s in _has_scheme)
proxy = Proxy.from_line(stripped, default_type=ProxyType.SOCKS5)
if proxy: if proxy:
self._proxies.append(proxy) self._proxies.append(proxy)
self._working_status[proxy.id] = True self._working_status[proxy.id] = True
@@ -252,6 +263,52 @@ class ProxyManager:
f"socks5:{detected['socks5']} socks4:{detected['socks4']} " f"socks5:{detected['socks5']} socks4:{detected['socks4']} "
f"http:{detected['http']} failed:{detected['failed']}" f"http:{detected['http']} failed:{detected['failed']}"
) )
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, self._save_proxies_file)
def _save_proxies_file(self) -> None:
"""Перезаписывает proxies.txt с актуальными типами и пометками."""
if not os.path.exists(self.proxy_file):
return
try:
with open(self.proxy_file, 'r', encoding='utf-8') as f:
raw_lines = [l.rstrip('\n') for l in f]
new_lines = []
for line in raw_lines:
stripped = line.strip()
# Пустые строки и комментарии — без изменений
if not stripped or stripped.startswith('#'):
new_lines.append(line)
continue
# Нерабочие — оставляем как есть (уже с !)
if stripped.startswith('!'):
new_lines.append(line)
continue
proxy = Proxy.from_line(stripped, default_type=ProxyType.SOCKS5)
if not proxy:
new_lines.append(line)
continue
working = self._working_status.get(proxy.id, True)
scheme = proxy.proxy_type.value # socks5, http, etc.
creds = f"{proxy.login}:{proxy.password}@" if proxy.login else ""
new_line = f"{scheme}://{creds}{proxy.ip}:{proxy.port}"
if not working:
new_line = f"!{new_line}"
new_lines.append(new_line)
with open(self.proxy_file, 'w', encoding='utf-8') as f:
f.write('\n'.join(new_lines) + '\n')
logger.info(f"proxies.txt updated with detected types and status")
except Exception as e:
logger.error(f"Failed to save proxies file: {e}")
def _is_available(self, proxy: Proxy) -> bool: def _is_available(self, proxy: Proxy) -> bool:
"""Проверка доступности прокси.""" """Проверка доступности прокси."""
@@ -326,6 +383,7 @@ class ProxyManager:
return return
proxy_id = proxy.id proxy_id = proxy.id
mark_failed = False
async with self._lock: async with self._lock:
if proxy_id in self._in_use: if proxy_id in self._in_use:
@@ -340,9 +398,18 @@ class ProxyManager:
if not success: if not success:
self._working_status[proxy_id] = False self._working_status[proxy_id] = False
# Удаляем из пула полностью
self._proxies = [p for p in self._proxies if p.id != proxy_id]
self._needs_detection.discard(proxy_id)
mark_failed = True
logger.warning(f"Proxy {proxy_id} marked as failed and removed from pool")
logger.debug(f"Proxy released: {proxy_id}") logger.debug(f"Proxy released: {proxy_id}")
if mark_failed:
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, self._save_proxies_file)
def get_stats(self) -> dict: def get_stats(self) -> dict:
"""Статистика прокси.""" """Статистика прокси."""
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
+9
View File
@@ -167,6 +167,15 @@ class BrowserService:
humanize=True, humanize=True,
exclude_addons=[DefaultAddons.UBO], exclude_addons=[DefaultAddons.UBO],
proxy=proxy_config, proxy=proxy_config,
firefox_prefs={
# Запрещаем WebRTC использовать локальные IP-кандидаты
"media.peerconnection.ice.no_host": True,
# Только ICE через прокси — блокирует утечку реального IP
"media.peerconnection.ice.proxy_only_if_behind_proxy": True,
# DNS только через прокси (предотвращает DNS-утечку)
"network.dns.disablePrefetch": True,
"network.prefetch-next": False,
},
) )
if proxy_locale: if proxy_locale:
camoufox_kwargs["locale"] = proxy_locale camoufox_kwargs["locale"] = proxy_locale