fix comand

This commit is contained in:
Yuriy Yuriev
2026-05-18 19:30:15 +07:00
parent 69bd0c1d63
commit 88bd8bfefa
+226 -81
View File
@@ -819,11 +819,14 @@ class BotInterface:
f"Текущее: {cur}\n"
f"Диапазон `2-5` или фиксированно `3`."
)
_d_mn = params.min_delay // 60
_d_mx = params.max_delay // 60
_d_cur = f"{_d_mn}{_d_mx}" if _d_mn != _d_mx else str(_d_mn)
delay_label = (
f"⏱️ *Пауза между циклами*\n"
f"Сколько секунд ждать после каждого цикла кликов.\n"
f"Текущая: {params.min_delay}{params.max_delay} сек\n"
f"Диапазон `30-60` или фиксированно `45`."
f"Сколько минут ждать после каждого цикла кликов.\n"
f"Текущая: {_d_cur} мин\n"
f"Диапазон `2-5` или фиксированно `3`."
)
else:
perlink_label = (
@@ -873,12 +876,12 @@ class BotInterface:
interface._user_input_state[uid] = {
"task_id": task_id,
"param": param,
"menu_msg_id": callback.message.message_id,
}
builder = InlineKeyboardBuilder()
builder.row(InlineKeyboardButton(text="❌ Отмена", callback_data=f"utask_{task_id}"))
sent = await callback.message.answer(prompt, reply_markup=builder.as_markup())
interface._user_input_state[uid]["prompt_msg_id"] = sent.message_id
await callback.answer(f"Введите значение")
await callback.message.edit_text(prompt, reply_markup=builder.as_markup())
await callback.answer()
@dp.callback_query(F.data == "confirm_buy")
async def cb_confirm_buy(callback: CallbackQuery):
@@ -1036,6 +1039,10 @@ class BotInterface:
await interface._show_user_menu(callback.message, user_id=uid)
await callback.answer("👤 Переключились в режим пользователя")
@dp.callback_query(F.data == "noop")
async def _cb_noop(callback: CallbackQuery):
await callback.answer()
@dp.callback_query(F.data == "cancel_new_task")
async def cb_cancel_new_task(callback: CallbackQuery):
uid = callback.from_user.id
@@ -1048,6 +1055,16 @@ class BotInterface:
await interface._show_user_tasks(callback.message, callback.from_user.id, edit=True)
await callback.answer()
@dp.callback_query(F.data == "my_tasks_visits")
async def cb_my_tasks_visits(callback: CallbackQuery):
await interface._show_user_visits(callback.message, callback.from_user.id, edit=True)
await callback.answer()
@dp.callback_query(F.data == "my_tasks_monitors")
async def cb_my_tasks_monitors(callback: CallbackQuery):
await interface._show_user_monitors(callback.message, callback.from_user.id, edit=True)
await callback.answer()
async def _get_user_task(callback: CallbackQuery, tid: str):
uid = callback.from_user.id
if not interface.auth_manager.is_authenticated(uid):
@@ -1690,14 +1707,11 @@ class BotInterface:
user_id = message.from_user.id
state = self._user_input_state.pop(user_id)
# Удаляем prompt и ответ пользователя
prompt_id = state.get("prompt_msg_id")
if prompt_id:
await self._safe_delete(message.bot, message.chat.id, prompt_id)
await self._safe_delete(message.bot, message.chat.id, message.message_id)
task_id = state["task_id"]
param = state["param"]
menu_msg_id = state.get("menu_msg_id")
value = message.text.strip() if message.text else ""
value = value.replace("'", "").replace('"', "").replace("`", "").strip()
@@ -1705,17 +1719,23 @@ class BotInterface:
logger.info(f"Process param: {param} = {value}")
if not value:
await message.answer("❌ Пустое значение. Попробуйте ещё раз.")
await self._send_temp(message, "❌ Пустое значение. Попробуйте ещё раз.")
return
confirm = ""
try:
if param == "delay":
if "-" in value:
mn, mx = parse_range(value)
else:
mn = mx = int(value)
await self.task_manager.update_task(task_id, min_delay=mn, max_delay=mx)
await message.answer(f"✅ Задержка: {format_range(mn, mx)}с")
task_obj = await self.task_manager.get_task(task_id)
if task_obj and task_obj.task_type == "user_visit":
await self.task_manager.update_task(task_id, min_delay=mn * 60, max_delay=mx * 60)
confirm = f"✅ Пауза: {format_range(mn, mx)} мин"
else:
await self.task_manager.update_task(task_id, min_delay=mn, max_delay=mx)
confirm = f"✅ Задержка: {format_range(mn, mx)}с"
elif param == "reading":
if "-" in value:
@@ -1723,7 +1743,7 @@ class BotInterface:
else:
mn = mx = int(value)
await self.task_manager.update_task(task_id, min_reading=mn, max_reading=mx)
await message.answer(f"✅ Чтение: {format_range(mn, mx)}с")
confirm = f"✅ Чтение: {format_range(mn, mx)}с"
elif param == "perlink":
params_obj = await self.task_manager.get_task(task_id)
@@ -1734,10 +1754,10 @@ class BotInterface:
mn = mx = int(value)
await self.task_manager.update_task(task_id, min_series=mn, max_series=mx)
lbl = f"{mn}{mx}" if mn != mx else str(mn)
await message.answer(f"✅ Цикл: {lbl} кликов")
confirm = f"✅ Цикл: {lbl} кликов"
else:
await self.task_manager.update_task(task_id, visits_per_link=int(value))
await message.answer(f"✅ На ссылку: {value}")
confirm = f"✅ На ссылку: {value}"
elif param == "ctr":
if "-" in value:
@@ -1750,27 +1770,27 @@ class BotInterface:
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
await self.task_manager.update_task(task_id, min_ctr=mn_c, max_ctr=mx_c)
lbl = f"{mn_c}%{mx_c}%" if mn_c != mx_c else f"{mn_c}%"
await message.answer(f"✅ CTR: {lbl}")
confirm = f"✅ CTR: {lbl}"
elif param == "minutes":
await self.task_manager.update_task(task_id, monitor_minutes=int(value))
await message.answer(f"✅ Мониторинг: {value} мин")
confirm = f"✅ Мониторинг: {value} мин"
elif param == "domains":
if value.lower() in ["all", "все"]:
await self.task_manager.update_task(task_id, allowed_domains=None)
await message.answer("✅ Домены: все")
confirm = "✅ Домены: все"
else:
domains = [d.strip().lower() for d in value.split(",") if d.strip()]
await self.task_manager.update_task(task_id, allowed_domains=domains)
await message.answer(f"✅ Домены: {', '.join(domains)}")
confirm = f"✅ Домены: {', '.join(domains)}"
elif param == "percent":
pct = float(value.replace(",", "."))
if pct < 0 or pct > 100:
raise ValueError("Значение от 0 до 100")
await self.task_manager.update_task(task_id, visits_percent=pct)
await message.answer(f"✅ % зрителей: {pct}%" if pct > 0 else "% зрителей отключён")
confirm = f"✅ % зрителей: {pct}%" if pct > 0 else "% зрителей отключён"
elif param == "clickdelay":
if "-" in value:
@@ -1778,26 +1798,92 @@ class BotInterface:
else:
mn = mx = int(value)
await self.task_manager.update_task(task_id, min_click_delay=mn, max_click_delay=mx)
await message.answer(f"✅ Задержка между кликами: {format_range(mn, mx)}с")
elif param == "ctr":
if "-" in value:
parts_v = value.split("-", 1)
mn_c = float(parts_v[0].replace(",", "."))
mx_c = float(parts_v[1].replace(",", "."))
else:
mn_c = mx_c = float(value.replace(",", "."))
if not (0 < mn_c <= mx_c <= 100):
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
await self.task_manager.update_task(task_id, min_ctr=mn_c, max_ctr=mx_c)
lbl = f"{mn_c}%{mx_c}%" if mn_c != mx_c else f"{mn_c}%"
await message.answer(f"✅ CTR: {lbl}")
confirm = f"✅ Задержка между кликами: {format_range(mn, mx)}с"
else:
await message.answer(f"❌ Неизвестный параметр: {param}")
await self._send_temp(message, f"❌ Неизвестный параметр: {param}")
return
except ValueError as e:
await message.answer(f"❌ Ошибка: {e}")
await self._send_temp(message, f"❌ Ошибка: {e}")
return
# Обновляем меню с параметрами (заменяем prompt обратно на настройки задачи)
updated = await self.task_manager.get_task(task_id)
if updated and menu_msg_id:
try:
await self._rebuild_user_task_menu(
message.bot, message.chat.id, menu_msg_id, task_id, updated, confirm
)
return
except Exception:
pass
await self._send_temp(message, confirm, delay=4)
async def _rebuild_user_task_menu(
self, bot, chat_id: int, msg_id: int,
task_id: str, params: TaskParams, confirm: str = ""
):
"""Редактирует сообщение обратно в настройки задачи после ввода параметра."""
if params.task_type == "user_visit":
series_range = (
f"{params.min_series}{params.max_series}"
if params.min_series != params.max_series
else str(params.min_series)
)
info = (
f"🔗 {params.url[:50]}\n"
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
f"🔢 Кликов в цикле: {series_range}\n"
f"⏳ Задержка между кликами: {params.min_click_delay}{params.max_click_delay} сек\n"
f"⏱ Пауза между циклами: {params.min_delay // 60}{params.max_delay // 60} мин\n"
f"📖 Время на странице: {params.min_reading}{params.max_reading} сек"
)
else:
domains = ", ".join(params.allowed_domains) if params.allowed_domains else "все"
ctr_str = (
f"{params.min_ctr}%{params.max_ctr}%"
if params.min_ctr != params.max_ctr
else f"{params.min_ctr}%"
)
info = (
f"📺 Стример: {params.channel}\n"
f"🌐 Домены: {domains}\n\n"
f"🔗 Ссылок найдено: {params.links_found}\n"
f"✅ Успешных кликов: {params.successful_visits}\n\n"
f"📊 CTR: {ctr_str}\n"
f"⏱ Пауза между кликами: {params.min_delay}{params.max_delay} сек\n"
f"📖 Время на странице: {params.min_reading}{params.max_reading} сек"
)
builder = InlineKeyboardBuilder()
if params.task_type == "user_visit":
builder.row(
InlineKeyboardButton(text="⏱️ Пауза (мин)", callback_data=f"uset_{task_id}_delay"),
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
)
builder.row(
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
)
else:
builder.row(
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
)
builder.row(
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
)
builder.row(InlineKeyboardButton(text="🔙 К задачам", callback_data="my_tasks"))
prefix = f"{confirm}\n\n" if confirm else ""
await bot.edit_message_text(
f"{prefix}⚙️ Параметры задачи\n\n{info}",
chat_id=chat_id,
message_id=msg_id,
reply_markup=builder.as_markup()
)
async def _show_user_task_detail(self, callback: CallbackQuery, task_id: str, params: TaskParams):
if params.task_type == "user_visit":
@@ -1811,7 +1897,7 @@ class BotInterface:
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
f"🔢 Кликов в цикле: {series_range}\n"
f"⏳ Задержка между кликами: {params.min_click_delay}{params.max_click_delay} сек\n"
f"⏱ Пауза между циклами: {params.min_delay}{params.max_delay} сек\n"
f"⏱ Пауза между циклами: {params.min_delay // 60}{params.max_delay // 60} мин\n"
f"📖 Время на странице: {params.min_reading}{params.max_reading} сек"
)
else:
@@ -1838,16 +1924,20 @@ class BotInterface:
)
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
)
if params.task_type == "user_visit":
builder.row(
InlineKeyboardButton(text="⏱️ Пауза (мин)", callback_data=f"uset_{task_id}_delay"),
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
)
builder.row(
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
)
else:
builder.row(
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
)
builder.row(
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
@@ -2146,55 +2236,106 @@ class BotInterface:
all_tasks = await self.task_manager.get_all_tasks()
user_tasks = {tid: p for tid, p in all_tasks.items() if p.user_id == user_id}
visits = {tid: p for tid, p in user_tasks.items() if p.task_type == "user_visit"}
monitors = {tid: p for tid, p in user_tasks.items() if p.task_type != "user_visit"}
v_active = sum(1 for p in visits.values() if not p.completed and not p.stopped)
m_active = sum(1 for p in monitors.values() if not p.completed and not p.stopped)
if not user_tasks:
text = f"📋 Задачи {str(user_id) if for_admin else ''}\n\nЗадач нет."
else:
header = f"📋 Задачи пользователя {user_id}\n\n" if for_admin else "📋 Мои задачи\n\n"
text = header
for tid, p in list(user_tasks.items())[:10]:
if p.task_type == "user_visit":
text += (
f"{p.get_status_emoji()} 🔗 {p.url[:40]}\n"
f"{p.successful_visits}/{p.max_visits} | 📊 {p.total_visits}\n"
)
else:
domains = ", ".join(p.allowed_domains) if p.allowed_domains else "все"
text += (
f"{p.get_status_emoji()} 📺 {p.channel} — 🌐 {domains}\n"
f" 🔗 {p.links_found} | ✅ {p.successful_visits} | 📊 {p.total_visits}\n"
)
if visits:
text += f"🔗 Посещения — {v_active} акт. / {len(visits)} всего\n"
if monitors:
text += f"📺 Мониторинг — {m_active} акт. / {len(monitors)} всего\n"
builder = InlineKeyboardBuilder()
if for_admin:
builder.row(InlineKeyboardButton(text="🔙 К пользователю", callback_data=f"udetail_{user_id}"))
else:
for tid, p in list(user_tasks.items())[:8]:
if p.task_type == "user_visit":
domain = extract_domain(p.url)[:18] if p.url else "?"
label = f"🔗 {domain}"
else:
label = f"📺 {p.channel}"
if not p.completed and not p.stopped:
pause_btn = (
InlineKeyboardButton(text="▶️", callback_data=f"uresume_{tid}")
if p.paused else
InlineKeyboardButton(text="⏸️", callback_data=f"upause_{tid}")
)
builder.row(
InlineKeyboardButton(text=label, callback_data=f"utask_{tid}"),
pause_btn,
InlineKeyboardButton(text="⚙️", callback_data=f"utask_{tid}"),
InlineKeyboardButton(text="🗑️", callback_data=f"ustop_{tid}"),
)
else:
builder.row(InlineKeyboardButton(
text=f"🗑️ {label} (завершена)",
callback_data=f"ustop_{tid}"
))
builder.row(
InlineKeyboardButton(
text=f"🔗 Посещения ({len(visits)})",
callback_data="my_tasks_visits"
),
InlineKeyboardButton(
text=f"📺 Мониторинг ({len(monitors)})",
callback_data="my_tasks_monitors"
),
)
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_menu"))
await self._edit_or_send(message, text, builder.as_markup(), edit)
def _build_task_buttons(self, builder: InlineKeyboardBuilder, tasks: dict):
for tid, p in list(tasks.items())[:8]:
if p.task_type == "user_visit":
domain = extract_domain(p.url)[:16] if p.url else "?"
label = f"🔗 {domain}"
else:
label = f"📺 {p.channel}"
if not p.completed and not p.stopped:
pause_btn = (
InlineKeyboardButton(text="▶️", callback_data=f"uresume_{tid}")
if p.paused else
InlineKeyboardButton(text="⏸️", callback_data=f"upause_{tid}")
)
builder.row(
InlineKeyboardButton(text=label, callback_data=f"utask_{tid}"),
pause_btn,
InlineKeyboardButton(text="⚙️", callback_data=f"utask_{tid}"),
InlineKeyboardButton(text="🗑️", callback_data=f"ustop_{tid}"),
)
else:
builder.row(InlineKeyboardButton(
text=f"🗑️ {label} (завершена)",
callback_data=f"ustop_{tid}"
))
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
builder.row(InlineKeyboardButton(text="🔙 Мои задачи", callback_data="my_tasks"))
async def _show_user_visits(self, message: Message, user_id: int, edit: bool = False):
all_tasks = await self.task_manager.get_all_tasks()
visits = {
tid: p for tid, p in all_tasks.items()
if p.user_id == user_id and p.task_type == "user_visit"
}
if not visits:
text = "🔗 Посещения\n\nЗадач нет."
else:
text = "🔗 Посещения\n\n"
for _, p in list(visits.items())[:8]:
text += (
f"{p.get_status_emoji()} {p.url[:40]}\n"
f"{p.successful_visits}/{p.max_visits} | 📊 {p.total_visits}\n"
)
builder = InlineKeyboardBuilder()
self._build_task_buttons(builder, visits)
await self._edit_or_send(message, text, builder.as_markup(), edit)
async def _show_user_monitors(self, message: Message, user_id: int, edit: bool = False):
all_tasks = await self.task_manager.get_all_tasks()
monitors = {
tid: p for tid, p in all_tasks.items()
if p.user_id == user_id and p.task_type != "user_visit"
}
if not monitors:
text = "📺 Мониторинг\n\nЗадач нет."
else:
text = "📺 Мониторинг\n\n"
for _, p in list(monitors.items())[:8]:
domains = ", ".join(p.allowed_domains) if p.allowed_domains else "все"
text += (
f"{p.get_status_emoji()} {p.channel}{domains}\n"
f" 🔗 {p.links_found} | ✅ {p.successful_visits} | 📊 {p.total_visits}\n"
)
builder = InlineKeyboardBuilder()
self._build_task_buttons(builder, monitors)
await self._edit_or_send(message, text, builder.as_markup(), edit)
async def _process_user_task_input(self, message: Message):
user_id = message.from_user.id
state = self._user_task_state[user_id]
@@ -2303,18 +2444,22 @@ class BotInterface:
sent = await message.answer(
f"✅ Цикл: {series_label} кликов\n\n"
"Шаг 4/4 — таймаут между циклами (в минутах)\n\n"
"Введите одно число, например `3` — пауза 3 минуты.",
"`3` — ровно 3 минуты.\n"
"`2-5` — случайно от 2 до 5 минут.",
reply_markup=builder.as_markup()
)
self._menu_msg[user_id] = sent.message_id
elif state["step"] == "delay":
try:
mn_d = mx_d = int(text)
if "-" in text:
mn_d, mx_d = parse_range(text, default_min=1)
else:
mn_d = mx_d = int(text)
if mn_d < 1:
raise ValueError
except Exception:
await self._send_temp(message, "Введите целое число минут, например: `3`")
await self._send_temp(message, "Введите число или диапазон минут, например: `3` или `2-5`")
return
del self._user_task_state[user_id]
@@ -2325,7 +2470,7 @@ class BotInterface:
mn = state["min_series"]
mx = state["max_series"]
series_label = f"{mn}{mx}" if mn != mx else str(mn)
delay_label = str(mn_d)
delay_label = f"{mn_d}{mx_d}" if mn_d != mx_d else str(mn_d)
task_id = f"u{user_id}_{extract_domain(url)[:12]}_{datetime.now().strftime('%H%M%S')}"
params = TaskParams(