You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Fox-V3/chatter/chat.py

158 lines
4.9 KiB

import asyncio
7 years ago
from datetime import datetime, timedelta
import discord
from discord.ext import commands
from redbot.core import Config
7 years ago
from chatter.chatterbot import ChatBot
from chatter.chatterbot.trainers import ListTrainer
7 years ago
class Chatter:
"""
This cog trains a chatbot that will talk like members of your Guild
"""
def __init__(self, bot):
self.bot = bot
self.config = Config.get_conf(self, identifier=6710497116116101114)
default_global = {}
7 years ago
default_guild = {
"whitelist": None,
"days": 1
7 years ago
}
self.chatbot = ChatBot(
"ChatterBot",
7 years ago
storage_adapter='chatter.chatterbot.storage.SQLStorageAdapter',
7 years ago
database='./database.sqlite3'
)
7 years ago
self.chatbot.set_trainer(ListTrainer)
self.config.register_global(**default_global)
self.config.register_guild(**default_guild)
7 years ago
7 years ago
self.loop = asyncio.get_event_loop()
7 years ago
async def _get_conversation(self, ctx, in_channel: discord.TextChannel = None):
"""
7 years ago
Compiles all conversation in the Guild this bot can get it's hands on
Currently takes a stupid long time
Returns a list of text
"""
out = []
7 years ago
after = datetime.today() - timedelta(days=(await self.config.guild(ctx.guild).days()))
7 years ago
for channel in ctx.guild.text_channels:
7 years ago
if in_channel:
channel = in_channel
await ctx.send("Gathering {}".format(channel.mention))
user = None
try:
7 years ago
async for message in channel.history(limit=None, reverse=True, after=after):
if user == message.author:
7 years ago
out[-1] += "\n" + message.clean_content
else:
user = message.author
out.append(message.clean_content)
except discord.Forbidden:
pass
except discord.HTTPException:
pass
7 years ago
7 years ago
if in_channel:
break
7 years ago
return out
7 years ago
7 years ago
def _train(self, data):
try:
self.chatbot.train(data)
except:
return False
return True
7 years ago
@commands.group()
7 years ago
async def chatter(self, ctx: RedContext):
"""
Base command for this cog. Check help for the commands list.
"""
if ctx.invoked_subcommand is None:
await ctx.send_help()
7 years ago
7 years ago
@chatter.command()
7 years ago
async def age(self, ctx: RedContext, days: int):
7 years ago
"""
Sets the number of days to look back
Will train on 1 day otherwise
"""
7 years ago
7 years ago
await self.config.guild(ctx.guild).days.set(days)
await ctx.send("Success")
7 years ago
7 years ago
@chatter.command()
async def backup(self, ctx, backupname):
"""
Backup your training data to a json for later use
"""
7 years ago
await ctx.send("Backing up data, this may take a while")
future = await self.loop.run_in_executor(None, self.chatbot.trainer.export_for_training, './{}.json'.format(backupname))
7 years ago
7 years ago
if future:
await ctx.send("Backup successful!")
else:
await ctx.send("Error occurred :(")
7 years ago
7 years ago
@chatter.command()
7 years ago
async def train(self, ctx: commands.Context, channel: discord.TextChannel):
"""
Trains the bot based on language in this guild
"""
7 years ago
7 years ago
conversation = await self._get_conversation(ctx, channel)
7 years ago
if not conversation:
await ctx.send("Failed to gather training data")
return
7 years ago
7 years ago
await ctx.send("Gather successful! Training begins now\n(**This will take a long time, be patient**)")
7 years ago
embed = discord.Embed(title="Loading")
7 years ago
embed.set_image(url="http://www.loop.universaleverything.com/animations/1295.gif")
7 years ago
temp_message = await ctx.send(embed=embed)
7 years ago
future = await self.loop.run_in_executor(None, self._train, conversation)
7 years ago
7 years ago
try:
await temp_message.delete()
except:
pass
7 years ago
7 years ago
if future:
7 years ago
await ctx.send("Training successful!")
else:
7 years ago
await ctx.send("Error occurred :(")
7 years ago
async def on_message(self, message):
7 years ago
"""
Credit to https://github.com/Twentysix26/26-Cogs/blob/master/cleverbot/cleverbot.py
for on_message recognition of @bot
"""
author = message.author
channel = message.channel
7 years ago
7 years ago
if message.author.id != self.bot.user.id:
to_strip = "@" + author.guild.me.display_name + " "
text = message.clean_content
if not text.startswith(to_strip):
return
text = text.replace(to_strip, "", 1)
async with channel.typing():
7 years ago
future = await self.loop.run_in_executor(None, self.chatbot.get_response, text)
7 years ago
if future:
await channel.send(str(future))
else:
await channel.send(':thinking:')