Чистка «лишнего»: остатки ИКП→БАЗА, мёртвый код, новый логотип

- Пользовательские сообщения и подписи с «ИКП» переименованы в «Кибершкола БАЗА»
  (права админа, стартовый пинг, отправитель писем, докстроки).
- Удалён мёртвый код: метод _notify_allowed + связанные _last_notify/NOTIFY_COOLDOWN_SEC
  (нигде не вызывались), осиротевшие комментарии-заголовки от удалённой карьеры,
  лишние пустые строки.
- Удалена скрытая фича «Наши соцсети» (нет в ТЗ, вела на старые ИКП-ссылки) + её клавиатура.
- Обновлён логотип приветствия (help_img/Logo.jpg).

Не тронуто намеренно: веб-форма (form/server.py) — отдельный компонент; слой БД.
pytest 31 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kenik
2026-07-23 20:04:55 +03:00
parent a5a96f31f5
commit 4095b2ec61
4 changed files with 4 additions and 104 deletions
+3 -87
View File
@@ -38,8 +38,6 @@ db = DatabaseManager()
# Анти-флуд: максимум сообщений от одного пользователя за окно времени
FLOOD_MAX_MSGS = 12
FLOOD_WINDOW_SEC = 10
# Кулдаун между уведомлениями оператора о заявке/отклике от одного пользователя (сек)
NOTIFY_COOLDOWN_SEC = 120
# Временный бан при повторном флуде: после BAN_STRIKES срабатываний за BAN_WINDOW_SEC — бан на BAN_SEC
BAN_STRIKES = 3
BAN_WINDOW_SEC = 60
@@ -101,7 +99,6 @@ class VKBotApplication:
self._flood_warned: Dict[int, float] = {} # user_id -> когда предупредили о флуде
self._flood_strikes: Dict[int, list] = defaultdict(list) # user_id -> метки срабатываний флуда
self._banned_until: Dict[int, float] = {} # user_id -> до какого времени забанен
self._last_notify: Dict[int, float] = {} # user_id -> время последнего уведомления оператора
self._last_antiflood_cleanup: float = 0.0 # когда последний раз чистили словари анти-флуда
# Кэш рантайм-админов (из БД), чтобы не бить в SQLite на каждое сообщение
self._admins_cache: Optional[set] = None
@@ -301,7 +298,7 @@ class VKBotApplication:
self._admins_cache = None # инвалидируем кэш админов
self.send_message(user_id, f"✅ Пользователь vk.com/id{new_id} теперь администратор.")
try:
self.send_message(new_id, "🛡 Вам выданы права администратора бота ИКП. "
self.send_message(new_id, "🛡 Вам выданы права администратора бота Кибершколы БАЗА. "
"Откройте меню — появится кнопка «Админка ⚙️».")
except Exception:
pass
@@ -345,16 +342,6 @@ class VKBotApplication:
del self._banned_until[uid]
for uid in [u for u, t in self._flood_warned.items() if now - t > FLOOD_WINDOW_SEC]:
del self._flood_warned[uid]
for uid in [u for u, t in self._last_notify.items() if now - t > NOTIFY_COOLDOWN_SEC]:
del self._last_notify[uid]
def _notify_allowed(self, user_id: int) -> bool:
"""Антиспам: не чаще раза в NOTIFY_COOLDOWN_SEC уведомляем оператора об одном пользователе."""
now = time.time()
if now - self._last_notify.get(user_id, 0) < NOTIFY_COOLDOWN_SEC:
return False
self._last_notify[user_id] = now
return True
def handle_message(self, user_id: int, text: str, attachments: Optional[list] = None):
"""Маршрутизатор входящих сообщений на основе состояний пользователя."""
@@ -607,15 +594,6 @@ class VKBotApplication:
self._baza_ask_question(user_id)
return
# 5. Площадки — кнопки-ссылки
if text_lower in ["наши соцсети 🔗", "наши соцсети", "соцсети", "площадки", "ссылки"]:
self.send_message(
user_id,
"🔗 Мы на площадках Кибершколы БАЗА — заходите и подписывайтесь 👇",
keyboard=get_socials_keyboard()
)
return
# 6. Возврат в главное меню
if text_lower in ["назад в меню ↩️", "меню", "назад", "в главное меню ↩️", "главное меню"]:
self.send_message(
@@ -1189,26 +1167,6 @@ class VKBotApplication:
f"до {getattr(config, 'WORK_HOUR_END', 21)}:00) — ответим утром.")
self.send_message(user_id, client_text, keyboard=get_operator_keyboard())
def _upload_photo(self, peer_id: int, image_path: str) -> Optional[Dict[str, str]]:
"""Загружает фото в VK для прикрепления к сообщению. Возвращает {'attachment','raw'} или None."""
@@ -1236,9 +1194,8 @@ class VKBotApplication:
return None
def get_logo_attachment(self, peer_id: int) -> Optional[str]:
"""Attachment-строка с логотипом ИКП для прикрепления к приветствию."""
"""Attachment-строка с логотипом Кибершколы БАЗА для прикрепления к приветствию."""
import os
logo_path = os.path.join(os.path.dirname(__file__), "help_img", "Logo.jpg")
info = self._upload_photo(peer_id, logo_path)
@@ -1264,15 +1221,6 @@ class VKBotApplication:
logger.error(f"Не удалось предзагрузить медиа: {e}")
def _handle_operator_chat(self, user_id: int, text: str, text_lower: str):
"""Поведение бота в режиме активного диалога с живым человеком."""
# Пользователь хочет выйти из диалога с оператором
@@ -1291,34 +1239,6 @@ class VKBotApplication:
logger.info(f"[OPERATOR MODE] Message from {user_id} bypasses bot: {text}")
self._forward_to_operator(user_id, text)
# ------------------------------------------
# СЦЕНАРИИ ПЕРЕДАЧИ ОПЕРАТОРУ И СВЯЗИ
# ------------------------------------------
# ------------------------------------------
# РАЗДЕЛ "КАРЬЕРА В ИКП" (НАЙМ ИГРОКОВ И СОТРУДНИКОВ)
# ------------------------------------------
# ----- Ветка игрока -----
# ----- Ветка сотрудника -----
def _forward_to_operator(self, user_id: int, text: str):
"""Пересылка сообщений от клиента всем операторам."""
self._notify_operators(f"💬 Сообщение от vk.com/id{user_id}:\n{text}")
@@ -1455,9 +1375,6 @@ class VKBotApplication:
self._send_admin_panel(user_id)
def _handle_admin_stats(self, user_id: int):
"""Формирует и отправляет админу сводную статистику по заявкам и диалогам."""
ls = db.get_lead_stats()
@@ -1554,7 +1471,6 @@ class VKBotApplication:
self._send_faq_admin(user_id)
def _handle_admin_broadcast(self, user_id: int, text: str):
"""Рассылка по подписчикам: 'рассылка <текст>' → предпросмотр → 'рассылка подтвердить' → отправка."""
# Отрезаем ключевое слово 'рассылка'
@@ -1670,7 +1586,7 @@ class VKBotApplication:
from datetime import datetime
ts = datetime.now().strftime("%d.%m.%Y %H:%M")
for admin_id in getattr(config, "ADMIN_IDS", []):
self.send_message(admin_id, f"✅ Бот ИКП запущен и на связи ({ts}).")
self.send_message(admin_id, f"✅ Бот Кибершколы БАЗА запущен и на связи ({ts}).")
except Exception as e:
logger.error(f"Не удалось отправить старт-пинг: {e}")