From 9c1109107b6cbf7a3404574a9b4e02e67a1ed086 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Sun, 25 Apr 2021 11:01:05 -0500 Subject: [PATCH] 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) --- ircbot/ircplugins/ircmgmt.py | 12 +++------ ircbot/ircplugins/topicmonitor.py | 8 +----- ircbot/migrations/0017_ircchannel_server.py | 30 +++++++++++++++++++++ ircbot/models.py | 6 ++++- markov/ircplugin.py | 2 +- twitter/ircplugin.py | 6 +++++ 6 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 ircbot/migrations/0017_ircchannel_server.py diff --git a/ircbot/ircplugins/ircmgmt.py b/ircbot/ircplugins/ircmgmt.py index bbf6281..0a5ce65 100644 --- a/ircbot/ircplugins/ircmgmt.py +++ b/ircbot/ircplugins/ircmgmt.py @@ -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)) diff --git a/ircbot/ircplugins/topicmonitor.py b/ircbot/ircplugins/topicmonitor.py index 987681d..bbdd3bf 100644 --- a/ircbot/ircplugins/topicmonitor.py +++ b/ircbot/ircplugins/topicmonitor.py @@ -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 diff --git a/ircbot/migrations/0017_ircchannel_server.py b/ircbot/migrations/0017_ircchannel_server.py new file mode 100644 index 0000000..73be70f --- /dev/null +++ b/ircbot/migrations/0017_ircchannel_server.py @@ -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'), + ), + ] diff --git a/ircbot/models.py b/ircbot/models.py index 3769702..0effe57 100644 --- a/ircbot/models.py +++ b/ircbot/models.py @@ -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"), ) diff --git a/markov/ircplugin.py b/markov/ircplugin.py index 92387b0..6df4614 100644 --- a/markov/ircplugin.py +++ b/markov/ircplugin.py @@ -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) diff --git a/twitter/ircplugin.py b/twitter/ircplugin.py index 04c247e..201429e 100644 --- a/twitter/ircplugin.py +++ b/twitter/ircplugin.py @@ -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: