fix comand
This commit is contained in:
+202
-57
@@ -819,11 +819,14 @@ class BotInterface:
|
|||||||
f"Текущее: {cur}\n"
|
f"Текущее: {cur}\n"
|
||||||
f"Диапазон `2-5` или фиксированно `3`."
|
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 = (
|
delay_label = (
|
||||||
f"⏱️ *Пауза между циклами*\n"
|
f"⏱️ *Пауза между циклами*\n"
|
||||||
f"Сколько секунд ждать после каждого цикла кликов.\n"
|
f"Сколько минут ждать после каждого цикла кликов.\n"
|
||||||
f"Текущая: {params.min_delay}–{params.max_delay} сек\n"
|
f"Текущая: {_d_cur} мин\n"
|
||||||
f"Диапазон `30-60` или фиксированно `45`."
|
f"Диапазон `2-5` или фиксированно `3`."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
perlink_label = (
|
perlink_label = (
|
||||||
@@ -873,12 +876,12 @@ class BotInterface:
|
|||||||
interface._user_input_state[uid] = {
|
interface._user_input_state[uid] = {
|
||||||
"task_id": task_id,
|
"task_id": task_id,
|
||||||
"param": param,
|
"param": param,
|
||||||
|
"menu_msg_id": callback.message.message_id,
|
||||||
}
|
}
|
||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
builder.row(InlineKeyboardButton(text="❌ Отмена", callback_data=f"utask_{task_id}"))
|
builder.row(InlineKeyboardButton(text="❌ Отмена", callback_data=f"utask_{task_id}"))
|
||||||
sent = await callback.message.answer(prompt, reply_markup=builder.as_markup())
|
await callback.message.edit_text(prompt, reply_markup=builder.as_markup())
|
||||||
interface._user_input_state[uid]["prompt_msg_id"] = sent.message_id
|
await callback.answer()
|
||||||
await callback.answer(f"Введите значение")
|
|
||||||
|
|
||||||
@dp.callback_query(F.data == "confirm_buy")
|
@dp.callback_query(F.data == "confirm_buy")
|
||||||
async def cb_confirm_buy(callback: CallbackQuery):
|
async def cb_confirm_buy(callback: CallbackQuery):
|
||||||
@@ -1036,6 +1039,10 @@ class BotInterface:
|
|||||||
await interface._show_user_menu(callback.message, user_id=uid)
|
await interface._show_user_menu(callback.message, user_id=uid)
|
||||||
await callback.answer("👤 Переключились в режим пользователя")
|
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")
|
@dp.callback_query(F.data == "cancel_new_task")
|
||||||
async def cb_cancel_new_task(callback: CallbackQuery):
|
async def cb_cancel_new_task(callback: CallbackQuery):
|
||||||
uid = callback.from_user.id
|
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 interface._show_user_tasks(callback.message, callback.from_user.id, edit=True)
|
||||||
await callback.answer()
|
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):
|
async def _get_user_task(callback: CallbackQuery, tid: str):
|
||||||
uid = callback.from_user.id
|
uid = callback.from_user.id
|
||||||
if not interface.auth_manager.is_authenticated(uid):
|
if not interface.auth_manager.is_authenticated(uid):
|
||||||
@@ -1690,14 +1707,11 @@ class BotInterface:
|
|||||||
user_id = message.from_user.id
|
user_id = message.from_user.id
|
||||||
state = self._user_input_state.pop(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)
|
await self._safe_delete(message.bot, message.chat.id, message.message_id)
|
||||||
|
|
||||||
task_id = state["task_id"]
|
task_id = state["task_id"]
|
||||||
param = state["param"]
|
param = state["param"]
|
||||||
|
menu_msg_id = state.get("menu_msg_id")
|
||||||
|
|
||||||
value = message.text.strip() if message.text else ""
|
value = message.text.strip() if message.text else ""
|
||||||
value = value.replace("'", "").replace('"', "").replace("`", "").strip()
|
value = value.replace("'", "").replace('"', "").replace("`", "").strip()
|
||||||
@@ -1705,17 +1719,23 @@ class BotInterface:
|
|||||||
logger.info(f"Process param: {param} = {value}")
|
logger.info(f"Process param: {param} = {value}")
|
||||||
|
|
||||||
if not value:
|
if not value:
|
||||||
await message.answer("❌ Пустое значение. Попробуйте ещё раз.")
|
await self._send_temp(message, "❌ Пустое значение. Попробуйте ещё раз.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
confirm = ""
|
||||||
try:
|
try:
|
||||||
if param == "delay":
|
if param == "delay":
|
||||||
if "-" in value:
|
if "-" in value:
|
||||||
mn, mx = parse_range(value)
|
mn, mx = parse_range(value)
|
||||||
else:
|
else:
|
||||||
mn = mx = int(value)
|
mn = mx = int(value)
|
||||||
|
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)
|
await self.task_manager.update_task(task_id, min_delay=mn, max_delay=mx)
|
||||||
await message.answer(f"✅ Задержка: {format_range(mn, mx)}с")
|
confirm = f"✅ Задержка: {format_range(mn, mx)}с"
|
||||||
|
|
||||||
elif param == "reading":
|
elif param == "reading":
|
||||||
if "-" in value:
|
if "-" in value:
|
||||||
@@ -1723,7 +1743,7 @@ class BotInterface:
|
|||||||
else:
|
else:
|
||||||
mn = mx = int(value)
|
mn = mx = int(value)
|
||||||
await self.task_manager.update_task(task_id, min_reading=mn, max_reading=mx)
|
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":
|
elif param == "perlink":
|
||||||
params_obj = await self.task_manager.get_task(task_id)
|
params_obj = await self.task_manager.get_task(task_id)
|
||||||
@@ -1734,10 +1754,10 @@ class BotInterface:
|
|||||||
mn = mx = int(value)
|
mn = mx = int(value)
|
||||||
await self.task_manager.update_task(task_id, min_series=mn, max_series=mx)
|
await self.task_manager.update_task(task_id, min_series=mn, max_series=mx)
|
||||||
lbl = f"{mn}–{mx}" if mn != mx else str(mn)
|
lbl = f"{mn}–{mx}" if mn != mx else str(mn)
|
||||||
await message.answer(f"✅ Цикл: {lbl} кликов")
|
confirm = f"✅ Цикл: {lbl} кликов"
|
||||||
else:
|
else:
|
||||||
await self.task_manager.update_task(task_id, visits_per_link=int(value))
|
await self.task_manager.update_task(task_id, visits_per_link=int(value))
|
||||||
await message.answer(f"✅ На ссылку: {value}")
|
confirm = f"✅ На ссылку: {value}"
|
||||||
|
|
||||||
elif param == "ctr":
|
elif param == "ctr":
|
||||||
if "-" in value:
|
if "-" in value:
|
||||||
@@ -1750,27 +1770,27 @@ class BotInterface:
|
|||||||
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
|
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
|
||||||
await self.task_manager.update_task(task_id, min_ctr=mn_c, max_ctr=mx_c)
|
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}%"
|
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":
|
elif param == "minutes":
|
||||||
await self.task_manager.update_task(task_id, monitor_minutes=int(value))
|
await self.task_manager.update_task(task_id, monitor_minutes=int(value))
|
||||||
await message.answer(f"✅ Мониторинг: {value} мин")
|
confirm = f"✅ Мониторинг: {value} мин"
|
||||||
|
|
||||||
elif param == "domains":
|
elif param == "domains":
|
||||||
if value.lower() in ["all", "все"]:
|
if value.lower() in ["all", "все"]:
|
||||||
await self.task_manager.update_task(task_id, allowed_domains=None)
|
await self.task_manager.update_task(task_id, allowed_domains=None)
|
||||||
await message.answer("✅ Домены: все")
|
confirm = "✅ Домены: все"
|
||||||
else:
|
else:
|
||||||
domains = [d.strip().lower() for d in value.split(",") if d.strip()]
|
domains = [d.strip().lower() for d in value.split(",") if d.strip()]
|
||||||
await self.task_manager.update_task(task_id, allowed_domains=domains)
|
await self.task_manager.update_task(task_id, allowed_domains=domains)
|
||||||
await message.answer(f"✅ Домены: {', '.join(domains)}")
|
confirm = f"✅ Домены: {', '.join(domains)}"
|
||||||
|
|
||||||
elif param == "percent":
|
elif param == "percent":
|
||||||
pct = float(value.replace(",", "."))
|
pct = float(value.replace(",", "."))
|
||||||
if pct < 0 or pct > 100:
|
if pct < 0 or pct > 100:
|
||||||
raise ValueError("Значение от 0 до 100")
|
raise ValueError("Значение от 0 до 100")
|
||||||
await self.task_manager.update_task(task_id, visits_percent=pct)
|
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":
|
elif param == "clickdelay":
|
||||||
if "-" in value:
|
if "-" in value:
|
||||||
@@ -1778,26 +1798,92 @@ class BotInterface:
|
|||||||
else:
|
else:
|
||||||
mn = mx = int(value)
|
mn = mx = int(value)
|
||||||
await self.task_manager.update_task(task_id, min_click_delay=mn, max_click_delay=mx)
|
await self.task_manager.update_task(task_id, min_click_delay=mn, max_click_delay=mx)
|
||||||
await message.answer(f"✅ Задержка между кликами: {format_range(mn, mx)}с")
|
confirm = 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}")
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await message.answer(f"❌ Неизвестный параметр: {param}")
|
await self._send_temp(message, f"❌ Неизвестный параметр: {param}")
|
||||||
|
return
|
||||||
|
|
||||||
except ValueError as e:
|
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):
|
async def _show_user_task_detail(self, callback: CallbackQuery, task_id: str, params: TaskParams):
|
||||||
if params.task_type == "user_visit":
|
if params.task_type == "user_visit":
|
||||||
@@ -1811,7 +1897,7 @@ class BotInterface:
|
|||||||
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
|
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
|
||||||
f"🔢 Кликов в цикле: {series_range}\n"
|
f"🔢 Кликов в цикле: {series_range}\n"
|
||||||
f"⏳ Задержка между кликами: {params.min_click_delay}–{params.max_click_delay} сек\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} сек"
|
f"📖 Время на странице: {params.min_reading}–{params.max_reading} сек"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -1838,16 +1924,20 @@ class BotInterface:
|
|||||||
)
|
)
|
||||||
|
|
||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
|
if params.task_type == "user_visit":
|
||||||
builder.row(
|
builder.row(
|
||||||
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
|
InlineKeyboardButton(text="⏱️ Пауза (мин)", callback_data=f"uset_{task_id}_delay"),
|
||||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||||
)
|
)
|
||||||
if params.task_type == "user_visit":
|
|
||||||
builder.row(
|
builder.row(
|
||||||
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
|
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
|
||||||
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
|
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
builder.row(
|
||||||
|
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
|
||||||
|
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||||
|
)
|
||||||
builder.row(
|
builder.row(
|
||||||
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
|
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
|
||||||
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
|
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
|
||||||
@@ -2146,31 +2236,44 @@ class BotInterface:
|
|||||||
all_tasks = await self.task_manager.get_all_tasks()
|
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}
|
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:
|
if not user_tasks:
|
||||||
text = f"📋 Задачи {str(user_id) if for_admin else ''}\n\nЗадач нет."
|
text = f"📋 Задачи {str(user_id) if for_admin else ''}\n\nЗадач нет."
|
||||||
else:
|
else:
|
||||||
header = f"📋 Задачи пользователя {user_id}\n\n" if for_admin else "📋 Мои задачи\n\n"
|
header = f"📋 Задачи пользователя {user_id}\n\n" if for_admin else "📋 Мои задачи\n\n"
|
||||||
text = header
|
text = header
|
||||||
for tid, p in list(user_tasks.items())[:10]:
|
if visits:
|
||||||
if p.task_type == "user_visit":
|
text += f"🔗 Посещения — {v_active} акт. / {len(visits)} всего\n"
|
||||||
text += (
|
if monitors:
|
||||||
f"{p.get_status_emoji()} 🔗 {p.url[:40]}\n"
|
text += f"📺 Мониторинг — {m_active} акт. / {len(monitors)} всего\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"
|
|
||||||
)
|
|
||||||
|
|
||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
if for_admin:
|
if for_admin:
|
||||||
builder.row(InlineKeyboardButton(text="🔙 К пользователю", callback_data=f"udetail_{user_id}"))
|
builder.row(InlineKeyboardButton(text="🔙 К пользователю", callback_data=f"udetail_{user_id}"))
|
||||||
else:
|
else:
|
||||||
for tid, p in list(user_tasks.items())[:8]:
|
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":
|
if p.task_type == "user_visit":
|
||||||
domain = extract_domain(p.url)[:18] if p.url else "?"
|
domain = extract_domain(p.url)[:16] if p.url else "?"
|
||||||
label = f"🔗 {domain}"
|
label = f"🔗 {domain}"
|
||||||
else:
|
else:
|
||||||
label = f"📺 {p.channel}"
|
label = f"📺 {p.channel}"
|
||||||
@@ -2192,7 +2295,45 @@ class BotInterface:
|
|||||||
callback_data=f"ustop_{tid}"
|
callback_data=f"ustop_{tid}"
|
||||||
))
|
))
|
||||||
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
|
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
|
||||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_menu"))
|
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)
|
await self._edit_or_send(message, text, builder.as_markup(), edit)
|
||||||
|
|
||||||
async def _process_user_task_input(self, message: Message):
|
async def _process_user_task_input(self, message: Message):
|
||||||
@@ -2303,18 +2444,22 @@ class BotInterface:
|
|||||||
sent = await message.answer(
|
sent = await message.answer(
|
||||||
f"✅ Цикл: {series_label} кликов\n\n"
|
f"✅ Цикл: {series_label} кликов\n\n"
|
||||||
"Шаг 4/4 — таймаут между циклами (в минутах)\n\n"
|
"Шаг 4/4 — таймаут между циклами (в минутах)\n\n"
|
||||||
"Введите одно число, например `3` — пауза 3 минуты.",
|
"`3` — ровно 3 минуты.\n"
|
||||||
|
"`2-5` — случайно от 2 до 5 минут.",
|
||||||
reply_markup=builder.as_markup()
|
reply_markup=builder.as_markup()
|
||||||
)
|
)
|
||||||
self._menu_msg[user_id] = sent.message_id
|
self._menu_msg[user_id] = sent.message_id
|
||||||
|
|
||||||
elif state["step"] == "delay":
|
elif state["step"] == "delay":
|
||||||
try:
|
try:
|
||||||
|
if "-" in text:
|
||||||
|
mn_d, mx_d = parse_range(text, default_min=1)
|
||||||
|
else:
|
||||||
mn_d = mx_d = int(text)
|
mn_d = mx_d = int(text)
|
||||||
if mn_d < 1:
|
if mn_d < 1:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
except Exception:
|
except Exception:
|
||||||
await self._send_temp(message, "Введите целое число минут, например: `3`")
|
await self._send_temp(message, "Введите число или диапазон минут, например: `3` или `2-5`")
|
||||||
return
|
return
|
||||||
|
|
||||||
del self._user_task_state[user_id]
|
del self._user_task_state[user_id]
|
||||||
@@ -2325,7 +2470,7 @@ class BotInterface:
|
|||||||
mn = state["min_series"]
|
mn = state["min_series"]
|
||||||
mx = state["max_series"]
|
mx = state["max_series"]
|
||||||
series_label = f"{mn}–{mx}" if mn != mx else str(mn)
|
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')}"
|
task_id = f"u{user_id}_{extract_domain(url)[:12]}_{datetime.now().strftime('%H%M%S')}"
|
||||||
params = TaskParams(
|
params = TaskParams(
|
||||||
|
|||||||
Reference in New Issue
Block a user