fix get logs
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user