Working reply to chat
This commit is contained in:
parent
bff075f40a
commit
1f7e7a7e8b
|
@ -1,9 +1,12 @@
|
||||||
|
import random
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from orator.orm import Model
|
from orator.orm import Model
|
||||||
from orator.orm import belongs_to
|
from orator.orm import belongs_to
|
||||||
from orator.orm import has_many
|
from orator.orm import has_many
|
||||||
|
|
||||||
import src.domain.reply
|
|
||||||
import src.domain.chat
|
import src.domain.chat
|
||||||
|
import src.domain.reply
|
||||||
import src.domain.word
|
import src.domain.word
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,17 +25,32 @@ class Pair(Model):
|
||||||
def chat(self):
|
def chat(self):
|
||||||
return src.domain.chat.Chat
|
return src.domain.chat.Chat
|
||||||
|
|
||||||
|
@belongs_to
|
||||||
|
def first(self):
|
||||||
|
return src.domain.word.Word
|
||||||
|
|
||||||
|
@belongs_to
|
||||||
|
def second(self):
|
||||||
|
return src.domain.word.Word
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate(message):
|
def generate(message):
|
||||||
return ''
|
return Pair.generate_story(message, message.words, random.randint(0, 2) + 1)
|
||||||
# generate_story(message, message.words, rand(2) + 1)
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_story(message, words, sentences):
|
||||||
|
words_ids = src.domain.word.Word.where_in('word', words).get().pluck('id').all()
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for _ in range(0, sentences):
|
||||||
|
result.append(Pair.__generate_sentence(message, words_ids))
|
||||||
|
|
||||||
|
return ' '.join(result)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def learn(message):
|
def learn(message):
|
||||||
src.domain.word.Word.learn(message.words)
|
src.domain.word.Word.learn(message.words)
|
||||||
|
|
||||||
print("Msg words: " + str(message.words))
|
|
||||||
|
|
||||||
words = [None]
|
words = [None]
|
||||||
for word in message.words:
|
for word in message.words:
|
||||||
words.append(word)
|
words.append(word)
|
||||||
|
@ -41,14 +59,10 @@ class Pair(Model):
|
||||||
if words[-1:] is not None:
|
if words[-1:] is not None:
|
||||||
words.append(None)
|
words.append(None)
|
||||||
|
|
||||||
print("Words: "+str(words))
|
|
||||||
|
|
||||||
while any(word for word in words):
|
while any(word for word in words):
|
||||||
trigram = words[:3]
|
trigram = words[:3]
|
||||||
words.pop(0)
|
words.pop(0)
|
||||||
print("Trigram: " + str(trigram))
|
|
||||||
trigram_word_ids = list(map(lambda x: None if x is None else src.domain.word.Word.where('word', word).first().id, trigram))
|
trigram_word_ids = list(map(lambda x: None if x is None else src.domain.word.Word.where('word', word).first().id, trigram))
|
||||||
print("TrigramId: " + str(trigram_word_ids))
|
|
||||||
pair = Pair.first_or_create(chat_id=message.chat.id,
|
pair = Pair.first_or_create(chat_id=message.chat.id,
|
||||||
first_id=trigram_word_ids[0],
|
first_id=trigram_word_ids[0],
|
||||||
second_id=trigram_word_ids[1])
|
second_id=trigram_word_ids[1])
|
||||||
|
@ -61,11 +75,46 @@ class Pair(Model):
|
||||||
else:
|
else:
|
||||||
src.domain.reply.Reply.create(pair_id=pair.id, word_id=last_trigram_id)
|
src.domain.reply.Reply.create(pair_id=pair.id, word_id=last_trigram_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __generate_sentence(message, word_ids):
|
||||||
|
sentence = ''
|
||||||
|
safety_counter = 50
|
||||||
|
first_word = None
|
||||||
|
second_words = list(word_ids)
|
||||||
|
while safety_counter > 0:
|
||||||
|
pair = Pair.__get_pair(chat_id=message.chat.id, first_id=first_word, second_ids=second_words)
|
||||||
|
replies = getattr(pair, 'replies', [])
|
||||||
|
safety_counter -= 1
|
||||||
|
if pair is None or len(replies) == 0:
|
||||||
|
continue
|
||||||
|
reply = random.choice(replies.all())
|
||||||
|
first_word = pair.second.id
|
||||||
|
second_words = getattr(reply.word, 'id', [])
|
||||||
|
if sentence == '':
|
||||||
|
sentence = Pair.__capitalize(pair.second.word) + " "
|
||||||
|
word_ids.remove(pair.second.id)
|
||||||
|
reply_word = getattr(reply.word, 'word', '')
|
||||||
|
if reply_word not in sentence and Pair.__capitalize(reply_word) not in sentence:
|
||||||
|
sentence += reply_word
|
||||||
|
sentence = sentence.strip()
|
||||||
|
if sentence[-1:] not in Pair.end_sentence:
|
||||||
|
sentence += random.choice(list(Pair.end_sentence))
|
||||||
|
|
||||||
# @staticmethod
|
return sentence
|
||||||
# def get_pair(chat_id, first_id, second_id):
|
|
||||||
# Pair.includes(Pair.replies())
|
@staticmethod
|
||||||
# .where(chat_id: chat_id, first_id: first_id, second_id: second_id)
|
def __capitalize(string):
|
||||||
# .where("created_at < :latest", latest: 10.minutes.ago)
|
return string[:1].upper() + string[1:]
|
||||||
# .limit(3)\
|
|
||||||
# .sample
|
@staticmethod
|
||||||
|
def __get_pair(chat_id, first_id, second_ids):
|
||||||
|
pairs = Pair.with_('replies')\
|
||||||
|
.where('chat_id', chat_id)\
|
||||||
|
.where('first_id', first_id)\
|
||||||
|
.where_in('second_id', second_ids)\
|
||||||
|
.where('created_at', '<', (datetime.now() - timedelta(seconds=10 * 60)))\
|
||||||
|
.limit(3)\
|
||||||
|
.get()\
|
||||||
|
.all()
|
||||||
|
|
||||||
|
return random.choice(pairs) if len(pairs) != 0 else None
|
||||||
|
|
|
@ -4,6 +4,7 @@ import random
|
||||||
import src.domain.chat as chat
|
import src.domain.chat as chat
|
||||||
import src.domain.pair as pair
|
import src.domain.pair as pair
|
||||||
|
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
def __init__(self, bot, message, config):
|
def __init__(self, bot, message, config):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -13,7 +14,8 @@ class Message:
|
||||||
self.chat.migrate_to_chat_id = message.migrate_to_chat_id
|
self.chat.migrate_to_chat_id = message.migrate_to_chat_id
|
||||||
|
|
||||||
if self.has_text():
|
if self.has_text():
|
||||||
logging.debug("[chat %s %s bare_text] %s" %(self.chat.chat_type, self.chat.telegram_id, self.message.text))
|
logging.debug("[chat %s %s bare_text] %s" %
|
||||||
|
(self.chat.chat_type, self.chat.telegram_id, self.message.text))
|
||||||
self.text = message.text
|
self.text = message.text
|
||||||
self.words = self.__get_words()
|
self.words = self.__get_words()
|
||||||
self.command = self.__get_command() if self.text[0] == '/' else None
|
self.command = self.__get_command() if self.text[0] == '/' else None
|
||||||
|
@ -36,33 +38,44 @@ class Message:
|
||||||
return self.message.entities is not None
|
return self.message.entities is not None
|
||||||
|
|
||||||
def has_anchors(self):
|
def has_anchors(self):
|
||||||
return self.has_text() and (any(x in self.words for x in self.config['bot']['anchors'].split(',')))
|
return self.has_text() and \
|
||||||
|
(any(x in self.message.text.split(' ') for x in self.config['bot']['anchors'].split(',')))
|
||||||
|
|
||||||
def is_private(self):
|
def is_private(self):
|
||||||
return self.message.chat.type == 'private'
|
return self.message.chat.type == 'private'
|
||||||
|
|
||||||
def is_reply_to_bot(self):
|
def is_reply_to_bot(self):
|
||||||
return self.message.reply_to_message is not None \
|
reply_to_message = getattr(self.message, 'reply_to_message', None)
|
||||||
and self.message.reply_to_message.from_user.username == self.config['bot']['name']
|
from_user = getattr(reply_to_message, 'from_user', None)
|
||||||
|
user_name = getattr(from_user, 'username', None)
|
||||||
|
|
||||||
|
return user_name == self.config['bot']['name']
|
||||||
|
|
||||||
def is_random_answer(self):
|
def is_random_answer(self):
|
||||||
return random.randint(1, 100) < self.chat.random_chance
|
return random.randint(0, 100) < self.chat.random_chance
|
||||||
|
|
||||||
def is_command(self):
|
def is_command(self):
|
||||||
return self.command is not None
|
return self.command is not None
|
||||||
|
|
||||||
def __answer(self, message):
|
def __answer(self, message):
|
||||||
logging.debug("[Chat %s %s answer] %s" % (self.chat.chat_type, self.chat.telegram_id, message))
|
logging.debug("[Chat %s %s answer] %s" %
|
||||||
|
(self.chat.chat_type, self.chat.telegram_id, message))
|
||||||
self.bot.sendMessage(chat_id=self.chat.telegram_id, text=message)
|
self.bot.sendMessage(chat_id=self.chat.telegram_id, text=message)
|
||||||
|
|
||||||
def __reply(self, message):
|
def __reply(self, message):
|
||||||
logging.debug("[Chat %s %s reply] %s" % (self.chat.chat_type, self.chat.telegram_id, message))
|
logging.debug("[Chat %s %s reply] %s" %
|
||||||
self.bot.sendMessage(chat_id=self.chat.telegram_id, reply_to_message_id=self.message.message_id, text=message)
|
(self.chat.chat_type, self.chat.telegram_id, message))
|
||||||
|
self.bot.sendMessage(chat_id=self.chat.telegram_id,
|
||||||
|
reply_to_message_id=self.message.message_id,
|
||||||
|
text=message)
|
||||||
|
|
||||||
def __process_message(self):
|
def __process_message(self):
|
||||||
pair.Pair.learn(self)
|
pair.Pair.learn(self)
|
||||||
|
|
||||||
if self.has_anchors() or self.is_private() or self.is_reply_to_bot() or self.is_random_answer():
|
if self.has_anchors() \
|
||||||
|
or self.is_private() \
|
||||||
|
or self.is_reply_to_bot() \
|
||||||
|
or self.is_random_answer():
|
||||||
reply = pair.Pair.generate(self)
|
reply = pair.Pair.generate(self)
|
||||||
if reply != '':
|
if reply != '':
|
||||||
self.__answer(reply)
|
self.__answer(reply)
|
||||||
|
@ -72,7 +85,8 @@ class Message:
|
||||||
for entity in self.message.entities:
|
for entity in self.message.entities:
|
||||||
text[entity.offset:entity.length] = ' ' * entity.length
|
text[entity.offset:entity.length] = ' ' * entity.length
|
||||||
result = list(map(lambda x: x.lower(), ''.join(text).split(' ')))
|
result = list(map(lambda x: x.lower(), ''.join(text).split(' ')))
|
||||||
logging.debug("[chat %s %s get_words] %s" % (self.chat.chat_type, self.chat.telegram_id, result))
|
logging.debug("[chat %s %s get_words] %s" %
|
||||||
|
(self.chat.chat_type, self.chat.telegram_id, result))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue