fix get logs
This commit is contained in:
+83
-16
@@ -181,24 +181,35 @@ class ProxyManager:
|
||||
self._load_proxies()
|
||||
|
||||
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):
|
||||
logger.warning(f"Proxy file not found: {self.proxy_file}")
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
with open(self.proxy_file, 'r', encoding='utf-8') as f:
|
||||
lines = [
|
||||
line.strip()
|
||||
for line in f
|
||||
if line.strip() and not line.startswith('#')
|
||||
]
|
||||
|
||||
raw_lines = [l.rstrip('\n') for l in f]
|
||||
|
||||
loaded = []
|
||||
_has_scheme = {"socks5://", "socks4://", "http://", "https://"}
|
||||
for line in lines:
|
||||
explicit_type = any(line.lower().startswith(s) for s in _has_scheme)
|
||||
proxy = Proxy.from_line(line, default_type=ProxyType.SOCKS5)
|
||||
for line in raw_lines:
|
||||
stripped = line.strip()
|
||||
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:
|
||||
self._proxies.append(proxy)
|
||||
self._working_status[proxy.id] = True
|
||||
@@ -252,6 +263,52 @@ class ProxyManager:
|
||||
f"socks5:{detected['socks5']} socks4:{detected['socks4']} "
|
||||
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:
|
||||
"""Проверка доступности прокси."""
|
||||
@@ -324,24 +381,34 @@ class ProxyManager:
|
||||
"""Освобождает прокси."""
|
||||
if not proxy:
|
||||
return
|
||||
|
||||
|
||||
proxy_id = proxy.id
|
||||
|
||||
mark_failed = False
|
||||
|
||||
async with self._lock:
|
||||
if proxy_id in self._in_use:
|
||||
del self._in_use[proxy_id]
|
||||
|
||||
|
||||
if self._usage_count[proxy_id] >= self.max_usage:
|
||||
loop = asyncio.get_running_loop()
|
||||
self._cooldown_until[proxy_id] = (
|
||||
loop.time() + self.cooldown_time
|
||||
)
|
||||
self._usage_count[proxy_id] = 0
|
||||
|
||||
|
||||
if not success:
|
||||
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}")
|
||||
|
||||
if mark_failed:
|
||||
loop = asyncio.get_running_loop()
|
||||
await loop.run_in_executor(None, self._save_proxies_file)
|
||||
|
||||
def get_stats(self) -> dict:
|
||||
"""Статистика прокси."""
|
||||
|
||||
Reference in New Issue
Block a user