瀏覽代碼

more rotbot refactoring

tBKwtWS 6 年之前
父節點
當前提交
b488786f07
共有 7 個文件被更改,包括 415 次插入429 次删除
  1. 13 10
      rotbot/bot.py
  2. 141 140
      rotbot/commands/admin.py
  3. 4 11
      rotbot/commands/common.py
  4. 88 97
      rotbot/commands/games.py
  5. 99 102
      rotbot/commands/public.py
  6. 67 69
      rotbot/commands/statistics.py
  7. 3 0
      rotbot/events/common.py

+ 13 - 10
rotbot/bot.py

@@ -6,7 +6,7 @@ import irc.bot#, irc.strings    #https://python-irc.readthedocs.io/en/latest/irc
 from jaraco.stream import buffer
 from postgres import Postgres   # https://postgres-py.readthedocs.io/en/latest/
 
-#import commands.public, commands.admin, commands.games, commands.statistics
+import commands.public, commands.admin, commands.games, commands.statistics
 import events.on_welcome, events.on_join, events.on_kick, events.on_mode, events.on_pubmsg, events.on_action, events.on_whoreply, events.on_nick
 from common import log, font
 from common.networkservices import NickServ
@@ -111,15 +111,15 @@ class PyRot(irc.bot.SingleServerIRCBot):
 #
     def on_pubmsg(self, connection,  event):
         events.on_pubmsg.process_event(self, connection, event)
-#         commands.public.do_command(self, connection, event)
-#         commands.admin.do_command(self, connection, event)
+        commands.public.do_command(self, connection, event)
+        commands.admin.do_command(self, connection, event)
 #         commands.statistics.do_command(self, connection, event)
 #         commands.games.do_command(self, connection, event)
 #
     def on_privmsg(self, connection, event):
         log.info(event)
-#         commands.public.do_command(self, connection, event)
-#         commands.admin.do_command(self, connection, event)
+        commands.public.do_command(self, connection, event)
+        commands.admin.do_command(self, connection, event)
 #         commands.statistics.do_command(self, connection, event)
 #         commands.games.do_command(self, connection, event)
         if not event.source.nick == connection.get_nickname():
@@ -136,21 +136,24 @@ class PyRot(irc.bot.SingleServerIRCBot):
 
     def on_privnotice(self,  connection,  event):
         log.info(event)
-        # commands.public.do_command(self, connection, event)
-        # commands.admin.do_command(self, connection, event)
+        commands.public.do_command(self, connection, event)
+        commands.admin.do_command(self, connection, event)
         # commands.statistics.do_command(self, connection, event)
         # commands.games.do_command(self, connection, event)
         if event.source.nick == connection.get_nickname():  # Message came from bot?
             return
         elif event.source.nick == "NickServ":
-            print(event.arguments)
-            print(event.arguments[0])
             if event.arguments[0].startswith("This nickname is registered"):
                 connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password)) # Identify with NickServ.
             if event.arguments[0].startswith("You are already identified."):
                 return
-            if event.arguments[0].startswith(self.network.username + " is not a registered nickname."): # Username from database is not registered.
+
+                # Nick \x02RotBot\x02 isn't registered.
+            if event.arguments[0].startswith(self.network.username + " is not a registered nickname.") or event.arguments[0].startswith('Nick ') and event.arguments[0].endswith(' isn\'t registered.'): # Username from database is not registered.
                 connection.privmsg('NickServ', 'register %s spamtBK@xs4all.nl' % (self.network.password)) # Register with NickServ.
+                log.info('Registerring with NickServ.')
+            if event.arguments[0].startswith('Nickname ') and event.arguments[0].endswith(' registered.'):
+                Inform.home_channel(seld, connection, 'Registerred nickname %s%s%s with NickServ.' % font.red, self.network.nickname, font.reset)
         # elif event.source.nick == "ChanServ":
         #     if event.arguments[0].startswith("Key for channel ") and len(event.arguments[0]) > 5:   # Received channel key.
         #         self.channelkeys[event.arguments[0].split(' ')[3]] = event.arguments[0].split(' ')[5][:-1]

+ 141 - 140
rotbot/commands/admin.py

@@ -3,43 +3,40 @@ from common import userstatus, do_everything_to, log, font
 from commands.common import CommandHelpers as CH
 from commands.common import AdminHelpers as AH
 
-bold = "\x02"
-italic = "\x1D"
-underline = "\x1F"
-reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-reset = "\x0F"
-blue = "\x0302"
-green = "\x0303"
-red = "\x0304"
-grey = "\x0314"
 
 def do_command(self, connection, event):
     cmdtype, trigger, command, replyto = CH.disect_command(self, event)
 
+    # Do nothing if it's not a type of command.
+    if not cmdtype:
+        return
+
     # Do nothing if there is no command.
     if not command:
         return
+
+    # The first word of the command sting with arguments, is just the command without arguments.
     try:
-        command.split()[0]
+        one = command.split()[0]    # Get raw command.
     except:
         return
 
-    # Ignore channel commands from users that do not have at least voice in homechannel or operator status in target channel.
-    if event.type == "pubmsg":   # It's a channel message.
-        if not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target): # Does not have at least voiced status in homechannel or operator status in target channel.
-            return
-
-    # Secret command to let the bot give you channel status.
-    if trigger.split()[0] == "!uXVETIkWIL~qG5CasftKKAL<MFpfOyap|F]65v,E" and event.target == connection.get_nickname():   # It's a PM. # Keep the command secret.
+    # Secret command to let the bot give you channel status. ANd a HUGE security issue ;)
+    if trigger.split()[0] == "!uXVETIkWIL~qG5CasftKKAL<MFpfOyap|F]65v,E" and event.target == connection.get_nickname():   # It's a PM. # Keep the command secret, for the sake of your reptation.
         if len(command.split()) == 2: # 2 arguments.
             if command.split()[1] in self.channels:   # Stop silently if thebot is not in the requested channel.
-                connection.mode(command.split()[1], "+ohv " + event.source.nick + " " + event.source.nick + " " + event.source.nick)
+                connection.mode(command.split()[1], "+ohv %s %s %s" % event.source.nick, event.source.nick, event.source.nick)
         elif len(command.split()) == 1: # 1 argument.
             for channel in self.channels:
-                connection.mode(channel, "+ohv " + event.source.nick + " " + event.source.nick + " " + event.source.nick)
+                connection.mode(channel, "+ohv %s %s %s" % event.source.nick, event.source.nick, event.source.nick)
 
-    elif command == "cmd" or command == "cmds" or command == "commands":
-        if cmdtype == "help":    # Display help text.
+
+    # Do not even consider to run the latter admin commands for users who do not atleast have operator status in the concerning channel or halfop in the home_channel.
+    elif not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target):
+        return
+
+    elif command == 'cmd' or command == 'cmds' or command == 'commands':
+        if cmdtype == 'help':    # Display help text.
             connection.privmsg(replyto, 'Lists commands, usage: %s%s ' % self.network.command_character, command)
         if cmdtype == "cmd":
             message = grey + "Admin: "
@@ -65,17 +62,17 @@ def do_command(self, connection, event):
                 message += CH.ccc(self, "act", {"homechan": "oper",  "chan": "oper"}, event)
             if message == grey + "Admin: ": # No commands to display.
                 return
-            connection.privmsg(replyto, message[:-2] + ".")
+            connection.privmsg(replyto, '%s.' % message[:-2])
 
-    elif command.split()[0] == "quit":
-        if cmdtype == "help":    # Display help text.
+    elif one == 'quit':
+        if cmdtype == 'help':    # Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Disconnect and terminate " + connection.get_nickname() + ". Optionally with reason.")
-            connection.privmsg(replyto,  grey + "Usage: " + blue + "!quit " + reset + italic + "reason")
+            connection.privmsg(replyto,  grey + "Usage: " + blue + "!quit " + font.reset + font.italic + "reason")
         elif cmdtype == "cmd":
             if not userstatus.atleast_admin(self, event.source.nick, self.network.home_channel): #Insufficient rights.
-                connection.privmsg(replyto, "Denied, you need to have admin (super operator) status or higher in " + red + self.network.home_channel  + reset + ".")
+                connection.privmsg(replyto, "Denied, you need to have admin (super operator) status or higher in " + font.font.red + self.network.home_channel  + font.reset + ".")
                 return
             if len(command.split()) == 1:
                 log.info("Killed by: " + event.source.nick)
@@ -84,24 +81,24 @@ def do_command(self, connection, event):
                 log.info("Killed by " + event.source.nick + " for " + trigger.split(maxsplit=1)[1])
                 self.die(msg = "[" + event.source.nick + "] " + trigger.split(maxsplit=1)[1])
 
-    elif command.split()[0] == "reconnect":
+    elif one == "reconnect":
         if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel):
-            connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + red + self.network.home_channel  + reset + ".")
+            connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + font.font.red + self.network.home_channel  + font.reset + ".")
             return
         if cmdtype == "help":    # Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Reconnect " + connection.get_nickname() + ". Reason optional.")
-            connection.privmsg(replyto,  grey + "Usage: " + blue + "!reconnect " + reset + italic + "reason")
+            connection.privmsg(replyto,  grey + "Usage: " + blue + "!reconnect " + font.reset + font.italic + "reason")
         elif cmdtype == "cmd":
             if len(command.split()) == 1:
                 self.disconnect(msg = "Reconnect requested by " + event.source.nick)
             else:
                 self.disconnect(msg = "[" + event.source.nick + "] " + command.split(maxsplit=1)[1])
 
-    elif command.split()[0] == "recovernick":
+    elif one == "recovernick":
         if not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):
-            connection.privmsg(replyto, "Denied, you need to have voiced status or higher in " + red + self.network.home_channel  + reset + ".")
+            connection.privmsg(replyto, "Denied, you need to have voiced status or higher in " + font.font.red + self.network.home_channel  + font.reset + ".")
             return
         if cmdtype == "help":    # Display help text.
             if len(command.split()) is not 1:
@@ -109,20 +106,20 @@ def do_command(self, connection, event):
             connection.privmsg(replyto, "Let " + connection.get_nickname() + " try to recover " + connection.nickname + " as nickname.")
         elif cmdtype == "cmd":
             if connection.get_nickname() == connection.nickname:
-                connection.action(replyto,  "is already named " + red + connection.nickname + reset + ".")
+                connection.action(replyto,  "is already named " + font.font.red + connection.nickname + font.reset + ".")
                 return
             from common.networkservices import NickServ
             NickServ.recover_nick(connection, self.password)
 
-    elif command.split()[0] == "join":
+    elif one == "join":
         if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel):
-            connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + red + self.network.home_channel  + reset + ".")
+            connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + font.font.red + self.network.home_channel  + font.reset + ".")
             return
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Make " + connection.get_nickname() + " join a channel. Password optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "join " + red + italic + "channel " + reset + italic + "password")
+            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "join " + font.font.red + font.italic + "channel " + font.reset + font.italic + "password")
         elif cmdtype == "cmd":
             try:
                 channel = command.split()[1]
@@ -136,12 +133,12 @@ def do_command(self, connection, event):
                 return
             do_everything_to.join(self, connection, channel, key)
 
-    elif command.split()[0] == "part":
+    elif one == "part":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Make " + connection.get_nickname() + " part a channel. Reason optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "join " + red + italic + "channel " + reset + italic + "password")
+            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "join " + font.font.red + font.italic + "channel " + font.reset + font.italic + "password")
         elif cmdtype == "cmd":
 
             homeadmin = False
@@ -155,20 +152,20 @@ def do_command(self, connection, event):
             if len(command.split()) == 1:   # No arguments.
                 if event.target in self.channels:   # It's a channel message.
                     if not homeadmin and not targetadmin:   # Insufficient rights:
-                        connection.privmsg(replyto, "Denied. You need to have at least operator status in " + red + self.homechan + reset + " or " + red + event.target + reset + ".")
+                        connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.font.red + self.homechan + font.reset + " or " + font.font + event.target + font.reset + ".")
                         return
                     if event.target == self.network.home_channel:
                         connection.action(replyto, "shall not abandon it's home channel!")
                         return
                     connection.part(event.target, event.source.nick)
                 else:   # It's a PM.
-                    connection.privmsg(replyto, "Specify a channel to part. For help type " + blue + self.helpchar + "part" + reset + ".")
+                    connection.privmsg(replyto, "Specify a channel to part. For help type " + blue + self.helpchar + "part" + font.reset + ".")
             elif len(command.split()) > 1:   # Arguments
                 if command.split()[1] not in self.channels: # First argument is not a channel the bot inhabits.
-                    connection.action(replyto, "does not inhabit " + red + command.split()[1] + reset + ". For help type " + blue + self.helpchar + "part" + reset + ".")
+                    connection.action(replyto, "does not inhabit " + font.red + command.split()[1] + font.reset + ". For help type " + blue + self.helpchar + "part" + font.reset + ".")
                     return
                 if not homeadmin and not userstatus.atleast_oper(self, event.source.nick, command.split()[1]):  # Insufficient rights.
-                    connection.privmsg(replyto, "Denied. You need to have at least operator status in " + red + self.homechan + reset + " or " + red + command.split()[1] + reset + ".")
+                    connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + self.homechan + font.reset + " or " + font.red + command.split()[1] + font.reset + ".")
                     return
                 if command.split()[1] == self.network.home_channel:
                     connection.action("shall not abandon it's home channel!")
@@ -178,7 +175,7 @@ def do_command(self, connection, event):
                 except:
                     connection.part(command.split()[1], event.source.nick)
 
-    elif command.split()[0] == "msg" or  command.split(maxsplit=1)[0] == "act":
+    elif one == "msg" or  command.split(maxsplit=1)[0] == "act":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
@@ -189,7 +186,7 @@ def do_command(self, connection, event):
                 message = "Let " + connection.get_nickname() + "send a message to a channel."
                 arguments = "name message"
             connection.privmsg(replyto, message)
-            connection.privmsg(replyto, grey + "Usage: " + blue + "!" + command.split(maxsplit=1)[0] + reset + italic + " target " + arguments)
+            connection.privmsg(replyto, grey + "Usage: " + blue + "!" + command.split(maxsplit=1)[0] + font.reset + font.italic + " target " + arguments)
         elif cmdtype == "cmd":
 
             # Parse user input.
@@ -207,124 +204,128 @@ def do_command(self, connection, event):
             # Send the message if user has owner status in the home channel.
             if self.channels[self.network.home_channel].is_owner(event.source.nick):
                 if destination == connection.get_nickname():
-                    connection.privmsg(replyto, "To prevent dying in a loop I shall not message myself.")
+                    connection.privmsg(replyto, "I just love talking to myself.")
                     return
                 if command.split(maxsplit=1)[0] == "act":
                     connection.action(destination, message)
                 else:
                     connection.privmsg(destination, message)
 
-            # Reply error when bot does not inhabit destination channel.
-            elif destination not in self.channels:
-                connection.action(replyto, "does not inhabit " + red + destination + reset + ".")
+            # # Reply error when bot does not inhabit destination channel.
+            # elif destination not in self.channels:
+            #     connection.action(replyto, "does not inhabit " + font.red + destination + font.reset + ".")
 
-            # Send message if user has at least operator status the home channel or the channel the message is intended for.
-            elif userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) or userstatus.atleast_oper(self, event.source.nick, destination):
+            # Send message if user has at least half operator status the home channel or the channel the message is intended for.
+            elif userstatus.atleast_halfop(self, event.source.nick, self.network.home_channel) or userstatus.atleast_halfop(self, event.source.nick, destination):
                 if command.split(maxsplit=1)[0] == "act":
                     connection.action(destination, message)
                 else:
+                    if message.startwith('.') or message.startswith('!'):
+                        connection.privmsg(replyto, 'I\'d rather not send commands on behalf of anonymous senders. This command is more intended to joke around with people')
+                        connection.privmsg(reply, 'If there are complaints about your spamming your rights could be revoked.')
+                        return
                     connection.privmsg(destination, message)
 
             # Reply error if user is not operator of destination channel.
             else:
-                connection.privmsg(replyto, "Denied, you need to be an operator of " + red + destination + reset +".")
-
-    elif command.split()[0] == "channelfunctions":
-        if cmdtype == "help":    #Display help text. # Help code block first, as it is impossible to predict for what channel a later command is going to be issued. Rights filtering after help test.
-            if len(command.split()) is not 1:
-                return
-            connection.privmsg(replyto, "Display or toggle the status channel functions. Channel, function and value optional. Get a description of a functio via the help argument.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + "!channelfunctions " + red + italic + "channel " + reset + italic + "function value")
-            connection.privmsg(replyto, grey + "Usage: " + blue + "!channelfunctions describe " + reset + italic + "function")
-        elif cmdtype == "cmd":
+                connection.privmsg(replyto, "Denied, you need to be an operator of " + font.red + destination + font.reset +".")
 
-            if len(command.split()) == 1:   # No arguments.
-                if event.target == connection.get_nickname():   # Command issued via PM.
-                    connection.privmsg(replyto, "Nothing to display, Specify a channel.")
-                else:   # Command issued as channel message.
-                    message = AH.get_channelfunctions(self, event.target)
-                    connection.privmsg(replyto, message)
-
-            elif len(command.split()) == 2:   # One argument.
-                if command.split()[1] in self.channels: # Info requested on specific channel.
-                    message = AH.get_channelfunctions(self, command.split()[1])
-                    connection.privmsg(replyto, message)
-                else:   # First argument is not a channel the bot inhabits.
-                    if not command.split()[1].lower() == "help":    # Not a help request.
-                        connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                    else:   # Help request.
-                        connection.privmsg(replyto, "Specify a channel function to get a description of. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-
-            elif len(command.split()) == 3: # Two arguments.
-                channel = event.target
-                if event.target == connection.get_nickname():   # Command issued via PM.
-                    connection.privmsg(replyto, "One or three arguments required. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                else:   # Command issued via channel.
-                    if not AH.is_channelfunction(command.split()[1]):   # First argument is not a channelfunction.
-                        if not command.split()[1].lower() == "describe":    # Not a help request.
-                            connection.privmsg(replyto, command.split()[1] + " is not a channel function. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                            return
-                        if not AH.is_channelfunction(command.split()[2]): # Second argument not a channel function.
-                                connection.privmsg(replyto, command.split()[2] + " is not a channel function.")
-                                return
-                        connection.privmsg(replyto, AH.describe_channelfunction(command.split()[2]))
-                        return
-                    # Second argument unsupported.
-                    if not command.split()[2].lower() in ["on",  "off"]:
-                        if command.split()[1].lower() == "aggressiveness":
-                            if not AH.is_aggressiveness(command.split()[2].lower()):    # Is not an aggressiveness setting.
-                                connection.privmsg(replyto, command.split()[2] + " is not an aggressiveness setting. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                                return
-                        else:   # Channel function is not aggresiveness.
-                            connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                            return
-                    if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target):   # Does not have operator status or higher in target or home channel.
-                        connection.privmsg(replyto, "Denied. You need to have at least operator status in " + red + event.target + reset + " or " + red + self.network.home_channel + reset + ".")
-                        return
-                    if command.split()[1].lower() == "autojoin" and event.target == self.network.home_channel:   # Chaning autojoin of homechannel.
-                        connection.action(replyto, "will always join it's homechannel " + red + self.network.home_channel + reset + ", regardless of the autojoin function.")
-                    #self.db.run("UPDATE channels SET " + command.split()[1].lower() + "='" + command.split()[2].lower() + "' WHERE name='" + event.target + "' AND network='" + self.network + "'")
-                    self.db.run("UPDATE channels SET " + command.split()[1].lower() + "=%s WHERE name='" + event.target + "' AND network='" + self.network + "'", (command.split()[2].lower(), ))
-
-            elif len(command.split()) == 4: # Three arguments.
-                if not command.split()[1] in self.channels: # Bot does not inhabit channel to be altered.
-                    connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                    return
-                if not AH.is_channelfunction(command.split()[2]):  # Function does not exist.
-                    connection.privmsg(replyto, command.split()[2] + " is not a valid channel function. For a list help type: " + blue + self.cmdchar + "channelfunctions" + red + italic + "channel")
-                    return
-
-                if not command.split()[3].lower() in ["on", "off"] and not command.split()[2].lower() == "aggressiveness": # Third argument unsupported.
-                    connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
-                    return
-                if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, command.split()[1]):   # Does not have operator status or higher in target or home channel.
-                    connection.privmsg(replyto, "Denied. You need to have at least operator status in " + red + event.target + reset + " or " + red + self.network.home_channel + reset + ".")
-                    return
-                if command.split()[2].lower() == "autojoin" and command.split()[1] == self.network.home_channel:   # Chaning autojoin of homechannel.
-                    connection.action(replyto, "will always join it's homechannel " + red + self.network.home_channel + reset + ", regardless of the autojoin function.")
-                try:
-                    self.db.run("UPDATE channels SET " + command.split()[2].lower() + "='" + command.split()[3].lower() + "' WHERE LOWER(name)=LOWER('" + command.split()[1] + "') AND network='" + self.network + "'")
-                except:
-                    connection.privmsg(replyto, "Error, database record not updated.")
-                    return
-            else:   # Too many arguments.
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "channelfunctions" + reset + ".")
+    # elif one == "channelfunctions":
+    #     if cmdtype == "help":    #Display help text. # Help code block first, as it is impossible to predict for what channel a later command is going to be issued. Rights filtering after help test.
+    #         if len(command.split()) is not 1:
+    #             return
+    #         connection.privmsg(replyto, "Display or toggle the status channel functions. Channel, function and value optional. Get a description of a functio via the help argument.")
+    #         connection.privmsg(replyto, grey + "Usage: " + blue + "!channelfunctions " + font.red + font.italic + "channel " + font.reset + font.italic + "function value")
+    #         connection.privmsg(replyto, grey + "Usage: " + blue + "!channelfunctions describe " + font.reset + font.italic + "function")
+    #     elif cmdtype == "cmd":
+    #
+    #         if len(command.split()) == 1:   # No arguments.
+    #             if event.target == connection.get_nickname():   # Command issued via PM.
+    #                 connection.privmsg(replyto, "Nothing to display, Specify a channel.")
+    #             else:   # Command issued as channel message.
+    #                 message = AH.get_channelfunctions(self, event.target)
+    #                 connection.privmsg(replyto, message)
+    #
+    #         elif len(command.split()) == 2:   # One argument.
+    #             if command.split()[1] in self.channels: # Info requested on specific channel.
+    #                 message = AH.get_channelfunctions(self, command.split()[1])
+    #                 connection.privmsg(replyto, message)
+    #             else:   # First argument is not a channel the bot inhabits.
+    #                 if not command.split()[1].lower() == "help":    # Not a help request.
+    #                     connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                 else:   # Help request.
+    #                     connection.privmsg(replyto, "Specify a channel function to get a description of. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #
+    #         elif len(command.split()) == 3: # Two arguments.
+    #             channel = event.target
+    #             if event.target == connection.get_nickname():   # Command issued via PM.
+    #                 connection.privmsg(replyto, "One or three arguments required. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #             else:   # Command issued via channel.
+    #                 if not AH.is_channelfunction(command.split()[1]):   # First argument is not a channelfunction.
+    #                     if not command.split()[1].lower() == "describe":    # Not a help request.
+    #                         connection.privmsg(replyto, command.split()[1] + " is not a channel function. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                         return
+    #                     if not AH.is_channelfunction(command.split()[2]): # Second argument not a channel function.
+    #                             connection.privmsg(replyto, command.split()[2] + " is not a channel function.")
+    #                             return
+    #                     connection.privmsg(replyto, AH.describe_channelfunction(command.split()[2]))
+    #                     return
+    #                 # Second argument unsupported.
+    #                 if not command.split()[2].lower() in ["on",  "off"]:
+    #                     if command.split()[1].lower() == "aggressiveness":
+    #                         if not AH.is_aggressiveness(command.split()[2].lower()):    # Is not an aggressiveness setting.
+    #                             connection.privmsg(replyto, command.split()[2] + " is not an aggressiveness setting. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                             return
+    #                     else:   # Channel function is not aggresiveness.
+    #                         connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                         return
+    #                 if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target):   # Does not have operator status or higher in target or home channel.
+    #                     connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + event.target + font.reset + " or " + font.red + self.network.home_channel + font.reset + ".")
+    #                     return
+    #                 if command.split()[1].lower() == "autojoin" and event.target == self.network.home_channel:   # Chaning autojoin of homechannel.
+    #                     connection.action(replyto, "will always join it's homechannel " + font.red + self.network.home_channel + font.reset + ", regardless of the autojoin function.")
+    #                 #self.db.run("UPDATE channels SET " + command.split()[1].lower() + "='" + command.split()[2].lower() + "' WHERE name='" + event.target + "' AND network='" + self.network + "'")
+    #                 self.db.run("UPDATE channels SET " + command.split()[1].lower() + "=%s WHERE name='" + event.target + "' AND network='" + self.network + "'", (command.split()[2].lower(), ))
+    #
+    #         elif len(command.split()) == 4: # Three arguments.
+    #             if not command.split()[1] in self.channels: # Bot does not inhabit channel to be altered.
+    #                 connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                 return
+    #             if not AH.is_channelfunction(command.split()[2]):  # Function does not exist.
+    #                 connection.privmsg(replyto, command.split()[2] + " is not a valid channel function. For a list help type: " + blue + self.cmdchar + "channelfunctions" + font.red + font.italic + "channel")
+    #                 return
+    #
+    #             if not command.split()[3].lower() in ["on", "off"] and not command.split()[2].lower() == "aggressiveness": # Third argument unsupported.
+    #                 connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
+    #                 return
+    #             if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, command.split()[1]):   # Does not have operator status or higher in target or home channel.
+    #                 connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + event.target + font.reset + " or " + font.red + self.network.home_channel + font.reset + ".")
+    #                 return
+    #             if command.split()[2].lower() == "autojoin" and command.split()[1] == self.network.home_channel:   # Chaning autojoin of homechannel.
+    #                 connection.action(replyto, "will always join it's homechannel " + font.red + self.network.home_channel + font.reset + ", regardless of the autojoin function.")
+    #             try:
+    #                 self.db.run("UPDATE channels SET " + command.split()[2].lower() + "='" + command.split()[3].lower() + "' WHERE LOWER(name)=LOWER('" + command.split()[1] + "') AND network='" + self.network + "'")
+    #             except:
+    #                 connection.privmsg(replyto, "Error, database record not updated.")
+    #                 return
+    #         else:   # Too many arguments.
+    #             connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "channelfunctions" + font.reset + ".")
 
-    elif command.split()[0] == "registernick":
+    elif one == "registernick":
         if not self.channels[self.network.home_channel].is_owner(event.source.nick): #Insufficient rights.
-            connection.privmsg(replyto, "Denied, you need to be the owner of " + red + self.network.home_channel  + reset + ".")
+            connection.privmsg(replyto, "Denied, you need to be the owner of " + font.red + self.network.home_channel  + font.reset + ".")
             return
         if cmdtype == "help":    # Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Register with NickServ.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "registernick " + reset + italic + "email")
+            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "registernick " + font.reset + font.italic + "email")
         elif cmdtype == "cmd":
 
             if len(command.split()) == 1:
-                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "registernick" + reset + ".")
+                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "registernick" + font.reset + ".")
             elif len(command.split()) > 2:
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "registernick" + reset + ".")
+                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "registernick" + font.reset + ".")
             elif not self.db.one("SELECT password FROM networks WHERE name='" + self.network + "'"):
                 alphabet = string.ascii_letters + string.digits
                 password = ''.join(secrets.choice(alphabet) for i in range(20)) # 20-character password.
@@ -333,21 +334,21 @@ def do_command(self, connection, event):
             else:
                 connection.privmsg("NickServ", "REGISTER " + self.db.one("SELECT password FROM networks WHERE name='" + self.network + "'") + " " + trigger.split()[1])
 
-    elif command.split()[0] == "banall":
+    elif one == "banall":
         if not self.channels[self.network.home_channel].is_owner(event.source.nick): #Insufficient rights.
-            connection.privmsg(replyto, "Denied, you need to be the owner of " + red + self.network.home_channel  + reset + ".")
+            connection.privmsg(replyto, "Denied, you need to be the owner of " + font.red + self.network.home_channel  + font.reset + ".")
             return
         if cmdtype == "help":    # Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Ban all nicknames and usernames for a host in all channels.")
-            connection.privmsg(replyto, grey + "Example: " + blue + self.cmdchar + "banall " + reset + italic + "host")
+            connection.privmsg(replyto, grey + "Example: " + blue + self.cmdchar + "banall " + font.reset + font.italic + "host")
         elif cmdtype == "cmd":
 
             if len(command.split()) == 1:
-                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "banall" + reset + ".")
+                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "banall" + font.reset + ".")
             elif len(command.split()) > 2:
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "banall" + reset + ".")
+                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "banall" + font.reset + ".")
             else:
                 labels = trigger.split()[1].split(".")
                 allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)

+ 4 - 11
rotbot/commands/common.py

@@ -1,18 +1,11 @@
 import random
-bold = "\x02"
-italic = "\x1D"
-underline = "\x1F"
-reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-reset = "\x0F"
-blue = "\x0302"
-green = "\x0303"
-red = "\x0304"
-grey = "\x0314"
+from common import font
+
 
 class CommandHelpers():
     def disect_command(self, event):
-        trigger = event.arguments[0]
-        command = trigger[1:].lower()   #Command without prefix.
+        trigger = event.arguments[0]    # Everything the user inputted.
+        command = trigger[1:].lower()   # Command without prefix. = trigger minus first character.
 
         # Determine command type.
         if trigger.startswith(self.network.command_character):

+ 88 - 97
rotbot/commands/games.py

@@ -1,20 +1,11 @@
 import random
+from common import font
 from commands.common import CommandHelpers as CH
 from commands.common import GameHelpers
 
-bold = "\x02"
-italic = "\x1D"
-underline = "\x1F"
-reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-reset = "\x0F"
-blue = "\x0302"
-green = "\x0303"
-red = "\x0304"
-grey = "\x0314"
-
 def do_command(self, connection, event):
     cmdtype, trigger, command, replyto = CH.disect_command(self, event)
-    
+
     # Do nothing if there is no command.
     if not command:
         return
@@ -22,73 +13,73 @@ def do_command(self, connection, event):
         command.split()[0]
     except:
         return
-    
+
     # Do noting if the games channel function is off and it's a channel message.
     if not self.db.one("SELECT games FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'") and not event.target == connection.get_nickname():
         return
-    
+
     if command == "cmd" or command == "cmds" or command == "commands":
         if cmdtype == "cmd":
-            connection.privmsg(replyto, grey + "Games: " + CH.ccc(self, "8ball") + CH.ccc(self, "dice") + CH.ccc(self, "player") + CH.ccc(self, "players") + CH.ccc(self, "levelup") + CH.ccc(self, "givecoin")[:-2] + ".")
-            connection.privmsg(replyto, grey + "Game help: " + blue + self.helpchar + "level" + grey + ", " + blue + self.helpchar + "xp" + grey + ", " + blue + self.helpchar + "ap" + grey + ", " + blue + self.helpchar + "coin" + grey + ", " + blue + self.helpchar + "karma" + grey + ".")
-    
+            connection.privmsg(replyto, font.grey + "Games: " + CH.ccc(self, "8ball") + CH.ccc(self, "dice") + CH.ccc(self, "player") + CH.ccc(self, "players") + CH.ccc(self, "levelup") + CH.ccc(self, "givecoin")[:-2] + ".")
+            connection.privmsg(replyto, font.grey + "Game help: " + blue + self.helpchar + "level" + font.grey + ", " + blue + self.helpchar + "xp" + font.grey + ", " + blue + self.helpchar + "ap" + font.grey + ", " + blue + self.helpchar + "coin" + font.grey + ", " + blue + self.helpchar + "karma" + font.grey + ".")
+
     elif command.split()[0] == "8ball":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Ask a question of the mighty and illusive 8-Ball.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "8ball " + reset + italic + "question")
+            connection.privmsg(replyto, font.grey + "Usage: " + blue + self.cmdchar + "8ball " + font.reset + font.italic + "question")
         elif cmdtype == "cmd":
-            
+
             if len(command.split()) < 2:    # Command contains only !8ball.
                 messages = [
-                    "Don't forget to ask a question...", 
-                    "Hey, that's not a question!", 
-                    "What would you like to know?", 
-                    "You want me to predict nothing?", 
-                    "Are you intentionally not asking a question?", 
-                    "Ask a question you tease!", 
-                    "You do not seem to grasp this, for help type: " + blue + self.helpchar + "8ball", 
-                    "You will die alone.", 
+                    "Don't forget to ask a question...",
+                    "Hey, that's not a question!",
+                    "What would you like to know?",
+                    "You want me to predict nothing?",
+                    "Are you intentionally not asking a question?",
+                    "Ask a question you tease!",
+                    "You do not seem to grasp this, for help type: " + blue + self.helpchar + "8ball",
+                    "You will die alone.",
                 ]
                 connection.privmsg(replyto, random.choice(messages))
             else:
                 messages = [
-                    "Yes.", 
-                    "No.", 
+                    "Yes.",
+                    "No.",
                     "Affirmative.",
-                    "No way!", 
-                    "Negative.", 
-                    "Positive.", 
-                    "Correct.", 
-                    "Incorrect.", 
-                    "Likely", 
-                    "Unlikely", 
-                    "Maybe.", 
-                    "Definately!", 
-                    "Perhaps?", 
-                    "Most indubitably.", 
-                    "Does the pope shit in the woods?", 
-                    "When hell freezes over.", 
-                    "Only between 9 and 5.", 
-                    "Only just before you die.", 
-                    red + bold + "ERROR: " + bold + "probability failure.", 
-                    "Ask again later.", 
-                    "I don't know.", 
-                    "Unpredictable.", 
+                    "No way!",
+                    "Negative.",
+                    "Positive.",
+                    "Correct.",
+                    "Incorrect.",
+                    "Likely",
+                    "Unlikely",
+                    "Maybe.",
+                    "Definately!",
+                    "Perhaps?",
+                    "Most indubitably.",
+                    "Does the pope shit in the woods?",
+                    "When hell freezes over.",
+                    "Only between 9 and 5.",
+                    "Only just before you die.",
+                    font.red + font.bold + "ERROR: " + font.bold + "probability failure.",
+                    "Ask again later.",
+                    "I don't know.",
+                    "Unpredictable.",
                 ]
                 connection.privmsg(replyto, random.choice(messages))
-    
+
     elif command.split()[0] == "dice":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Rolls multiple dices of chosen type. Specifying type or amount is optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "dice " + reset + italic + "amount type")
-            connection.privmsg(replyto, grey + "Example: " + blue + self.cmdchar + "dice " + reset + italic + "2 d10")
-            connection.privmsg(replyto, grey + "Note: " + reset + "The dice type is specified as a " + italic + "d " + reset + "followed by the amount of sides.")
+            connection.privmsg(replyto, font.grey + "Usage: " + blue + self.cmdchar + "dice " + font.reset + font.italic + "amount type")
+            connection.privmsg(replyto, font.grey + "Example: " + blue + self.cmdchar + "dice " + font.reset + font.italic + "2 d10")
+            connection.privmsg(replyto, font.grey + "Note: " + font.reset + "The dice type is specified as a " + font.italic + "d " + font.reset + "followed by the amount of sides.")
         elif cmdtype == "cmd":
-            
+
             arguments = len(command.split()) - 1
-            if arguments == 0: 
+            if arguments == 0:
                 connection.privmsg(replyto,  str(random.randint(1,  6)) + " & " + str(random.randint(1,  6)) + ".")
             elif arguments == 1:
                 try:
@@ -98,17 +89,17 @@ def do_command(self, connection, event):
                         try:
                             dicetype = int(command.split()[1][1:])
                         except ValueError:  # "d" not followd by interger.
-                            connection.privmsg(replyto, "Invalid number or type of dice. For help type: " + blue + self.helpchar + "dice" + reset + ".")
+                            connection.privmsg(replyto, "Invalid number or type of dice. For help type: " + blue + self.helpchar + "dice" + font.reset + ".")
                             return
                         if dicetype < 1:
                             connection.action(replyto, "can not create objects with less then one side.")
                         else:
                             connection.privmsg(replyto, str(GameHelpers.roll_dice(1,  dicetype)[0]))
                     else:   # Argument does not start with "d" and is not an integer.
-                        connection.privmsg(replyto, "Invalid number or type of dice. For help type: " + blue + self.helpchar + "dice" + reset + ".")
+                        connection.privmsg(replyto, "Invalid number or type of dice. For help type: " + blue + self.helpchar + "dice" + font.reset + ".")
                     return
                 if diceamount < 1:
-                    connection.privmsg(replyto, "Rolling " + bold + "no " + reset + "dice.")
+                    connection.privmsg(replyto, "Rolling " + font.bold + "no " + font.reset + "dice.")
                 elif diceamount > 10:
                     connection.action(replyto, "can not fit that many dice into it's robot hands.")
                 else:
@@ -117,15 +108,15 @@ def do_command(self, connection, event):
                 try:
                     diceamount = int(command.split()[1])
                 except ValueError:  # First argument not an integer.
-                    connection.privmsg(replyto, "Invalid number of dice. For help type: " + blue + self.helpchar + "dice" + reset + ".")
+                    connection.privmsg(replyto, "Invalid number of dice. For help type: " + blue + self.helpchar + "dice" + font.reset + ".")
                     return
                 try:
                     dicetype = int(command.split()[2][1:])
                 except ValueError:  # Second argument not a dice type.
-                    connection.privmsg(replyto, "Invalid type of dice. For help type: " + blue + self.helpchar + "dice" + reset + ".")
+                    connection.privmsg(replyto, "Invalid type of dice. For help type: " + blue + self.helpchar + "dice" + font.reset + ".")
                     return
                 if diceamount < 1:
-                    connection.privmsg(replyto, "Rolling " + bold + "no " + reset + "dice.")
+                    connection.privmsg(replyto, "Rolling " + font.bold + "no " + font.reset + "dice.")
                 elif diceamount > 10:
                     connection.action(replyto, "can not fit that many dice into it's robot hands.")
                 elif dicetype < 1:
@@ -135,44 +126,44 @@ def do_command(self, connection, event):
                 else:
                     connection.privmsg(replyto, ", ".join(str(rolls) for rolls in GameHelpers.roll_dice(diceamount,  dicetype)) + ".") # Roll x amount of x type dice.
             else:   # Invalid amount of arguments.
-                connection.privmsg(replyto, "Too many arguments. For help type: " + blue + self.helpchar + "dice" + reset + ".")
-    
+                connection.privmsg(replyto, "Too many arguments. For help type: " + blue + self.helpchar + "dice" + font.reset + ".")
+
     elif command.split()[0] == "player":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Displays a users game statistics. User optional.")
         elif cmdtype == "cmd":
-            
+
             if len(command.split()) == 1:
                 user = event.source.nick.lower()
-                message = grey + "Your statistics. " + reset
+                message = font.grey + "Your statistics. " + reset
             elif len(command.split()) == 2:
                 user = command.split()[1]
                 if not self.db.one("SELECT id FROM users WHERE LOWER(name)=%s AND network='" + self.network + "'", (user, )):
-                    connection.action(replyto, "does not know of a " + red + trigger.split()[1] + reset + ".")
+                    connection.action(replyto, "does not know of a " + font.red + trigger.split()[1] + font.reset + ".")
                     return
                 if user == connection.get_nickname().lower():
                     connection.privmsg(replyto, "The game does not play the master.")
                     return
                 if user == event.source.nick.lower():
-                    message = grey + "Your statistics. " + reset
+                    message = font.grey + "Your statistics. " + reset
                 else:
-                    message = grey + "Statistics for " + red + trigger.split()[1] + reset + ". "
+                    message = font.grey + "Statistics for " + font.red + trigger.split()[1] + font.reset + ". "
             else:
-                connection.privmsg(replyto, "Too many arguments, For help type " + blue + self.helpchar + "players " + reset + ".")
+                connection.privmsg(replyto, "Too many arguments, For help type " + blue + self.helpchar + "players " + font.reset + ".")
                 return
-             
+
             level, xp, xpspent, totalxp, karma, coin, coinspent, coingiven, ap, apspent = GameHelpers.get_info(self, user)
             if ap < 0:
                 ap = 0
             info = GameHelpers.player_info(self, user)
             connection.privmsg(replyto, message + info)
-    
+
     elif command.split()[0] == "levelup":
         user = event.source.nick.lower()
         level, xp, xpspent, totalxp, karma, coin, coinspent, coingiven, ap, apspent = GameHelpers.get_info(self, user)
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Spend " + str(int(level * 2.7)) + " XP to gain your next level. Gain multiple levels (for the price of the lowest level) by specifying the amount.")
-        elif cmdtype == "cmd":    
+        elif cmdtype == "cmd":
             if len(command.split()) == 1:
                 if xp < int(level * 2.7):
                     connection.privmsg(replyto, "Insufficient XP, you need at least " + str(int(level * 2.7)) + ".")
@@ -201,56 +192,56 @@ def do_command(self, connection, event):
                     info = GameHelpers.player_info(self, user)
                     connection.privmsg(replyto, "Your new statistics: " + info)
             else:
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "levelup " + reset + ".")
-    
+                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "levelup " + font.reset + ".")
+
     elif command.split()[0] == "givecoin":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Give coins to another player. Amount optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "givecoin " + reset + italic + "user amount")
+            connection.privmsg(replyto, font.grey + "Usage: " + blue + self.cmdchar + "givecoin " + font.reset + font.italic + "user amount")
         elif cmdtype == "cmd":
-            
+
             if len(command.split()) == 1:
-                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "givecoin" + reset + ".")
+                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "givecoin" + font.reset + ".")
                 return
             elif len(command.split()) > 3:
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "givecoin" + reset + ".")
+                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "givecoin" + font.reset + ".")
                 return
             elif command.split()[1] == event.source.nick.lower():
-                connection.privmsg(replyto, "You already have your own coin. For help type " + blue + self.helpchar + "givecoin" + reset + ".")
+                connection.privmsg(replyto, "You already have your own coin. For help type " + blue + self.helpchar + "givecoin" + font.reset + ".")
                 return
             elif len(command.split()) == 3:
                 stop = False
                 try:
                     if float(command.split()[2]) < 0:
-                        connection.privmsg(replyto, "You clever abuser! The " + red + self.cmdchar + bold + "give" + bold + "coin" + reset + " command is not designed for robbing. There will be consequences...")
+                        connection.privmsg(replyto, "You clever abuser! The " + font.red + self.cmdchar + font.bold + "give" + font.bold + "coin" + font.reset + " command is not designed for robbing. There will be consequences...")
                         self.db.run("UPDATE users SET coin=coin-3, karma_correction=karma_correction-0.5 WHERE name=%s AND network=%s", (event.source.nick, self.network))
                         stop = True
                 except TypeError:
-                    connection.privmsg(replyto, "Invalid amount. For help type " + blue + self.helpchar + "givecoin" + reset + ".")
+                    connection.privmsg(replyto, "Invalid amount. For help type " + blue + self.helpchar + "givecoin" + font.reset + ".")
                     return
                 if stop:
                     return
             elif not event.target == connection.get_nickname():
                 if not command.split()[1] in self.channels[event.target].users():
-                    connection.privmsg(replyto, red + trigger.split()[1] + reset + " is not present.")
+                    connection.privmsg(replyto, font.red + trigger.split()[1] + font.reset + " is not present.")
                     return
-                
+
             level, xp, xpspent, totalxp, karma, coin, coinspent, coingiven, ap, apspent = GameHelpers.get_info(self, event.source.nick)
             receivingrecord = self.db.one("SELECT level, away FROM users WHERE LOWER(name)=%s AND network=%s", (command.split()[1], self.network, ))
             if level < 1:
-                connection.privmsg(replyto, "You need to " + blue + self.cmdchar + "levelup " + reset + "to be able to give coin.")
+                connection.privmsg(replyto, "You need to " + blue + self.cmdchar + "levelup " + font.reset + "to be able to give coin.")
                 return
             elif coin < 1:
                 connection.privmsg(replyto, "You have no coin to give.")
                 return
             elif not receivingrecord:
-                connection.action(replyto, "does not know of any \"" + red + trigger.split()[1] + reset + "\".")
+                connection.action(replyto, "does not know of any \"" + font.red + trigger.split()[1] + font.reset + "\".")
                 return
             elif receivingrecord[0] == 0:
-                connection.privmsg(replyto, red + trigger.split()[1] + reset + " is not playing the game.")
+                connection.privmsg(replyto, font.red + trigger.split()[1] + font.reset + " is not playing the game.")
                 return
             elif receivingrecord[1] == True:
-                connection.privmsg(replyto, red + trigger.split()[1] + reset + "is not here right now.")
+                connection.privmsg(replyto, font.red + trigger.split()[1] + font.reset + "is not here right now.")
                 return
             elif ap < 1:
                 connection.privmsg(replyto, "You have no action points, go use IRC some more...")
@@ -263,12 +254,12 @@ def do_command(self, connection, event):
                 self.db.run("UPDATE users SET coin=coin+%s WHERE LOWER(name)=%s AND network=%s", (command.split()[2], command.split()[1], self.network))
             info = GameHelpers.player_info(self, event.source.nick)
             connection.notice(event.source.nick, "Your new statistics: " + info)
-    
+
     elif command.split()[0] == "players":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Display top player rankings.")
         elif cmdtype == "cmd":
-            
+
             toplevel = GameHelpers.list_top_players(self, "level")
             if toplevel:
                 connection.notice(event.source.nick, "Ranking level: " + toplevel)
@@ -280,31 +271,31 @@ def do_command(self, connection, event):
                 connection.notice(event.source.nick, "Ranking wealth: " + topcoin)
             if not toplevel and not topxp and not topcoin:
                 connection.privmsg(replyto, "Nobody is playing the game.")
-    
+
     elif command.split()[0] == "level":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "For 10 XP you can use !levelup to gain a level. As your level increases, things become more difficult, while more capabilities and options are unlocked.")
     elif command.split()[0] == "xp":
         if cmdtype == "help":    #Display help text.
-            connection.privmsg(replyto, "XP is earned by using IRC and playing the game, in channels with " + red + connection.get_nickname() + reset + ". Ask any operator in " + red + self.homechannel + reset + " to add a channel. XP is used to level up, advance classes, as a limit and as a multiplier. Once XP is expended it keeps counting towards your total.")
+            connection.privmsg(replyto, "XP is earned by using IRC and playing the game, in channels with " + font.red + connection.get_nickname() + font.reset + ". Ask any operator in " + font.red + self.homechannel + font.reset + " to add a channel. XP is used to level up, advance classes, as a limit and as a multiplier. Once XP is expended it keeps counting towards your total.")
     elif command.split()[0] == "ap":
         if cmdtype == "help":    #Display help text.
-            connection.privmsg(replyto, "AP is earned by using IRC and playing the game in channels with " + red + connection.get_nickname() + reset + ". Ask any operator in " + red + self.homechannel + reset + " to add a channel. AP is expended for every action you take in the game.")
+            connection.privmsg(replyto, "AP is earned by using IRC and playing the game in channels with " + font.red + connection.get_nickname() + font.reset + ". Ask any operator in " + font.red + self.homechannel + font.reset + " to add a channel. AP is expended for every action you take in the game.")
     elif command.split()[0] == "coin":
         if cmdtype == "help":    #Display help text.
-            connection.privmsg(replyto, "Coin is earned when certain events occur, for instance when a player expends XP. Coin is used to buy items and classes. To give a player coin use " + blue + self.cmdchar + "givecoin" + reset + ". Coin affects karma.")
+            connection.privmsg(replyto, "Coin is earned when certain events occur, for instance when a player expends XP. Coin is used to buy items and classes. To give a player coin use " + blue + self.cmdchar + "givecoin" + font.reset + ". Coin affects karma.")
     elif command.split()[0] == "karma":
         if cmdtype == "help":    #Display help text.
             connection.privmsg(replyto, "Karma is a secret formula, based upon on your IRC events and how you play the game. It does not increase like XP. Some events, skills and items are karma based.")
-    
+
 #    elif command.split()[0] == "classup":
 #        if cmdtype == "help":    #Display help text.
-#            connection.privmsg(replyto, "Spend 10 XP to gain a class in your current level. List available classes with " + blue + self.helpchar + "classup available " + reset + ".")
-#            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + "classup " + reset + italic + "class")
+#            connection.privmsg(replyto, "Spend 10 XP to gain a class in your current level. List available classes with " + blue + self.helpchar + "classup available " + font.reset + ".")
+#            connection.privmsg(replyto, font.grey + "Usage: " + blue + self.cmdchar + "classup " + font.reset + font.italic + "class")
 #        elif cmdtype == "cmd":
-#            
+#
 #            if len(command.split()) == 1:
-#                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "classup" + reset + ".")
+#                connection.privmsg(replyto, "Insufficient arguments. For help type " + blue + self.helpchar + "classup" + font.reset + ".")
 #            if len(command.split()) == 2:
 #                if command.split()[1] == "available":
 #                    level, xp, xpspent, karma = GameHelpers.get_info(self, event.source.nick)
@@ -322,4 +313,4 @@ def do_command(self, connection, event):
 #                        connection.privmsg(replyto, "Level 4 classes: ")
 #                else:
 #            else:
-#                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "classup" + reset + ".")
+#                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "classup" + font.reset + ".")

+ 99 - 102
rotbot/commands/public.py

@@ -1,24 +1,21 @@
-from common import userstatus, queries
+from common import userstatus, queries, font
 from commands.common import CommandHelpers as CH
 
-bold = "\x02"
-italic = "\x1D"
-underline = "\x1F"
-reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-reset = "\x0F"
-blue = "\x0302"
-green = "\x0303"
-red = "\x0304"
-grey = "\x0314"
-
 def do_command(self, connection, event):
     cmdtype, trigger, command, replyto = CH.disect_command(self, event)
 
+    # Do nothing if it's not a type of command.
+    if not cmdtype:
+        return
+
     # Do nothing if there is no command.
     if not command:
         return
+
+    # The first word of the command sting with arguments, is just the command without arguments.
     try:
-        command.split()[0]
+        one = command.split()[0]
+
     except:
         return
 
@@ -32,16 +29,16 @@ def do_command(self, connection, event):
     #         connection.privmsg(replyto, str(self.channels[self.homechannel].owners()))
     #         connection.privmsg(event.source.nick, self.channels[event.target].users())
 
-    elif command == "cmd" or command == "cmds" or command == "commands":
+    if command == "cmd" or command == "cmds" or command == "commands":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Displays a list of commands.")
         elif cmdtype == "cmd":
             if not event.target == connection.get_nickname() and not self.db.one("SELECT join_greeting FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'"):
-                connection.privmsg(replyto, grey + "Public: " + CH.ccc(self, "cmd") + CH.ccc(self, "help") + CH.ccc(self, "away")[:-2] + ".")
+                connection.privmsg(replyto, grey + "Public: " + CH.ccc(self, "cmd") + CH.ccc(self, "help"))# + CH.ccc(self, "away")[:-2] + ".")
             else:
-                connection.privmsg(replyto, grey + "Public: " + CH.ccc(self, "cmd") + CH.ccc(self, "help") + CH.ccc(self, "away") + CH.ccc(self, "stopgreet")[:-2] + ".")
+                connection.privmsg(replyto, grey + "Public: " + CH.ccc(self, "cmd") + CH.ccc(self, "help"))# + CH.ccc(self, "away") + CH.ccc(self, "stopgreet")[:-2] + ".")
 
     elif command == "help":
         if cmdtype == "help":    #Display help text.
@@ -49,93 +46,93 @@ def do_command(self, connection, event):
                 return
             connection.privmsg(replyto, "Explains how to get help on any specific command and hints the user to the commandlist.")
         elif cmdtype == "cmd":
-            connection.privmsg(replyto, "Replace the " + italic + "! " + reset + "prefix of any comand with " + italic + self.helpchar + " " + reset + "for help with a specific command. Request the command list with: " + blue + "!cmd")
+            connection.privmsg(replyto, "Replace the " + font.italic + "! " + reset + "prefix of any comand with " + font.italic + self.helpchar + " " + reset + "for help with a specific command. Request the command list with: " + blue + "!cmd")
             connection.privmsg(replyto, grey + "Example: " + reset + blue + self.helpchar + "help")
 
 
-    elif command.split()[0] == "stopgreet":
-        if cmdtype == "help":    #Display help text.
-            if len(command.split()) is not 1:
-                return
-            connection.privmsg(replyto, "Stops the bot from greeting you or a specific user. Channel, user and option to resume optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + "!stopgreet " + reset + italic + "resume " + red + "channel user")
-        elif cmdtype == "cmd":
-
-            # Check for resume variation of command.
-            resume = False
-            try:
-                if command.split()[1] == "resume":
-                    resume = True
-                    command = command.split(' ', 1)[1]  # Remove the resume argument. Which makes the following logic easier.
-            except:
-                pass
-
-            if len(command.split()) == 1:    # No arguments.
-                if event.target == connection.get_nickname():   # PM.
-                    connection.privmsg(replyto, "Specify at least a channel. For help type " + blue + self.helpchar + "stopgreet" + reset + ".")
-                    return
-                user = event.source.nick
-                channel = event.target
-
-            if len(command.split()) == 2:    # One argument.
-                if command.split()[1] not in self.channels: # Argument is not a channel the bot inhabits.
-                    if event.target == connection.get_nickname():   # PM.
-                        connection.action(replyto, "does not inhabit " + red + command.split()[1] + reset + ".")
-                        return
-                    # Channel message
-                    if not userstatus.atleast_halfop(self, event.source.nick, self.homechannel) and not userstatus.atleast_halfop(self, event.source.nick, event.target):  # Insufficient rights.
-                        connection.privmsg(replyto, "Denied. You need to have at least halfop status in " + red + self.homechannel + reset + " or " + red + event.target + reset + ".")
-                        return
-                    # Stopgreet for x user in current channel
-                    user = command.split()[1]
-                    channel = event.target
-                else:   # Bot inhabit channel.
-                    user = event.source.nick
-                    channel = command.split()[1]
-            if len(command.split()) == 3:    # Two arguments.
-                if command.split()[1] not in self.channels: # Bot does not inhabit channel.
-                    connection.action(replyto, "does not inhabit " + red + command.split()[1] + reset + ".")
-                    return
-                if not userstatus.atleast_halfop(self, event.source.nick, self.homechannel) and not userstatus.atleast_halfop(self, event.source.nick, command.split()[1]):  # Insufficient rights.
-                    connection.privmsg(replyto, "Denied. You need to have at least halfop status in " + red + self.homechannel + reset + " or " + red + command.split()[1] + reset + ".")
-                    return
-                user = command.split()[2]
-                channel = command.split()[1]
-            if len(command.split()) > 3:    # Too many arguments.
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "stopgreet" + reset + ".")
-                return
-
-            # Check for database record.
-            result = self.db.one("SELECT id, stopgreet FROM joins WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "' AND LOWER(channel)=LOWER('" + channel + "') AND channel_network='" + self.network + "'")
-            if not result:  # No record in database.
-                connection.action(replyto, "has not yet had the pleasure of greeting " + red + user + reset + " in " + red + channel + reset + ".")
-                return
-
-            if resume:
-                stopgreet = False
-                message = "has already every intention to greet "
-            else:
-                stopgreet = True
-                message = "has already stopped greeting "
-            if result[1] == stopgreet:
-                connection.action(replyto, message + red + user + reset + " in " + red + channel + reset + ".")
-                return
-            print(str(stopgreet) + str(user) + str(channel))
-            try:
-                self.db.run("UPDATE joins SET stopgreet='" + str(stopgreet) + "' WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "' AND lower(channel)=LOWER('" + channel + "') AND channel_network='" + self.network + "'")
-            except:
-                connection.privmsg(replyto, "Failed to update database.")
-
-    elif command.split()[0] == "away":
-        if cmdtype == "help":    #Display help text.
-            if len(command.split()) is not 1:
-                return
-            connection.privmsg(replyto, "Sets you away, optionally with reason. This affects the !seen command and the game.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + "!away " + reset + italic + "reason")
-
-        elif cmdtype == "cmd":
-            queries.create_ifnot_onrecord(self, "users", event.source.nick)
-            if len(trigger.split()) == 1:
-                self.db.run("UPDATE users SET away=TRUE, away_reason=NULL WHERE name='" + event.source.nick + "' AND network='" + self.network + "'")
-            else:
-                self.db.run("UPDATE users SET away=TRUE, away_reason=%s WHERE name='" + event.source.nick + "' AND network='" + self.network + "'", (trigger.split(maxsplit=1)[1], ))
+    # elif one == "stopgreet":
+    #     if cmdtype == "help":    #Display help text.
+    #         if len(command.split()) is not 1:
+    #             return
+    #         connection.privmsg(replyto, "Stops the bot from greeting you or a specific user. Channel, user and option to resume optional.")
+    #         connection.privmsg(replyto, grey + "Usage: " + blue + "!stopgreet " + reset + font.italic + "resume " + font.red + "channel user")
+    #     elif cmdtype == "cmd":
+    #
+    #         # Check for resume variation of command.
+    #         resume = False
+    #         try:
+    #             if command.split()[1] == "resume":
+    #                 resume = True
+    #                 command = command.split(' ', 1)[1]  # Remove the resume argument. Which makes the following logic easier.
+    #         except:
+    #             pass
+    #
+    #         if len(command.split()) == 1:    # No arguments.
+    #             if event.target == connection.get_nickname():   # PM.
+    #                 connection.privmsg(replyto, "Specify at least a channel. For help type " + blue + self.helpchar + "stopgreet" + reset + ".")
+    #                 return
+    #             user = event.source.nick
+    #             channel = event.target
+    #
+    #         if len(command.split()) == 2:    # One argument.
+    #             if command.split()[1] not in self.channels: # Argument is not a channel the bot inhabits.
+    #                 if event.target == connection.get_nickname():   # PM.
+    #                     connection.action(replyto, "does not inhabit " + font.red + command.split()[1] + reset + ".")
+    #                     return
+    #                 # Channel message
+    #                 if not userstatus.atleast_halfop(self, event.source.nick, self.homechannel) and not userstatus.atleast_halfop(self, event.source.nick, event.target):  # Insufficient rights.
+    #                     connection.privmsg(replyto, "Denied. You need to have at least halfop status in " + font.red + self.homechannel + reset + " or " + font.red + event.target + reset + ".")
+    #                     return
+    #                 # Stopgreet for x user in current channel
+    #                 user = command.split()[1]
+    #                 channel = event.target
+    #             else:   # Bot inhabit channel.
+    #                 user = event.source.nick
+    #                 channel = command.split()[1]
+    #         if len(command.split()) == 3:    # Two arguments.
+    #             if command.split()[1] not in self.channels: # Bot does not inhabit channel.
+    #                 connection.action(replyto, "does not inhabit " + font.red + command.split()[1] + reset + ".")
+    #                 return
+    #             if not userstatus.atleast_halfop(self, event.source.nick, self.homechannel) and not userstatus.atleast_halfop(self, event.source.nick, command.split()[1]):  # Insufficient rights.
+    #                 connection.privmsg(replyto, "Denied. You need to have at least halfop status in " + font.red + self.homechannel + reset + " or " + font.red + command.split()[1] + reset + ".")
+    #                 return
+    #             user = command.split()[2]
+    #             channel = command.split()[1]
+    #         if len(command.split()) > 3:    # Too many arguments.
+    #             connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "stopgreet" + reset + ".")
+    #             return
+    #
+    #         # Check for database record.
+    #         result = self.db.one("SELECT id, stopgreet FROM joins WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "' AND LOWER(channel)=LOWER('" + channel + "') AND channel_network='" + self.network + "'")
+    #         if not result:  # No record in database.
+    #             connection.action(replyto, "has not yet had the pleasure of greeting " + font.red + user + reset + " in " + font.red + channel + reset + ".")
+    #             return
+    #
+    #         if resume:
+    #             stopgreet = False
+    #             message = "has already every intention to greet "
+    #         else:
+    #             stopgreet = True
+    #             message = "has already stopped greeting "
+    #         if result[1] == stopgreet:
+    #             connection.action(replyto, message + font.red + user + reset + " in " + font.red + channel + reset + ".")
+    #             return
+    #         print(str(stopgreet) + str(user) + str(channel))
+    #         try:
+    #             self.db.run("UPDATE joins SET stopgreet='" + str(stopgreet) + "' WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "' AND lower(channel)=LOWER('" + channel + "') AND channel_network='" + self.network + "'")
+    #         except:
+    #             connection.privmsg(replyto, "Failed to update database.")
+    #
+    # elif one == "away":
+    #     if cmdtype == "help":    #Display help text.
+    #         if len(command.split()) is not 1:
+    #             return
+    #         connection.privmsg(replyto, "Sets you away, optionally with reason. This affects the !seen command and the game.")
+    #         connection.privmsg(replyto, grey + "Usage: " + blue + "!away " + reset + font.italic + "reason")
+    #
+    #     elif cmdtype == "cmd":
+    #         queries.create_ifnot_onrecord(self, "users", event.source.nick)
+    #         if len(trigger.split()) == 1:
+    #             self.db.run("UPDATE users SET away=TRUE, away_reason=NULL WHERE name='" + event.source.nick + "' AND network='" + self.network + "'")
+    #         else:
+    #             self.db.run("UPDATE users SET away=TRUE, away_reason=%s WHERE name='" + event.source.nick + "' AND network='" + self.network + "'", (trigger.split(maxsplit=1)[1], ))

+ 67 - 69
rotbot/commands/statistics.py

@@ -1,27 +1,25 @@
 from datetime import datetime
+from common import font
 from commands.common import CommandHelpers as CH, StatisticsHelpers
 
-bold = "\x02"
-italic = "\x1D"
-underline = "\x1F"
-reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-reset = "\x0F"
-blue = "\x0302"
-green = "\x0303"
-red = "\x0304"
-grey = "\x0314"
 
 def do_command(self, connection, event):
     cmdtype, trigger, command, replyto = CH.disect_command(self, event)
-    
+
+    # Do nothing if it's not a type of command.
+    if not cmdtype:
+        return
+
     # Do nothing if there is no command.
-    if not command: 
+    if not command:
         return
+
+    # The first word of the command sting with arguments, is just the command without arguments.
     try:
-        command.split()[0]
+        one = command.split()[0]    # Get raw command.
     except:
         return
-    
+
     # Do noting if the games channel function is off and it's a channel message.
     if not self.db.one("SELECT statistics_commands FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'") and not event.target == connection.get_nickname():
         return
@@ -29,16 +27,16 @@ def do_command(self, connection, event):
     if command == "cmd" or command == "cmds" or command == "commands":
         if cmdtype == "cmd":
             connection.privmsg(replyto, grey + "Statistics: " + CH.ccc(self, "seen") + CH.ccc(self, "joins") + CH.ccc(self, "kicks") + CH.ccc(self, "messages") + CH.ccc(self, "actions") + CH.ccc(self, "notices")[:-2] + ".")
-    
-    
+
+
     elif command.split()[0] == "joins" or command.split()[0] == "kicks" or command.split()[0] == "messages" or command.split()[0] == "actions" or command.split()[0] == "notices":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Display amount of " + command.split()[0] + " of user and channel. Channel and user optional.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + command.split()[0] + " " + reset + italic + "channel user")
+            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + command.split()[0] + " " + font.reset + font.italic + "channel user")
         elif cmdtype == "cmd":
-            
+
             # Parse user input
             user = event.source.nick
             channel = None
@@ -57,7 +55,7 @@ def do_command(self, connection, event):
             elif len(command.split()) == 3: # Command has two arguments.
                 if not command.split()[1] in self.channels: # Bot does not inhabit requested channel.
                     if not command.split()[2] in self.channels: # User did not revert channel and user in command syntax.
-                        connection.action(replyto, "does not inhabit " + red + command.split()[1] + reset + ".")
+                        connection.action(replyto, "does not inhabit " + font.red + command.split()[1] + font.reset + ".")
                         return
                     else:   # User reverted user and channel in command syntax.
                         user = trigger.split()[1]
@@ -66,9 +64,9 @@ def do_command(self, connection, event):
                     user = trigger.split()[2]
                     channel = trigger.split()[1]
             elif len(command.split()) < 5:  # To many arguments
-                connection.privmsg(replyto, "To many arguments. For help type " + blue + self.helpchar + "joins" + reset + ".")
+                connection.privmsg(replyto, "To many arguments. For help type " + blue + self.helpchar + "joins" + font.reset + ".")
                 return
-            
+
             if command.split()[0] == "joins":
                 if channel: # User and channel.
                     userstat = str(sum(self.db.all("SELECT " + command.split()[0] + " FROM " + command.split()[0] + " WHERE channel_network='" + self.network + "' AND LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "'")))
@@ -77,17 +75,17 @@ def do_command(self, connection, event):
                     if userchannelstat == "None":
                         userchannelstat = "0"
                     if channelonly:
-                        connection.privmsg(replyto, red + channel + reset + " has " + green + channelstat + reset + " " + command.split()[0] + reset + " in total.")
+                        connection.privmsg(replyto, font.red + channel + font.reset + " has " + green + channelstat + font.reset + " " + command.split()[0] + font.reset + " in total.")
                     elif userstat == "0" and not channelonly: # No user joins on record.
-                        connection.action(replyto, "has no record of any joins by " + red + user + reset + " in " + red + channel + reset + ".")
+                        connection.action(replyto, "has no record of any joins by " + font.red + user + font.reset + " in " + font.red + channel + font.reset + ".")
                     else:   # User joins on record.
-                        connection.privmsg(replyto, red + user + reset + " has " + green + userstat + reset + " " + command.split()[0] + ". Of which " + green + userchannelstat + reset + " have been in " + red + channel + reset + ", that has " + green + channelstat + reset + " " + command.split()[0] + reset + " in total.")
+                        connection.privmsg(replyto, font.red + user + font.reset + " has " + green + userstat + font.reset + " " + command.split()[0] + ". Of which " + green + userchannelstat + font.reset + " have been in " + font.red + channel + font.reset + ", that has " + green + channelstat + font.reset + " " + command.split()[0] + font.reset + " in total.")
                 else:   # Only user.
                     userstat = str(sum(self.db.all("SELECT " + command.split()[0] + " FROM " + command.split()[0] + " WHERE channel_network='" + self.network + "' AND LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "'")))
                     if userstat == "0":    # No statistics on user.
-                        connection.action(replyto, "has no record of any joins by " + red + user + reset + ".")
+                        connection.action(replyto, "has no record of any joins by " + font.red + user + font.reset + ".")
                     else:   # Got statistics on user.
-                        connection.privmsg(replyto, red + user + reset + " has " + green + userstat + reset + " " + command.split()[0] + " in channels I monitor.")
+                        connection.privmsg(replyto, font.red + user + font.reset + " has " + green + userstat + font.reset + " " + command.split()[0] + " in channels I monitor.")
             elif command.split()[0] == "kicks":
                 if channel: # User and channel.
                     try:
@@ -96,12 +94,12 @@ def do_command(self, connection, event):
                         givenkicks = 0
                         receivedkicks = 0
                     if channelonly:
-                        connection.privmsg(replyto, red + channel + reset + " has " + green + channelstat + reset + " " + command.split()[0] + reset + " in total.")
+                        connection.privmsg(replyto, font.red + channel + font.reset + " has " + green + channelstat + font.reset + " " + command.split()[0] + font.reset + " in total.")
                     elif givenkicks == 0 and receivedkicks == 0:  # No kicks on record.
-                        connection.action(replyto, "has no record of any kicks for " + red + user + reset + " in " + red + channel + reset + ".")
+                        connection.action(replyto, "has no record of any kicks for " + font.red + user + font.reset + " in " + font.red + channel + font.reset + ".")
                     else:   # Kciks on record.
                         channelkicks = self.db.all("SELECT given FROM " + command.split()[0] + " WHERE LOWER(channel)=LOWER('" + channel + "') AND channel_network='" + self.network + "'")
-                        connection.privmsg(replyto, red + user + reset + " has kicked " + green + str(givenkicks) + reset + " and been kicked " + green + str(receivedkicks) + reset + " times in " + red + channel + reset + ", where were " + green + str(sum(channelkicks)) + reset + " kicks in total.")
+                        connection.privmsg(replyto, font.red + user + font.reset + " has kicked " + green + str(givenkicks) + font.reset + " and been kicked " + green + str(receivedkicks) + font.reset + " times in " + font.red + channel + font.reset + ", where were " + green + str(sum(channelkicks)) + font.reset + " kicks in total.")
                 else:   # Only user.
                     userstat = self.db.all("SELECT given, received FROM kicks WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "'")
                     kicksgiven = 0
@@ -110,9 +108,9 @@ def do_command(self, connection, event):
                         kicksgiven += record[0]
                         kicksreceived += record[1]
                     if kicksgiven == 0 and kicksreceived == 0:
-                        connection.action(replyto, red + user + reset + " has no record of any kicks for " + red + user + reset + " in " + red + channel + reset + ".")
+                        connection.action(replyto, font.red + user + font.reset + " has no record of any kicks for " + font.red + user + font.reset + " in " + font.red + channel + font.reset + ".")
                     else:
-                        connection.privmsg(replyto, red + user + reset + " has given " + green + str(kicksgiven) + reset + " and received " + green + str(kicksreceived) + reset + " kicks")
+                        connection.privmsg(replyto, font.red + user + font.reset + " has given " + green + str(kicksgiven) + font.reset + " and received " + green + str(kicksreceived) + font.reset + " kicks")
             elif command.split()[0] == "messages" or command.split()[0] == "actions" or command.split()[0] == "notices":
                 userstat = self.db.all("SELECT " + command.split()[0] + ", " + command.split()[0] + "_words, " + command.split()[0] + "_characters FROM messages WHERE LOWER(\"user\")=LOWER('" + user + "') AND user_network='" + self.network + "'")
 
@@ -120,46 +118,46 @@ def do_command(self, connection, event):
                 for record in userstat:
                     if not record[0] == 0:
                         userrecord = True
-                
+
                 if not userrecord:
                     if command.split()[0] == "messages":
-                        connection.action(replyto, "has no record of " + red + user + reset + " speaking.")
+                        connection.action(replyto, "has no record of " + font.red + user + font.reset + " speaking.")
                         return
                     if command.split()[0] == "actions":
-                        connection.action(replyto, "has no record of " + red + user + reset + " acting.")
+                        connection.action(replyto, "has no record of " + font.red + user + font.reset + " acting.")
                         return
                     if command.split()[0] == "notices":
-                        connection.action(replyto, "has not noticed " + red + user + reset + ".")
+                        connection.action(replyto, "has not noticed " + font.red + user + font.reset + ".")
                         return
                 messages, words, characters = StatisticsHelpers.add_message_stats(userstat)
-                message = "Totals of " + red + user + " " + green + str(messages) + reset + " " + blue + command.split()[0] + reset + ", " + green + str(words) + reset + " words, " + green + str(characters) + reset + " characters."
+                message = "Totals of " + font.red + user + " " + green + str(messages) + font.reset + " " + blue + command.split()[0] + font.reset + ", " + green + str(words) + font.reset + " words, " + green + str(characters) + font.reset + " characters."
                 if channel: # User and channel.
                     userchanstat = self.db.one("SELECT " + command.split()[0] + ", " + command.split()[0] + "_words, " + command.split()[0] + "_characters FROM messages WHERE lower(channel)=lower('" + channel + "') AND channel_network='" + self.network + "' AND lower(\"user\")=lower('" + user + "') AND user_network='" + self.network + "'")
                     chanstat = self.db.all("SELECT " + command.split()[0] + ", " + command.split()[0] + "_words, " + command.split()[0] + "_characters FROM messages WHERE lower(channel)=lower('" + channel + "') AND channel_network='" + self.network + "'")
                     if not userchanstat[0] == 0:
-                        message += " " + red + user + reset + " in " + red + channel + " " + green + str(userchanstat[0]) + reset + " " + blue + command.split()[0] + reset + ", " + green + str(userchanstat[1]) + reset + " words, " + green + str(userchanstat[2]) + reset + " chars."
+                        message += " " + font.red + user + font.reset + " in " + font.red + channel + " " + green + str(userchanstat[0]) + font.reset + " " + blue + command.split()[0] + font.reset + ", " + green + str(userchanstat[1]) + font.reset + " words, " + green + str(userchanstat[2]) + font.reset + " chars."
                     channelrecord = False
                     for record in chanstat:
                         if not record[0] == 0:
                             channelrecord = True
                     if channelrecord:
                         messages, words, characters = StatisticsHelpers.add_message_stats(chanstat)
-                        message += " Total in " + red + channel + " " + green + str(messages) + reset + " " + blue + command.split()[0] + reset + ", " + green + str(words) + reset + " wrd, " + green + str(characters) + reset + " chr." 
+                        message += " Total in " + font.red + channel + " " + green + str(messages) + font.reset + " " + blue + command.split()[0] + font.reset + ", " + green + str(words) + font.reset + " wrd, " + green + str(characters) + font.reset + " chr."
                 connection.privmsg(replyto, message)
-    
+
     elif command.split()[0] == "seen":
         if cmdtype == "help":    #Display help text.
             if len(command.split()) is not 1:
                 return
             connection.privmsg(replyto, "Report the last sighting of a user.")
-            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + command.split()[0] + " " + reset + italic + "user")
+            connection.privmsg(replyto, grey + "Usage: " + blue + self.cmdchar + command.split()[0] + " " + font.reset + font.italic + "user")
         elif cmdtype == "cmd":
-        
+
             if len(command.split()) == 1:
-                connection.privmsg(replyto, "I am seeing you right now. For help type " + blue + self.helpchar + reset + ".")
+                connection.privmsg(replyto, "I am seeing you right now. For help type " + blue + self.helpchar + font.reset + ".")
             elif len(command.split()) == 2:
                 if not self.db.one("SELECT last_act_type FROM users WHERE LOWER(name)='" + command.split()[1] + "' AND network='" + self.network + "'"):
-                    connection.action(replyto, "has never seen " + red + trigger.split()[1] + reset + ".")
+                    connection.action(replyto, "has never seen " + font.red + trigger.split()[1] + font.reset + ".")
                 elif command.split()[1] == event.source.nick.lower():
                     connection.action(replyto, "holds up a mirror to " + event.source.nick + ".")
                 elif "!" in command.split()[1] and "@" in command.split()[1]:
@@ -169,77 +167,77 @@ def do_command(self, connection, event):
                     if command.split()[1] == connection.get_nickname().lower():
                         action = "last action was "
                     else:
-                        action = "last saw " + red + trigger.split()[1] + reset + " "
+                        action = "last saw " + font.red + trigger.split()[1] + font.reset + " "
                     if record[0] == "nick":
-                        action += "changing nickname to " + red + record[3]
+                        action += "changing nickname to " + font.red + record[3]
                     elif record[0] == "join":
-                        action += "joining " + red + record[2]
+                        action += "joining " + font.red + record[2]
                     elif record[0] == "kick":
                         if record[4]:
-                            action += "kicking " + red + record[4] + reset + " for " + green + record[3]
+                            action += "kicking " + font.red + record[4] + font.reset + " for " + green + record[3]
                         else:
-                            action += "kicking " + red + record[3]
+                            action += "kicking " + font.red + record[3]
                     elif record[0] == "kicked":
                         if record[4]:
-                            action += "being kicked by " + red + record[3] + reset + " for " + green + record[4]
+                            action += "being kicked by " + font.red + record[3] + font.reset + " for " + green + record[4]
                         else:
-                            action += "being kicked by " + red + record[3]
+                            action += "being kicked by " + font.red + record[3]
                     elif record[0] == "mode":
-                        action += "changing modes on " + red + record[3]
+                        action += "changing modes on " + font.red + record[3]
                     elif record[0] == "part":
-                        action += "parting " + red + record[2]
+                        action += "parting " + font.red + record[2]
                         if record[3]:
-                            action += reset + " for " + record[3]
+                            action += font.reset + " for " + record[3]
                     elif record[0] == "quit":
                         action += "disconnecting"
                         if record[3]:
                             action += " due to " + green + record[3]
                     elif record[0] == "topic":
-                        action += "changing the topic of " + red + record[2] + reset + " to " + green + record[3]
+                        action += "changing the topic of " + font.red + record[2] + font.reset + " to " + green + record[3]
                     elif record[0] == "msg":
-                        action += "posting " + green + record[3] + reset + " to " + red + record[2]
+                        action += "posting " + green + record[3] + font.reset + " to " + font.red + record[2]
                     elif record[0] == "notice":
-                        action += "posting the notice " + green + record[3] + " to " + red + record[2]
+                        action += "posting the notice " + green + record[3] + " to " + font.red + record[2]
                     elif record[0] == "action":
-                        action += green + record[3] + reset + " in " + red + record[2]
+                        action += green + record[3] + font.reset + " in " + font.red + record[2]
                     else:
                         connection.privmsg(replyto, "Last stored action unsupported by command code.")
                         return
-                    action += reset + ", "
+                    action += font.reset + ", "
                     differential = datetime.now() - record[1]
                     if differential.seconds < 5:    # Less then 5 seconds.
                         action += blue + "right now."
                     elif differential.seconds < 20: # Less then 20 seconds.
                         action += blue + "just now."
                     elif differential.seconds < 60: # Less then a minute.
-                        action += green + str(differential.seconds) + blue + " seconds " + reset + "ago."
+                        action += green + str(differential.seconds) + blue + " seconds " + font.reset + "ago."
                     elif differential.seconds / 60 == 1: # 1 minute.
-                        action += green + "1 " + blue + "minute " + reset + "ago."
+                        action += green + "1 " + blue + "minute " + font.reset + "ago."
                     elif int(differential.seconds / 60) < 60:   # Less then an hour.
-                        action += green + str(int(differential.seconds / 60)) + blue + " minutes " + reset + "ago."
+                        action += green + str(int(differential.seconds / 60)) + blue + " minutes " + font.reset + "ago."
                     elif int(differential.seconds / 60) ==  60: # 1 hour.
-                        action += green + "1 " + blue + "hour " + reset + "ago."
+                        action += green + "1 " + blue + "hour " + font.reset + "ago."
                     elif int(differential.seconds / 3600) < 24 : # Less then a day.
                         remaining_seconds = int(differential.seconds - int(differential.seconds / 3600) * 3600)
-                        action += green + str(int(differential.seconds / 3600)) + blue + " hours" + reset + " and " + str(int(remaining_seconds / 60)) + " minutes ago."
+                        action += green + str(int(differential.seconds / 3600)) + blue + " hours" + font.reset + " and " + str(int(remaining_seconds / 60)) + " minutes ago."
                     elif int(differential.seconds / 3600) == 24 : # 1 day.
-                        action += green + "1 " + blue + "day " + reset + "ago."
+                        action += green + "1 " + blue + "day " + font.reset + "ago."
                     elif differential.days < 7: # Less then a week.
                         remaining = differential - datetime.timedelta(days=differential.days)
-                        action += green + str(differential.days) + blue + " days " + reset + "and " + str(int(remaining.seconds / 3600)) + " hours ago."
+                        action += green + str(differential.days) + blue + " days " + font.reset + "and " + str(int(remaining.seconds / 3600)) + " hours ago."
                     elif differential.days < 365:   # Less then a year.
-                        action += green + str(differential.days) + blue + " days " + reset + "ago."
+                        action += green + str(differential.days) + blue + " days " + font.reset + "ago."
                     elif differential.days < 365:   # Less then 5 years.
                         remaining_days = int(int(differential.days / 365) * 365)
                         remaining = differential - datetime.timedelta(days=remaining_days)
-                        action += green + str(int(differential.days / 365)) + blue + " years " + reset + "and " + str(remaining.days) + " days."
+                        action += green + str(int(differential.days / 365)) + blue + " years " + font.reset + "and " + str(remaining.days) + " days."
                     else:   # More then 5 years.
                         action += green + str(int(differential.days / 365)) + blue + " years ago."
                     connection.action(replyto, action)
                     if record[5]:
                         if record[6]:
-                            connection.privmsg(replyto, red + trigger.split()[1] + reset + " is away " + green + record[6] + ".")
+                            connection.privmsg(replyto, font.red + trigger.split()[1] + font.reset + " is away " + green + record[6] + ".")
                         else:
-                            connection.privmsg(replyto, red + trigger.split()[1] + reset + " is away.")
+                            connection.privmsg(replyto, font.red + trigger.split()[1] + font.reset + " is away.")
             else:   # Too many arguments.
-                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "seen" + reset + ".")
+                connection.privmsg(replyto, "Too many arguments. For help type " + blue + self.helpchar + "seen" + font.reset + ".")

+ 3 - 0
rotbot/events/common.py

@@ -124,3 +124,6 @@ class Inform():
                     connection.privmsg(user, message)
                 for user in self.channels[self.homechannel].opers():
                     connection.privmsg(user, message)
+
+        def home_channel(self, connection, message):
+            connection.privmsg(self.network.home_channel, message)