1
0
Fork 0
forked from zovos/bot_tg

Merge pull request '/watch' (#30) from SUDOZOVCHIK/bot_tg:main into main

Reviewed-on: zovos/bot_tg#30
This commit is contained in:
q 2026-04-23 10:08:24 +00:00
commit 41b5c001dc
5 changed files with 19 additions and 4 deletions

0
.codex Normal file
View file

2
.env
View file

@ -1,4 +1,4 @@
BOT_TOKEN=8156642467:AAEalekr-33lFS3tTTkXIEiaawfDzR6lBJc BOT_TOKEN=8505447901:AAHFkaDG0fT0tAixuJ4QP91IwMgO6cZndRM #8156642467:AAEalekr-33lFS3tTTkXIEiaawfDzR6lBJc
TZ=Europe/Moscow TZ=Europe/Moscow
ODDS_API_KEY=c29bc26dee8aa9d95a5ce8d14ea63923 ODDS_API_KEY=c29bc26dee8aa9d95a5ce8d14ea63923
LLAMA_API_URL=https://mirror.porno4free.ru/zovos-ai/ LLAMA_API_URL=https://mirror.porno4free.ru/zovos-ai/

View file

@ -10,6 +10,7 @@ import re
import sqlite3 import sqlite3
import time import time
from io import BytesIO from io import BytesIO
import re
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@ -237,6 +238,7 @@ AUTONOMOUS_SIGNAL_RE = re.compile(
re.IGNORECASE, re.IGNORECASE,
) )
LETTER_RE = re.compile(r"[A-Za-zА-Яа-яЁё0-9]") LETTER_RE = re.compile(r"[A-Za-zА-Яа-яЁё0-9]")
WATCH_COMMAND_RE = re.compile(r"^/watch(?:@[A-Za-z0-9_]+)?(?:\s+(.*))?$", re.IGNORECASE | re.DOTALL)
_reply_lock = asyncio.Lock() _reply_lock = asyncio.Lock()
_summary_lock = asyncio.Lock() _summary_lock = asyncio.Lock()
@ -903,12 +905,13 @@ async def handle_photo_message(message: Message) -> bool:
is_image_document = bool(message.document and (message.document.mime_type or "").startswith("image/")) is_image_document = bool(message.document and (message.document.mime_type or "").startswith("image/"))
if not (message.photo or is_image_document) or not message.from_user or message.from_user.is_bot: if not (message.photo or is_image_document) or not message.from_user or message.from_user.is_bot:
return False return False
if message.caption and message.caption.startswith("/"): watch_match = WATCH_COMMAND_RE.match((message.caption or "").strip())
if not watch_match:
return False return False
chat_id = message.chat.id chat_id = message.chat.id
user_name = message.from_user.first_name or "кент" user_name = message.from_user.first_name or "кент"
caption = _clean_text(message.caption or "") caption = _clean_text(watch_match.group(1) or "")
logger.warning( logger.warning(
"Received image message for analysis. chat_id=%s user=%s has_photo=%s has_image_document=%s caption=%s", "Received image message for analysis. chat_id=%s user=%s has_photo=%s has_image_document=%s caption=%s",

View file

@ -18,6 +18,7 @@ CAPTIONS = [
"Шо ты блять псюнчик решил свой подергать?", "Шо ты блять псюнчик решил свой подергать?",
"Решил подрочить сука?", "Решил подрочить сука?",
"гнойный писюн у тебя кнч, да", "гнойный писюн у тебя кнч, да",
"Ух нихуя, это ШПАЧИХА!?",
] ]
LESAINT_POSTS_API = "https://lesaintdesseins.fr/wp-json/wp/v2/posts" LESAINT_POSTS_API = "https://lesaintdesseins.fr/wp-json/wp/v2/posts"

13
main.py
View file

@ -58,6 +58,12 @@ def _is_supported_image_message(message: Message) -> bool:
) )
) )
def _is_watch_image_message(message: Message) -> bool:
if not _is_supported_image_message(message):
return False
caption = (message.caption or "").strip()
return bool(re.match(r"^/watch(?:@[A-Za-z0-9_]+)?(?:\s|$)", caption, flags=re.IGNORECASE))
async def handle_unmatched_message_debug(message: Message): async def handle_unmatched_message_debug(message: Message):
logger.warning( logger.warning(
@ -1199,6 +1205,10 @@ async def handle_keywords(message: Message):
chat_id = message.chat.id chat_id = message.chat.id
user_name = (message.from_user.first_name or "кент") if message.from_user else "кент" user_name = (message.from_user.first_name or "кент") if message.from_user else "кент"
# /ebalnik должен глушить все авто-реакции в чате, включая медиа/фото-ветки.
if chat_id in _autoreply_disabled_chats:
return
if any(re.search(rf'\b{word}\b', text_lower) for word in config.KEYWORDS): if any(re.search(rf'\b{word}\b', text_lower) for word in config.KEYWORDS):
audio_path = config.BASE_DIR / "maket" / "Radiohead - Creep.mp3" audio_path = config.BASE_DIR / "maket" / "Radiohead - Creep.mp3"
if audio_path.exists(): if audio_path.exists():
@ -1456,7 +1466,7 @@ def main():
dp.message.register(handle_gen_mem, Command("gen_mem")) dp.message.register(handle_gen_mem, Command("gen_mem"))
dp.message.register(handle_uwu_cmd, Command("uwu")) dp.message.register(handle_uwu_cmd, Command("uwu"))
dp.message.register(handle_nude_cmd, Command("nude")) dp.message.register(handle_nude_cmd, Command("nude"))
dp.message.register(handle_photo_message, _is_supported_image_message) dp.message.register(handle_photo_message, _is_watch_image_message)
dp.message.register(handle_keywords, F.text) dp.message.register(handle_keywords, F.text)
dp.message.register(handle_unmatched_message_debug) dp.message.register(handle_unmatched_message_debug)
@ -1477,6 +1487,7 @@ def main():
BotCommand(command="fetch", description="alias для /prices"), BotCommand(command="fetch", description="alias для /prices"),
BotCommand(command="zvetok", description="Цветянский бля"), BotCommand(command="zvetok", description="Цветянский бля"),
BotCommand(command="talk", description="Побазарить"), BotCommand(command="talk", description="Побазарить"),
BotCommand(command="watch", description="Коммент фото по подписи /watch"),
BotCommand(command="ebalnik", description="вкл/выкл автответов"), BotCommand(command="ebalnik", description="вкл/выкл автответов"),
BotCommand(command="penis_casino", description="казино на размер"), BotCommand(command="penis_casino", description="казино на размер"),
BotCommand(command="gadanie", description="гадание на фене"), BotCommand(command="gadanie", description="гадание на фене"),