pull/1/head
Bobloy 7 years ago
parent d7b91c4f4f
commit bb6a336e0e

@ -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):

@ -1,3 +0,0 @@
default_app_config = (
'chatterbot.ext.django_chatterbot.apps.DjangoChatterBotConfig'
)

@ -1,261 +0,0 @@
from chatterbot.conversation import StatementMixin
from chatterbot 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 chatterbot.ext.django_chatterbot.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 = 'chatterbot.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 chatterbot.ext.django_chatterbot import models
from chatterbot 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 chatterbot import ChatBot
from chatterbot.ext.django_chatterbot 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 chatterbot.ext.django_chatterbot.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 chatterbot import constants
CHATTERBOT_SETTINGS = getattr(settings, 'CHATTERBOT', {})
CHATTERBOT_DEFAULTS = {
'name': 'ChatterBot',
'storage_adapter': 'chatterbot.storage.DjangoStorageAdapter',
'input_adapter': 'chatterbot.input.VariableInputTypeAdapter',
'output_adapter': 'chatterbot.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 chatterbot import ChatBot
from chatterbot.ext.django_chatterbot 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 chatterbot.ext.django_chatterbot.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)

@ -1,11 +1,10 @@
from chatterbot.constants import TAG_NAME_MAX_LENGTH, STATEMENT_TEXT_MAX_LENGTH
from chatterbot.conversation import StatementMixin
from chatterbot.ext.sqlalchemy_app.types import UnicodeString
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 chatterbot.constants import TAG_NAME_MAX_LENGTH, STATEMENT_TEXT_MAX_LENGTH
from chatterbot.ext.sqlalchemy_app.types import UnicodeString
from chatterbot.conversation import StatementMixin
class ModelBase(object):

@ -1,12 +1,11 @@
from .input_adapter import InputAdapter
from .microsoft import Microsoft
from .gitter import Gitter
from .hipchat import HipChat
from .input_adapter import InputAdapter
from .mailgun import Mailgun
from .microsoft import Microsoft
from .terminal import TerminalAdapter
from .variable_input_type_adapter import VariableInputTypeAdapter
__all__ = (
'InputAdapter',
'Microsoft',

@ -1,7 +1,9 @@
from __future__ import unicode_literals
from time import sleep
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
class Gitter(InputAdapter):

@ -1,7 +1,9 @@
from __future__ import unicode_literals
from time import sleep
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
class HipChat(InputAdapter):

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from chatterbot.adapters import Adapter

@ -1,7 +1,9 @@
from __future__ import unicode_literals
import datetime
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
class Mailgun(InputAdapter):

@ -1,7 +1,9 @@
from __future__ import unicode_literals
from time import sleep
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
class Microsoft(InputAdapter):

@ -1,6 +1,7 @@
from __future__ import unicode_literals
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
from chatterbot.utils import input_function

@ -1,6 +1,7 @@
from __future__ import unicode_literals
from chatterbot.input import InputAdapter
from chatterbot.conversation import Statement
from chatterbot.input import InputAdapter
class VariableInputTypeAdapter(InputAdapter):

@ -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',

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .logic_adapter import LogicAdapter

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from chatterbot.adapters import Adapter
from chatterbot.utils import import_module

@ -1,5 +1,7 @@
from __future__ import unicode_literals
from chatterbot.conversation import Statement
from .best_match import BestMatch

@ -1,6 +1,7 @@
from __future__ import unicode_literals
from chatterbot.logic import LogicAdapter
from chatterbot.conversation import Statement
from chatterbot.logic import LogicAdapter
class MathematicalEvaluation(LogicAdapter):

@ -1,6 +1,9 @@
from __future__ import unicode_literals
from collections import Counter
from chatterbot import utils
from .logic_adapter import LogicAdapter

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .logic_adapter import LogicAdapter

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .logic_adapter import LogicAdapter

@ -1,5 +1,7 @@
from __future__ import unicode_literals
from datetime import datetime
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 .hipchat import HipChat
from .mailgun import Mailgun
from .microsoft import Microsoft
from .output_adapter import OutputAdapter
from .terminal import TerminalAdapter
__all__ = (
'OutputAdapter',

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .output_adapter import OutputAdapter

@ -1,5 +1,7 @@
from __future__ import unicode_literals
import json
from .output_adapter import OutputAdapter

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .output_adapter import OutputAdapter

@ -1,5 +1,7 @@
from __future__ import unicode_literals
import json
from .output_adapter import OutputAdapter

@ -1,4 +1,5 @@
from __future__ import unicode_literals
from .output_adapter import OutputAdapter

@ -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']

@ -1,12 +1,9 @@
from .storage_adapter import StorageAdapter
from .django_storage import DjangoStorageAdapter
from .mongodb import MongoDatabaseAdapter
from .sql_storage import SQLStorageAdapter
from .storage_adapter import StorageAdapter
__all__ = (
'StorageAdapter',
'DjangoStorageAdapter',
'MongoDatabaseAdapter',
'SQLStorageAdapter',
)

@ -1,220 +0,0 @@
from chatter.chatterbot.storage import StorageAdapter
from chatter.chatterbot 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)

@ -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):

Loading…
Cancel
Save