commit
877a08d3a6
@ -1,5 +1,11 @@
|
|||||||
from .chatter import Chatter
|
from . import chatterbot
|
||||||
|
from .chat import Chatter
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(Chatter(bot))
|
bot.add_cog(Chatter(bot))
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'chatterbot'
|
||||||
|
)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import importlib
|
import importlib
|
||||||
|
|
@ -1,12 +1,11 @@
|
|||||||
from .input_adapter import InputAdapter
|
from .input_adapter import InputAdapter
|
||||||
from .microsoft import Microsoft
|
|
||||||
from .gitter import Gitter
|
from .gitter import Gitter
|
||||||
from .hipchat import HipChat
|
from .hipchat import HipChat
|
||||||
from .mailgun import Mailgun
|
from .mailgun import Mailgun
|
||||||
|
from .microsoft import Microsoft
|
||||||
from .terminal import TerminalAdapter
|
from .terminal import TerminalAdapter
|
||||||
from .variable_input_type_adapter import VariableInputTypeAdapter
|
from .variable_input_type_adapter import VariableInputTypeAdapter
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'InputAdapter',
|
'InputAdapter',
|
||||||
'Microsoft',
|
'Microsoft',
|
@ -1,7 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from time import sleep
|
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):
|
class Gitter(InputAdapter):
|
@ -1,7 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from time import sleep
|
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):
|
class HipChat(InputAdapter):
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from ..adapters import Adapter
|
|
||||||
|
from chatter.chatterbot.adapters import Adapter
|
||||||
|
|
||||||
|
|
||||||
class InputAdapter(Adapter):
|
class InputAdapter(Adapter):
|
@ -1,7 +1,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from . import InputAdapter
|
|
||||||
from ..conversation import Statement
|
from chatter.chatterbot.conversation import Statement
|
||||||
|
from chatter.chatterbot.input import InputAdapter
|
||||||
|
|
||||||
|
|
||||||
class Mailgun(InputAdapter):
|
class Mailgun(InputAdapter):
|
@ -1,7 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from . import InputAdapter
|
|
||||||
from ..conversation import Statement
|
from chatter.chatterbot.conversation import Statement
|
||||||
from ..utils import input_function
|
from chatter.chatterbot.input import InputAdapter
|
||||||
|
from chatter.chatterbot.utils import input_function
|
||||||
|
|
||||||
|
|
||||||
class TerminalAdapter(InputAdapter):
|
class TerminalAdapter(InputAdapter):
|
@ -1,22 +1,18 @@
|
|||||||
from __future__ import unicode_literals
|
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'
|
JSON = 'json'
|
||||||
TEXT = 'text'
|
TEXT = 'text'
|
||||||
OBJECT = 'object'
|
OBJECT = 'object'
|
||||||
VALID_FORMATS = (JSON, TEXT, OBJECT, )
|
VALID_FORMATS = (JSON, TEXT, OBJECT,)
|
||||||
|
|
||||||
def detect_type(self, statement):
|
def detect_type(self, statement):
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info[0] < 3:
|
string_types = str
|
||||||
string_types = basestring # NOQA
|
|
||||||
else:
|
|
||||||
string_types = str
|
|
||||||
|
|
||||||
if hasattr(statement, 'text'):
|
if hasattr(statement, 'text'):
|
||||||
return self.OBJECT
|
return self.OBJECT
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .logic_adapter import LogicAdapter
|
from .logic_adapter import LogicAdapter
|
||||||
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from ..conversation import Statement
|
|
||||||
|
from chatter.chatterbot.conversation import Statement
|
||||||
from .best_match import BestMatch
|
from .best_match import BestMatch
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
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):
|
class MathematicalEvaluation(LogicAdapter):
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .logic_adapter import LogicAdapter
|
from .logic_adapter import LogicAdapter
|
||||||
|
|
||||||
|
|
@ -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 .gitter import Gitter
|
||||||
from .hipchat import HipChat
|
from .hipchat import HipChat
|
||||||
|
from .mailgun import Mailgun
|
||||||
|
from .microsoft import Microsoft
|
||||||
|
from .output_adapter import OutputAdapter
|
||||||
|
from .terminal import TerminalAdapter
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'OutputAdapter',
|
'OutputAdapter',
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .output_adapter import OutputAdapter
|
from .output_adapter import OutputAdapter
|
||||||
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .output_adapter import OutputAdapter
|
from .output_adapter import OutputAdapter
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .output_adapter import OutputAdapter
|
from .output_adapter import OutputAdapter
|
||||||
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .output_adapter import OutputAdapter
|
from .output_adapter import OutputAdapter
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
from ..adapters import Adapter
|
from chatter.chatterbot.adapters import Adapter
|
||||||
|
|
||||||
|
|
||||||
class OutputAdapter(Adapter):
|
class OutputAdapter(Adapter):
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .output_adapter import OutputAdapter
|
from .output_adapter import OutputAdapter
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import calendar
|
||||||
import re
|
import re
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
import calendar
|
|
||||||
|
|
||||||
# Variations of dates that the parser can capture
|
# Variations of dates that the parser can capture
|
||||||
year_variations = ['year', 'years', 'yrs']
|
year_variations = ['year', 'years', 'yrs']
|
@ -1,12 +1,9 @@
|
|||||||
from .storage_adapter import StorageAdapter
|
from .storage_adapter import StorageAdapter
|
||||||
from .django_storage import DjangoStorageAdapter
|
|
||||||
from .mongodb import MongoDatabaseAdapter
|
from .mongodb import MongoDatabaseAdapter
|
||||||
from .sql_storage import SQLStorageAdapter
|
from .sql_storage import SQLStorageAdapter
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'StorageAdapter',
|
'StorageAdapter',
|
||||||
'DjangoStorageAdapter',
|
|
||||||
'MongoDatabaseAdapter',
|
'MongoDatabaseAdapter',
|
||||||
'SQLStorageAdapter',
|
'SQLStorageAdapter',
|
||||||
)
|
)
|
@ -1,10 +1,30 @@
|
|||||||
{
|
{
|
||||||
"author" : ["Bobloy"],
|
"author": [
|
||||||
"bot_version" : [3,0,0],
|
"Bobloy"
|
||||||
"description" : "Create an offline chatbot that talks like your average member using Machine Learning",
|
],
|
||||||
"hidden" : false,
|
"bot_version": [
|
||||||
"install_msg" : "Thank you for installing Chatter!",
|
3,
|
||||||
"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"],
|
0,
|
||||||
"short" : "Local Chatbot run on machine learning",
|
0
|
||||||
"tags" : ["chat", "chatbot", "cleverbot", "clever","bobloy"]
|
],
|
||||||
|
"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"
|
||||||
|
]
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +0,0 @@
|
|||||||
default_app_config = (
|
|
||||||
'chatter.source.ext.django_chatterbot.apps.DjangoChatterBotConfig'
|
|
||||||
)
|
|
@ -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 '<empty>'
|
|
||||||
|
|
||||||
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
|
|
@ -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)
|
|
@ -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'
|
|
@ -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
|
|
@ -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))
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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,
|
|
||||||
),
|
|
||||||
]
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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.'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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.'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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
|
|
@ -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)
|
|
@ -1,11 +0,0 @@
|
|||||||
from django.conf.urls import url
|
|
||||||
from .views import ChatterBotView
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
url(
|
|
||||||
r'^$',
|
|
||||||
ChatterBotView.as_view(),
|
|
||||||
name='chatterbot',
|
|
||||||
),
|
|
||||||
]
|
|
@ -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)
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue