Compare commits
8 Commits
419994ee32
...
cf648cd555
Author | SHA1 | Date |
---|---|---|
Brian S. Stephan | cf648cd555 | |
Brian S. Stephan | c67b56ee5e | |
Brian S. Stephan | b9c2a96231 | |
Brian S. Stephan | ff5e95a53e | |
Brian S. Stephan | 3468622aa5 | |
Brian S. Stephan | e05d0a1a1c | |
Brian S. Stephan | dfda9d8c71 | |
Brian S. Stephan | 4c89989b8e |
|
@ -60,15 +60,10 @@ class Markov(Plugin):
|
|||
def handle_chatter(self, connection, event):
|
||||
"""Learn from IRC chatter."""
|
||||
what = event.arguments[0]
|
||||
if connection.server_config.additional_addressed_nicks:
|
||||
all_nicks = '|'.join(connection.server_config.additional_addressed_nicks.split('\n') +
|
||||
[connection.get_nickname()])
|
||||
else:
|
||||
all_nicks = connection.get_nickname()
|
||||
trimmed_what = re.sub(r'^(({nicks})[:,]|@({nicks}))\s+'.format(nicks=all_nicks), '', what)
|
||||
nick = irc.client.NickMask(event.source).nick
|
||||
who = irc.client.NickMask(event.source).nick
|
||||
target = reply_destination_for_event(event)
|
||||
|
||||
log.debug("what: '%s', who: '%s', target: '%s'", what, who, target)
|
||||
# check to see whether or not we should learn from this channel
|
||||
channel = None
|
||||
if irc.client.is_channel(target):
|
||||
|
@ -78,11 +73,23 @@ class Markov(Plugin):
|
|||
log.debug("not learning from %s as i've been told to ignore it", channel)
|
||||
else:
|
||||
# learn the line
|
||||
# remove our own nick and aliases from what we learn
|
||||
if connection.server_config.additional_addressed_nicks:
|
||||
all_nicks = '|'.join(connection.server_config.additional_addressed_nicks.split('\n') +
|
||||
[connection.get_nickname()])
|
||||
else:
|
||||
all_nicks = connection.get_nickname()
|
||||
what = re.sub(r'^(({nicks})[:,]|@({nicks}))\s+'.format(nicks=all_nicks), '', what)
|
||||
|
||||
# don't learn the speaker's nick if this came over a bridge
|
||||
if channel and who == channel.discord_bridge:
|
||||
what = ' '.join(what.split(' ')[1:])
|
||||
|
||||
recursing = getattr(event, 'recursing', False)
|
||||
if not recursing:
|
||||
log.debug("learning %s", trimmed_what)
|
||||
log.debug("learning %s", what)
|
||||
context = markovlib.get_or_create_target_context(target)
|
||||
markovlib.learn_line(trimmed_what, context)
|
||||
markovlib.learn_line(what, context)
|
||||
|
||||
log.debug("searching '%s' for '%s'", what, all_nicks)
|
||||
if re.search(all_nicks, what, re.IGNORECASE) is not None:
|
||||
|
@ -96,7 +103,7 @@ class Markov(Plugin):
|
|||
topics = [x for x in match.group('addressed_msg').split(' ') if len(x) >= 3]
|
||||
|
||||
return self.bot.reply(event, "{0:s}: {1:s}"
|
||||
"".format(nick, " ".join(markovlib.generate_line(context, topics=topics))))
|
||||
"".format(who, " ".join(markovlib.generate_line(context, topics=topics))))
|
||||
else:
|
||||
# i wasn't addressed directly, so just respond
|
||||
topics = [x for x in what.split(' ') if len(x) >= 3]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Provide methods for manipulating markov chain processing."""
|
||||
import logging
|
||||
from random import SystemRandom as sysrand
|
||||
import random
|
||||
|
||||
from django.db.models import Sum
|
||||
|
||||
|
@ -22,7 +22,7 @@ def generate_line(context, topics=None, min_words=15, max_words=30, sentence_bia
|
|||
else:
|
||||
if len(line) > 0:
|
||||
if line[-1][-1] not in [',', '.', '!', '?', ':']:
|
||||
line[-1] += sysrand.choice(['?', '.', '!'])
|
||||
line[-1] += random.SystemRandom().choice(['?', '.', '!'])
|
||||
|
||||
tries += 1
|
||||
|
||||
|
@ -53,7 +53,7 @@ def generate_sentence(context, topics=None, min_words=15, max_words=30):
|
|||
words = []
|
||||
# if we have topics, try to work from it and work backwards
|
||||
if topics:
|
||||
topic_word = sysrand.choice(topics)
|
||||
topic_word = random.SystemRandom().choice(topics)
|
||||
topics.remove(topic_word)
|
||||
log.debug("looking for topic '%s'", topic_word)
|
||||
new_states = MarkovState.objects.filter(context=context, v=topic_word)
|
||||
|
@ -100,7 +100,7 @@ def generate_sentence(context, topics=None, min_words=15, max_words=30):
|
|||
words.append(MarkovState._stop)
|
||||
elif len(target_hits) > 0:
|
||||
# if there's a target word in the states, pick it
|
||||
target_hit = sysrand.choice(target_hits)
|
||||
target_hit = random.SystemRandom().choice(target_hits)
|
||||
log.debug("found a topic hit %s, using it", target_hit)
|
||||
topics.remove(target_hit)
|
||||
words.append(target_hit)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
"""Test IRC behavior of the markov plugin."""
|
||||
from unittest import mock
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from ircbot.models import IrcServer
|
||||
from markov.ircplugin import Markov
|
||||
|
||||
|
||||
class MarkovTestCase(TestCase):
|
||||
"""Test the markov plugin."""
|
||||
|
||||
fixtures = ['tests/fixtures/irc_server_fixture.json']
|
||||
|
||||
def setUp(self):
|
||||
"""Create common objects."""
|
||||
self.mock_bot = mock.MagicMock()
|
||||
self.mock_connection = mock.MagicMock()
|
||||
|
||||
self.mock_connection.get_nickname.return_value = 'test_bot'
|
||||
self.mock_connection.server_config = IrcServer.objects.get(pk=1)
|
||||
|
||||
self.plugin = Markov(self.mock_bot, self.mock_connection, mock.MagicMock())
|
||||
|
||||
def test_learn(self):
|
||||
"""Test that an IRC event triggers learning as expected."""
|
||||
mock_event = mock.MagicMock()
|
||||
mock_event.arguments = ['hello this is a test message']
|
||||
mock_event.target = '#test'
|
||||
mock_event.recursing = False
|
||||
|
||||
with mock.patch('markov.lib.learn_line') as mock_learn_line:
|
||||
self.plugin.handle_chatter(self.mock_connection, mock_event)
|
||||
|
||||
self.assertEqual(mock_learn_line.call_args.args[0], 'hello this is a test message')
|
||||
|
||||
def test_learn_self_edit(self):
|
||||
"""Test that we don't learn our own name when learning something addressed to us."""
|
||||
mock_event = mock.MagicMock()
|
||||
mock_event.arguments = ['test_bot: hello this is a test message']
|
||||
mock_event.target = '#test'
|
||||
mock_event.recursing = False
|
||||
|
||||
with mock.patch('markov.lib.learn_line') as mock_learn_line:
|
||||
self.plugin.handle_chatter(self.mock_connection, mock_event)
|
||||
|
||||
self.assertEqual(mock_learn_line.call_args.args[0], 'hello this is a test message')
|
||||
|
||||
def test_learn_variant_self_edit(self):
|
||||
"""Test that we don't learn our own name when learning something addressed to us, discord style."""
|
||||
mock_event = mock.MagicMock()
|
||||
mock_event.arguments = ['@test_bot hello this is a test message']
|
||||
mock_event.target = '#test'
|
||||
mock_event.recursing = False
|
||||
|
||||
with mock.patch('markov.lib.learn_line') as mock_learn_line:
|
||||
self.plugin.handle_chatter(self.mock_connection, mock_event)
|
||||
|
||||
self.assertEqual(mock_learn_line.call_args.args[0], 'hello this is a test message')
|
||||
|
||||
def test_learn_bridge_edit(self):
|
||||
"""Test that we don't learn the speaker's nick when learning a message from the bridge."""
|
||||
mock_event = mock.MagicMock()
|
||||
mock_event.arguments = ['<tester> hello this is a test message']
|
||||
mock_event.target = '#test'
|
||||
mock_event.recursing = False
|
||||
mock_event.source = 'bridge!bridge@localhost'
|
||||
|
||||
with mock.patch('markov.lib.learn_line') as mock_learn_line:
|
||||
self.plugin.handle_chatter(self.mock_connection, mock_event)
|
||||
|
||||
self.assertEqual(mock_learn_line.call_args.args[0], 'hello this is a test message')
|
Loading…
Reference in New Issue