mirror of
https://github.com/EDeev/chatping_abobot.git
synced 2026-10-07 20:49:45 +03:00
Исправлены упоминания, экранирование и блокировка бота
- ответ на текст в неправильной раскладке упоминал автора ссылкой tg://user_id?id= — такой нет, упоминание не работало; теперь tg://user?id=; - имена и текст пользователей подставлялись в Markdown как есть: «_» или «*» в имени ломали отправку статистики, ивентов и упоминаний; - каждое голосовое в группе распознавалось через Google прямо в обработчике, и бот на это время не отвечал никому; распознавание, озвучка и запрос совета — в отдельном потоке, у запроса совета есть таймаут; - временные файлы голосовых и озвучки — во временной папке на запрос (раньше общий voice.ogg и файлы со случайным номером, остававшиеся при ошибке); - падения: упоминание двух имён, одно из которых — автор; сообщение из одних знаков препинания; глагол, который pymorphy3 не может поставить в прошедшее время; - script.py берёт соединения с базами из init.py, а не открывает вторые; - токен — из BOT_TOKEN.
This commit is contained in:
parent
e4786d8b68
commit
f5441bdde6
4 changed files with 165 additions and 145 deletions
10
code/base.py
10
code/base.py
|
|
@ -1,8 +1,10 @@
|
|||
# ДАННЫЕ БОТА
|
||||
TOKEN = "XXXXXXXXXX" # @chat_abobot
|
||||
DEBAG = "XXXXXXXXXX" # Технический чат
|
||||
import os
|
||||
|
||||
TEX_GROUP = "XXXXXXXXXX"
|
||||
# ДАННЫЕ БОТА (из переменных окружения)
|
||||
TOKEN = os.getenv("BOT_TOKEN", "XXXXXXXXXX") # @chat_abobot
|
||||
DEBAG = os.getenv("DEBUG_CHAT_ID", "") # Технический чат
|
||||
|
||||
TEX_GROUP = os.getenv("TECH_GROUP_ID", "")
|
||||
|
||||
# ОБРАЩЕНИЯ К ПОЛЬЗОВАТЕЛЯМ
|
||||
KILL_LIST = ["побить", "отмудохать", "избить", "уебать", "отметелить"]
|
||||
|
|
|
|||
238
code/handlers.py
238
code/handlers.py
|
|
@ -3,17 +3,60 @@ from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKe
|
|||
from aiogram.filters import Command, CommandStart
|
||||
from aiogram.enums import ContentType
|
||||
|
||||
import logging, random, requests, os, re
|
||||
import speech_recognition as sr
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
import requests
|
||||
import soundfile as sf
|
||||
import speech_recognition as sr
|
||||
from gtts import gTTS
|
||||
|
||||
from init import *
|
||||
from script import *
|
||||
import base
|
||||
from init import bot, db, du, dg, dm, morph, engl_dict
|
||||
from script import upd_stat, lang_form, notice, checker, translator, revers, md, plain
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
def recognize_file(oga_path):
|
||||
"""Голосовое (OGG/Opus) → текст через Google Web Speech. Синхронно — вызывается в отдельном потоке"""
|
||||
data, samplerate = sf.read(oga_path)
|
||||
wav_path = oga_path[:-4] + ".wav"
|
||||
sf.write(wav_path, data, samplerate)
|
||||
|
||||
r = sr.Recognizer()
|
||||
with sr.AudioFile(wav_path) as source:
|
||||
r.pause_threshold = 100
|
||||
audio = r.listen(source)
|
||||
return r.recognize_google(audio, language='ru-RU')
|
||||
|
||||
|
||||
async def recognize_voice(file_id):
|
||||
"""Распознавание без блокировки бота: раньше каждое голосовое в группе распознавалось прямо
|
||||
в обработчике, и бот на это время не отвечал никому. Файлы — во временной папке на запрос
|
||||
(раньше ../data/voices/<id>_<случайное число>, при ошибке файлы оставались)"""
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
oga = os.path.join(tmp, "voice.oga")
|
||||
file = await bot.get_file(file_id)
|
||||
await bot.download_file(file.file_path, oga)
|
||||
try:
|
||||
return await asyncio.to_thread(recognize_file, oga)
|
||||
except sr.UnknownValueError: # речь не разобрана
|
||||
return None
|
||||
except Exception:
|
||||
logging.exception("Ошибка распознавания голосового")
|
||||
return None
|
||||
|
||||
|
||||
def inflect_past(word):
|
||||
"""Глагол в прошедшем времени; если pymorphy3 не справился — как есть"""
|
||||
form = morph.parse(word.lower())[0].inflect({'past', 'sing', 'indc'})
|
||||
return form.word if form else word
|
||||
|
||||
# НОВЫЕ УЧАСТНИКИ ГРУППЫ
|
||||
@router.message(F.content_type == ContentType.NEW_CHAT_MEMBERS)
|
||||
async def notification(message: Message):
|
||||
|
|
@ -26,7 +69,7 @@ async def notification(message: Message):
|
|||
|
||||
await bot.send_message(
|
||||
message.chat.id,
|
||||
f'*Привет группа {message.chat.title}!*\n\n'
|
||||
f'*Привет группа {plain(message.chat.title)}!*\n\n'
|
||||
f'Все функции вы можете узнать по команде /help! Для того, чтобы '
|
||||
f'уведомления по имени и команда /all нормально функционировали, '
|
||||
f'необходимо чтобы каждый участник группы написал хотя бы одно '
|
||||
|
|
@ -147,47 +190,20 @@ async def every(message: Message):
|
|||
# КОМАНДА RECOGNIZE
|
||||
@router.message(Command("recognize"))
|
||||
async def recognise(message: Message):
|
||||
user_id = du.get_user_id(message.from_user.id)
|
||||
if not (message.reply_to_message and message.reply_to_message.voice):
|
||||
await message.reply("Ответьте этой командой на голосовое сообщение!")
|
||||
return
|
||||
|
||||
if message.reply_to_message and message.reply_to_message.voice:
|
||||
num = random.randint(1000, 9999)
|
||||
audio = f"../data/voices/{user_id}_{num}.oga"
|
||||
|
||||
file_id = message.reply_to_message.voice.file_id
|
||||
file = await bot.get_file(file_id)
|
||||
file_path = file.file_path
|
||||
await bot.download_file(file_path, audio)
|
||||
|
||||
data, samplerate = sf.read(audio)
|
||||
os.remove(audio)
|
||||
audio = f"../data/voices/{user_id}_{num}.wav"
|
||||
sf.write(audio, data, samplerate)
|
||||
|
||||
af = sr.AudioFile(audio)
|
||||
r = sr.Recognizer()
|
||||
with af as source:
|
||||
r.pause_threshold = 100
|
||||
source = r.listen(source)
|
||||
|
||||
try:
|
||||
mes = await bot.send_message(
|
||||
chat_id=message.chat.id,
|
||||
text="Распознавание.....",
|
||||
reply_to_message_id=message.reply_to_message.message_id
|
||||
)
|
||||
try:
|
||||
query = r.recognize_google(source, language='ru-RU')
|
||||
os.remove(audio)
|
||||
await mes.edit_text(f'*{message.reply_to_message.from_user.first_name} сказал(a)* "{query}"')
|
||||
except Exception:
|
||||
try:
|
||||
os.remove(audio)
|
||||
except Exception:
|
||||
pass
|
||||
await mes.edit_text("Распознать сообщение не удалось!")
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
pass
|
||||
mes = await bot.send_message(
|
||||
chat_id=message.chat.id,
|
||||
text="Распознавание.....",
|
||||
reply_to_message_id=message.reply_to_message.message_id
|
||||
)
|
||||
query = await recognize_voice(message.reply_to_message.voice.file_id)
|
||||
if query:
|
||||
await mes.edit_text(f'*{plain(message.reply_to_message.from_user.first_name)} сказал(a)* "{md(query)}"')
|
||||
else:
|
||||
await mes.edit_text("Распознать сообщение не удалось!")
|
||||
|
||||
# СТАТИСТИКА ГРУППЫ
|
||||
@router.message(Command('stat_group'))
|
||||
|
|
@ -231,7 +247,7 @@ async def stat_user(message: Message):
|
|||
name = name.word
|
||||
|
||||
await message.answer(
|
||||
text=f'*| СТАТИСТИКА {name.upper()} |*\n\n'
|
||||
text=f'*| СТАТИСТИКА {plain(name.upper())} |*\n\n'
|
||||
f'*- За всё время* / *За месяц -*\n'
|
||||
f'*>>* Сообщений в базе *[ {group[0]} / {month[0]} ]*\n\n'
|
||||
f'*>* Ответов *- [ {group[1]} / {month[1]} ]*\n'
|
||||
|
|
@ -263,9 +279,9 @@ async def update(message: Message):
|
|||
db.add_edit_user(user_id)
|
||||
|
||||
dg.update_name(user_id, group_id, name)
|
||||
await message.reply(f'{name.title()}, ваше имя было успешно изменено)')
|
||||
await message.reply(f'{md(name.title())}, ваше имя было успешно изменено)')
|
||||
else:
|
||||
await message.reply(f'{message.from_user.first_name.lower().title()}, такое имя уже присутствует в чате!')
|
||||
await message.reply(f'{md(message.from_user.first_name.lower().title())}, такое имя уже присутствует в чате!')
|
||||
else:
|
||||
await message.reply('Вы не правильно ввели имя! Имя должно быть '
|
||||
'из одного слова и идти сразу после команды!')
|
||||
|
|
@ -282,9 +298,9 @@ async def update_return(message: Message):
|
|||
db.del_edit_user(user_id)
|
||||
dg.update_name(user_id, group_id, name)
|
||||
|
||||
await message.reply(f'{name.title()}, вы успешно вернулись к динамическому изменению имени)')
|
||||
await message.reply(f'{md(name.title())}, вы успешно вернулись к динамическому изменению имени)')
|
||||
else:
|
||||
await message.reply(f'{name.title()}, вы не устанавливали постоянное имя!')
|
||||
await message.reply(f'{md(name.title())}, вы не устанавливали постоянное имя!')
|
||||
|
||||
# ВКЛЮЧЕНИЕ ТЕКСТОВЫХ ИВЕНТОВ
|
||||
@router.message(Command('start_bot'))
|
||||
|
|
@ -361,47 +377,21 @@ async def voice(message: Message):
|
|||
if message.chat.id < 0:
|
||||
upd_stat(message.from_user.id, message.chat.id, 7, message.from_user.first_name, True)
|
||||
|
||||
if message.voice and message.chat.id < 0:
|
||||
if message.voice.duration <= 60:
|
||||
user_id = du.get_user_id(message.from_user.id)
|
||||
|
||||
num = random.randint(1000, 9999)
|
||||
audio = f"../data/voices/{user_id}_{num}.oga"
|
||||
# упоминание по имени, произнесённому в голосовом
|
||||
if message.voice and message.chat.id < 0 and message.voice.duration <= 60:
|
||||
query = await recognize_voice(message.voice.file_id)
|
||||
if not query:
|
||||
return
|
||||
|
||||
file_id = message.voice.file_id
|
||||
file = await bot.get_file(file_id)
|
||||
file_path = file.file_path
|
||||
await bot.download_file(file_path, audio)
|
||||
group_id = du.get_group_id(message.chat.id)
|
||||
unsigned = re.sub(r'[^\w\s]', '', query.lower()).split()
|
||||
first_form = [morph.parse(i)[0].normal_form for i in unsigned]
|
||||
chat_names = [x[0] for x in dg.all_names(group_id)]
|
||||
names = [_ for _ in first_form if _ in chat_names]
|
||||
|
||||
data, samplerate = sf.read(audio)
|
||||
os.remove(audio)
|
||||
audio = f"../data/voices/{user_id}_{num}.wav"
|
||||
sf.write(audio, data, samplerate)
|
||||
|
||||
af = sr.AudioFile(audio)
|
||||
r = sr.Recognizer()
|
||||
with af as source:
|
||||
r.pause_threshold = 100
|
||||
source = r.listen(source)
|
||||
|
||||
try:
|
||||
query = r.recognize_google(source, language='ru-RU')
|
||||
os.remove(audio)
|
||||
|
||||
group_id = message.chat.id
|
||||
unsigned = re.sub(r'[^\w\s]', '', query.lower()).split()
|
||||
first_form = [morph.parse(i)[0].normal_form for i in unsigned]
|
||||
names = [_ for _ in first_form if _ in list(map(lambda x: x[0], dg.all_names(du.get_group_id(group_id))))]
|
||||
|
||||
if names:
|
||||
await message.reply(notice(names, False, du.get_group_id(group_id), message.from_user.id))
|
||||
return
|
||||
|
||||
except Exception:
|
||||
try:
|
||||
os.remove(audio)
|
||||
except Exception:
|
||||
pass
|
||||
text = notice(names, False, group_id, message.from_user.id) if names else None
|
||||
if text:
|
||||
await message.reply(text)
|
||||
|
||||
# СТИКЕРЫ
|
||||
@router.message(F.content_type == ContentType.STICKER)
|
||||
|
|
@ -431,7 +421,8 @@ async def send_events(message: Message):
|
|||
if message.chat.id < 0:
|
||||
names = [_ for _ in first_form if _ in list(map(lambda x: x[0], dg.all_names(du.get_group_id(group_id))))]
|
||||
|
||||
if len(words) >= 2:
|
||||
# сообщение только из знаков препинания: дальше нужны слова (раньше — IndexError на unsigned[0])
|
||||
if len(words) >= 2 and unsigned:
|
||||
# ПОЛЕЗНЫЕ ФУНКЦИИ
|
||||
if len(words) == 5 and "число от" in low_mes:
|
||||
try:
|
||||
|
|
@ -445,29 +436,32 @@ async def send_events(message: Message):
|
|||
|
||||
if unsigned[0] == 'переведи':
|
||||
if "переведи - " in low_mes:
|
||||
await message.answer(lang_form([words[_] for _ in range(len(words)) if _ > 1]))
|
||||
elif f"переведи ({unsigned[1]}) - " in low_mes:
|
||||
await message.answer(md(lang_form([words[_] for _ in range(len(words)) if _ > 1])))
|
||||
elif len(unsigned) > 1 and f"переведи ({unsigned[1]}) - " in low_mes:
|
||||
if len(unsigned[1]) == 1:
|
||||
await message.answer(lang_form([words[_] for _ in range(len(words)) if _ > 2], unsigned[1]))
|
||||
await message.answer(md(lang_form([words[_] for _ in range(len(words)) if _ > 2], unsigned[1])))
|
||||
return
|
||||
|
||||
if unsigned[0] == 'переверни':
|
||||
if "переверни - " in low_mes:
|
||||
await message.answer(revers(message.text[12:], True))
|
||||
await message.answer(md(revers(message.text[12:], True)))
|
||||
elif "переверни полностью - " in low_mes:
|
||||
await message.answer(revers(message.text[22:], False))
|
||||
await message.answer(md(revers(message.text[22:], False)))
|
||||
return
|
||||
|
||||
if unsigned[0] == 'озвучь' and "озвучь - " in low_mes:
|
||||
text_to_voice = message.text[9:]
|
||||
tts = gTTS(text_to_voice, lang='ru')
|
||||
tts.save('../data/voices/voice.ogg')
|
||||
await bot.send_voice(
|
||||
chat_id=group_id,
|
||||
voice=FSInputFile('../data/voices/voice.ogg'),
|
||||
caption=f"*{text_to_voice}*"
|
||||
)
|
||||
os.remove('../data/voices/voice.ogg')
|
||||
# синтез — в отдельном потоке и во временный файл (раньше общий voice.ogg:
|
||||
# одновременные запросы перезаписывали друг друга)
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = os.path.join(tmp, "voice.mp3")
|
||||
try:
|
||||
await asyncio.to_thread(gTTS(text_to_voice, lang='ru').save, path)
|
||||
except Exception:
|
||||
logging.exception("gTTS")
|
||||
await message.reply("Озвучить не получилось, попробуйте позже")
|
||||
return
|
||||
await bot.send_voice(chat_id=group_id, voice=FSInputFile(path), caption=f"*{plain(text_to_voice)}*")
|
||||
return
|
||||
|
||||
# РАНДОМ ИВЕНТЫ
|
||||
|
|
@ -477,14 +471,14 @@ async def send_events(message: Message):
|
|||
if random.randint(0, 1) == 0:
|
||||
await message.answer_photo(
|
||||
photo=FSInputFile(f"../data/fight/({random.randint(1, 8)}).jpg"),
|
||||
caption=f"{message.from_user.first_name}, ты был унижен {text.title()}"
|
||||
caption=f"{md(message.from_user.first_name)}, ты был унижен {md(text.title())}"
|
||||
f", с помощью {base.VAR_LOSE[random.randint(0, 3)]}"
|
||||
)
|
||||
else:
|
||||
await message.answer_photo(
|
||||
photo=FSInputFile(f"../data/fight/({random.randint(1, 8)}).jpg"),
|
||||
caption=f"{message.from_user.first_name}, ты победил в драке "
|
||||
f"с {text.title()}, {base.VAR_WIN[random.randint(0, 1)]}"
|
||||
caption=f"{md(message.from_user.first_name)}, ты победил в драке "
|
||||
f"с {md(text.title())}, {base.VAR_WIN[random.randint(0, 1)]}"
|
||||
)
|
||||
|
||||
# ИВЕНТ ВЗАИМОДЕЙСТВИЯ
|
||||
|
|
@ -493,11 +487,10 @@ async def send_events(message: Message):
|
|||
lst = [words[i] for i in range(len(words)) if i != 0]
|
||||
text = " ".join(lst)
|
||||
|
||||
slv = morph.parse(words[0].lower())[0]
|
||||
await message.answer_photo(
|
||||
photo=FSInputFile(f"../data/tmok/({random.randint(1, 4)}).jpg"),
|
||||
caption=f"{message.from_user.first_name} "
|
||||
f"{slv.inflect({'past', 'sing', 'indc'}).word} {text}"
|
||||
caption=f"{md(message.from_user.first_name)} "
|
||||
f"{inflect_past(words[0])} {md(text)}"
|
||||
)
|
||||
|
||||
for word in base.KILL_LIST:
|
||||
|
|
@ -505,36 +498,37 @@ async def send_events(message: Message):
|
|||
lst = [words[i] for i in range(len(words)) if i != 0]
|
||||
text = " ".join(lst)
|
||||
|
||||
slv = morph.parse(words[0].lower())[0]
|
||||
await message.answer_photo(
|
||||
photo=FSInputFile(f"../data/kill/({random.randint(1, 6)}).jpg"),
|
||||
caption=f"{message.from_user.first_name} "
|
||||
f"{slv.inflect({'past', 'sing', 'indc'}).word} {text}"
|
||||
caption=f"{md(message.from_user.first_name)} "
|
||||
f"{inflect_past(words[0])} {md(text)}"
|
||||
)
|
||||
|
||||
if (unsigned[0] in base.QUAT_LIST[0] and
|
||||
if (len(unsigned) >= 3 and
|
||||
unsigned[0] in base.QUAT_LIST[0] and
|
||||
unsigned[1] in base.QUAT_LIST[1] and
|
||||
unsigned[2] in base.QUAT_LIST[2]):
|
||||
try:
|
||||
word = requests.get('http://fucking-great-advice.ru/api/random').json()
|
||||
await message.reply(word["text"])
|
||||
except:
|
||||
pass
|
||||
# без таймаута и в обработчике запрос мог надолго заморозить бота
|
||||
resp = await asyncio.to_thread(requests.get, 'http://fucking-great-advice.ru/api/random', timeout=5)
|
||||
await message.reply(md(resp.json()["text"]))
|
||||
except Exception:
|
||||
logging.warning("Сервис советов недоступен")
|
||||
return
|
||||
|
||||
if message.chat.id < 0:
|
||||
# УПОМИНАНИЯ ПО ИМЕНАМ
|
||||
if names:
|
||||
try:
|
||||
await message.reply(notice(names, False, du.get_group_id(group_id), user_id))
|
||||
except Exception:
|
||||
pass
|
||||
text = notice(names, False, du.get_group_id(group_id), user_id)
|
||||
if text:
|
||||
await message.reply(text)
|
||||
return
|
||||
|
||||
# ПЕРЕВОДЧИК СЛОВ
|
||||
if (checker([i for i in low_mes], words, group_id, user_id, name.lower()) == len(low_mes) and
|
||||
not any([engl_dict.check(i) for i in unsigned if len(i) > 1])):
|
||||
await message.reply(
|
||||
f"[{message.from_user.first_name}](tg://user_id?id={user_id}) *>* {translator(words)}"
|
||||
# раньше tg://user_id?id= — такой ссылки нет, упоминание не работало
|
||||
f"[{plain(message.from_user.first_name)}](tg://user?id={user_id}) *>* {md(translator(words))}"
|
||||
)
|
||||
return
|
||||
|
|
@ -4,7 +4,11 @@ from aiogram.fsm.storage.memory import MemoryStorage
|
|||
from aiogram.client.bot import DefaultBotProperties
|
||||
|
||||
|
||||
import base, enchant, pymorphy3
|
||||
import os
|
||||
|
||||
import base
|
||||
import enchant
|
||||
import pymorphy3
|
||||
|
||||
bot = Bot(token=base.TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.MARKDOWN))
|
||||
dp = Dispatcher(storage=MemoryStorage())
|
||||
|
|
@ -15,6 +19,7 @@ engl_dict = enchant.Dict("en_US")
|
|||
|
||||
import sql
|
||||
|
||||
os.makedirs('../db', exist_ok=True)
|
||||
db = sql.Base('../db/base.db')
|
||||
du = sql.User('../db/users.db')
|
||||
dg = sql.Group('../db/groups.db')
|
||||
|
|
|
|||
|
|
@ -1,12 +1,28 @@
|
|||
from base import ERR, ERR_, TRU, TRU_, ALB
|
||||
import re
|
||||
from string import digits, punctuation
|
||||
import re, sql
|
||||
|
||||
# инициализируем соединение с БД
|
||||
db = sql.Base('../db/base.db')
|
||||
du = sql.User('../db/users.db')
|
||||
dg = sql.Group('../db/groups.db')
|
||||
dm = sql.Month('../db/month.db')
|
||||
from base import ERR, ERR_, TRU, TRU_, ALB
|
||||
# одни и те же соединения с базами, что и у обработчиков (раньше здесь открывались вторые)
|
||||
from init import db, du, dg, dm
|
||||
|
||||
MD_SPECIAL = "_*`["
|
||||
|
||||
|
||||
def md(text):
|
||||
"""Экранирование для Markdown вне разметки: «_» или «*» в имени или тексте иначе ломают отправку"""
|
||||
return "".join("\\" + ch if ch in MD_SPECIAL else ch for ch in str(text))
|
||||
|
||||
|
||||
def plain(text):
|
||||
"""Текст внутри *жирного* или [ссылки]: экранирование там не работает, спецсимволы убираются"""
|
||||
return "".join(ch for ch in str(text) if ch not in MD_SPECIAL + "]")
|
||||
|
||||
|
||||
def join_names(items):
|
||||
"""«а», «а и б», «а, б и в»"""
|
||||
if len(items) <= 1:
|
||||
return "".join(items)
|
||||
return ", ".join(items[:-1]) + " и " + items[-1]
|
||||
|
||||
|
||||
def upd_stat(user_id, group_id, var_id, name, mes=False):
|
||||
|
|
@ -63,23 +79,26 @@ def notice(name, all_users, group_id, author):
|
|||
|
||||
if all_users:
|
||||
name = dg.user_name(name, group_id)
|
||||
usr = [f"[{names[i].title()}](tg://user?id={str(ids[i])})" for i in range(len(names)) if names[i] != name.lower()]
|
||||
usr.append(f'{usr[-2]} и {usr[-1]}')
|
||||
del usr[-2], usr[-2]
|
||||
return f'{", ".join(usr)} вас вызывает {name.title()}'
|
||||
usr = [f"[{plain(names[i].title())}](tg://user?id={str(ids[i])})" for i in range(len(names)) if names[i] != name.lower()]
|
||||
if len(usr) < 2:
|
||||
raise ValueError("в группе меньше трёх участников")
|
||||
return f'{join_names(usr)} вас вызывает {md(name.title())}'
|
||||
else:
|
||||
no_copy = []
|
||||
for i in name:
|
||||
if i not in no_copy:
|
||||
no_copy.append(i)
|
||||
|
||||
if len(no_copy) > 1: # ПЕРЕПИСАТЬ КОД ГАВНА КУСОК
|
||||
usr = [f"[{_.title()}](tg://user?id={str(ids[names.index(_)])})" for _ in no_copy if int(author) != ids[names.index(_)]]
|
||||
usr.append(f'{usr[-2]} и {usr[-1]}')
|
||||
del usr[-2], usr[-2]
|
||||
return f"{', '.join(usr)} вас упомянули)"
|
||||
if len(no_copy) > 1:
|
||||
# раньше при двух именах, одно из которых — автор, падало на usr[-2]
|
||||
usr = [f"[{plain(_.title())}](tg://user?id={str(ids[names.index(_)])})" for _ in no_copy if int(author) != ids[names.index(_)]]
|
||||
if len(usr) > 1:
|
||||
return f"{join_names(usr)} вас упомянули)"
|
||||
if usr:
|
||||
return f"{usr[0]}, тебя упомянули)"
|
||||
return None
|
||||
else:
|
||||
usr = f"[{no_copy[0].title()}](tg://user?id={str(ids[names.index(no_copy[0])])})"
|
||||
usr = f"[{plain(no_copy[0].title())}](tg://user?id={str(ids[names.index(no_copy[0])])})"
|
||||
return f"{usr}, тебя упомянули)"
|
||||
|
||||
|
||||
|
|
@ -142,7 +161,7 @@ def revers(message, var):
|
|||
pct.append(''.join(pnc))
|
||||
pnc = []
|
||||
|
||||
wrd, rev, lst, txt = no_pct.split(), [], [], []
|
||||
wrd, rev, txt = no_pct.split(), [], []
|
||||
for i in wrd:
|
||||
word, up, itg = [i[-1 - l].lower() for l in range(len(i))], [], []
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue