This repository has been archived on 2025-01-28. You can view files and clone it, but cannot push or open issues or pull requests.
natsuko/cogs/talk_module.py
2023-05-11 13:14:06 +03:00

213 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
import re
from random import randint, choice
import Levenshtein
import discord
from discord.ext import commands
from discord import app_commands
from discord.app_commands import locale_str as _T
from cogs.checks import is_secret
from bot import db
meow = ['Мяу', '?', ':Р', ':3', '^___^', '(o・ω・o)', '(≧◡≦)']
vase_error = ['По техническим причинам падение вазы невозможно по причинам '
'отсутствия этих самых ваз\n'
'Обратитесь к специализированному сотруднику для пополнения '
'ресурсов. __Спасибо за понимание__',
'Сотрудники Лаборатории Aperture Science обеспокоены частым разрушением '
'важного и дорогого лабораторного оборудования, из-за чего на это '
'был установлен запрет\n'
'Обратитесь к специализированному сотруднику для снятия '
'запрета. __Спасибо за понимание__']
class TalkModule(commands.Cog, name="Общение"):
"""Работа с разговорным модулем кота"""
def __init__(self, bot):
self.bot = bot
self.unknown_phrases = []
if os.path.exists('speak_data.json'):
with open('speak_data.json', 'r') as f:
self.data = json.load(f)
else:
self.data = [[['привет', 'здаров', 'приветушки'], ['Привет', 'Дароу', 'Мяу', ':)']]]
@commands.Cog.listener()
async def on_message(self, message):
if db.guild_settings.find_one({'id': message.guild.id}) is None: return
if message.author.name != 'Котейка' and db.guild_settings.find_one({"id": message.guild.id})['aux']['talk']:
try:
pattern = re.compile(
r'(^|[^а-яА-ЯЁёa-zA-Z]|[,.])((ко(т((ейк)|(ик)|(ан)|([её]нок)|(я[рт]))?|(шак)))([иаыуэя]|(ов)|(ом))?)([^а-яА-ЯЁёa-zA-Z]|$)')
if pattern.search(message.content.lower()):
rand_meow = meow[randint(0, len(meow) - 1)]
if False: pass # rand_meow == '\*Роняет вазу\*':
# try:
# if self.data['vase'] <= 0:
# await message.channel.send(vase_error[randint(0, len(vase_error) - 1)])
# self.data['vase'] = 0
# else:
# await message.channel.send(rand_meow)
# self.data['vase'] -= 1
# except IndexError:
# self.data['vasa'] = 10
else:
sended = False
max_con = 0
right_answer = ''
i = pattern.search(message.content.lower()).group(0)
text = message.content.lower().replace(i, '')
if text.startswith(','):
text = text[1:]
if text.startswith(' '):
text = text[1:]
text = text.replace('<@>', '')
if len(text) >= 3:
for group in self.data:
# print(group)
for known_pharase in group[0]:
# print(known_pharase)
con = Levenshtein.ratio(known_pharase, text)
# print(con)
if con >= 0.65:
if max_con < con:
max_con = con
right_answer = choice(self.data[self.data.index(group)][1])
sended = True
if not sended:
await message.channel.send(choice(meow))
text = message.content.lower().replace(i, '')
if text.startswith(','):
text = text[1:]
if text.startswith(' '):
text = text[1:]
text = text.replace('<@>', '')
if len(text) >= 3:
self.unknown_phrases.append(text)
else:
await message.reply(right_answer)
except Exception as e:
print(repr(e))
@commands.command(brief="Выводит список неизвестных фраз",
help="Если кот найдет сообщение, в котором содержится слово \"кот\" (неважно какого "
"вида/числа/рода) он попытается на него ответить. Если в базе нет нужного ответа, то кот"
"положит сообщение в этот список")
@commands.check(is_secret)
async def up(self, ctx):
if len(self.unknown_phrases) <= 10:
e = discord.Embed(title="Неизвестные фразы:",
description='\n'.join([f"{self.unknown_phrases.index(el) + 1}. {el}"
for el in self.unknown_phrases]))
else:
e = discord.Embed(title="Неизвестные фразы:",
description='\n'.join(
[f"{len(self.unknown_phrases) - 10 + i}. {self.unknown_phrases[-10 + i]}"
for i in range(10)]))
await ctx.send(embed=e)
@commands.command(brief="Вносит фразу в список неизвестних для дальнейшего обучения")
@commands.check(is_secret)
async def down(self, ctx, phrase):
self.unknown_phrases.append(phrase)
@commands.command(brief="Обучение коты разговору с жалкими человеками",
help="На одну неизвестную фразу может приходиться от одного до нескольких ответов.\n"
"Кот будет по одному писать неизвестную фразу и ждать минуту\n"
"Для ввода нескольких ответов напиши `+`, а потом по одной пиши ответы. После ввода всех"
"ответов напиши `stop`\n"
"`cancel` для отмены обучения\n"
"`next` для пропуска и удаления вопроса из списка\n"
"`pass` для пропуска \"на потом\"\n")
@commands.check(is_secret)
async def teach(self, ctx):
t_author = ctx.message.author
t_channel = ctx.message.channel
pharases = tuple(self.unknown_phrases)
def check(m):
return (m.author == t_author) and (m.channel == t_channel)
for phrase in phrases:
await ctx.send(phrase)
try:
answer = await self.bot.wait_for('message', timeout=60.0, check=check)
except:
await ctx.send("Обучение прервано. Сработал таймаут на минуту")
if answer.content.lower() == 'cancel':
break
elif answer.content.lower() == 'next':
del self.unknown_phrases[self.unknown_phrases.index(phrase)]
continue
elif answer.content.lower() == 'pass':
continue
elif answer.content.lower() == '+':
await ctx.send('OK')
id = len(self.data)
self.data.append([[phrase], []])
while 1:
answerInCycle = await self.bot.wait_for('message', timeout=60.0, check=check)
if answerInCycle.content.lower() == 'cancel':
break
elif answerInCycle.content.lower() == 'stop':
del self.unknown_phrases[self.unknown_phrases.index(phrase)]
break
else:
self.data[id][1].append(answerInCycle.content.replace("\'", "\\'"))
with open('speak_data.json', 'w') as f:
json.dump(self.data, f)
await ctx.send('Сохранено')
continue
else:
self.data.append([[phrase], [answer.content]])
with open('speak_data.json', 'w') as f:
json.dump(self.data, f)
await ctx.send('Сохранено')
await ctx.send('Неизвестных фраз нет')
@commands.command(name='del', brief="Удаляет элемент разговорного-БД кота")
@commands.check(is_secret)
async def del_f(self, ctx, q, *, a: int = None):
if a is None:
del self.data[q]
else:
del self.data[q][a]
with open('speak_data.json', 'w') as f:
json.dump(self.data, f)
await ctx.send('Сохранено')
@commands.command(brief="Выводит сайт с базой данных кота")
@commands.check(is_secret)
async def knowledge(self, ctx):
await ctx.send('https://miyakobot.ru')
@app_commands.command()
async def meow(self, inter):
await inter.response.send_message("Meow")
@app_commands.command(name=_T("cats"))
async def cats(self, inter):
await inter.response.send_message(_T("are cutes"))
async def setup(bot):
await bot.add_cog(TalkModule(bot))