when creating a markov target, tie it to ircbot models
This commit is contained in:
parent
76a052e091
commit
0227b74eee
@ -7,6 +7,7 @@ import irc.client
|
||||
import markov.lib as markovlib
|
||||
from ircbot.lib import Plugin, reply_destination_for_event
|
||||
from ircbot.models import IrcChannel
|
||||
from markov.models import MarkovContext, MarkovTarget
|
||||
|
||||
log = logging.getLogger('markov.ircplugin')
|
||||
|
||||
@ -40,7 +41,7 @@ class Markov(Plugin):
|
||||
|
||||
min_size = 15
|
||||
max_size = 30
|
||||
context = markovlib.get_or_create_target_context(target)
|
||||
context = self.get_or_create_target_context(target)
|
||||
|
||||
if match.group(2):
|
||||
min_size = int(match.group(2))
|
||||
@ -90,12 +91,12 @@ class Markov(Plugin):
|
||||
recursing = getattr(event, 'recursing', False)
|
||||
if not recursing:
|
||||
log.debug("learning %s", learning_what)
|
||||
context = markovlib.get_or_create_target_context(target)
|
||||
context = self.get_or_create_target_context(target)
|
||||
markovlib.learn_line(learning_what, context)
|
||||
|
||||
log.debug("searching '%s' for '%s'", what, all_nicks)
|
||||
if re.search(all_nicks, what, re.IGNORECASE) is not None:
|
||||
context = markovlib.get_or_create_target_context(target)
|
||||
context = self.get_or_create_target_context(target)
|
||||
|
||||
addressed_pattern = r'^(({nicks})[:,]|@({nicks}))\s+(?P<addressed_msg>.*)'.format(nicks=all_nicks)
|
||||
match = re.match(addressed_pattern, what, re.IGNORECASE)
|
||||
@ -113,5 +114,31 @@ class Markov(Plugin):
|
||||
return self.bot.reply(event, "{0:s}"
|
||||
"".format(" ".join(markovlib.generate_line(context, topics=topics))))
|
||||
|
||||
def get_or_create_target_context(self, target_name):
|
||||
"""Return the context for a provided nick/channel, creating missing ones."""
|
||||
target_name = target_name.lower()
|
||||
|
||||
# find the stuff, or create it
|
||||
try:
|
||||
target = MarkovTarget.objects.get(name=target_name)
|
||||
except MarkovTarget.DoesNotExist:
|
||||
# we need to create a context and a target, and we have to make the context first
|
||||
# make a context --- lacking a good idea, just create one with this target name until configured otherwise
|
||||
channel, c = IrcChannel.objects.get_or_create(name=target_name, server=self.connection.server_config)
|
||||
context, c = MarkovContext.objects.get_or_create(name=target_name)
|
||||
target, c = MarkovTarget.objects.get_or_create(name=target_name, context=context, channel=channel)
|
||||
|
||||
return target.context
|
||||
|
||||
try:
|
||||
return target.context
|
||||
except MarkovContext.DoesNotExist:
|
||||
# make a context --- lacking a good idea, just create one with this target name until configured otherwise
|
||||
context, c = MarkovContext.objects.get_or_create(name=target_name)
|
||||
target.context = context
|
||||
target.save()
|
||||
|
||||
return target.context
|
||||
|
||||
|
||||
plugin = Markov
|
||||
|
@ -4,7 +4,7 @@ import random
|
||||
|
||||
from django.db.models import Sum
|
||||
|
||||
from markov.models import MarkovContext, MarkovState, MarkovTarget
|
||||
from markov.models import MarkovState
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -124,32 +124,6 @@ def generate_sentence(context, topics=None, min_words=15, max_words=30):
|
||||
return words
|
||||
|
||||
|
||||
def get_or_create_target_context(target_name):
|
||||
"""Return the context for a provided nick/channel, creating missing ones."""
|
||||
target_name = target_name.lower()
|
||||
|
||||
# find the stuff, or create it
|
||||
try:
|
||||
target = MarkovTarget.objects.get(name=target_name)
|
||||
except MarkovTarget.DoesNotExist:
|
||||
# we need to create a context and a target, and we have to make the context first
|
||||
# make a context --- lacking a good idea, just create one with this target name until configured otherwise
|
||||
context, c = MarkovContext.objects.get_or_create(name=target_name)
|
||||
target, c = MarkovTarget.objects.get_or_create(name=target_name, context=context)
|
||||
|
||||
return target.context
|
||||
|
||||
try:
|
||||
return target.context
|
||||
except MarkovContext.DoesNotExist:
|
||||
# make a context --- lacking a good idea, just create one with this target name until configured otherwise
|
||||
context, c = MarkovContext.objects.get_or_create(name=target_name)
|
||||
target.context = context
|
||||
target.save()
|
||||
|
||||
return target.context
|
||||
|
||||
|
||||
def get_word_out_of_states(states, backwards=False):
|
||||
"""Pick one random word out of the given states."""
|
||||
# work around possible broken data, where a k1,k2 should have a value but doesn't
|
||||
|
20
markov/migrations/0005_markovtarget_channel.py
Normal file
20
markov/migrations/0005_markovtarget_channel.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 3.2.18 on 2023-02-20 00:09
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ircbot', '0019_ircchannel_discord_bridge'),
|
||||
('markov', '0004_alter_markovstate_context'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='markovtarget',
|
||||
name='channel',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='ircbot.ircchannel'),
|
||||
),
|
||||
]
|
24
markov/migrations/0006_link_markovtarget_to_ircchannel.py
Normal file
24
markov/migrations/0006_link_markovtarget_to_ircchannel.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""Generated by Django 3.2.18 on 2023-02-19 23:15."""
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def link_markovcontext_to_ircchannel(apps, schema_editor):
|
||||
"""Link the markov targets to a hopefully matching channel, by name."""
|
||||
IrcChannel = apps.get_model('ircbot', 'IrcChannel')
|
||||
MarkovTarget = apps.get_model('markov', 'MarkovTarget')
|
||||
for target in MarkovTarget.objects.all():
|
||||
channel = IrcChannel.objects.get(name=target.name)
|
||||
target.channel = channel
|
||||
target.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
"""Populate the markov target to IRC channel link."""
|
||||
|
||||
dependencies = [
|
||||
('markov', '0005_markovtarget_channel'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(link_markovcontext_to_ircchannel)
|
||||
]
|
20
markov/migrations/0007_alter_markovtarget_channel.py
Normal file
20
markov/migrations/0007_alter_markovtarget_channel.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 3.2.18 on 2023-02-20 00:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ircbot', '0019_ircchannel_discord_bridge'),
|
||||
('markov', '0006_link_markovtarget_to_ircchannel'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='markovtarget',
|
||||
name='channel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ircbot.ircchannel'),
|
||||
),
|
||||
]
|
@ -3,6 +3,8 @@ import logging
|
||||
|
||||
from django.db import models
|
||||
|
||||
from ircbot.models import IrcChannel
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -21,6 +23,7 @@ class MarkovTarget(models.Model):
|
||||
|
||||
name = models.CharField(max_length=200, unique=True)
|
||||
context = models.ForeignKey(MarkovContext, on_delete=models.CASCADE)
|
||||
channel = models.ForeignKey(IrcChannel, on_delete=models.CASCADE)
|
||||
|
||||
chatter_chance = models.IntegerField(default=0)
|
||||
|
||||
|
@ -3,7 +3,7 @@ from unittest import mock
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from ircbot.models import IrcServer
|
||||
from ircbot.models import IrcChannel, IrcServer
|
||||
from markov.ircplugin import Markov
|
||||
|
||||
|
||||
@ -100,3 +100,15 @@ class MarkovTestCase(TestCase):
|
||||
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_autocreate_ircchannel(self):
|
||||
"""Test that we create the necessary config objects when seeing a target for the first time."""
|
||||
self.assertEqual(IrcChannel.objects.filter(name='#fakechannel').count(), 0)
|
||||
context = self.plugin.get_or_create_target_context('#fakechannel')
|
||||
|
||||
self.assertEqual(IrcChannel.objects.filter(name='#fakechannel').count(), 1)
|
||||
self.assertIsNotNone(context)
|
||||
self.assertIsNotNone(context.markovtarget_set)
|
||||
self.assertIsNotNone(context.markovtarget_set.all()[0].channel)
|
||||
self.assertEqual(context.markovtarget_set.all()[0].channel.name, '#fakechannel')
|
||||
self.assertEqual(context.markovtarget_set.all()[0].name, '#fakechannel')
|
||||
|
Loading…
Reference in New Issue
Block a user