diff --git a/README.md b/README.md index 44ef0f8..1a807de 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,21 @@ Cog Function -| Name | Status | Description +| Name | Status | Description (Click to see full status) | --- | --- | --- | -| ccrole | **Beta** | Create custom commands that also assign roles | -| chatter | **Alpha** | Chat-bot trained to talk like your guild -| fight | **Incomplete** | Organize bracket tournaments within discord | -| flag | **Beta** | Create temporary marks on users that expire after specified time | -| hangman | **Incomplete** | Play a game of hangman | -| immortal | **Private** | Cog designed for a specific server, not recommended to install | -| leaver | **Incomplete** | Send a message in a channel when a user leaves the server | -| reactrestrict | **Alpha** | Removes reactions by role per channel | -| stealemoji | **Alpha** | Steals any custom emoji it sees | -| werewolf | **Incomplete** | Play the classic party game Werewolf within discord | +| ccrole | **Beta** |
Create custom commands that also assign rolesMay have some bugs, please create an issue if you find any
| +| chatter | **Alpha** |
Chat-bot trained to talk like your guildMissing some key features, but currently functional
| +| fight | **Incomplete** |
Organize bracket tournaments within discordStill in-progress, a massive project
| +| flag | **Incomplete** |
Create temporary marks on users that expire after specified timeNot yet ported to v3
| +| hangman | **Alpha** |
Play a game of hangmanSome visual glitches and needs more customization
| +| howdoi | **Incomplete** |
Create temporary marks on users that expire after specified timeNot yet ported to v3
| +| leaver | **Incomplete** |
Send a message in a channel when a user leaves the serverNot yet ported to v3
| +| reactrestrict | **Alpha** |
Removes reactions by role per channelA bit clunky, but functional
| +| secrethitler | **Incomplete** |
Play the Secret Hitler gameConcept, no work done yet
| +| stealemoji | **Alpha** |
Steals any custom emoji it sees in a reactionSome planned upgrades for server generation
| +| werewolf | **Incomplete** |
Play the classic party game Werewolf within discordAnother massive project, will be fully customizable
| -Cog Status Descriptions - - ccrole: May have some bugs, please create an issue if you find any - - chatter: Missing some key features, but currently functional - - fight: Still in-progress, a massive project - - flag: Not yet ported to v3 - - hangman: Not yet ported to v3 - - immortal: Designed for a specific server, not recommended to install - - leaver: Not yet ported to v3 - - reactrestrict: A bit clunky, but functional - - stealemoji: Some planned upgrades for server generation - - werewolf: Another massive project, will be fully customizable +Check out my V2 cogs at [Fox-Cogs v2](https://github.com/bobloy/Fox-Cogs) -Many of these are functional in my V2 cogs at [Fox-Cogs v2](https://github.com/bobloy/Fox-Cogs) - \ No newline at end of file +Get support on the [Third Party Cog Server](https://discord.gg/GET4DVk) diff --git a/ccrole/ccrole.py b/ccrole/ccrole.py index 38cff39..2459b6e 100644 --- a/ccrole/ccrole.py +++ b/ccrole/ccrole.py @@ -1,13 +1,10 @@ -import discord -import asyncio +import asyncio +import re +import discord from discord.ext import commands - from redbot.core import Config, checks - from redbot.core.utils.chat_formatting import pagify, box -import os -import re class CCRole: @@ -20,23 +17,27 @@ class CCRole: self.bot = bot self.config = Config.get_conf(self, identifier=9999114111108101) default_guild = { - "cmdlist" : {}, + "cmdlist": {}, "settings": {} } - - self.config.register_guild(**default_guild) + self.config.register_guild(**default_guild) @commands.group(no_pm=True) async def ccrole(self, ctx): - """Custom commands management""" + """Custom commands management with roles + + Highly customizable custom commands with role management.""" if not ctx.invoked_subcommand: await ctx.send_help() @ccrole.command(name="add") @checks.mod_or_permissions(administrator=True) - async def ccrole_add(self, ctx, command : str): - """Adds a custom command with roles""" + async def ccrole_add(self, ctx, command: str): + """Adds a custom command with roles + + When adding text, put arguments in `{}` to eval them + Options: `{author}`, `{target}`, `{server}`, `{channel}`, `{message}`""" command = command.lower() if command in self.bot.all_commands: await ctx.send("That command is already a standard command.") @@ -45,125 +46,164 @@ class CCRole: guild = ctx.guild author = ctx.author channel = ctx.channel - - cmdlist = self.config.guild(ctx.guild).cmdlist - - if await cmdlist.get_raw(command, default=None): + + cmd_list = self.config.guild(guild).cmdlist + + if await cmd_list.get_raw(command, default=None): await ctx.send("This command already exists. Delete it with `{}ccrole delete` first.".format(ctx.prefix)) return # Roles to add await ctx.send('What roles should it add? (Must be **comma separated**)\nSay `None` to skip adding roles') - + def check(m): - return m.author == author and m.channel==channel - + return m.author == author and m.channel == channel + try: answer = await self.bot.wait_for('message', timeout=120, check=check) except asyncio.TimeoutError: await ctx.send("Timed out, canceling") - + return + arole_list = [] - if answer.content.upper()!="NONE": + if answer.content.upper() != "NONE": arole_list = await self._get_roles_from_content(ctx, answer.content) if arole_list is None: await ctx.send("Invalid answer, canceling") return - + # Roles to remove await ctx.send('What roles should it remove? (Must be comma separated)\nSay `None` to skip removing roles') try: answer = await self.bot.wait_for('message', timeout=120, check=check) except asyncio.TimeoutError: await ctx.send("Timed out, canceling") - + return + rrole_list = [] - if answer.content.upper()!="NONE": + if answer.content.upper() != "NONE": rrole_list = await self._get_roles_from_content(ctx, answer.content) if rrole_list is None: await ctx.send("Invalid answer, canceling") return - + # Roles to use - await ctx.send('What roles are allowed to use this command? (Must be comma separated)\nSay `None` to allow all roles') - + await ctx.send( + 'What roles are allowed to use this command? (Must be comma separated)\nSay `None` to allow all roles') + try: answer = await self.bot.wait_for('message', timeout=120, check=check) except asyncio.TimeoutError: await ctx.send("Timed out, canceling") - + return + prole_list = [] - if answer.content.upper()!="NONE": + if answer.content.upper() != "NONE": prole_list = await self._get_roles_from_content(ctx, answer.content) if prole_list is None: await ctx.send("Invalid answer, canceling") return - + # Selfrole await ctx.send('Is this a targeted command?(yes/no)\nNo will make this a selfrole command') - + try: answer = await self.bot.wait_for('message', timeout=120, check=check) except asyncio.TimeoutError: await ctx.send("Timed out, canceling") - + return + if answer.content.upper() in ["Y", "YES"]: targeted = True await ctx.send("This command will be **`targeted`**") else: targeted = False await ctx.send("This command will be **`selfrole`**") - + # Message to send - await ctx.send('What message should the bot say when using this command?\nSay `None` to send the default `Success!` message') - + await ctx.send( + 'What message should the bot say when using this command?\n' + 'Say `None` to send the default `Success!` message\n' + 'Eval Options: `{author}`, `{target}`, `{server}`, `{channel}`, `{message}`\n' + 'For example: `Welcome {target.mention} to {server.name}!`') + try: answer = await self.bot.wait_for('message', timeout=120, check=check) except asyncio.TimeoutError: await ctx.send("Timed out, canceling") + return + text = "Success!" - if answer.content.upper()!="NONE": + if answer.content.upper() != "NONE": text = answer.content # Save the command - + out = {'text': text, 'aroles': arole_list, 'rroles': rrole_list, "proles": prole_list, "targeted": targeted} - - await cmdlist.set_raw(command, value=out) - - ctx.send("Custom Command **`{}`** successfully added".format(command)) - + + await cmd_list.set_raw(command, value=out) + + await ctx.send("Custom Command **`{}`** successfully added".format(command)) + @ccrole.command(name="delete") @checks.mod_or_permissions(administrator=True) - async def ccrole_delete(self, ctx, command : str): + async def ccrole_delete(self, ctx, command: str): """Deletes a custom command + Example: - [p]ccrole delete yourcommand""" + `[p]ccrole delete yourcommand`""" guild = ctx.guild command = command.lower() - if not await self.config.guild(ctx.guild).cmdlist.get_raw(command, default=None): + if not await self.config.guild(guild).cmdlist.get_raw(command, default=None): await ctx.send("That command doesn't exist") else: - await self.config.guild(ctx.guild).cmdlist.set_raw(command, value=None) + await self.config.guild(guild).cmdlist.set_raw(command, value=None) await ctx.send("Custom command successfully deleted.") + @ccrole.command(name="details") + async def ccrole_details(self, ctx, command: str): + """Provide details about passed custom command""" + guild = ctx.guild + command = command.lower() + cmd = await self.config.guild(guild).cmdlist.get_raw(command, default=None) + if cmd is None: + await ctx.send("That command doesn't exist") + return + + embed = discord.Embed(title=command, + description="{} custom command".format("Targeted" if cmd['targeted'] else "Non-Targeted")) + + def process_roles(role_list): + if not role_list: + return "None" + return ", ".join([discord.utils.get(ctx.guild.roles, id=roleid).name for roleid in role_list]) + + embed.add_field(name="Text", value="```{}```".format(cmd['text'])) + embed.add_field(name="Adds Roles", value=process_roles(cmd['aroles']), inline=True) + embed.add_field(name="Removes Roles", value=process_roles(cmd['rroles']), inline=True) + embed.add_field(name="Role Restrictions", value=process_roles(cmd['proles']), inline=True) + + await ctx.send(embed=embed) + @ccrole.command(name="list") async def ccrole_list(self, ctx): """Shows custom commands list""" guild = ctx.guild - commands = await self.config.guild(ctx.guild).cmdlist() - - if not commands: - await ctx.send("There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format(ctx.prefix)) + cmd_list = await self.config.guild(guild).cmdlist() + cmd_list = {k: v for k,v in cmd_list.items() if v} + if not cmd_list: + await ctx.send( + "There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format( + ctx.prefix)) return - commands = ", ".join([ctx.prefix + c for c in sorted(commands.keys())]) - commands = "Custom commands:\n\n" + commands + cmd_list = ", ".join([ctx.prefix + c for c in sorted(cmd_list.keys())]) + cmd_list = "Custom commands:\n\n" + cmd_list - if len(commands) < 1500: - await ctx.send(box(commands)) + if len(cmd_list) < 1500: # I'm allowed to have arbitrary numbers for when it's too much to dm dammit + await ctx.send(box(cmd_list)) else: - for page in pagify(commands, delims=[" ", "\n"]): + for page in pagify(cmd_list, delims=[" ", "\n"]): await ctx.author.send(box(page)) await ctx.send("Command list DM'd") @@ -177,24 +217,22 @@ class CCRole: except ValueError: return - cmdlist = self.config.guild(guild).cmdlist - cmd = message.content[len(prefix):].split()[0] - cmd = await cmdlist.get_raw(cmd.lower(), default=None) - - if cmd: + cmd = message.content[len(prefix):].split()[0].lower() + cmd = await cmdlist.get_raw(cmd, default=None) + + if cmd is not None: await self.eval_cc(cmd, message) - + async def _get_roles_from_content(self, ctx, content): content_list = content.split(",") - role_list = [] try: role_list = [discord.utils.get(ctx.guild.roles, name=role.strip(' ')).id for role in content_list] - except: + except (discord.HTTPException, AttributeError): # None.id is attribute error return None else: return role_list - + async def get_prefix(self, message: discord.Message) -> str: """ Borrowed from alias cog @@ -214,27 +252,26 @@ class CCRole: if content.startswith(p): return p raise ValueError - + async def eval_cc(self, cmd, message): """Does all the work""" if cmd['proles'] and not (set(role.id for role in message.author.roles) & set(cmd['proles'])): return # Not authorized, do nothing - + if cmd['targeted']: try: target = discord.utils.get(message.guild.members, mention=message.content.split()[1]) - except: + except IndexError: # .split() return list of len<2 target = None - + if not target: - out_message = "This command is targeted! @mention a target\n`{} `".format(message.content.split()[0]) - + out_message = "This custom command is targeted! @mention a target\n`{} `".format( + message.content.split()[0]) await message.channel.send(out_message) - return else: target = message.author - + if cmd['aroles']: arole_list = [discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd['aroles']] # await self.bot.send_message(message.channel, "Adding: "+str([str(arole) for arole in arole_list])) @@ -243,7 +280,7 @@ class CCRole: except discord.Forbidden: await message.channel.send("Permission error: Unable to add roles") await asyncio.sleep(1) - + if cmd['rroles']: rrole_list = [discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd['rroles']] # await self.bot.send_message(message.channel, "Removing: "+str([str(rrole) for rrole in rrole_list])) @@ -251,37 +288,40 @@ class CCRole: await target.remove_roles(*rrole_list) except discord.Forbidden: await message.channel.send("Permission error: Unable to remove roles") - await message.channel.send(cmd['text']) - - # {'text': text, 'aroles': arole_list, 'rroles': rrole_list, "proles", prole_list, "targeted": targeted} - - # def format_cc(self, command, message): - # results = re.findall("\{([^}]+)\}", command) - # for result in results: - # param = self.transform_parameter(result, message) - # command = command.replace("{" + result + "}", param) - # return command - - # def transform_parameter(self, result, message): - # """ - # For security reasons only specific objects are allowed - # Internals are ignored - # """ - # raw_result = "{" + result + "}" - # objects = { - # "message" : message, - # "author" : message.author, - # "channel" : message.channel, - # "server" : message.server - # } - # if result in objects: - # return str(objects[result]) - # try: - # first, second = result.split(".") - # except ValueError: - # return raw_result - # if first in objects and not second.startswith("_"): - # first = objects[first] - # else: - # return raw_result - # return str(getattr(first, second, raw_result)) \ No newline at end of file + + out_message = self.format_cc(cmd, message, target) + await message.channel.send(out_message) + + def format_cc(self, cmd, message, target): + out = cmd['text'] + results = re.findall("{([^}]+)\}", out) + for result in results: + param = self.transform_parameter(result, message, target) + out = out.replace("{" + result + "}", param) + return out + + def transform_parameter(self, result, message, target): + """ + For security reasons only specific objects are allowed + Internals are ignored + """ + raw_result = "{" + result + "}" + objects = { + "message": message, + "author": message.author, + "channel": message.channel, + "server": message.guild, + "guild": message.guild, + "target": target + } + if result in objects: + return str(objects[result]) + try: + first, second = result.split(".") + except ValueError: + return raw_result + if first in objects and not second.startswith("_"): + first = objects[first] + else: + return raw_result + return str(getattr(first, second, raw_result)) diff --git a/chatter/__init__.py b/chatter/__init__.py index 2d7a8e8..cc101b7 100644 --- a/chatter/__init__.py +++ b/chatter/__init__.py @@ -1,5 +1,11 @@ -from .chatter import Chatter +from . import chatterbot +from .chat import Chatter def setup(bot): bot.add_cog(Chatter(bot)) + + +__all__ = ( + 'chatterbot' +) diff --git a/chatter/chatter.py b/chatter/chat.py similarity index 72% rename from chatter/chatter.py rename to chatter/chat.py index 5e02d39..32d83a3 100644 --- a/chatter/chatter.py +++ b/chatter/chat.py @@ -1,16 +1,13 @@ import asyncio -from typing import List, Union +from datetime import datetime, timedelta import discord from discord.ext import commands +from redbot.core import Config -from redbot.core import Config, RedContext -from redbot.core.bot import Red +from chatter.chatterbot import ChatBot +from chatter.chatterbot.trainers import ListTrainer -from .source import ChatBot -from .source.trainers import ListTrainer - -from datetime import datetime,timedelta class Chatter: @@ -25,17 +22,21 @@ class Chatter: default_guild = { "whitelist": None, "days": 1 - } - - self.chatbot = ChatBot("ChatterBot") + } + + self.chatbot = ChatBot( + "ChatterBot", + storage_adapter='chatter.chatterbot.storage.SQLStorageAdapter', + database='./database.sqlite3' + ) self.chatbot.set_trainer(ListTrainer) self.config.register_global(**default_global) self.config.register_guild(**default_guild) - + self.loop = asyncio.get_event_loop() - - async def _get_conversation(self, ctx, in_channel: discord.TextChannel=None): + + async def _get_conversation(self, ctx, in_channel: discord.TextChannel = None): """ Compiles all conversation in the Guild this bot can get it's hands on Currently takes a stupid long time @@ -43,9 +44,8 @@ class Chatter: """ out = [] after = datetime.today() - timedelta(days=(await self.config.guild(ctx.guild).days())) - - for channel in ctx.guild.text_channels: + for channel in ctx.guild.text_channels: if in_channel: channel = in_channel await ctx.send("Gathering {}".format(channel.mention)) @@ -53,7 +53,7 @@ class Chatter: try: async for message in channel.history(limit=None, reverse=True, after=after): if user == message.author: - out[-1] += "\n"+message.clean_content + out[-1] += "\n" + message.clean_content else: user = message.author out.append(message.clean_content) @@ -61,12 +61,12 @@ class Chatter: pass except discord.HTTPException: pass - + if in_channel: break - + return out - + def _train(self, data): try: self.chatbot.train(data) @@ -81,45 +81,59 @@ class Chatter: """ if ctx.invoked_subcommand is None: await ctx.send_help() + @chatter.command() async def age(self, ctx: RedContext, days: int): """ Sets the number of days to look back Will train on 1 day otherwise """ - + await self.config.guild(ctx.guild).days.set(days) await ctx.send("Success") - + + @chatter.command() + async def backup(self, ctx, backupname): + """ + Backup your training data to a json for later use + """ + 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)) + + if future: + await ctx.send("Backup successful!") + else: + await ctx.send("Error occurred :(") + @chatter.command() - async def train(self, ctx: RedContext, channel: discord.TextChannel = None): + async def train(self, ctx: commands.Context, channel: discord.TextChannel): """ Trains the bot based on language in this guild """ - + conversation = await self._get_conversation(ctx, channel) - + if not conversation: await ctx.send("Failed to gather training data") return - + await ctx.send("Gather successful! Training begins now\n(**This will take a long time, be patient**)") - embed=discord.Embed(title="Loading") + embed = discord.Embed(title="Loading") embed.set_image(url="http://www.loop.universaleverything.com/animations/1295.gif") temp_message = await ctx.send(embed=embed) future = await self.loop.run_in_executor(None, self._train, conversation) - + try: await temp_message.delete() except: pass - + if future: await ctx.send("Training successful!") else: await ctx.send("Error occurred :(") - - async def on_message(self, message: discord.Message): + + async def on_message(self, message): """ Credit to https://github.com/Twentysix26/26-Cogs/blob/master/cleverbot/cleverbot.py for on_message recognition of @bot @@ -135,9 +149,9 @@ class Chatter: return text = text.replace(to_strip, "", 1) async with channel.typing(): - response = self.chatbot.get_response(text) - if not response: - response = ":thinking:" - await channel.send(response) - + future = await self.loop.run_in_executor(None, self.chatbot.get_response, text) + if future: + await channel.send(str(future)) + else: + await channel.send(':thinking:') diff --git a/chatter/source/__init__.py b/chatter/chatterbot/__init__.py similarity index 91% rename from chatter/source/__init__.py rename to chatter/chatterbot/__init__.py index 2ea55f6..7a127ee 100644 --- a/chatter/source/__init__.py +++ b/chatter/chatterbot/__init__.py @@ -3,7 +3,7 @@ ChatterBot is a machine learning, conversational dialog engine. """ from .chatterbot import ChatBot -__version__ = '0.8.4' +__version__ = '0.8.5' __author__ = 'Gunther Cox' __email__ = 'gunthercx@gmail.com' __url__ = 'https://github.com/gunthercox/ChatterBot' diff --git a/chatter/source/__main__.py b/chatter/chatterbot/__main__.py similarity index 99% rename from chatter/source/__main__.py rename to chatter/chatterbot/__main__.py index a27f483..0322854 100644 --- a/chatter/source/__main__.py +++ b/chatter/chatterbot/__main__.py @@ -1,6 +1,5 @@ import sys - if __name__ == '__main__': import importlib diff --git a/chatter/source/adapters.py b/chatter/chatterbot/adapters.py similarity index 96% rename from chatter/source/adapters.py rename to chatter/chatterbot/adapters.py index f99734d..83ce94c 100644 --- a/chatter/source/adapters.py +++ b/chatter/chatterbot/adapters.py @@ -16,7 +16,7 @@ class Adapter(object): """ Gives the adapter access to an instance of the ChatBot class. - :param chatbot: A chat bot instanse. + :param chatbot: A chat bot instance. :type chatbot: ChatBot """ self.chatbot = chatbot diff --git a/chatter/source/chatterbot.py b/chatter/chatterbot/chatterbot.py similarity index 91% rename from chatter/source/chatterbot.py rename to chatter/chatterbot/chatterbot.py index 66a92b9..c7a92cb 100644 --- a/chatter/source/chatterbot.py +++ b/chatter/chatterbot/chatterbot.py @@ -1,9 +1,11 @@ from __future__ import unicode_literals + import logging -from .storage import StorageAdapter + +from . import utils from .input import InputAdapter from .output import OutputAdapter -from . import utils +from .storage import StorageAdapter class ChatBot(object): @@ -20,15 +22,15 @@ class ChatBot(object): self.default_session = None - storage_adapter = kwargs.get('storage_adapter', 'chatter.source.storage.SQLStorageAdapter') + storage_adapter = kwargs.get('storage_adapter', 'chatter.chatterbot.storage.SQLStorageAdapter') logic_adapters = kwargs.get('logic_adapters', [ - 'chatter.source.logic.BestMatch' + 'chatter.chatterbot.logic.BestMatch' ]) - input_adapter = kwargs.get('input_adapter', 'chatter.source.input.VariableInputTypeAdapter') + input_adapter = kwargs.get('input_adapter', 'chatter.chatterbot.input.VariableInputTypeAdapter') - output_adapter = kwargs.get('output_adapter', 'chatter.source.output.OutputAdapter') + output_adapter = kwargs.get('output_adapter', 'chatter.chatterbot.output.OutputAdapter') # Check that each adapter is a valid subclass of it's respective parent utils.validate_adapter_class(storage_adapter, StorageAdapter) @@ -45,7 +47,7 @@ class ChatBot(object): # Add required system logic adapter self.logic.system_adapters.append( - utils.initialize_class('chatter.source.logic.NoKnowledgeAdapter', **kwargs) + utils.initialize_class('chatter.chatterbot.logic.NoKnowledgeAdapter', **kwargs) ) for adapter in logic_adapters: @@ -59,7 +61,7 @@ class ChatBot(object): preprocessors = kwargs.get( 'preprocessors', [ - 'chatter.source.preprocessors.clean_whitespace' + 'chatter.chatterbot.preprocessors.clean_whitespace' ] ) @@ -69,7 +71,7 @@ class ChatBot(object): self.preprocessors.append(utils.import_module(preprocessor)) # Use specified trainer or fall back to the default - trainer = kwargs.get('trainer', 'chatter.source.trainers.Trainer') + trainer = kwargs.get('trainer', 'chatter.chatterbot.trainers.Trainer') TrainerClass = utils.import_module(trainer) self.trainer = TrainerClass(self.storage, **kwargs) self.training_data = kwargs.get('training_data') diff --git a/chatter/source/comparisons.py b/chatter/chatterbot/comparisons.py similarity index 96% rename from chatter/source/comparisons.py rename to chatter/chatterbot/comparisons.py index 816e175..59efa95 100644 --- a/chatter/source/comparisons.py +++ b/chatter/chatterbot/comparisons.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import sys """ @@ -58,19 +57,14 @@ class LevenshteinDistance(Comparator): :rtype: float """ - PYTHON = sys.version_info[0] - # Return 0 if either statement has a falsy text value if not statement.text or not other_statement.text: return 0 # Get the lowercase version of both strings - if PYTHON < 3: - statement_text = unicode(statement.text.lower()) # NOQA - other_statement_text = unicode(other_statement.text.lower()) # NOQA - else: - statement_text = str(statement.text.lower()) - other_statement_text = str(other_statement.text.lower()) + + statement_text = str(statement.text.lower()) + other_statement_text = str(other_statement.text.lower()) similarity = SequenceMatcher( None, @@ -130,7 +124,7 @@ class SynsetDistance(Comparator): """ from nltk.corpus import wordnet from nltk import word_tokenize - from . import utils + from chatter.chatterbot import utils import itertools tokens1 = word_tokenize(statement.text.lower()) diff --git a/chatter/source/constants.py b/chatter/chatterbot/constants.py similarity index 100% rename from chatter/source/constants.py rename to chatter/chatterbot/constants.py diff --git a/chatter/source/conversation.py b/chatter/chatterbot/conversation.py similarity index 96% rename from chatter/source/conversation.py rename to chatter/chatterbot/conversation.py index ea674aa..c9dfcb4 100644 --- a/chatter/source/conversation.py +++ b/chatter/chatterbot/conversation.py @@ -25,7 +25,6 @@ class Statement(StatementMixin): """ def __init__(self, text, **kwargs): - import sys # Try not to allow non-string types to be passed to statements try: @@ -33,13 +32,6 @@ class Statement(StatementMixin): except UnicodeEncodeError: pass - # Prefer decoded utf8-strings in Python 2.7 - if sys.version_info[0] < 3: - try: - text = text.decode('utf-8') - except UnicodeEncodeError: - pass - self.text = text self.tags = kwargs.pop('tags', []) self.in_response_to = kwargs.pop('in_response_to', []) diff --git a/chatter/source/corpus.py b/chatter/chatterbot/corpus.py similarity index 99% rename from chatter/source/corpus.py rename to chatter/chatterbot/corpus.py index 65da8eb..4bf0e4b 100644 --- a/chatter/source/corpus.py +++ b/chatter/chatterbot/corpus.py @@ -5,7 +5,6 @@ View the corpus on GitHub at https://github.com/gunthercox/chatterbot-corpus from chatterbot_corpus import Corpus - __all__ = ( 'Corpus', ) diff --git a/chatter/source/ext/__init__.py b/chatter/chatterbot/ext/__init__.py similarity index 100% rename from chatter/source/ext/__init__.py rename to chatter/chatterbot/ext/__init__.py diff --git a/chatter/source/ext/django_chatterbot/management/__init__.py b/chatter/chatterbot/ext/sqlalchemy_app/__init__.py similarity index 100% rename from chatter/source/ext/django_chatterbot/management/__init__.py rename to chatter/chatterbot/ext/sqlalchemy_app/__init__.py diff --git a/chatter/source/ext/sqlalchemy_app/models.py b/chatter/chatterbot/ext/sqlalchemy_app/models.py similarity index 88% rename from chatter/source/ext/sqlalchemy_app/models.py rename to chatter/chatterbot/ext/sqlalchemy_app/models.py index 9f1b0d3..6a7dc00 100644 --- a/chatter/source/ext/sqlalchemy_app/models.py +++ b/chatter/chatterbot/ext/sqlalchemy_app/models.py @@ -1,11 +1,11 @@ from sqlalchemy import Table, Column, Integer, DateTime, ForeignKey, PickleType +from sqlalchemy.ext.declarative import declared_attr, declarative_base from sqlalchemy.orm import relationship from sqlalchemy.sql import func -from sqlalchemy.ext.declarative import declared_attr, declarative_base -from ...constants import TAG_NAME_MAX_LENGTH, STATEMENT_TEXT_MAX_LENGTH -from .types import UnicodeString -from ...conversation import StatementMixin +from chatter.chatterbot.constants import TAG_NAME_MAX_LENGTH, STATEMENT_TEXT_MAX_LENGTH +from chatter.chatterbot.conversation import StatementMixin +from chatter.chatterbot.ext.sqlalchemy_app.types import UnicodeString class ModelBase(object): @@ -29,7 +29,6 @@ class ModelBase(object): Base = declarative_base(cls=ModelBase) - tag_association_table = Table( 'tag_association', Base.metadata, @@ -73,8 +72,8 @@ class Statement(Base, StatementMixin): return [tag.name for tag in self.tags] def get_statement(self): - from ...conversation import Statement as StatementObject - from ...conversation import Response as ResponseObject + from chatter.chatterbot.conversation import Statement as StatementObject + from chatter.chatterbot.conversation import Response as ResponseObject statement = StatementObject( self.text, diff --git a/chatter/source/ext/sqlalchemy_app/types.py b/chatter/chatterbot/ext/sqlalchemy_app/types.py similarity index 70% rename from chatter/source/ext/sqlalchemy_app/types.py rename to chatter/chatterbot/ext/sqlalchemy_app/types.py index b48f4f6..ee9b123 100644 --- a/chatter/source/ext/sqlalchemy_app/types.py +++ b/chatter/chatterbot/ext/sqlalchemy_app/types.py @@ -13,9 +13,4 @@ class UnicodeString(TypeDecorator): Coerce Python bytestrings to unicode before saving them to the database. """ - import sys - - if sys.version_info[0] < 3: - if isinstance(value, str): - value = value.decode('utf-8') return value diff --git a/chatter/source/filters.py b/chatter/chatterbot/filters.py similarity index 100% rename from chatter/source/filters.py rename to chatter/chatterbot/filters.py diff --git a/chatter/source/input/__init__.py b/chatter/chatterbot/input/__init__.py similarity index 99% rename from chatter/source/input/__init__.py rename to chatter/chatterbot/input/__init__.py index 34d9568..53c53f9 100644 --- a/chatter/source/input/__init__.py +++ b/chatter/chatterbot/input/__init__.py @@ -1,12 +1,11 @@ from .input_adapter import InputAdapter -from .microsoft import Microsoft from .gitter import Gitter from .hipchat import HipChat from .mailgun import Mailgun +from .microsoft import Microsoft from .terminal import TerminalAdapter from .variable_input_type_adapter import VariableInputTypeAdapter - __all__ = ( 'InputAdapter', 'Microsoft', diff --git a/chatter/source/input/gitter.py b/chatter/chatterbot/input/gitter.py similarity index 98% rename from chatter/source/input/gitter.py rename to chatter/chatterbot/input/gitter.py index 6ed83db..9018e37 100644 --- a/chatter/source/input/gitter.py +++ b/chatter/chatterbot/input/gitter.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals + from time import sleep -from . import InputAdapter -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter class Gitter(InputAdapter): diff --git a/chatter/source/input/hipchat.py b/chatter/chatterbot/input/hipchat.py similarity index 96% rename from chatter/source/input/hipchat.py rename to chatter/chatterbot/input/hipchat.py index b251157..b5da731 100644 --- a/chatter/source/input/hipchat.py +++ b/chatter/chatterbot/input/hipchat.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals + from time import sleep -from . import InputAdapter -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter class HipChat(InputAdapter): diff --git a/chatter/source/input/input_adapter.py b/chatter/chatterbot/input/input_adapter.py similarity index 95% rename from chatter/source/input/input_adapter.py rename to chatter/chatterbot/input/input_adapter.py index 3bc4b08..49c63db 100644 --- a/chatter/source/input/input_adapter.py +++ b/chatter/chatterbot/input/input_adapter.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals -from ..adapters import Adapter + +from chatter.chatterbot.adapters import Adapter class InputAdapter(Adapter): diff --git a/chatter/source/input/mailgun.py b/chatter/chatterbot/input/mailgun.py similarity index 93% rename from chatter/source/input/mailgun.py rename to chatter/chatterbot/input/mailgun.py index b1fe705..6fb78a8 100644 --- a/chatter/source/input/mailgun.py +++ b/chatter/chatterbot/input/mailgun.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals + import datetime -from . import InputAdapter -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter class Mailgun(InputAdapter): diff --git a/chatter/source/input/microsoft.py b/chatter/chatterbot/input/microsoft.py similarity index 92% rename from chatter/source/input/microsoft.py rename to chatter/chatterbot/input/microsoft.py index 395a3de..3a255bf 100644 --- a/chatter/source/input/microsoft.py +++ b/chatter/chatterbot/input/microsoft.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals + from time import sleep -from . import InputAdapter -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter class Microsoft(InputAdapter): @@ -21,10 +23,10 @@ class Microsoft(InputAdapter): # NOTE: Direct Line client credentials are different from your bot's # credentials - self.direct_line_token_or_secret = kwargs.\ + self.direct_line_token_or_secret = kwargs. \ get('direct_line_token_or_secret') - authorization_header = 'BotConnector {}'.\ + authorization_header = 'BotConnector {}'. \ format(self.direct_line_token_or_secret) self.headers = { @@ -62,7 +64,7 @@ class Microsoft(InputAdapter): def get_most_recent_message(self): import requests - endpoint = '{host}/api/conversations/{id}/messages'\ + endpoint = '{host}/api/conversations/{id}/messages' \ .format(host=self.directline_host, id=self.conversation_id) diff --git a/chatter/source/input/terminal.py b/chatter/chatterbot/input/terminal.py similarity index 70% rename from chatter/source/input/terminal.py rename to chatter/chatterbot/input/terminal.py index e2d7ba2..20cb3c2 100644 --- a/chatter/source/input/terminal.py +++ b/chatter/chatterbot/input/terminal.py @@ -1,7 +1,8 @@ from __future__ import unicode_literals -from . import InputAdapter -from ..conversation import Statement -from ..utils import input_function + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter +from chatter.chatterbot.utils import input_function class TerminalAdapter(InputAdapter): diff --git a/chatter/source/input/variable_input_type_adapter.py b/chatter/chatterbot/input/variable_input_type_adapter.py similarity index 86% rename from chatter/source/input/variable_input_type_adapter.py rename to chatter/chatterbot/input/variable_input_type_adapter.py index 9158611..d2d598c 100644 --- a/chatter/source/input/variable_input_type_adapter.py +++ b/chatter/chatterbot/input/variable_input_type_adapter.py @@ -1,22 +1,18 @@ from __future__ import unicode_literals -from . import InputAdapter -from ..conversation import Statement +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.input import InputAdapter -class VariableInputTypeAdapter(InputAdapter): +class VariableInputTypeAdapter(InputAdapter): JSON = 'json' TEXT = 'text' OBJECT = 'object' - VALID_FORMATS = (JSON, TEXT, OBJECT, ) + VALID_FORMATS = (JSON, TEXT, OBJECT,) def detect_type(self, statement): - import sys - if sys.version_info[0] < 3: - string_types = basestring # NOQA - else: - string_types = str + string_types = str if hasattr(statement, 'text'): return self.OBJECT diff --git a/chatter/source/logic/__init__.py b/chatter/chatterbot/logic/__init__.py similarity index 99% rename from chatter/source/logic/__init__.py rename to chatter/chatterbot/logic/__init__.py index ecb1020..1930556 100644 --- a/chatter/source/logic/__init__.py +++ b/chatter/chatterbot/logic/__init__.py @@ -1,5 +1,5 @@ -from .logic_adapter import LogicAdapter from .best_match import BestMatch +from .logic_adapter import LogicAdapter from .low_confidence import LowConfidenceAdapter from .mathematical_evaluation import MathematicalEvaluation from .multi_adapter import MultiLogicAdapter @@ -7,7 +7,6 @@ from .no_knowledge_adapter import NoKnowledgeAdapter from .specific_response import SpecificResponseAdapter from .time_adapter import TimeLogicAdapter - __all__ = ( 'LogicAdapter', 'BestMatch', diff --git a/chatter/source/logic/best_match.py b/chatter/chatterbot/logic/best_match.py similarity index 99% rename from chatter/source/logic/best_match.py rename to chatter/chatterbot/logic/best_match.py index 712c8f9..5c48121 100644 --- a/chatter/source/logic/best_match.py +++ b/chatter/chatterbot/logic/best_match.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .logic_adapter import LogicAdapter diff --git a/chatter/source/logic/logic_adapter.py b/chatter/chatterbot/logic/logic_adapter.py similarity index 93% rename from chatter/source/logic/logic_adapter.py rename to chatter/chatterbot/logic/logic_adapter.py index df2c143..1239cca 100644 --- a/chatter/source/logic/logic_adapter.py +++ b/chatter/chatterbot/logic/logic_adapter.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals -from ..adapters import Adapter -from ..utils import import_module + +from chatter.chatterbot.adapters import Adapter +from chatter.chatterbot.utils import import_module class LogicAdapter(Adapter): @@ -17,8 +18,8 @@ class LogicAdapter(Adapter): def __init__(self, **kwargs): super(LogicAdapter, self).__init__(**kwargs) - from ..comparisons import levenshtein_distance - from ..response_selection import get_first_response + from chatter.chatterbot.comparisons import levenshtein_distance + from chatter.chatterbot.response_selection import get_first_response # Import string module parameters if 'statement_comparison_function' in kwargs: diff --git a/chatter/source/logic/low_confidence.py b/chatter/chatterbot/logic/low_confidence.py similarity index 97% rename from chatter/source/logic/low_confidence.py rename to chatter/chatterbot/logic/low_confidence.py index fb5435c..585cf20 100644 --- a/chatter/source/logic/low_confidence.py +++ b/chatter/chatterbot/logic/low_confidence.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement from .best_match import BestMatch diff --git a/chatter/source/logic/mathematical_evaluation.py b/chatter/chatterbot/logic/mathematical_evaluation.py similarity index 95% rename from chatter/source/logic/mathematical_evaluation.py rename to chatter/chatterbot/logic/mathematical_evaluation.py index 2a65fdc..af27548 100644 --- a/chatter/source/logic/mathematical_evaluation.py +++ b/chatter/chatterbot/logic/mathematical_evaluation.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals -from . import LogicAdapter -from ..conversation import Statement + +from chatter.chatterbot.conversation import Statement +from chatter.chatterbot.logic import LogicAdapter class MathematicalEvaluation(LogicAdapter): diff --git a/chatter/source/logic/multi_adapter.py b/chatter/chatterbot/logic/multi_adapter.py similarity index 96% rename from chatter/source/logic/multi_adapter.py rename to chatter/chatterbot/logic/multi_adapter.py index 150f6c3..6cfe30f 100644 --- a/chatter/source/logic/multi_adapter.py +++ b/chatter/chatterbot/logic/multi_adapter.py @@ -1,6 +1,8 @@ from __future__ import unicode_literals + from collections import Counter -from .. import utils + +from chatter.chatterbot import utils from .logic_adapter import LogicAdapter @@ -13,7 +15,7 @@ class MultiLogicAdapter(LogicAdapter): """ def __init__(self, **kwargs): - super().__init__(**kwargs) + super(MultiLogicAdapter, self).__init__(**kwargs) # Logic adapters added by the chat bot self.adapters = [] @@ -49,7 +51,7 @@ class MultiLogicAdapter(LogicAdapter): if adapter.can_process(statement): output = adapter.process(statement) - results.append((output.confidence, output, )) + results.append((output.confidence, output,)) self.logger.info( '{} selected "{}" as a response with a confidence of {}'.format( diff --git a/chatter/source/logic/no_knowledge_adapter.py b/chatter/chatterbot/logic/no_knowledge_adapter.py similarity index 99% rename from chatter/source/logic/no_knowledge_adapter.py rename to chatter/chatterbot/logic/no_knowledge_adapter.py index 59b11fd..55208b4 100644 --- a/chatter/source/logic/no_knowledge_adapter.py +++ b/chatter/chatterbot/logic/no_knowledge_adapter.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .logic_adapter import LogicAdapter diff --git a/chatter/source/logic/specific_response.py b/chatter/chatterbot/logic/specific_response.py similarity index 94% rename from chatter/source/logic/specific_response.py rename to chatter/chatterbot/logic/specific_response.py index 2ed6da1..101dd3b 100644 --- a/chatter/source/logic/specific_response.py +++ b/chatter/chatterbot/logic/specific_response.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .logic_adapter import LogicAdapter @@ -15,7 +16,7 @@ class SpecificResponseAdapter(LogicAdapter): def __init__(self, **kwargs): super(SpecificResponseAdapter, self).__init__(**kwargs) - from ..conversation import Statement + from chatter.chatterbot.conversation import Statement self.input_text = kwargs.get('input_text') diff --git a/chatter/source/logic/time_adapter.py b/chatter/chatterbot/logic/time_adapter.py similarity index 94% rename from chatter/source/logic/time_adapter.py rename to chatter/chatterbot/logic/time_adapter.py index 3de4001..72902e2 100644 --- a/chatter/source/logic/time_adapter.py +++ b/chatter/chatterbot/logic/time_adapter.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals + from datetime import datetime + from .logic_adapter import LogicAdapter @@ -40,8 +42,8 @@ class TimeLogicAdapter(LogicAdapter): ]) labeled_data = ( - [(name, 0) for name in self.negative] + - [(name, 1) for name in self.positive] + [(name, 0) for name in self.negative] + + [(name, 1) for name in self.positive] ) train_set = [ @@ -79,7 +81,7 @@ class TimeLogicAdapter(LogicAdapter): return features def process(self, statement): - from ..conversation import Statement + from chatter.chatterbot.conversation import Statement now = datetime.now() diff --git a/chatter/source/output/__init__.py b/chatter/chatterbot/output/__init__.py similarity index 100% rename from chatter/source/output/__init__.py rename to chatter/chatterbot/output/__init__.py index 0d64ca4..80abe4f 100644 --- a/chatter/source/output/__init__.py +++ b/chatter/chatterbot/output/__init__.py @@ -1,9 +1,9 @@ -from .output_adapter import OutputAdapter -from .microsoft import Microsoft -from .terminal import TerminalAdapter -from .mailgun import Mailgun from .gitter import Gitter from .hipchat import HipChat +from .mailgun import Mailgun +from .microsoft import Microsoft +from .output_adapter import OutputAdapter +from .terminal import TerminalAdapter __all__ = ( 'OutputAdapter', diff --git a/chatter/source/output/gitter.py b/chatter/chatterbot/output/gitter.py similarity index 99% rename from chatter/source/output/gitter.py rename to chatter/chatterbot/output/gitter.py index db654e2..ba01fa8 100644 --- a/chatter/source/output/gitter.py +++ b/chatter/chatterbot/output/gitter.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .output_adapter import OutputAdapter diff --git a/chatter/source/output/hipchat.py b/chatter/chatterbot/output/hipchat.py similarity index 99% rename from chatter/source/output/hipchat.py rename to chatter/chatterbot/output/hipchat.py index 4eaa9a7..2546092 100644 --- a/chatter/source/output/hipchat.py +++ b/chatter/chatterbot/output/hipchat.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals + import json + from .output_adapter import OutputAdapter diff --git a/chatter/source/output/mailgun.py b/chatter/chatterbot/output/mailgun.py similarity index 99% rename from chatter/source/output/mailgun.py rename to chatter/chatterbot/output/mailgun.py index 6bb4954..71a9a7a 100644 --- a/chatter/source/output/mailgun.py +++ b/chatter/chatterbot/output/mailgun.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .output_adapter import OutputAdapter diff --git a/chatter/source/output/microsoft.py b/chatter/chatterbot/output/microsoft.py similarity index 99% rename from chatter/source/output/microsoft.py rename to chatter/chatterbot/output/microsoft.py index 177dc35..816fc97 100644 --- a/chatter/source/output/microsoft.py +++ b/chatter/chatterbot/output/microsoft.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals + import json + from .output_adapter import OutputAdapter diff --git a/chatter/source/output/output_adapter.py b/chatter/chatterbot/output/output_adapter.py similarity index 92% rename from chatter/source/output/output_adapter.py rename to chatter/chatterbot/output/output_adapter.py index 880cb18..5d13dd7 100644 --- a/chatter/source/output/output_adapter.py +++ b/chatter/chatterbot/output/output_adapter.py @@ -1,4 +1,4 @@ -from ..adapters import Adapter +from chatter.chatterbot.adapters import Adapter class OutputAdapter(Adapter): diff --git a/chatter/source/output/terminal.py b/chatter/chatterbot/output/terminal.py similarity index 99% rename from chatter/source/output/terminal.py rename to chatter/chatterbot/output/terminal.py index f189aba..8ab63e1 100644 --- a/chatter/source/output/terminal.py +++ b/chatter/chatterbot/output/terminal.py @@ -1,4 +1,5 @@ from __future__ import unicode_literals + from .output_adapter import OutputAdapter diff --git a/chatter/source/parsing.py b/chatter/chatterbot/parsing.py similarity index 100% rename from chatter/source/parsing.py rename to chatter/chatterbot/parsing.py index cf955ff..d7ad4d2 100644 --- a/chatter/source/parsing.py +++ b/chatter/chatterbot/parsing.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +import calendar import re from datetime import timedelta, datetime -import calendar # Variations of dates that the parser can capture year_variations = ['year', 'years', 'yrs'] diff --git a/chatter/source/preprocessors.py b/chatter/chatterbot/preprocessors.py similarity index 80% rename from chatter/source/preprocessors.py rename to chatter/chatterbot/preprocessors.py index f7043b1..2ab0ee0 100644 --- a/chatter/source/preprocessors.py +++ b/chatter/chatterbot/preprocessors.py @@ -27,14 +27,9 @@ def unescape_html(chatbot, statement): Convert escaped html characters into unescaped html characters. For example: "<b>" becomes "". """ - import sys # Replace HTML escape characters - if sys.version_info[0] < 3: - from HTMLParser import HTMLParser - html = HTMLParser() - else: - import html + import html statement.text = html.unescape(statement.text) @@ -47,11 +42,6 @@ def convert_to_ascii(chatbot, statement): For example: "pรฅ fรฉdรฉral" becomes "pa federal". """ import unicodedata - import sys - - # Normalize unicode characters - if sys.version_info[0] < 3: - statement.text = unicode(statement.text) # NOQA text = unicodedata.normalize('NFKD', statement.text) text = text.encode('ascii', 'ignore').decode('utf-8') diff --git a/chatter/source/response_selection.py b/chatter/chatterbot/response_selection.py similarity index 100% rename from chatter/source/response_selection.py rename to chatter/chatterbot/response_selection.py diff --git a/chatter/source/storage/__init__.py b/chatter/chatterbot/storage/__init__.py similarity index 73% rename from chatter/source/storage/__init__.py rename to chatter/chatterbot/storage/__init__.py index 2b4e286..77d3e04 100644 --- a/chatter/source/storage/__init__.py +++ b/chatter/chatterbot/storage/__init__.py @@ -1,12 +1,9 @@ from .storage_adapter import StorageAdapter -from .django_storage import DjangoStorageAdapter from .mongodb import MongoDatabaseAdapter from .sql_storage import SQLStorageAdapter - __all__ = ( 'StorageAdapter', - 'DjangoStorageAdapter', 'MongoDatabaseAdapter', 'SQLStorageAdapter', ) diff --git a/chatter/source/storage/mongodb.py b/chatter/chatterbot/storage/mongodb.py similarity index 97% rename from chatter/source/storage/mongodb.py rename to chatter/chatterbot/storage/mongodb.py index 92ce5a1..1ddb625 100644 --- a/chatter/source/storage/mongodb.py +++ b/chatter/chatterbot/storage/mongodb.py @@ -1,10 +1,13 @@ -from . import StorageAdapter +from chatter.chatterbot.storage import StorageAdapter class Query(object): - def __init__(self, query={}): - self.query = query + def __init__(self, query=None): + if query is None: + self.query = {} + else: + self.query = query def value(self): return self.query.copy() @@ -116,7 +119,7 @@ class MongoDatabaseAdapter(StorageAdapter): """ Return the class for the statement model. """ - from ..conversation import Statement + from chatter.chatterbot.conversation import Statement # Create a storage-aware statement statement = Statement @@ -128,7 +131,7 @@ class MongoDatabaseAdapter(StorageAdapter): """ Return the class for the response model. """ - from ..conversation import Response + from chatter.chatterbot.conversation import Response # Create a storage-aware response response = Response diff --git a/chatter/source/storage/sql_storage.py b/chatter/chatterbot/storage/sql_storage.py similarity index 95% rename from chatter/source/storage/sql_storage.py rename to chatter/chatterbot/storage/sql_storage.py index 21c84e6..32b9535 100644 --- a/chatter/source/storage/sql_storage.py +++ b/chatter/chatterbot/storage/sql_storage.py @@ -1,8 +1,8 @@ -from . import StorageAdapter +from chatter.chatterbot.storage import StorageAdapter def get_response_table(response): - from ..ext.sqlalchemy_app.models import Response + from chatter.chatterbot.ext.sqlalchemy_app.models import Response return Response(text=response.text, occurrence=response.occurrence) @@ -86,28 +86,28 @@ class SQLStorageAdapter(StorageAdapter): """ Return the statement model. """ - from ..ext.sqlalchemy_app.models import Statement + from chatter.chatterbot.ext.sqlalchemy_app.models import Statement return Statement def get_response_model(self): """ Return the response model. """ - from ..ext.sqlalchemy_app.models import Response + from chatter.chatterbot.ext.sqlalchemy_app.models import Response return Response def get_conversation_model(self): """ Return the conversation model. """ - from ..ext.sqlalchemy_app.models import Conversation + from chatter.chatterbot.ext.sqlalchemy_app.models import Conversation return Conversation def get_tag_model(self): """ Return the conversation model. """ - from ..ext.sqlalchemy_app.models import Tag + from chatter.chatterbot.ext.sqlalchemy_app.models import Tag return Tag def count(self): @@ -379,14 +379,14 @@ class SQLStorageAdapter(StorageAdapter): """ Drop the database attached to a given adapter. """ - from ..ext.sqlalchemy_app.models import Base + from chatter.chatterbot.ext.sqlalchemy_app.models import Base Base.metadata.drop_all(self.engine) def create(self): """ Populate the database with the tables. """ - from ..ext.sqlalchemy_app.models import Base + from chatter.chatterbot.ext.sqlalchemy_app.models import Base Base.metadata.create_all(self.engine) def _session_finish(self, session, statement_text=None): diff --git a/chatter/source/storage/storage_adapter.py b/chatter/chatterbot/storage/storage_adapter.py similarity index 95% rename from chatter/source/storage/storage_adapter.py rename to chatter/chatterbot/storage/storage_adapter.py index 50beac7..046ae63 100644 --- a/chatter/source/storage/storage_adapter.py +++ b/chatter/chatterbot/storage/storage_adapter.py @@ -24,12 +24,12 @@ class StorageAdapter(object): # The string must be lowercase model_name = model_name.lower() - kwarg_model_key = '%s_model' % (model_name, ) + kwarg_model_key = '%s_model' % (model_name,) if kwarg_model_key in self.kwargs: return self.kwargs.get(kwarg_model_key) - get_model_method = getattr(self, 'get_%s_model' % (model_name, )) + get_model_method = getattr(self, 'get_%s_model' % (model_name,)) return get_model_method() @@ -157,7 +157,8 @@ class StorageAdapter(object): class EmptyDatabaseException(Exception): - def __init__(self, value='The database currently contains no entries. At least one entry is expected. You may need to train your chat bot to populate your database.'): + def __init__(self, + value='The database currently contains no entries. At least one entry is expected. You may need to train your chat bot to populate your database.'): self.value = value def __str__(self): diff --git a/chatter/source/trainers.py b/chatter/chatterbot/trainers.py similarity index 96% rename from chatter/source/trainers.py rename to chatter/chatterbot/trainers.py index 1f634d1..42ccd47 100644 --- a/chatter/source/trainers.py +++ b/chatter/chatterbot/trainers.py @@ -1,8 +1,9 @@ import logging import os import sys -from .conversation import Statement, Response + from . import utils +from .conversation import Statement, Response class Trainer(object): @@ -60,8 +61,8 @@ class Trainer(object): def __init__(self, value=None): default = ( - 'A training class must be specified before calling train(). ' + - 'See http://chatterbot.readthedocs.io/en/stable/training.html' + 'A training class must be specified before calling train(). ' + + 'See http://chatterbot.readthedocs.io/en/stable/training.html' ) self.value = value or default @@ -84,7 +85,7 @@ class Trainer(object): import json export = {'conversations': self._generate_export_data()} with open(file_path, 'w+') as jsonfile: - json.dump(export, jsonfile, ensure_ascii=False) + json.dump(export, jsonfile, ensure_ascii=True) class ListTrainer(Trainer): @@ -392,10 +393,9 @@ class UbuntuCorpusTrainer(Trainer): file_kwargs = {} - if sys.version_info[0] > 2: - # Specify the encoding in Python versions 3 and up - file_kwargs['encoding'] = 'utf-8' - # WARNING: This might fail to read a unicode corpus file in Python 2.x + # Specify the encoding in Python versions 3 and up + file_kwargs['encoding'] = 'utf-8' + # WARNING: This might fail to read a unicode corpus file in Python 2.x for file in glob.iglob(extracted_corpus_path): self.logger.info('Training from: {}'.format(file)) diff --git a/chatter/source/utils.py b/chatter/chatterbot/utils.py similarity index 93% rename from chatter/source/utils.py rename to chatter/chatterbot/utils.py index 684d7f7..e18549e 100644 --- a/chatter/source/utils.py +++ b/chatter/chatterbot/utils.py @@ -75,17 +75,8 @@ def input_function(): Normalizes reading input between python 2 and 3. The function 'raw_input' becomes 'input' in Python 3. """ - import sys - - if sys.version_info[0] < 3: - user_input = str(raw_input()) # NOQA - # Avoid problems using format strings with unicode characters - if user_input: - user_input = user_input.decode('utf-8') - - else: - user_input = input() # NOQA + user_input = input() # NOQA return user_input @@ -137,7 +128,7 @@ def remove_stopwords(tokens, language): Stop words are words like "is, the, a, ..." Be sure to download the required NLTK corpus before calling this function: - - from chatterbot.utils import nltk_download_corpus + - from chatter.chatterbot.utils import nltk_download_corpus - nltk_download_corpus('corpora/stopwords') """ from nltk.corpus import stopwords diff --git a/chatter/info.json b/chatter/info.json index bd4870a..d2ebffd 100644 --- a/chatter/info.json +++ b/chatter/info.json @@ -1,10 +1,30 @@ { - "author" : ["Bobloy"], - "bot_version" : [3,0,0], - "description" : "Create an offline chatbot that talks like your average member using Machine Learning", - "hidden" : false, - "install_msg" : "Thank you for installing Chatter!", - "requirements" : ["sqlalchemy<1.3,>=1.2", "python-twitter<4.0,>=3.0", "python-dateutil<2.7,>=2.6", "pymongo<4.0,>=3.3", "nltk<4.0,>=3.2", "mathparse<0.2,>=0.1", "chatterbot-corpus<1.2,>=1.1"], - "short" : "Local Chatbot run on machine learning", - "tags" : ["chat", "chatbot", "cleverbot", "clever","bobloy"] + "author": [ + "Bobloy" + ], + "bot_version": [ + 3, + 0, + 0 + ], + "description": "Create an offline chatbot that talks like your average member using Machine Learning", + "hidden": false, + "install_msg": "Thank you for installing Chatter!", + "requirements": [ + "sqlalchemy<1.3,>=1.2", + "python-twitter<4.0,>=3.0", + "python-dateutil<2.7,>=2.6", + "pymongo<4.0,>=3.3", + "nltk<4.0,>=3.2", + "mathparse<0.2,>=0.1", + "chatterbot-corpus<1.2,>=1.1" + ], + "short": "Local Chatbot run on machine learning", + "tags": [ + "chat", + "chatbot", + "cleverbot", + "clever", + "bobloy" + ] } \ No newline at end of file diff --git a/chatter/source/__pycache__/__init__.cpython-36.pyc b/chatter/source/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index b9aa8f4..0000000 Binary files a/chatter/source/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/adapters.cpython-36.pyc b/chatter/source/__pycache__/adapters.cpython-36.pyc deleted file mode 100644 index b4f47b3..0000000 Binary files a/chatter/source/__pycache__/adapters.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/chatterbot.cpython-36.pyc b/chatter/source/__pycache__/chatterbot.cpython-36.pyc deleted file mode 100644 index 4b790ba..0000000 Binary files a/chatter/source/__pycache__/chatterbot.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/comparisons.cpython-36.pyc b/chatter/source/__pycache__/comparisons.cpython-36.pyc deleted file mode 100644 index e1372db..0000000 Binary files a/chatter/source/__pycache__/comparisons.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/constants.cpython-36.pyc b/chatter/source/__pycache__/constants.cpython-36.pyc deleted file mode 100644 index e1dd4ef..0000000 Binary files a/chatter/source/__pycache__/constants.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/conversation.cpython-36.pyc b/chatter/source/__pycache__/conversation.cpython-36.pyc deleted file mode 100644 index e9e644a..0000000 Binary files a/chatter/source/__pycache__/conversation.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/preprocessors.cpython-36.pyc b/chatter/source/__pycache__/preprocessors.cpython-36.pyc deleted file mode 100644 index 954526b..0000000 Binary files a/chatter/source/__pycache__/preprocessors.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/response_selection.cpython-36.pyc b/chatter/source/__pycache__/response_selection.cpython-36.pyc deleted file mode 100644 index f1c2ecf..0000000 Binary files a/chatter/source/__pycache__/response_selection.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/trainers.cpython-36.pyc b/chatter/source/__pycache__/trainers.cpython-36.pyc deleted file mode 100644 index 2c3633d..0000000 Binary files a/chatter/source/__pycache__/trainers.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/__pycache__/utils.cpython-36.pyc b/chatter/source/__pycache__/utils.cpython-36.pyc deleted file mode 100644 index d4d4097..0000000 Binary files a/chatter/source/__pycache__/utils.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/ext/__pycache__/__init__.cpython-36.pyc b/chatter/source/ext/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 502c4b0..0000000 Binary files a/chatter/source/ext/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/ext/django_chatterbot/__init__.py b/chatter/source/ext/django_chatterbot/__init__.py deleted file mode 100644 index c683f59..0000000 --- a/chatter/source/ext/django_chatterbot/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -default_app_config = ( - 'chatter.source.ext.django_chatterbot.apps.DjangoChatterBotConfig' -) diff --git a/chatter/source/ext/django_chatterbot/abstract_models.py b/chatter/source/ext/django_chatterbot/abstract_models.py deleted file mode 100644 index 4531186..0000000 --- a/chatter/source/ext/django_chatterbot/abstract_models.py +++ /dev/null @@ -1,261 +0,0 @@ -from ...conversation import StatementMixin -from ... import constants -from django.db import models -from django.apps import apps -from django.utils import timezone -from django.conf import settings - - -DJANGO_APP_NAME = constants.DEFAULT_DJANGO_APP_NAME -STATEMENT_MODEL = 'Statement' -RESPONSE_MODEL = 'Response' - -if hasattr(settings, 'CHATTERBOT'): - """ - Allow related models to be overridden in the project settings. - Default to the original settings if one is not defined. - """ - DJANGO_APP_NAME = settings.CHATTERBOT.get( - 'django_app_name', - DJANGO_APP_NAME - ) - STATEMENT_MODEL = settings.CHATTERBOT.get( - 'statement_model', - STATEMENT_MODEL - ) - RESPONSE_MODEL = settings.CHATTERBOT.get( - 'response_model', - RESPONSE_MODEL - ) - - -class AbstractBaseStatement(models.Model, StatementMixin): - """ - The abstract base statement allows other models to - be created using the attributes that exist on the - default models. - """ - - text = models.CharField( - unique=True, - blank=False, - null=False, - max_length=constants.STATEMENT_TEXT_MAX_LENGTH - ) - - extra_data = models.CharField( - max_length=500, - blank=True - ) - - # This is the confidence with which the chat bot believes - # this is an accurate response. This value is set when the - # statement is returned by the chat bot. - confidence = 0 - - class Meta: - abstract = True - - def __str__(self): - if len(self.text.strip()) > 60: - return '{}...'.format(self.text[:57]) - elif len(self.text.strip()) > 0: - return self.text - return '' - - def __init__(self, *args, **kwargs): - super(AbstractBaseStatement, self).__init__(*args, **kwargs) - - # Responses to be saved if the statement is updated with the storage adapter - self.response_statement_cache = [] - - @property - def in_response_to(self): - """ - Return the response objects that are for this statement. - """ - ResponseModel = apps.get_model(DJANGO_APP_NAME, RESPONSE_MODEL) - return ResponseModel.objects.filter(statement=self) - - def add_extra_data(self, key, value): - """ - Add extra data to the extra_data field. - """ - import json - - if not self.extra_data: - self.extra_data = '{}' - - extra_data = json.loads(self.extra_data) - extra_data[key] = value - - self.extra_data = json.dumps(extra_data) - - def add_tags(self, tags): - """ - Add a list of strings to the statement as tags. - (Overrides the method from StatementMixin) - """ - for tag in tags: - self.tags.create( - name=tag - ) - - def add_response(self, statement): - """ - Add a response to this statement. - """ - self.response_statement_cache.append(statement) - - def remove_response(self, response_text): - """ - Removes a response from the statement's response list based - on the value of the response text. - - :param response_text: The text of the response to be removed. - :type response_text: str - """ - is_deleted = False - response = self.in_response.filter(response__text=response_text) - - if response.exists(): - is_deleted = True - - return is_deleted - - def get_response_count(self, statement): - """ - Find the number of times that the statement has been used - as a response to the current statement. - - :param statement: The statement object to get the count for. - :type statement: chatterbot.conversation.Statement - - :returns: Return the number of times the statement has been used as a response. - :rtype: int - """ - return self.in_response.filter(response__text=statement.text).count() - - def serialize(self): - """ - :returns: A dictionary representation of the statement object. - :rtype: dict - """ - import json - data = {} - - if not self.extra_data: - self.extra_data = '{}' - - data['text'] = self.text - data['in_response_to'] = [] - data['extra_data'] = json.loads(self.extra_data) - - for response in self.in_response.all(): - data['in_response_to'].append(response.serialize()) - - return data - - -class AbstractBaseResponse(models.Model): - """ - The abstract base response allows other models to - be created using the attributes that exist on the - default models. - """ - - statement = models.ForeignKey( - STATEMENT_MODEL, - related_name='in_response', - on_delete=models.CASCADE - ) - - response = models.ForeignKey( - STATEMENT_MODEL, - related_name='responses', - on_delete=models.CASCADE - ) - - created_at = models.DateTimeField( - default=timezone.now, - help_text='The date and time that this response was created at.' - ) - - class Meta: - abstract = True - - @property - def occurrence(self): - """ - Return a count of the number of times this response has occurred. - """ - ResponseModel = apps.get_model(DJANGO_APP_NAME, RESPONSE_MODEL) - - return ResponseModel.objects.filter( - statement__text=self.statement.text, - response__text=self.response.text - ).count() - - def __str__(self): - statement = self.statement.text - response = self.response.text - return '{} => {}'.format( - statement if len(statement) <= 20 else statement[:17] + '...', - response if len(response) <= 40 else response[:37] + '...' - ) - - def serialize(self): - """ - :returns: A dictionary representation of the statement object. - :rtype: dict - """ - data = {} - - data['text'] = self.response.text - data['created_at'] = self.created_at.isoformat() - data['occurrence'] = self.occurrence - - return data - - -class AbstractBaseConversation(models.Model): - """ - The abstract base conversation allows other models to - be created using the attributes that exist on the - default models. - """ - - responses = models.ManyToManyField( - RESPONSE_MODEL, - related_name='conversations', - help_text='The responses in this conversation.' - ) - - class Meta: - abstract = True - - def __str__(self): - return str(self.id) - - -class AbstractBaseTag(models.Model): - """ - The abstract base tag allows other models to - be created using the attributes that exist on the - default models. - """ - - name = models.SlugField( - max_length=constants.TAG_NAME_MAX_LENGTH - ) - - statements = models.ManyToManyField( - STATEMENT_MODEL, - related_name='tags' - ) - - class Meta: - abstract = True - - def __str__(self): - return self.name diff --git a/chatter/source/ext/django_chatterbot/admin.py b/chatter/source/ext/django_chatterbot/admin.py deleted file mode 100644 index 193c264..0000000 --- a/chatter/source/ext/django_chatterbot/admin.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.contrib import admin -from .models import ( - Statement, Response, Conversation, Tag -) - - -class StatementAdmin(admin.ModelAdmin): - list_display = ('text', ) - list_filter = ('text', ) - search_fields = ('text', ) - - -class ResponseAdmin(admin.ModelAdmin): - list_display = ('statement', 'response', 'occurrence', ) - search_fields = ['statement__text', 'response__text'] - - -class ConversationAdmin(admin.ModelAdmin): - list_display = ('id', ) - - -class TagAdmin(admin.ModelAdmin): - list_display = ('name', ) - list_filter = ('name', ) - search_fields = ('name', ) - - -admin.site.register(Statement, StatementAdmin) -admin.site.register(Response, ResponseAdmin) -admin.site.register(Conversation, ConversationAdmin) -admin.site.register(Tag, TagAdmin) diff --git a/chatter/source/ext/django_chatterbot/apps.py b/chatter/source/ext/django_chatterbot/apps.py deleted file mode 100644 index b873e3e..0000000 --- a/chatter/source/ext/django_chatterbot/apps.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.apps import AppConfig - - -class DjangoChatterBotConfig(AppConfig): - - name = 'chatter.source.ext.django_chatterbot' - label = 'django_chatterbot' - verbose_name = 'Django ChatterBot' diff --git a/chatter/source/ext/django_chatterbot/factories.py b/chatter/source/ext/django_chatterbot/factories.py deleted file mode 100644 index 7367b58..0000000 --- a/chatter/source/ext/django_chatterbot/factories.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -These factories are used to generate fake data for testing. -""" -import factory -from . import models -from ... import constants -from factory.django import DjangoModelFactory - - -class StatementFactory(DjangoModelFactory): - - text = factory.Faker( - 'text', - max_nb_chars=constants.STATEMENT_TEXT_MAX_LENGTH - ) - - class Meta: - model = models.Statement - - -class ResponseFactory(DjangoModelFactory): - - statement = factory.SubFactory(StatementFactory) - - response = factory.SubFactory(StatementFactory) - - class Meta: - model = models.Response - - -class ConversationFactory(DjangoModelFactory): - - class Meta: - model = models.Conversation - - -class TagFactory(DjangoModelFactory): - - name = factory.Faker('word') - - class Meta: - model = models.Tag diff --git a/chatter/source/ext/django_chatterbot/management/commands/__init__.py b/chatter/source/ext/django_chatterbot/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/chatter/source/ext/django_chatterbot/management/commands/train.py b/chatter/source/ext/django_chatterbot/management/commands/train.py deleted file mode 100644 index d4810b8..0000000 --- a/chatter/source/ext/django_chatterbot/management/commands/train.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.core.management.base import BaseCommand - - -class Command(BaseCommand): - """ - A Django management command for calling a - chat bot's training method. - """ - - help = 'Trains the database used by the chat bot' - can_import_settings = True - - def handle(self, *args, **options): - from ..... import ChatBot - from ... import settings - - chatterbot = ChatBot(**settings.CHATTERBOT) - - chatterbot.train(chatterbot.training_data) - - # Django 1.8 does not define SUCCESS - if hasattr(self.style, 'SUCCESS'): - style = self.style.SUCCESS - else: - style = self.style.NOTICE - - self.stdout.write(style('Starting training...')) - training_class = chatterbot.trainer.__class__.__name__ - self.stdout.write(style('ChatterBot trained using "%s"' % training_class)) diff --git a/chatter/source/ext/django_chatterbot/migrations/0001_initial.py b/chatter/source/ext/django_chatterbot/migrations/0001_initial.py deleted file mode 100644 index 9c20907..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0001_initial.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [] - - operations = [ - migrations.CreateModel( - name='Response', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('occurrence', models.PositiveIntegerField(default=0)), - ], - ), - migrations.CreateModel( - name='Statement', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('text', models.CharField(max_length=255, unique=True)), - ], - ), - migrations.AddField( - model_name='response', - name='response', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='django_chatterbot.Statement'), - ), - migrations.AddField( - model_name='response', - name='statement', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='in_response_to', to='django_chatterbot.Statement'), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0002_statement_extra_data.py b/chatter/source/ext/django_chatterbot/migrations/0002_statement_extra_data.py deleted file mode 100644 index 5ed2f4a..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0002_statement_extra_data.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.2 on 2016-10-30 12:13 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='statement', - name='extra_data', - field=models.CharField(default='{}', max_length=500), - preserve_default=False, - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0003_change_occurrence_default.py b/chatter/source/ext/django_chatterbot/migrations/0003_change_occurrence_default.py deleted file mode 100644 index 8da6869..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0003_change_occurrence_default.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2016-12-12 00:06 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0002_statement_extra_data'), - ] - - operations = [ - migrations.AlterField( - model_name='response', - name='occurrence', - field=models.PositiveIntegerField(default=1), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0004_rename_in_response_to.py b/chatter/source/ext/django_chatterbot/migrations/0004_rename_in_response_to.py deleted file mode 100644 index 7860d49..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0004_rename_in_response_to.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.3 on 2016-12-04 23:52 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0003_change_occurrence_default'), - ] - - operations = [ - migrations.AlterField( - model_name='response', - name='statement', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='in_response', to='django_chatterbot.Statement'), - ), - migrations.AlterField( - model_name='response', - name='response', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='django_chatterbot.Statement'), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0005_statement_created_at.py b/chatter/source/ext/django_chatterbot/migrations/0005_statement_created_at.py deleted file mode 100644 index 7b38f00..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0005_statement_created_at.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.1 on 2016-12-29 19:20 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0004_rename_in_response_to'), - ] - - operations = [ - migrations.AddField( - model_name='statement', - name='created_at', - field=models.DateTimeField( - default=django.utils.timezone.now, - help_text='The date and time that this statement was created at.' - ), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0006_create_conversation.py b/chatter/source/ext/django_chatterbot/migrations/0006_create_conversation.py deleted file mode 100644 index 1cf95d9..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0006_create_conversation.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9 on 2017-01-17 07:02 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0005_statement_created_at'), - ] - - operations = [ - migrations.CreateModel( - name='Conversation', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ], - ), - migrations.AlterField( - model_name='statement', - name='created_at', - field=models.DateTimeField(default=django.utils.timezone.now, help_text='The date and time that this statement was created at.'), - ), - migrations.AddField( - model_name='conversation', - name='statements', - field=models.ManyToManyField(help_text='The statements in this conversation.', related_name='conversation', to='django_chatterbot.Statement'), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0007_response_created_at.py b/chatter/source/ext/django_chatterbot/migrations/0007_response_created_at.py deleted file mode 100644 index 1a0b5ac..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0007_response_created_at.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2017-07-18 00:16 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0006_create_conversation'), - ] - - operations = [ - migrations.AddField( - model_name='response', - name='created_at', - field=models.DateTimeField( - default=django.utils.timezone.now, - help_text='The date and time that this response was created at.' - ), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0008_update_conversations.py b/chatter/source/ext/django_chatterbot/migrations/0008_update_conversations.py deleted file mode 100644 index f3bd720..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0008_update_conversations.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2017-07-18 11:25 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0007_response_created_at'), - ] - - operations = [ - migrations.RemoveField( - model_name='conversation', - name='statements', - ), - migrations.RemoveField( - model_name='response', - name='occurrence', - ), - migrations.RemoveField( - model_name='statement', - name='created_at', - ), - migrations.AddField( - model_name='conversation', - name='responses', - field=models.ManyToManyField(help_text='The responses in this conversation.', related_name='conversations', to='django_chatterbot.Response'), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0009_tags.py b/chatter/source/ext/django_chatterbot/migrations/0009_tags.py deleted file mode 100644 index ee71713..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0009_tags.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11a1 on 2017-07-07 00:12 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0008_update_conversations'), - ] - - operations = [ - migrations.CreateModel( - name='Tag', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.SlugField()), - ], - options={ - 'abstract': False, - }, - ), - migrations.AlterField( - model_name='statement', - name='text', - field=models.CharField(max_length=255, unique=True), - ), - migrations.AddField( - model_name='tag', - name='statements', - field=models.ManyToManyField(related_name='tags', to='django_chatterbot.Statement'), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0010_statement_text.py b/chatter/source/ext/django_chatterbot/migrations/0010_statement_text.py deleted file mode 100644 index 84940a7..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0010_statement_text.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.4 on 2017-08-16 00:56 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0009_tags'), - ] - - operations = [ - migrations.AlterField( - model_name='statement', - name='text', - field=models.CharField(max_length=400, unique=True), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/0011_blank_extra_data.py b/chatter/source/ext/django_chatterbot/migrations/0011_blank_extra_data.py deleted file mode 100644 index 4f7b327..0000000 --- a/chatter/source/ext/django_chatterbot/migrations/0011_blank_extra_data.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.4 on 2017-08-20 13:55 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_chatterbot', '0010_statement_text'), - ] - - operations = [ - migrations.AlterField( - model_name='statement', - name='extra_data', - field=models.CharField(blank=True, max_length=500), - ), - ] diff --git a/chatter/source/ext/django_chatterbot/migrations/__init__.py b/chatter/source/ext/django_chatterbot/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/chatter/source/ext/django_chatterbot/models.py b/chatter/source/ext/django_chatterbot/models.py deleted file mode 100644 index ac51c06..0000000 --- a/chatter/source/ext/django_chatterbot/models.py +++ /dev/null @@ -1,34 +0,0 @@ -from .abstract_models import ( - AbstractBaseConversation, AbstractBaseResponse, - AbstractBaseStatement, AbstractBaseTag -) - - -class Statement(AbstractBaseStatement): - """ - A statement represents a single spoken entity, sentence or - phrase that someone can say. - """ - pass - - -class Response(AbstractBaseResponse): - """ - A connection between a statement and anther statement - that response to it. - """ - pass - - -class Conversation(AbstractBaseConversation): - """ - A sequence of statements representing a conversation. - """ - pass - - -class Tag(AbstractBaseTag): - """ - A label that categorizes a statement. - """ - pass diff --git a/chatter/source/ext/django_chatterbot/settings.py b/chatter/source/ext/django_chatterbot/settings.py deleted file mode 100644 index 802b77d..0000000 --- a/chatter/source/ext/django_chatterbot/settings.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Default ChatterBot settings for Django. -""" -from django.conf import settings -from ... import constants - - -CHATTERBOT_SETTINGS = getattr(settings, 'CHATTERBOT', {}) - -CHATTERBOT_DEFAULTS = { - 'name': 'ChatterBot', - 'storage_adapter': 'chatter.source.storage.DjangoStorageAdapter', - 'input_adapter': 'chatter.source.input.VariableInputTypeAdapter', - 'output_adapter': 'chatter.source.output.OutputAdapter', - 'django_app_name': constants.DEFAULT_DJANGO_APP_NAME -} - -CHATTERBOT = CHATTERBOT_DEFAULTS.copy() -CHATTERBOT.update(CHATTERBOT_SETTINGS) diff --git a/chatter/source/ext/django_chatterbot/urls.py b/chatter/source/ext/django_chatterbot/urls.py deleted file mode 100644 index 079005d..0000000 --- a/chatter/source/ext/django_chatterbot/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.conf.urls import url -from .views import ChatterBotView - - -urlpatterns = [ - url( - r'^$', - ChatterBotView.as_view(), - name='chatterbot', - ), -] diff --git a/chatter/source/ext/django_chatterbot/views.py b/chatter/source/ext/django_chatterbot/views.py deleted file mode 100644 index d73408e..0000000 --- a/chatter/source/ext/django_chatterbot/views.py +++ /dev/null @@ -1,118 +0,0 @@ -import json -from django.views.generic import View -from django.http import JsonResponse -from ... import ChatBot -from . import settings - - -class ChatterBotViewMixin(object): - """ - Subclass this mixin for access to the 'chatterbot' attribute. - """ - - chatterbot = ChatBot(**settings.CHATTERBOT) - - def validate(self, data): - """ - Validate the data recieved from the client. - - * The data should contain a text attribute. - """ - from django.core.exceptions import ValidationError - - if 'text' not in data: - raise ValidationError('The attribute "text" is required.') - - def get_conversation(self, request): - """ - Return the conversation for the session if one exists. - Create a new conversation if one does not exist. - """ - from .models import Conversation, Response - - class Obj(object): - def __init__(self): - self.id = None - self.statements = [] - - conversation = Obj() - - conversation.id = request.session.get('conversation_id', 0) - existing_conversation = False - try: - Conversation.objects.get(id=conversation.id) - existing_conversation = True - - except Conversation.DoesNotExist: - conversation_id = self.chatterbot.storage.create_conversation() - request.session['conversation_id'] = conversation_id - conversation.id = conversation_id - - if existing_conversation: - responses = Response.objects.filter( - conversations__id=conversation.id - ) - - for response in responses: - conversation.statements.append(response.statement.serialize()) - conversation.statements.append(response.response.serialize()) - - return conversation - - -class ChatterBotView(ChatterBotViewMixin, View): - """ - Provide an API endpoint to interact with ChatterBot. - """ - - def post(self, request, *args, **kwargs): - """ - Return a response to the statement in the posted data. - """ - input_data = json.loads(request.read().decode('utf-8')) - - self.validate(input_data) - - conversation = self.get_conversation(request) - - response = self.chatterbot.get_response(input_data, conversation.id) - response_data = response.serialize() - - return JsonResponse(response_data, status=200) - - def get(self, request, *args, **kwargs): - """ - Return data corresponding to the current conversation. - """ - conversation = self.get_conversation(request) - - data = { - 'detail': 'You should make a POST request to this endpoint.', - 'name': self.chatterbot.name, - 'conversation': conversation.statements - } - - # Return a method not allowed response - return JsonResponse(data, status=405) - - def patch(self, request, *args, **kwargs): - """ - The patch method is not allowed for this endpoint. - """ - data = { - 'detail': 'You should make a POST request to this endpoint.' - } - - # Return a method not allowed response - return JsonResponse(data, status=405) - - def delete(self, request, *args, **kwargs): - """ - The delete method is not allowed for this endpoint. - """ - data = { - 'detail': 'You should make a POST request to this endpoint.' - } - - # Return a method not allowed response - return JsonResponse(data, status=405) diff --git a/chatter/source/ext/sqlalchemy_app/__init__.py b/chatter/source/ext/sqlalchemy_app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/chatter/source/ext/sqlalchemy_app/__pycache__/__init__.cpython-36.pyc b/chatter/source/ext/sqlalchemy_app/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 2faf4fc..0000000 Binary files a/chatter/source/ext/sqlalchemy_app/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/ext/sqlalchemy_app/__pycache__/models.cpython-36.pyc b/chatter/source/ext/sqlalchemy_app/__pycache__/models.cpython-36.pyc deleted file mode 100644 index feb27f8..0000000 Binary files a/chatter/source/ext/sqlalchemy_app/__pycache__/models.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/ext/sqlalchemy_app/__pycache__/types.cpython-36.pyc b/chatter/source/ext/sqlalchemy_app/__pycache__/types.cpython-36.pyc deleted file mode 100644 index 93e7532..0000000 Binary files a/chatter/source/ext/sqlalchemy_app/__pycache__/types.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/__init__.cpython-36.pyc b/chatter/source/input/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 360dbeb..0000000 Binary files a/chatter/source/input/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/gitter.cpython-36.pyc b/chatter/source/input/__pycache__/gitter.cpython-36.pyc deleted file mode 100644 index 15765b3..0000000 Binary files a/chatter/source/input/__pycache__/gitter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/hipchat.cpython-36.pyc b/chatter/source/input/__pycache__/hipchat.cpython-36.pyc deleted file mode 100644 index 9ce7312..0000000 Binary files a/chatter/source/input/__pycache__/hipchat.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/input_adapter.cpython-36.pyc b/chatter/source/input/__pycache__/input_adapter.cpython-36.pyc deleted file mode 100644 index 59defa7..0000000 Binary files a/chatter/source/input/__pycache__/input_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/mailgun.cpython-36.pyc b/chatter/source/input/__pycache__/mailgun.cpython-36.pyc deleted file mode 100644 index 6ca78af..0000000 Binary files a/chatter/source/input/__pycache__/mailgun.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/microsoft.cpython-36.pyc b/chatter/source/input/__pycache__/microsoft.cpython-36.pyc deleted file mode 100644 index 58f5b4e..0000000 Binary files a/chatter/source/input/__pycache__/microsoft.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/terminal.cpython-36.pyc b/chatter/source/input/__pycache__/terminal.cpython-36.pyc deleted file mode 100644 index ed2c5bd..0000000 Binary files a/chatter/source/input/__pycache__/terminal.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/input/__pycache__/variable_input_type_adapter.cpython-36.pyc b/chatter/source/input/__pycache__/variable_input_type_adapter.cpython-36.pyc deleted file mode 100644 index 593d964..0000000 Binary files a/chatter/source/input/__pycache__/variable_input_type_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/__init__.cpython-36.pyc b/chatter/source/logic/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 56ea4ef..0000000 Binary files a/chatter/source/logic/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/best_match.cpython-36.pyc b/chatter/source/logic/__pycache__/best_match.cpython-36.pyc deleted file mode 100644 index da71469..0000000 Binary files a/chatter/source/logic/__pycache__/best_match.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/logic_adapter.cpython-36.pyc b/chatter/source/logic/__pycache__/logic_adapter.cpython-36.pyc deleted file mode 100644 index ca2c83d..0000000 Binary files a/chatter/source/logic/__pycache__/logic_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/low_confidence.cpython-36.pyc b/chatter/source/logic/__pycache__/low_confidence.cpython-36.pyc deleted file mode 100644 index a156f97..0000000 Binary files a/chatter/source/logic/__pycache__/low_confidence.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/mathematical_evaluation.cpython-36.pyc b/chatter/source/logic/__pycache__/mathematical_evaluation.cpython-36.pyc deleted file mode 100644 index 452d69f..0000000 Binary files a/chatter/source/logic/__pycache__/mathematical_evaluation.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/multi_adapter.cpython-36.pyc b/chatter/source/logic/__pycache__/multi_adapter.cpython-36.pyc deleted file mode 100644 index e3517c8..0000000 Binary files a/chatter/source/logic/__pycache__/multi_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/no_knowledge_adapter.cpython-36.pyc b/chatter/source/logic/__pycache__/no_knowledge_adapter.cpython-36.pyc deleted file mode 100644 index 7d286d6..0000000 Binary files a/chatter/source/logic/__pycache__/no_knowledge_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/specific_response.cpython-36.pyc b/chatter/source/logic/__pycache__/specific_response.cpython-36.pyc deleted file mode 100644 index 179e73d..0000000 Binary files a/chatter/source/logic/__pycache__/specific_response.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/logic/__pycache__/time_adapter.cpython-36.pyc b/chatter/source/logic/__pycache__/time_adapter.cpython-36.pyc deleted file mode 100644 index 9cbf60e..0000000 Binary files a/chatter/source/logic/__pycache__/time_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/__init__.cpython-36.pyc b/chatter/source/output/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 0f996ed..0000000 Binary files a/chatter/source/output/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/gitter.cpython-36.pyc b/chatter/source/output/__pycache__/gitter.cpython-36.pyc deleted file mode 100644 index 37a8524..0000000 Binary files a/chatter/source/output/__pycache__/gitter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/hipchat.cpython-36.pyc b/chatter/source/output/__pycache__/hipchat.cpython-36.pyc deleted file mode 100644 index 7d2dec4..0000000 Binary files a/chatter/source/output/__pycache__/hipchat.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/mailgun.cpython-36.pyc b/chatter/source/output/__pycache__/mailgun.cpython-36.pyc deleted file mode 100644 index 3295a1a..0000000 Binary files a/chatter/source/output/__pycache__/mailgun.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/microsoft.cpython-36.pyc b/chatter/source/output/__pycache__/microsoft.cpython-36.pyc deleted file mode 100644 index 73bc7a2..0000000 Binary files a/chatter/source/output/__pycache__/microsoft.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/output_adapter.cpython-36.pyc b/chatter/source/output/__pycache__/output_adapter.cpython-36.pyc deleted file mode 100644 index 478d6c1..0000000 Binary files a/chatter/source/output/__pycache__/output_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/output/__pycache__/terminal.cpython-36.pyc b/chatter/source/output/__pycache__/terminal.cpython-36.pyc deleted file mode 100644 index 98a931b..0000000 Binary files a/chatter/source/output/__pycache__/terminal.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/__pycache__/__init__.cpython-36.pyc b/chatter/source/storage/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 2eb08ba..0000000 Binary files a/chatter/source/storage/__pycache__/__init__.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/__pycache__/django_storage.cpython-36.pyc b/chatter/source/storage/__pycache__/django_storage.cpython-36.pyc deleted file mode 100644 index c8e1f3a..0000000 Binary files a/chatter/source/storage/__pycache__/django_storage.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/__pycache__/mongodb.cpython-36.pyc b/chatter/source/storage/__pycache__/mongodb.cpython-36.pyc deleted file mode 100644 index 4ef2bb1..0000000 Binary files a/chatter/source/storage/__pycache__/mongodb.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/__pycache__/sql_storage.cpython-36.pyc b/chatter/source/storage/__pycache__/sql_storage.cpython-36.pyc deleted file mode 100644 index b8acba2..0000000 Binary files a/chatter/source/storage/__pycache__/sql_storage.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/__pycache__/storage_adapter.cpython-36.pyc b/chatter/source/storage/__pycache__/storage_adapter.cpython-36.pyc deleted file mode 100644 index b3b34df..0000000 Binary files a/chatter/source/storage/__pycache__/storage_adapter.cpython-36.pyc and /dev/null differ diff --git a/chatter/source/storage/django_storage.py b/chatter/source/storage/django_storage.py deleted file mode 100644 index 5642b2c..0000000 --- a/chatter/source/storage/django_storage.py +++ /dev/null @@ -1,220 +0,0 @@ -from . import StorageAdapter -from .. import constants - - -class DjangoStorageAdapter(StorageAdapter): - """ - Storage adapter that allows ChatterBot to interact with - Django storage backends. - """ - - def __init__(self, **kwargs): - super(DjangoStorageAdapter, self).__init__(**kwargs) - - self.adapter_supports_queries = False - self.django_app_name = kwargs.get( - 'django_app_name', - constants.DEFAULT_DJANGO_APP_NAME - ) - - def get_statement_model(self): - from django.apps import apps - return apps.get_model(self.django_app_name, 'Statement') - - def get_response_model(self): - from django.apps import apps - return apps.get_model(self.django_app_name, 'Response') - - def get_conversation_model(self): - from django.apps import apps - return apps.get_model(self.django_app_name, 'Conversation') - - def get_tag_model(self): - from django.apps import apps - return apps.get_model(self.django_app_name, 'Tag') - - def count(self): - Statement = self.get_model('statement') - return Statement.objects.count() - - def find(self, statement_text): - Statement = self.get_model('statement') - try: - return Statement.objects.get(text=statement_text) - except Statement.DoesNotExist as e: - self.logger.info(str(e)) - return None - - def filter(self, **kwargs): - """ - Returns a list of statements in the database - that match the parameters specified. - """ - from django.db.models import Q - Statement = self.get_model('statement') - - order = kwargs.pop('order_by', None) - - RESPONSE_CONTAINS = 'in_response_to__contains' - - if RESPONSE_CONTAINS in kwargs: - value = kwargs[RESPONSE_CONTAINS] - del kwargs[RESPONSE_CONTAINS] - kwargs['in_response__response__text'] = value - - kwargs_copy = kwargs.copy() - - for kwarg in kwargs_copy: - value = kwargs[kwarg] - del kwargs[kwarg] - kwarg = kwarg.replace('in_response_to', 'in_response') - kwargs[kwarg] = value - - if 'in_response' in kwargs: - responses = kwargs['in_response'] - del kwargs['in_response'] - - if responses: - kwargs['in_response__response__text__in'] = [] - for response in responses: - kwargs['in_response__response__text__in'].append(response) - else: - kwargs['in_response'] = None - - parameters = {} - if 'in_response__response__text' in kwargs: - value = kwargs['in_response__response__text'] - parameters['responses__statement__text'] = value - - statements = Statement.objects.filter(Q(**kwargs) | Q(**parameters)) - - if order: - statements = statements.order_by(order) - - return statements - - def update(self, statement): - """ - Update the provided statement. - """ - Statement = self.get_model('statement') - Response = self.get_model('response') - - response_statement_cache = statement.response_statement_cache - - statement, created = Statement.objects.get_or_create(text=statement.text) - statement.extra_data = getattr(statement, 'extra_data', '') - statement.save() - - for _response_statement in response_statement_cache: - - response_statement, created = Statement.objects.get_or_create( - text=_response_statement.text - ) - response_statement.extra_data = getattr(_response_statement, 'extra_data', '') - response_statement.save() - - Response.objects.create( - statement=response_statement, - response=statement - ) - - return statement - - def get_random(self): - """ - Returns a random statement from the database - """ - Statement = self.get_model('statement') - return Statement.objects.order_by('?').first() - - def remove(self, statement_text): - """ - Removes the statement that matches the input text. - Removes any responses from statements if the response text matches the - input text. - """ - from django.db.models import Q - - Statement = self.get_model('statement') - Response = self.get_model('response') - - statements = Statement.objects.filter(text=statement_text) - - responses = Response.objects.filter( - Q(statement__text=statement_text) | Q(response__text=statement_text) - ) - - responses.delete() - statements.delete() - - def get_latest_response(self, conversation_id): - """ - Returns the latest response in a conversation if it exists. - Returns None if a matching conversation cannot be found. - """ - Response = self.get_model('response') - - response = Response.objects.filter( - conversations__id=conversation_id - ).order_by( - 'created_at' - ).last() - - if not response: - return None - - return response.response - - def create_conversation(self): - """ - Create a new conversation. - """ - Conversation = self.get_model('conversation') - conversation = Conversation.objects.create() - return conversation.id - - def add_to_conversation(self, conversation_id, statement, response): - """ - Add the statement and response to the conversation. - """ - Statement = self.get_model('statement') - Response = self.get_model('response') - - first_statement, created = Statement.objects.get_or_create(text=statement.text) - first_response, created = Statement.objects.get_or_create(text=response.text) - - response = Response.objects.create( - statement=first_statement, - response=first_response - ) - - response.conversations.add(conversation_id) - - def drop(self): - """ - Remove all data from the database. - """ - Statement = self.get_model('statement') - Response = self.get_model('response') - Conversation = self.get_model('conversation') - Tag = self.get_model('tag') - - Statement.objects.all().delete() - Response.objects.all().delete() - Conversation.objects.all().delete() - Tag.objects.all().delete() - - def get_response_statements(self): - """ - Return only statements that are in response to another statement. - A statement must exist which lists the closest matching statement in the - in_response_to field. Otherwise, the logic adapter may find a closest - matching statement that does not have a known response. - """ - Statement = self.get_model('statement') - Response = self.get_model('response') - - responses = Response.objects.all() - - return Statement.objects.filter(in_response__in=responses) diff --git a/fight/fight.py b/fight/fight.py index ff115e1..931c7c9 100644 --- a/fight/fight.py +++ b/fight/fight.py @@ -1142,7 +1142,7 @@ class Fight: #**************** Attempt 2, borrow from Squid******* - async def on_raw_reaction_add(self, emoji: discord.PartialReactionEmoji, + async def on_raw_reaction_add(self, emoji: discord.PartialEmoji, message_id: int, channel_id: int, user_id: int): """ Event handler for long term reaction watching. diff --git a/hangman/__init__.py b/hangman/__init__.py new file mode 100644 index 0000000..2168fdf --- /dev/null +++ b/hangman/__init__.py @@ -0,0 +1,9 @@ +from .hangman import Hangman +from redbot.core import data_manager + + +def setup(bot): + n = Hangman(bot) + data_manager.load_bundled_data(n, __file__) + bot.add_cog(n) + bot.add_listener(n._on_react, "on_reaction_add") diff --git a/hangman/hangman.py b/hangman/hangman.py index 987b3a2..766177f 100644 --- a/hangman/hangman.py +++ b/hangman/hangman.py @@ -1,356 +1,338 @@ -import discord -import os - -from discord.ext import commands +from collections import defaultdict from random import randint -from .utils.dataIO import dataIO -from .utils import checks +import discord +from discord.ext import commands +from redbot.core import Config, checks +from redbot.core.data_manager import cog_data_path, load_basic_configuration class Hangman: """Lets anyone play a game of hangman with custom phrases""" + navigate = "๐Ÿ”ผ๐Ÿ”ฝ" + letters = "๐Ÿ‡ฆ๐Ÿ‡ง๐Ÿ‡จ๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿ‡ซ๐Ÿ‡ฌ๐Ÿ‡ญ๐Ÿ‡ฎ๐Ÿ‡ฏ๐Ÿ‡ฐ๐Ÿ‡ฑ๐Ÿ‡ฒ๐Ÿ‡ณ๐Ÿ‡ด๐Ÿ‡ต๐Ÿ‡ถ๐Ÿ‡ท๐Ÿ‡ธ๐Ÿ‡น๐Ÿ‡บ๐Ÿ‡ป๐Ÿ‡ผ๐Ÿ‡ฝ๐Ÿ‡พ๐Ÿ‡ฟ" def __init__(self, bot): self.bot = bot - self.path = "data/Fox-Cogs/hangman" - self.file_path = "data/Fox-Cogs/hangman/hangman.json" - self.answer_path = "data/hangman/hanganswers.txt" - self.the_data = dataIO.load_json(self.file_path) - self.winbool = False - self.letters = "๐Ÿ‡ฆ๐Ÿ‡ง๐Ÿ‡จ๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿ‡ซ๐Ÿ‡ฌ๐Ÿ‡ญ๐Ÿ‡ฎ๐Ÿ‡ฏ๐Ÿ‡ฐ๐Ÿ‡ฑ๐Ÿ‡ฒ๐Ÿ‡ณ๐Ÿ‡ด๐Ÿ‡ต๐Ÿ‡ถ๐Ÿ‡ท๐Ÿ‡ธ๐Ÿ‡น๐Ÿ‡บ๐Ÿ‡ป๐Ÿ‡ผ๐Ÿ‡ฝ๐Ÿ‡พ๐Ÿ‡ฟ" - self.navigate = "๐Ÿ”ผ๐Ÿ”ฝ" - self._updateHanglist() - - def _updateHanglist(self): - self.hanglist = ( - """> - \_________ - |/ - | - | - | - | - | - |\___ - """, - - """> - \_________ - |/ | - | - | - | - | - | - |\___ - H""", - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | - | - | - | - |\___ - HA""", - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | | - | | - | - | - |\___ - HAN""", - - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | /| - | | - | - | - |\___ - HANG""", - - - """> - \_________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | - | - |\___ - HANGM""", - - - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | / - | - |\___ - HANGMA""", - - - """> - \________ - |/ | - | """+self.the_data["theface"]+""" - | /|\ - | | - | / \ - | - |\___ - HANGMAN""") - - def save_data(self): - """Saves the json""" - dataIO.save_json(self.file_path, self.the_data) - + self.config = Config.get_conf(self, identifier=1049711010310997110) + default_guild = { + "theface": ':thinking:', + } + + self.config.register_guild(**default_guild) + + self.the_data = defaultdict( + lambda: {"running": False, "hangman": 0, "guesses": [], "trackmessage": False, "answer": ''}) + self.path = str(cog_data_path(self)).replace('\\', '/') + + self.answer_path = self.path+"/bundled_data/hanganswers.txt" + + self.winbool = defaultdict(lambda: False) + + self.hanglist = {} + + async def _update_hanglist(self): + for guild in self.bot.guilds: + theface = await self.config.guild(guild).theface() + self.hanglist[guild] = ( + """> + \_________ + |/ + | + | + | + | + | + |\___ + """, + + """> + \_________ + |/ | + | + | + | + | + | + |\___ + H""", + + """> + \_________ + |/ | + | """ + theface + """ + | + | + | + | + |\___ + HA""", + + """> + \________ + |/ | + | """ + theface + """ + | | + | | + | + | + |\___ + HAN""", + + """> + \_________ + |/ | + | """ + theface + """ + | /| + | | + | + | + |\___ + HANG""", + + """> + \_________ + |/ | + | """ + theface + """ + | /|\ + | | + | + | + |\___ + HANGM""", + + """> + \________ + |/ | + | """ + theface + """ + | /|\ + | | + | / + | + |\___ + HANGMA""", + + """> + \________ + |/ | + | """ + theface + """ + | /|\ + | | + | / \ + | + |\___ + HANGMAN""") + @commands.group(aliases=['sethang'], pass_context=True) @checks.mod_or_permissions(administrator=True) async def hangset(self, ctx): """Adjust hangman settings""" - if ctx.invoked_subcommand is None: - await self.bot.send_cmd_help(ctx) - + if not ctx.invoked_subcommand: + await ctx.send_help() + @hangset.command(pass_context=True) - async def face(self, ctx, theface): + async def face(self, ctx: commands.Context, theface): message = ctx.message - #Borrowing FlapJack's emoji validation (https://github.com/flapjax/FlapJack-Cogs/blob/master/smartreact/smartreact.py) + # Borrowing FlapJack's emoji validation + # (https://github.com/flapjax/FlapJack-Cogs/blob/master/smartreact/smartreact.py) if theface[:2] == "<:": - theface = [r for server in self.bot.servers for r in server.emojis if r.id == theface.split(':')[2][:-1]][0] - + theface = [r for r in self.bot.emojis if r.id == theface.split(':')[2][:-1]][0] + try: # Use the face as reaction to see if it's valid (THANKS FLAPJACK <3) - await self.bot.add_reaction(message, theface) - self.the_data["theface"] = str(theface) - self.save_data() - self._updateHanglist() - await self.bot.say("Face has been updated!") - + await message.add_reaction(theface) except discord.errors.HTTPException: - await self.bot.say("That's not an emoji I recognize.") - + await ctx.send("That's not an emoji I recognize.") + return + + await self.config.guild(ctx.guild).theface.set(theface) + await self._update_hanglist() + await ctx.send("Face has been updated!") + @commands.command(aliases=['hang'], pass_context=True) - async def hangman(self, ctx, guess: str=None): + async def hangman(self, ctx, guess: str = None): """Play a game of hangman against the bot!""" if guess is None: - if self.the_data["running"]: - await self.bot.say("Game of hangman is already running!\nEnter your guess!") - self._printgame() + if self.the_data[ctx.guild]["running"]: + await ctx.send("Game of hangman is already running!\nEnter your guess!") + await self._printgame(ctx.channel) """await self.bot.send_cmd_help(ctx)""" else: - await self.bot.say("Starting a game of hangman!") - self._startgame() - await self._printgame() - elif not self.the_data["running"]: - await self.bot.say("Game of hangman is not yet running!\nStarting a game of hangman!") - self._startgame() - await self._printgame() - else: - await self._guessletter(guess) - - - - def _startgame(self): + await ctx.send("Starting a game of hangman!") + self._startgame(ctx.guild) + await self._printgame(ctx.channel) + elif not self.the_data[ctx.guild]["running"]: + await ctx.send("Game of hangman is not yet running!\nStarting a game of hangman!") + self._startgame(ctx.guild) + await self._printgame(ctx.channel) + else: + await ctx.send("Guess by reacting to the message") + # await self._guessletter(guess, ctx.channel) + + def _startgame(self, guild): """Starts a new game of hangman""" - self.the_data["answer"] = self._getphrase().upper() - self.the_data["hangman"] = 0 - self.the_data["guesses"] = [] - self.winbool = False - self.the_data["running"] = True - self.the_data["trackmessage"] = False - self.save_data() - - def _stopgame(self): + self.the_data[guild]["answer"] = self._getphrase().upper() + self.the_data[guild]["hangman"] = 0 + self.the_data[guild]["guesses"] = [] + self.winbool[guild] = False + self.the_data[guild]["running"] = True + self.the_data[guild]["trackmessage"] = False + + def _stopgame(self, guild): """Stops the game in current state""" - self.the_data["running"] = False - self.save_data() - - async def _checkdone(self, channel=None): - if self.winbool: - if channel: - await self.bot.send_message(channel, "You Win!") - else: - await self.bot.say("You Win!") - self._stopgame() - - if self.the_data["hangman"] >= 7: - if channel: - await self.bot.send_message(channel, "You Lose!\nThe Answer was: **"+self.the_data["answer"]+"**") - else: - await self.bot.say("You Lose!\nThe Answer was: **"+self.the_data["answer"]+"**") - - self._stopgame() - + self.the_data[guild]["running"] = False + self.the_data[guild]["trackmessage"] = False + + async def _checkdone(self, channel): + if self.winbool[channel.guild]: + await channel.send("You Win!") + self._stopgame(channel.guild) + elif self.the_data[channel.guild]["hangman"] >= 7: + await channel.send("You Lose!\nThe Answer was: **" + self.the_data[channel.guild]["answer"] + "**") + + self._stopgame(channel.guild) + def _getphrase(self): """Get a new phrase for the game and returns it""" - phrasefile = open(self.answer_path, 'r') - phrases = phrasefile.readlines() - + + with open(self.answer_path, 'r') as phrasefile: + phrases = phrasefile.readlines() + outphrase = "" while outphrase == "": - outphrase = phrases[randint(0, len(phrases)-1)].partition(" (")[0] -# outphrase = phrases[randint(0,10)].partition(" (")[0] + outphrase = phrases[randint(0, len(phrases) - 1)].partition(" (")[0] return outphrase - - def _hideanswer(self): + + def _hideanswer(self, guild): """Returns the obscured answer""" out_str = "" - - self.winbool = True - for i in self.the_data["answer"]: + + self.winbool[guild] = True + for i in self.the_data[guild]["answer"]: if i == " " or i == "-": - out_str += i*2 - elif i in self.the_data["guesses"] or i not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": - out_str += "__"+i+"__ " + out_str += i * 2 + elif i in self.the_data[guild]["guesses"] or i not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": + out_str += "__" + i + "__ " else: out_str += "**\_** " - self.winbool = False - + self.winbool[guild] = False + return out_str - - def _guesslist(self): + + def _guesslist(self, guild): """Returns the current letter list""" out_str = "" - for i in self.the_data["guesses"]: + for i in self.the_data[guild]["guesses"]: out_str += str(i) + "," out_str = out_str[:-1] - + return out_str - - async def _guessletter(self, guess, channel=None): + + async def _guessletter(self, guess, message): """Checks the guess on a letter and prints game if acceptable guess""" - if not guess.upper() in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or not len(guess) == 1: - if channel: - await self.bot.send_message(channel, "Invalid guess. Only A-Z is accepted") - else: - await self.bot.say("Invalid guess. Only A-Z is accepted") + channel = message.channel + if guess.upper() not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or len(guess) != 1: + await channel.send("Invalid guess. Only A-Z is accepted") return - if guess.upper() in self.the_data["guesses"]: - if channel: - await self.bot.send_message(channel, "Already guessed that! Try again") - else: - await self.bot.say("Already guessed that! Try again") + if guess.upper() in self.the_data[channel.guild]["guesses"]: + await channel.send("Already guessed that! Try again") return + if guess.upper() not in self.the_data[channel.guild]["answer"]: + self.the_data[channel.guild]["hangman"] += 1 + + self.the_data[channel.guild]["guesses"].append(guess.upper()) + + await self._reprintgame(message) - if not guess.upper() in self.the_data["answer"]: - self.the_data["hangman"] += 1 - - self.the_data["guesses"].append(guess.upper()) - self.save_data() - - await self._printgame(channel) - async def _on_react(self, reaction, user): """ Thanks to flapjack reactpoll for guidelines https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py""" - - - - if not self.the_data["trackmessage"]: + + if reaction.message.id != self.the_data[user.guild]["trackmessage"]: return - + if user == self.bot.user: return # Don't remove bot's own reactions message = reaction.message emoji = reaction.emoji - - if not message.id == self.the_data["trackmessage"]: - return - + if str(emoji) in self.letters: letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[self.letters.index(str(emoji))] - await self._guessletter(letter, message.channel) - - + await self._guessletter(letter, message) + await message.remove_reaction(emoji, user) + await message.remove_reaction(emoji, self.bot.user) + if str(emoji) in self.navigate: if str(emoji) == self.navigate[0]: await self._reactmessage_am(message) - + if str(emoji) == self.navigate[-1]: await self._reactmessage_nz(message) - - + async def _reactmessage_menu(self, message): """React with menu options""" - await self.bot.clear_reactions(message) - - await self.bot.add_reaction(message, self.navigate[0]) - await self.bot.add_reaction(message, self.navigate[-1]) - + await message.clear_reactions() + + await message.add_reaction(self.navigate[0]) + await message.add_reaction(self.navigate[-1]) + async def _reactmessage_am(self, message): - await self.bot.clear_reactions(message) + await message.clear_reactions() for x in range(len(self.letters)): - if x in [i for i,b in enumerate("ABCDEFGHIJKLM") if b not in self._guesslist()]: - await self.bot.add_reaction(message, self.letters[x]) - - await self.bot.add_reaction(message, self.navigate[-1]) + if x in [i for i, b in enumerate("ABCDEFGHIJKLM") if b not in self._guesslist(message.guild)]: + await message.add_reaction(self.letters[x]) + await message.add_reaction(self.navigate[-1]) async def _reactmessage_nz(self, message): - await self.bot.clear_reactions(message) + await message.clear_reactions() for x in range(len(self.letters)): - if x in [i for i,b in enumerate("NOPQRSTUVWXYZ") if b not in self._guesslist()]: - await self.bot.add_reaction(message, self.letters[x+13]) - - await self.bot.add_reaction(message, self.navigate[0]) + if x in [i for i, b in enumerate("NOPQRSTUVWXYZ") if b not in self._guesslist(message.guild)]: + await message.add_reaction(self.letters[x + 13]) + + await message.add_reaction(self.navigate[0]) + + def _make_say(self, guild): + c_say = "Guess this: " + str(self._hideanswer(guild)) + "\n" + c_say += "Used Letters: " + str(self._guesslist(guild)) + "\n" - async def _printgame(self, channel=None): + c_say += self.hanglist[guild][self.the_data[guild]["hangman"]] + "\n" + + c_say += self.navigate[0] + " for A-M, " + self.navigate[-1] + " for N-Z" + + return c_say + + async def _reprintgame(self, message): + if message.guild not in self.hanglist: + await self._update_hanglist() + + c_say = self._make_say(message.guild) + + await message.edit(content=c_say) + self.the_data[message.guild]["trackmessage"] = message.id + + await self._checkdone(message.channel) + + async def _printgame(self, channel): """Print the current state of game""" - cSay = ("Guess this: " + str(self._hideanswer()) + "\n" - + "Used Letters: " + str(self._guesslist()) + "\n" - + self.hanglist[self.the_data["hangman"]] + "\n" - + self.navigate[0]+" for A-M, "+self.navigate[-1]+" for N-Z") - if channel: - message = await self.bot.send_message(channel, cSay) - else: - message = await self.bot.say(cSay) - - self.the_data["trackmessage"] = message.id - self.save_data() + if channel.guild not in self.hanglist: + await self._update_hanglist() + + c_say = self._make_say(channel.guild) + + message = await channel.send(c_say) + + self.the_data[channel.guild]["trackmessage"] = message.id + await self._reactmessage_menu(message) await self._checkdone(channel) - - -def check_folders(): - if not os.path.exists("data/Fox-Cogs"): - print("Creating data/Fox-Cogs folder...") - os.makedirs("data/Fox-Cogs") - - if not os.path.exists("data/Fox-Cogs/hangman"): - print("Creating data/Fox-Cogs/hangman folder...") - os.makedirs("data/Fox-Cogs/hangman") - - -def check_files(): - if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"): - dataIO.save_json("data/Fox-Cogs/hangman/hangman.json", {"running": False, "hangman": 0, "guesses": [], "theface": "<:never:336861463446814720>", "trackmessage": False}) - + def setup(bot): - check_folders() - check_files() n = Hangman(bot) bot.add_cog(n) bot.add_listener(n._on_react, "on_reaction_add") - diff --git a/hangman/info.json b/hangman/info.json index ac146f1..655f00c 100644 --- a/hangman/info.json +++ b/hangman/info.json @@ -1,14 +1,20 @@ { - "AUTHOR": "Bobloy", - "DESCRIPTION": "Hangman Cog for Red Discord bot. Play a game of Hangman with your friends!", - "INSTALL_MSG": "Thank you for installing Hangman! Play with [p]hangman, edit with [p]hangset", - "NAME": "Hangman", - "SHORT": "Play a game of Hangman with your friends!", - "TAGS": [ - "fox", - "bobloy", - "fun", - "game" - ], - "HIDDEN": false + "author": [ + "Bobloy" + ], + "bot_version": [ + 3, + 0, + 0 + ], + "description": "Play Hangman with your friends", + "hidden": false, + "install_msg": "Thank you for installing Hangman!", + "requirements": [], + "short": "Play Hangman", + "tags": [ + "game", + "fun", + "bobloy" + ] } \ No newline at end of file diff --git a/immortal/immortal.py b/immortal/immortal.py deleted file mode 100644 index c20908c..0000000 --- a/immortal/immortal.py +++ /dev/null @@ -1,243 +0,0 @@ -import discord -import asyncio -import os -from datetime import datetime -from discord.ext import commands - -from .utils.dataIO import dataIO -from .utils import checks - - -class Immortal: - """Creates a goodbye message when people leave""" - - def __init__(self, bot): - self.bot = bot - self.path = "data/Fox-Cogs/immortal" - self.file_path = "data/Fox-Cogs/immortal/immortal.json" - self.the_data = dataIO.load_json(self.file_path) - - def save_data(self): - """Saves the json""" - dataIO.save_json(self.file_path, self.the_data) - - async def adj_roles(self, server, author, member: discord.Member=None, rrole_names=[], arole_names=[]): - # Thank you SML for the addrole code - # https://github.com/smlbiobot/SML-Cogs/tree/master/mm - - rroles = [r for r in server.roles if r.name in rrole_names] - aroles = [r for r in server.roles if r.name in arole_names] - try: - await self.bot.add_roles(member, *aroles) - await asyncio.sleep(0.5) - await self.bot.remove_roles(member, *rroles) - await asyncio.sleep(0.5) - - except discord.Forbidden: - await self.bot.say( - "{} does not have permission to edit {}โ€™s roles.".format( - author.display_name, member.display_name)) - - except discord.HTTPException: - await self.bot.say( - "Failed to adjust roles.") - except: - await self.bot.say("Unknown Exception") - - - - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def iresort(self, ctx, member: discord.Member=None): - """Sends someone on vacation!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Member", "Immortal", "Eternal", "Phantom", "Ghost", "Undead", "Revenant", "Crypt", "Relocate", "Guest"] - arole_names = ["Resort"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Resort" in [r.name for r in member.roles]: - await self.bot.say("You are being sent on Vacation! :tada:" + - "Please relocate to Immortal Resort (#889L92UQ) when you find the time.") - await self.bot.send_message(member, "You are being sent on Vacation! :tada: Please relocate " + - "to Immortal Resort (#889L92UQ) when you find the time.\n" + - "You'll have limited access to the server until you rejoin a main clan") - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def icrypt(self, ctx, member: discord.Member=None): - """Sends someone to Crypt!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Immortal", "Eternal", "Ghost", "Phantom", "Revenant", "Undead", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Crypt"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Crypt" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def irevenant(self, ctx, member: discord.Member=None): - """Sends someone to Revenant!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Immortal", "Eternal", "Ghost", "Phantom", "Undead", "Crypt", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Revenant"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Revenant" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def iundead(self, ctx, member: discord.Member=None): - """Sends someone to Undead!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Immortal", "Eternal", "Ghost", "Phantom", "Revenant", "Crypt", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Undead"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Undead" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def iphantom(self, ctx, member: discord.Member=None): - """Sends someone to Phantom!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Immortal", "Eternal", "Ghost", "Undead", "Revenant", "Crypt", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Phantom"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Phantom" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def ieternal(self, ctx, member: discord.Member=None): - """Sends someone to Eternal!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Immortal", "Phantom", "Ghost", "Undead", "Revenant", "Crypt", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Eternal"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Eternal" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.command(pass_context=True, no_pm=True) - @checks.mod_or_permissions(manage_roles=True) - async def iimmortal(self, ctx, member: discord.Member=None): - """Sends someone to Immortal!""" - - if member is None: - await self.bot.send_cmd_help(ctx) - else: - server = ctx.message.server - author = ctx.message.author - role_names = ["Eternal", "Phantom", "Ghost", "Undead", "Revenant", "Crypt", "Relocate", "Guest", "Resort"] - arole_names = ["Member", "Immortal"] - await self.adj_roles(server, author, member, role_names, arole_names) - if "Immortal" in [r.name for r in member.roles]: - await self.bot.say("Success") - await self.send_welcome(member) - - @commands.group(aliases=['setimmortal'], pass_context=True, no_pm=True) - @checks.mod_or_permissions(administrator=True) - async def immortalset(self, ctx): - """Adjust immortal settings""" - - server = ctx.message.server - if server.id not in self.the_data: - self.the_data[server.id] = {} - self.save_data() - - if ctx.invoked_subcommand is None: - await self.bot.send_cmd_help(ctx) - - @immortalset.command(pass_context=True, no_pm=True) - async def welcomechannel(self, ctx): - server = ctx.message.server - if 'WELCOMECHANNEL' not in self.the_data[server.id]: - self.the_data[server.id]['WELCOMECHANNEL'] = '' - - self.the_data[server.id]['WELCOMECHANNEL'] = ctx.message.channel.id - self.save_data() - await self.bot.say("Welcome Channel set to "+ctx.message.channel.name) - - async def send_welcome(self, member): - server = member.server - if server.id in self.the_data: - await self.bot.send_message(server.get_channel(self.the_data[server.id]['WELCOMECHANNEL']), - "You now have access to the server, " + member.mention + "\n" + - "Check " + server.get_channel("257557008662790145").mention + " & " + - server.get_channel("257560603093106688").mention+" for clan rules etc.\n" + - "We recommend turning all message notifications on for " + server.get_channel("257560603093106688").mention + - " if you want to know when tourneys are posted and other important info.\n" + - "You can also type `!help` for a list of bot commands/features.") - -# @immortalset.command(pass_context=True) -# async def channel(self, ctx): -# server = ctx.message.server -# if 'channel' not in self.the_data[server.id]: -# self.the_data[server.id]['channel'] = '' - -# self.the_data[server.id]['channel'] = ctx.message.channel.id -# self.save_data() - -# async def _when_leave(self, member): -# server = member.server -# if server.id not in self.the_data: -# return - -# await self.bot.say("YOU LEFT ME "+member.mention) -# self.the_data[server.id] - - -def check_folders(): - if not os.path.exists("data/Fox-Cogs"): - print("Creating data/Fox-Cogs folder...") - os.makedirs("data/Fox-Cogs") - - if not os.path.exists("data/Fox-Cogs/immortal"): - print("Creating data/Fox-Cogs/immortal folder...") - os.makedirs("data/Fox-Cogs/immortal") - - -def check_files(): - if not dataIO.is_valid_json("data/Fox-Cogs/immortal/immortal.json"): - dataIO.save_json("data/Fox-Cogs/immortal/immortal.json", {}) - - -def setup(bot): - check_folders() - check_files() - q = Immortal(bot) - bot.add_cog(q) diff --git a/immortal/info.json b/immortal/info.json deleted file mode 100644 index 8668a65..0000000 --- a/immortal/info.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "AUTHOR" : "Bobloy", - "INSTALL_MSG" : "Thank you for installing Immortal Family Cog", - "NAME" : "Immortal", - "SHORT" : "Cog for a specific server, will not work on other servers", - "DESCRIPTION" : "Cog specifically for the Immortal Family discord server. I do not recommend installing it", - "TAGS" : ["fox", "bobloy", "utilities", "tools", "utility", "tool"], - "HIDDEN" : false -} \ No newline at end of file