"""Track races and those racing them.""" import logging import irc.client from ircbot.lib import Plugin from races.models import Race, Racer, RaceUpdate log = logging.getLogger('races.ircplugin') class Races(Plugin): """Track races and allow for logging updates.""" def start(self): """Hook handler functions into the IRC library.""" self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!race\s+(\S+)\s+join$', self.join_race) self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!race\s+(\S+)\s+leave$', self.leave_race) self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!race\s+(\S+)\s+start$', self.start_race) self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!race\s+(\S+)\s+finish$', self.finish_race) self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!race\s+(\S+)\s+update\s+(.*)$', self.update_race) super(Races, self).start() def stop(self): """Unhook handler functions into the IRC library.""" self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.join_race) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.leave_race) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.start_race) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.finish_race) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.update_race) super(Races, self).stop() def join_race(self, connection, event, match): """Join a race.""" nick = irc.client.NickMask(event.source).nick race_id = match.group(1) try: race = Race.objects.get(key=race_id) # is the nick already in the race try: racer = Racer.objects.get(race=race, nick=nick) # ideally they're not in the db, but if they aren't flagged as joined, # then let them join again i guess if racer.joined: return self.bot.reply(event, "you are already in {0:s}.".format(race.name)) except Racer.DoesNotExist: racer = Racer() racer.race = race racer.nick = nick racer.joined = True racer.started = False racer.finished = False racer.save() return self.bot.reply(event, "you have joined {0:s}.".format(race.name)) except Race.DoesNotExist: return self.bot.reply(event, "race {0:s} not found.".format(race_id)) def leave_race(self, connection, event, match): """Leave a race.""" nick = irc.client.NickMask(event.source).nick race_id = match.group(1) try: race = Race.objects.get(key=race_id) try: racer = Racer.objects.get(race=race, nick=nick) if racer.finished: return self.bot.reply(event, "you can't leave {0:s} since you finished it." "".format(race.name)) if racer.joined: racer.joined = False racer.save() return self.bot.reply(event, "you have left {0:s}.".format(race.name)) else: return self.bot.reply(event, "you weren't in {0:s}.".format(race.name)) except Racer.DoesNotExist: return self.bot.reply(event, "you weren't in {0:s}.".format(race.name)) except Race.DoesNotExist: return self.bot.reply(event, "race {0:s} not found.".format(race_id)) def start_race(self, connection, event, match): """Start racing.""" nick = irc.client.NickMask(event.source).nick race_id = match.group(1) try: race = Race.objects.get(key=race_id) try: racer = Racer.objects.get(race=race, nick=nick) if racer.started: return self.bot.reply(event, "you have already started {0:s}.".format(race.name)) if racer.finished: return self.bot.reply(event, "you can't start {0:s} since you finished it." "".format(race.name)) racer.started = True racer.save() # create an event for this too RaceUpdate.objects.create(race=race, racer=racer, update="Started the race.") return self.bot.reply(event, "you have started {0:s}.".format(race.name)) except Racer.DoesNotExist: return self.bot.reply(event, "you have not joined {0:s}.".format(race.name)) except Race.DoesNotExist: return self.bot.reply(event, "race {0:s} not found.".format(race_id)) def finish_race(self, connection, event, match): """Finish racing.""" nick = irc.client.NickMask(event.source).nick race_id = match.group(1) try: race = Race.objects.get(key=race_id) try: racer = Racer.objects.get(race=race, nick=nick) if not racer.started: return self.bot.reply(event, "you have not started {0:s}.".format(race.name)) if racer.finished: return self.bot.reply(event, "you have already finished {0:s}." "".format(race.name)) racer.finished = True racer.save() # create an event for this too RaceUpdate.objects.create(race=race, racer=racer, update="Finished the race.") return self.bot.reply(event, "you have finished {0:s}.".format(race.name)) except Racer.DoesNotExist: return self.bot.reply(event, "you have not joined {0:s}.".format(race.name)) except Race.DoesNotExist: return self.bot.reply(event, "race {0:s} not found.".format(race_id)) def update_race(self, connection, event, match): """Add an update to an ongoing race.""" nick = irc.client.NickMask(event.source).nick race_id = match.group(1) update = match.group(2) try: race = Race.objects.get(key=race_id) try: racer = Racer.objects.get(race=race, nick=nick) if not racer.started: return self.bot.reply(event, "you have not started {0:s}.".format(race.name)) if racer.finished: return self.bot.reply(event, "you have already finished {0:s}." "".format(race.name)) # create an event RaceUpdate.objects.create(race=race, racer=racer, update=update) return self.bot.reply(event, "update logged.") except Racer.DoesNotExist: return self.bot.reply(event, "you have not joined {0:s}.".format(race.name)) except Race.DoesNotExist: return self.bot.reply(event, "race {0:s} not found.".format(race_id)) plugin = Races