add pause series
This commit is contained in:
+98
-30
@@ -2114,26 +2114,55 @@ class BotInterface:
|
||||
await asyncio.sleep(2)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
# Роут: [задержка] → клик1 → [задержка] → клик2 → ... → кликN → повтор
|
||||
# Пауза: текущий клик завершается, серия останавливается на N
|
||||
# Resume < 5 мин: продолжает с N+1 без задержки
|
||||
# Resume > 5 мин: серия этой ссылки отбрасывается, ждём следующий цикл
|
||||
|
||||
remaining_clicks = 0
|
||||
series_paused_at: Optional[float] = None
|
||||
SERIES_EXPIRY = 5 * 60
|
||||
|
||||
try:
|
||||
while params.successful_visits < max_v and not params.stopped:
|
||||
# --- пауза перед циклом ---
|
||||
await _sleep_interruptible(params.get_delay())
|
||||
|
||||
# Ждём паузу если активна перед новым циклом
|
||||
while params.paused and not params.stopped:
|
||||
await asyncio.sleep(2)
|
||||
if params.stopped:
|
||||
break
|
||||
|
||||
# размер цикла выбирается случайно каждый раз
|
||||
series_size = params.get_series_size()
|
||||
# Определяем размер серии
|
||||
if remaining_clicks > 0:
|
||||
elapsed = datetime.now().timestamp() - (series_paused_at or 0)
|
||||
if elapsed > SERIES_EXPIRY:
|
||||
# Серия устарела — отбрасываем, ждём следующую задержку
|
||||
logger.info(f"⏰ Series expired ({elapsed:.0f}s > {SERIES_EXPIRY//60}min), skipping remaining {remaining_clicks} clicks")
|
||||
remaining_clicks = 0
|
||||
series_paused_at = None
|
||||
# Стандартная задержка перед следующей серией
|
||||
await _sleep_interruptible(params.get_delay())
|
||||
if params.stopped:
|
||||
break
|
||||
series_size = params.get_series_size()
|
||||
else:
|
||||
# Продолжаем с сохранённого места — без задержки
|
||||
series_size = remaining_clicks
|
||||
remaining_clicks = 0
|
||||
series_paused_at = None
|
||||
logger.info(f"▶️ Resuming: {series_size} clicks left ({elapsed:.0f}s paused)")
|
||||
else:
|
||||
# Новая серия: задержка → рандомный размер
|
||||
await _sleep_interruptible(params.get_delay())
|
||||
if params.stopped:
|
||||
break
|
||||
series_size = params.get_series_size()
|
||||
|
||||
# --- цикл кликов ---
|
||||
# --- Серия кликов ---
|
||||
for click_num in range(series_size):
|
||||
if params.stopped or params.successful_visits >= max_v:
|
||||
break
|
||||
|
||||
while params.paused and not params.stopped:
|
||||
await asyncio.sleep(2)
|
||||
if params.stopped:
|
||||
break
|
||||
|
||||
balance = await self.balance_storage.get_balance(params.user_id)
|
||||
if balance <= 0:
|
||||
await self.task_manager.stop_task(task_id)
|
||||
@@ -2156,8 +2185,16 @@ class BotInterface:
|
||||
logger.error(f"URL visit error: {e}")
|
||||
params.total_visits += 1
|
||||
|
||||
# задержка между кликами внутри цикла (кроме последнего)
|
||||
if click_num < series_size - 1 and not params.stopped and params.successful_visits < max_v:
|
||||
# Клик завершён — проверяем паузу
|
||||
if params.paused or params.stopped:
|
||||
remaining_clicks = series_size - click_num - 1
|
||||
if remaining_clicks > 0 and not params.stopped:
|
||||
series_paused_at = datetime.now().timestamp()
|
||||
logger.info(f"⏸️ Paused after click {click_num+1}/{series_size}, {remaining_clicks} saved")
|
||||
break
|
||||
|
||||
# Задержка между кликами (кроме последнего)
|
||||
if click_num < series_size - 1 and params.successful_visits < max_v:
|
||||
await _sleep_interruptible(params.get_click_delay())
|
||||
|
||||
await self.task_manager.complete_task(task_id)
|
||||
@@ -2197,48 +2234,79 @@ class BotInterface:
|
||||
viewers = await get_viewer_count(params.channel)
|
||||
if viewers and viewers > 0:
|
||||
visits_count = max(1, round(viewers * ctr / 100))
|
||||
logger.info(f"visits: {viewers} viewers × {ctr:.2f}% = {visits_count}")
|
||||
calc_info = f"{viewers} зрителей × {ctr:.2f}% = {visits_count} кликов"
|
||||
else:
|
||||
visits_count = max(1, round(params.visits_per_link * ctr / 100))
|
||||
logger.info(f"visits: fallback {params.visits_per_link} × {ctr:.2f}% = {visits_count}")
|
||||
calc_info = f"зрители недоступны, фикс {params.visits_per_link} × {ctr:.2f}% = {visits_count} кликов"
|
||||
|
||||
logger.info(f"🔗 @{username}: {url}")
|
||||
logger.info(f"🔗 @{username} {url} → {visits_count} clicks ({calc_info})")
|
||||
await send_message_safe(
|
||||
message.bot, message.chat.id,
|
||||
f"🔗 @{username}: {url[:60]}"
|
||||
f"🔗 @{username}: {url[:60]}\n"
|
||||
f"📊 {calc_info}"
|
||||
)
|
||||
|
||||
for i in range(visits_count):
|
||||
while params.paused:
|
||||
await asyncio.sleep(1)
|
||||
# Роут: [задержка] → клик1 → [задержка] → клик2 → ... → кликN
|
||||
# Пауза: текущий клик завершается, серия останавливается
|
||||
# Resume < 5 мин: продолжает с сохранённого клика
|
||||
# Resume > 5 мин: серия этой ссылки полностью отбрасывается
|
||||
SERIES_EXPIRY = 5 * 60
|
||||
remaining = visits_count
|
||||
paused_at: Optional[float] = None
|
||||
|
||||
first_click = True
|
||||
while remaining > 0 and not params.stopped:
|
||||
# Проверяем не истекла ли серия после паузы
|
||||
if paused_at is not None:
|
||||
elapsed = datetime.now().timestamp() - paused_at
|
||||
if elapsed > SERIES_EXPIRY:
|
||||
logger.info(f"⏰ Серия устарела ({elapsed:.0f}s), ссылка {url[:40]} отброшена")
|
||||
return
|
||||
paused_at = None
|
||||
logger.info(f"▶️ Продолжаем серию: {remaining} кликов осталось")
|
||||
|
||||
# Задержка перед каждым кликом (включая первый)
|
||||
if not params.stopped and not params.paused:
|
||||
delay = params.get_delay()
|
||||
if first_click:
|
||||
logger.info(f"⏳ Задержка перед первым кликом: {delay}с")
|
||||
await asyncio.sleep(delay)
|
||||
first_click = False
|
||||
|
||||
if params.stopped:
|
||||
break
|
||||
return
|
||||
|
||||
reading = params.get_reading_time()
|
||||
try:
|
||||
result = await self.browser_service.visit_page_from_twitch(
|
||||
url=url,
|
||||
channel=params.channel,
|
||||
reading_time=reading
|
||||
)
|
||||
result = await self.browser_service.visit_page(url, reading)
|
||||
params.total_visits += 1
|
||||
if result.success:
|
||||
params.successful_visits += 1
|
||||
remaining -= 1
|
||||
if params.user_id:
|
||||
new_balance = await self.balance_storage.deduct(params.user_id, 1)
|
||||
if new_balance <= 0:
|
||||
params.stopped = True
|
||||
await send_message_safe(
|
||||
message.bot, params.chat_id,
|
||||
"⚠️ Баланс исчерпан — задача остановлена.\n"
|
||||
"Обратитесь к администратору для пополнения."
|
||||
"⚠️ Баланс исчерпан — задача остановлена."
|
||||
)
|
||||
break
|
||||
return
|
||||
else:
|
||||
remaining -= 1
|
||||
except Exception as e:
|
||||
logger.error(f"Visit error: {e}")
|
||||
remaining -= 1
|
||||
|
||||
# Клик завершён — проверяем паузу
|
||||
if params.paused and remaining > 0:
|
||||
paused_at = datetime.now().timestamp()
|
||||
logger.info(f"⏸️ Серия на паузе, {remaining} кликов сохранено (истечёт через {SERIES_EXPIRY//60}мин)")
|
||||
while params.paused and not params.stopped:
|
||||
await asyncio.sleep(2)
|
||||
if params.stopped:
|
||||
return
|
||||
|
||||
if i < visits_count - 1:
|
||||
await asyncio.sleep(params.get_delay())
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Process URL error: {e}")
|
||||
|
||||
Reference in New Issue
Block a user