relate channels to their server

this is necessary for supporting multiple irc servers in one bot config.
this also has the side effect of requiring some code in ircbot and
markov which autocreates channels to also include the server (retrieved
via the connection). this will again help keep channels coherent for
multi-server arrangements

the twitter bot change here is untested but seems like the right idea (I
haven't used the twitter package in forever)
This commit is contained in:
Brian S. Stephan 2021-04-25 11:01:05 -05:00
parent 6136127c5f
commit 9c1109107b
6 changed files with 46 additions and 18 deletions

View File

@ -1,19 +1,17 @@
"""Provide some commands for basic IRC functionality."""
import logging
from ircbot.lib import Plugin, has_permission
from ircbot.models import IrcChannel
log = logging.getLogger('ircbot.ircplugins.ircmgmt')
class ChannelManagement(Plugin):
"""Have IRC commands to do IRC things (join channels, quit, etc.)."""
def start(self):
"""Set up the handlers."""
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!join\s+([\S]+)',
self.handle_join, -20)
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!part\s+([\S]+)',
@ -25,7 +23,6 @@ class ChannelManagement(Plugin):
def stop(self):
"""Tear down handlers."""
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_join)
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_part)
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_quit)
@ -34,11 +31,10 @@ class ChannelManagement(Plugin):
def handle_join(self, connection, event, match):
"""Handle the join command."""
if has_permission(event.source, 'ircbot.manage_current_channels'):
channel = match.group(1)
# put it in the database if it isn't already
chan_mod, c = IrcChannel.objects.get_or_create(name=channel)
chan_mod, c = IrcChannel.objects.get_or_create(name=channel, server=connection.server_config)
log.debug("joining channel %s", channel)
self.connection.join(channel)
@ -46,11 +42,10 @@ class ChannelManagement(Plugin):
def handle_part(self, connection, event, match):
"""Handle the join command."""
if has_permission(event.source, 'ircbot.manage_current_channels'):
channel = match.group(1)
# put it in the database if it isn't already
chan_mod, c = IrcChannel.objects.get_or_create(name=channel)
chan_mod, c = IrcChannel.objects.get_or_create(name=channel, server=connection.server_config)
log.debug("parting channel %s", channel)
self.connection.part(channel)
@ -58,7 +53,6 @@ class ChannelManagement(Plugin):
def handle_quit(self, connection, event, match):
"""Handle the join command."""
if has_permission(event.source, 'ircbot.quit_bot'):
self.bot.die(msg=match.group(1))

View File

@ -1,5 +1,4 @@
"""Watch channel topics for changes and note them."""
import logging
from django.utils import timezone
@ -7,24 +6,20 @@ from django.utils import timezone
from ircbot.lib import Plugin
from ircbot.models import IrcChannel
log = logging.getLogger('ircbot.ircplugins.topicmonitor')
class TopicMonitor(Plugin):
"""Have IRC commands to do IRC things (join channels, quit, etc.)."""
def start(self):
"""Set up the handlers."""
self.connection.reactor.add_global_handler('topic', handle_topic, -20)
super(TopicMonitor, self).start()
def stop(self):
"""Tear down handlers."""
self.connection.reactor.remove_global_handler('topic', handle_topic)
super(TopicMonitor, self).stop()
@ -32,13 +27,12 @@ class TopicMonitor(Plugin):
def handle_topic(connection, event):
"""Store topic changes in the channel model."""
channel = event.target
topic = event.arguments[0]
setter = event.source
log.debug("topic change '%s' by %s in %s", topic, setter, channel)
channel, c = IrcChannel.objects.get_or_create(name=channel)
channel, c = IrcChannel.objects.get_or_create(name=channel, server=connection.server_config)
channel.topic_msg = topic
channel.topic_time = timezone.now()
channel.topic_by = setter

View File

@ -0,0 +1,30 @@
# Generated by Django 3.1.2 on 2021-04-25 16:11
from django.db import migrations, models
import django.db.models.deletion
import ircbot.models
class Migration(migrations.Migration):
dependencies = [
('ircbot', '0016_placeholder_ircserver'),
]
operations = [
migrations.AddField(
model_name='ircchannel',
name='server',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='ircbot.ircserver'),
preserve_default=False,
),
migrations.AlterField(
model_name='ircchannel',
name='name',
field=ircbot.models.LowerCaseCharField(max_length=200),
),
migrations.AddConstraint(
model_name='ircchannel',
constraint=models.UniqueConstraint(fields=('name', 'server'), name='unique_server_channel'),
),
]

View File

@ -92,7 +92,8 @@ class IrcServer(models.Model):
class IrcChannel(models.Model):
"""Track channel settings."""
name = LowerCaseCharField(max_length=200, unique=True)
name = LowerCaseCharField(max_length=200)
server = models.ForeignKey('IrcServer', on_delete=models.CASCADE)
autojoin = models.BooleanField(default=False)
topic_msg = models.TextField(default='', blank=True)
@ -104,6 +105,9 @@ class IrcChannel(models.Model):
class Meta:
"""Settings for the model."""
constraints = (
models.UniqueConstraint(fields=['name', 'server'], name='unique_server_channel'),
)
permissions = (
('manage_current_channels', "Can join/part channels via IRC"),
)

View File

@ -70,7 +70,7 @@ class Markov(Plugin):
# check to see whether or not we should learn from this channel
channel = None
if irc.client.is_channel(target):
channel, c = IrcChannel.objects.get_or_create(name=target)
channel, c = IrcChannel.objects.get_or_create(name=target, server=connection.server_config)
if channel and not channel.markov_learn_from_channel:
log.debug("not learning from %s as i've been told to ignore it", channel)

View File

@ -31,6 +31,8 @@ class Twitter(Plugin):
self.poll_mentions = False
self.server = connection.server_config
super(Twitter, self).__init__(bot, connection, event)
def start(self):
@ -272,6 +274,10 @@ class Twitter(Plugin):
out_chan = twittersettings.mentions_output_channel.name
since_id = twittersettings.mentions_since_id
if out_chan.server != self.server:
self.poll_mentions = False
return
mentions = self.twit.get_mentions_timeline(since_id=since_id)
mentions.reverse()
for mention in mentions: