add stiky
This commit is contained in:
+11
-115
@@ -22,7 +22,6 @@ from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
|
||||
|
||||
from config.settings import settings
|
||||
from managers.background_tasks import BackgroundTaskManager
|
||||
from managers.proxy_manager import ProxyManager
|
||||
from managers.task_manager import TaskManager, TaskParams
|
||||
from services.browser_service import BrowserService
|
||||
from services.browser_pool import BrowserPool
|
||||
@@ -45,7 +44,6 @@ class BotInterface:
|
||||
def __init__(
|
||||
self,
|
||||
background_tasks: BackgroundTaskManager,
|
||||
proxy_manager: ProxyManager,
|
||||
browser_service: BrowserService,
|
||||
browser_pool: BrowserPool = None,
|
||||
storage: TaskStorage = None,
|
||||
@@ -53,7 +51,6 @@ class BotInterface:
|
||||
bot_ref=None,
|
||||
):
|
||||
self.background_tasks = background_tasks
|
||||
self.proxy_manager = proxy_manager
|
||||
self.browser_service = browser_service
|
||||
self.browser_pool = browser_pool
|
||||
self.task_manager = TaskManager()
|
||||
@@ -259,29 +256,6 @@ class BotInterface:
|
||||
await interface._show_status(callback.message, edit=True)
|
||||
await callback.answer()
|
||||
|
||||
# === Перезапуск ===
|
||||
@dp.callback_query(F.data == "reload_proxies")
|
||||
async def cb_reload_proxies(callback: CallbackQuery):
|
||||
if not await require_admin(callback):
|
||||
return
|
||||
count = interface.proxy_manager.reload()
|
||||
await interface._show_status(callback.message, edit=True)
|
||||
await callback.answer(f"✅ Прокси перезагружены: {count} шт.")
|
||||
|
||||
@dp.callback_query(F.data == "check_proxies")
|
||||
async def cb_check_proxies(callback: CallbackQuery):
|
||||
if not await require_admin(callback):
|
||||
return
|
||||
total = interface.proxy_manager.count
|
||||
if total == 0:
|
||||
await callback.answer("❌ Нет загруженных прокси", show_alert=True)
|
||||
return
|
||||
await callback.message.edit_text(
|
||||
f"⏳ Проверка {total} прокси через туннель...\n\nЭто займёт несколько секунд."
|
||||
)
|
||||
await callback.answer()
|
||||
asyncio.create_task(interface._check_all_proxies(callback.message))
|
||||
|
||||
@dp.callback_query(F.data == "bot_restart_confirm")
|
||||
async def cb_restart_confirm(callback: CallbackQuery):
|
||||
if not await require_admin(callback):
|
||||
@@ -1742,7 +1716,6 @@ class BotInterface:
|
||||
|
||||
async def _show_status(self, message: Message, edit: bool = False):
|
||||
stats = await self.task_manager.get_stats()
|
||||
proxy_stats = self.proxy_manager.get_stats()
|
||||
bg_count = self.background_tasks.active_count
|
||||
|
||||
delta = datetime.now() - self._start_time
|
||||
@@ -1760,14 +1733,11 @@ class BotInterface:
|
||||
f"├ 🌐 Визиты: {stats['visit']}\n"
|
||||
f"├ ⏸️ Пауза: {stats['paused']}\n"
|
||||
f"└ 🔄 Активно: {stats['active']}\n\n"
|
||||
f"🔌 Прокси: {proxy_stats['total']} / {proxy_stats['available']} доступно\n"
|
||||
f"🔁 Фоновых задач: {bg_count}\n\n"
|
||||
f"{sys_info}"
|
||||
)
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(InlineKeyboardButton(text="🔄 Обновить", callback_data="menu_status"))
|
||||
builder.row(InlineKeyboardButton(text="🔃 Перезагрузить прокси", callback_data="reload_proxies"))
|
||||
builder.row(InlineKeyboardButton(text="🔍 Проверить прокси", callback_data="check_proxies"))
|
||||
builder.row(InlineKeyboardButton(text="🔁 Перезапустить бота", callback_data="bot_restart_confirm"))
|
||||
builder.row(InlineKeyboardButton(text="🔙 В меню", callback_data="menu_main"))
|
||||
await self._edit_or_send(message, text, builder.as_markup(), edit)
|
||||
@@ -1785,89 +1755,6 @@ class BotInterface:
|
||||
await asyncio.sleep(0.5)
|
||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
async def _check_all_proxies(self, message) -> None:
|
||||
"""Проверяет все загруженные прокси через туннель и редактирует сообщение с результатами."""
|
||||
from services.socks5_to_http_proxy import Socks5ToHttpProxy
|
||||
from managers.proxy_manager import ProxyType
|
||||
|
||||
proxies = list(self.proxy_manager._proxies)
|
||||
if not proxies:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(InlineKeyboardButton(text="🔙 К статусу", callback_data="menu_status"))
|
||||
try:
|
||||
await message.edit_text("❌ Нет загруженных прокси", reply_markup=builder.as_markup())
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
|
||||
sem = asyncio.Semaphore(5)
|
||||
results: dict[str, bool] = {}
|
||||
|
||||
async def _check_one(proxy):
|
||||
async with sem:
|
||||
try:
|
||||
if proxy.proxy_type == ProxyType.SOCKS5:
|
||||
tunnel = Socks5ToHttpProxy(
|
||||
socks5_host=proxy.ip,
|
||||
socks5_port=int(proxy.port),
|
||||
username=proxy.login,
|
||||
password=proxy.password,
|
||||
)
|
||||
await tunnel.start()
|
||||
try:
|
||||
ok = await tunnel.check_connection(timeout=8.0)
|
||||
finally:
|
||||
await tunnel.stop()
|
||||
else:
|
||||
from aiohttp import ClientSession, ClientTimeout
|
||||
proxy_url = proxy.server
|
||||
if proxy.login and proxy.password:
|
||||
from urllib.parse import urlparse
|
||||
parsed = urlparse(proxy_url)
|
||||
proxy_url = f"{parsed.scheme}://{proxy.login}:{proxy.password}@{parsed.netloc}"
|
||||
async with ClientSession(timeout=ClientTimeout(total=8)) as s:
|
||||
async with s.get(
|
||||
"https://www.google.com/generate_204",
|
||||
proxy=proxy_url,
|
||||
allow_redirects=False,
|
||||
) as resp:
|
||||
ok = resp.status in (200, 204)
|
||||
except Exception:
|
||||
ok = False
|
||||
results[proxy.id] = ok
|
||||
|
||||
await asyncio.gather(*[_check_one(p) for p in proxies], return_exceptions=True)
|
||||
|
||||
await self.proxy_manager.apply_check_results(results)
|
||||
|
||||
ok_ids = [pid for pid, ok in results.items() if ok]
|
||||
fail_ids = [pid for pid, ok in results.items() if not ok]
|
||||
|
||||
lines = [
|
||||
f"🔍 Проверка прокси завершена\n",
|
||||
f"✅ Рабочих: {len(ok_ids)} / {len(proxies)}",
|
||||
f"❌ Нерабочих: {len(fail_ids)}\n",
|
||||
]
|
||||
if ok_ids:
|
||||
lines.append("✅ Работают:")
|
||||
for pid in ok_ids[:15]:
|
||||
lines.append(f" • {pid}")
|
||||
if len(ok_ids) > 15:
|
||||
lines.append(f" ...ещё {len(ok_ids) - 15}")
|
||||
if fail_ids:
|
||||
lines.append("\n❌ Не работают:")
|
||||
for pid in fail_ids[:15]:
|
||||
lines.append(f" • {pid}")
|
||||
if len(fail_ids) > 15:
|
||||
lines.append(f" ...ещё {len(fail_ids) - 15}")
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(InlineKeyboardButton(text="🔙 К статусу", callback_data="menu_status"))
|
||||
try:
|
||||
await message.edit_text("\n".join(lines), reply_markup=builder.as_markup())
|
||||
except Exception as e:
|
||||
logger.error(f"Proxy check result edit failed: {e}")
|
||||
|
||||
# =========================================================================
|
||||
# УПРАВЛЕНИЕ ЗАДАЧЕЙ
|
||||
# =========================================================================
|
||||
@@ -2234,7 +2121,7 @@ class BotInterface:
|
||||
async def on_url(url, username):
|
||||
if params.stream_offline:
|
||||
return
|
||||
task = asyncio.create_task(self._process_url(url, username, params, message))
|
||||
task = asyncio.create_task(self._process_url(url, username, task_id, params, message))
|
||||
url_tasks.add(task)
|
||||
task.add_done_callback(url_tasks.discard)
|
||||
task.add_done_callback(
|
||||
@@ -2397,7 +2284,7 @@ class BotInterface:
|
||||
if self.storage:
|
||||
await self.storage.save_task(task_id, params)
|
||||
|
||||
async def _process_url(self, url: str, username: str, params: TaskParams, message: Message):
|
||||
async def _process_url(self, url: str, username: str, task_id: str, params: TaskParams, message: Message):
|
||||
"""Обрабатывает найденную ссылку (выполняется параллельно)."""
|
||||
try:
|
||||
params.links_found += 1
|
||||
@@ -2470,6 +2357,15 @@ class BotInterface:
|
||||
result = await visitor.visit_page(url, reading)
|
||||
params.total_visits += 1
|
||||
params.pending_visits = max(0, params.pending_visits - 1)
|
||||
if result.error == "PROXY_UNAVAILABLE":
|
||||
params.paused = True
|
||||
params.auto_paused = True
|
||||
await self.task_manager.update_task(task_id, paused=True)
|
||||
await send_message_safe(
|
||||
message.bot, params.chat_id,
|
||||
"⚠️ Прокси недоступен — задача поставлена на паузу"
|
||||
)
|
||||
return
|
||||
if result.success:
|
||||
params.successful_visits += 1
|
||||
remaining -= 1
|
||||
|
||||
Reference in New Issue
Block a user