From 5c689e4076461111ae249fb22ba8e373f306e957 Mon Sep 17 00:00:00 2001 From: Thomas Steen Rasmussen Date: Mon, 3 Jul 2017 19:28:50 +0200 Subject: [PATCH] queue an irc message when we sell a ticket --- src/ircbot/irc3module.py | 5 ++-- src/ircbot/ircworker.py | 29 +++++++++++++++++++ src/shop/__init__.py | 2 ++ src/shop/apps.py | 9 +++++- src/shop/signal_handlers.py | 28 ++++++++++++++++++ .../commands/run_managepy_worker.py | 8 +++-- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/ircbot/ircworker.py create mode 100644 src/shop/signal_handlers.py diff --git a/src/ircbot/irc3module.py b/src/ircbot/irc3module.py index eccca210..9a21336c 100644 --- a/src/ircbot/irc3module.py +++ b/src/ircbot/irc3module.py @@ -18,7 +18,6 @@ class Plugin(object): def __init__(self, bot): self.bot = bot - self.log = self.bot.log ############################################################################################### @@ -69,7 +68,7 @@ class Plugin(object): This method gets unprocessed OutgoingIrcMessage objects and attempts to send them to the target channel. Messages are skipped if the bot is not in the channel. """ - logger.debug("inside get_outgoing_messages()") + #logger.debug("inside get_outgoing_messages()") for msg in OutgoingIrcMessage.objects.filter(processed=False).order_by('created'): # if this message expired mark it as expired and processed without doing anything if msg.timeout < timezone.now(): @@ -92,7 +91,7 @@ class Plugin(object): else: logger.warning("skipping message to %s" % msg.target) - # call this function again in 60 seconds + # call this function again in X seconds self.bot.loop.call_later(settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS, self.bot.get_outgoing_messages) diff --git a/src/ircbot/ircworker.py b/src/ircbot/ircworker.py new file mode 100644 index 00000000..af0441cd --- /dev/null +++ b/src/ircbot/ircworker.py @@ -0,0 +1,29 @@ +from .models import OutgoingIrcMessage +from django.conf import settings +import logging, irc3 +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger('bornhack.%s' % __name__) + + +def do_work(): + """ + Run irc3 module code, wait for events on IRC and wait for messages in OutgoingIrcMessage + """ + config = { + 'nick': settings.IRCBOT_NICK, + 'autojoins': [settings.IRCBOT_SCHEDULE_ANNOUNCE_CHANNEL], + 'host': settings.IRCBOT_SERVER_HOSTNAME, + 'port': settings.IRCBOT_SERVER_PORT, + 'ssl': settings.IRCBOT_SERVER_USETLS, + 'timeout': 30, + 'includes': [ + 'ircbot.irc3module', + ], + } + logger.debug("Connecting to IRC with the following config: %s" % config) + try: + irc3.IrcBot(**config).run(forever=True) + except Exception as E: + logger.exception("Got exception inside do_work for %s" % self.workermodule) + raise + diff --git a/src/shop/__init__.py b/src/shop/__init__.py index e69de29b..2da9e616 100644 --- a/src/shop/__init__.py +++ b/src/shop/__init__.py @@ -0,0 +1,2 @@ +default_app_config = 'shop.apps.ShopConfig' + diff --git a/src/shop/apps.py b/src/shop/apps.py index a5c02621..9f11a60d 100644 --- a/src/shop/apps.py +++ b/src/shop/apps.py @@ -1,5 +1,12 @@ from django.apps import AppConfig - +from .signal_handlers import ticket_created +from django.db.models.signals import post_save +import logging +logger = logging.getLogger("bornhack.%s" % __name__) class ShopConfig(AppConfig): name = 'shop' + + def ready(self): + post_save.connect(ticket_created, sender='shop.Ticket') + diff --git a/src/shop/signal_handlers.py b/src/shop/signal_handlers.py new file mode 100644 index 00000000..e2c2004f --- /dev/null +++ b/src/shop/signal_handlers.py @@ -0,0 +1,28 @@ +from django.utils import timezone +from django.conf import settings +from datetime import timedelta +from django.db.models import Count +import logging +logger = logging.getLogger("bornhack.%s" % __name__) + + +def ticket_created(sender, instance, created, **kwargs): + # only send a message when a ticket is created + if not created: + return + + # queue an IRC message to the orga channel if any is defined, otherwise for the default channel + target = settings.IRCBOT_CHANNELS['orga'] if 'orga' in settings.IRCBOT_CHANNELS else settings.IRCBOT_CHANNELS['default'] + + # get ticket stats, FIXME: Camp name is hardcoded here for now + from shop.models import Ticket + stats = ", ".join(["%s: %s" % (tickettype['product__name'], tickettype['total']) for tickettype in Ticket.objects.filter(product__name__startswith="BornHack 2017").values('product__name').annotate(total=Count('product__name')).order_by('product__name')]) + + # queue the message + from ircbot.models import OutgoingIrcMessage + OutgoingIrcMessage.objects.create( + target=target, + message="%s sold! Totals: %s" % (instance.product.name, stats), + timeout=timezone.now()+timedelta(minutes=10) + ) + diff --git a/src/utils/management/commands/run_managepy_worker.py b/src/utils/management/commands/run_managepy_worker.py index 3dc784a0..3d70d6f1 100644 --- a/src/utils/management/commands/run_managepy_worker.py +++ b/src/utils/management/commands/run_managepy_worker.py @@ -53,8 +53,12 @@ class Command(BaseCommand): logger.info("Entering main loop...") while True: - # run worker code - getattr(self.workermodule, 'do_work')() + try: + # run worker code + getattr(self.workermodule, 'do_work')() + except Exception as E: + logger.exception("Got exception inside do_work for %s" % self.workermodule) + sys.exit(1) # sleep for N seconds before calling worker code again i = 0