Browse Source

rotbot refactoring

tBKwtWS 6 years ago
parent
commit
96f4ceaeb6

+ 3 - 2
rotbot/bot.py

@@ -93,7 +93,8 @@ class PyRot(irc.bot.SingleServerIRCBot):
         events.on_privnotice.process_event(self, connection, event)
         events.on_privnotice.process_event(self, connection, event)
 
 
     def on_whoreply(self, connection, event):
     def on_whoreply(self, connection, event):
-        events.on_whoreply.process_event(self, connection, event)
+        # events.on_whoreply.process_event(self, connection, event)
+        pass
 
 
     def on_keyset(self, connection, event):
     def on_keyset(self, connection, event):
         events.on_keyset.process_event(self, connection, event)
         events.on_keyset.process_event(self, connection, event)
@@ -141,7 +142,7 @@ def main():
 
 
     ### SETTINGS
     ### SETTINGS
     webgui = {
     webgui = {
-        'base_url': 'https://h0v1n8.nl/rotbot/',  # The django rotbot app url.
+        'base_url': 'https://rotbot.h0v1n8.nl/',  # The django rotbot app url.
         'register_url': '',
         'register_url': '',
     }
     }
 
 

+ 4 - 3
rotbot/commands/admin.py

@@ -246,11 +246,12 @@ def do_command(self, connection, event, user, channel):
                 connection.privmsg(replyto, "Message not specified. For help type: " + font.blue + self.network.help_character + command.split(maxsplit=1)[0])
                 connection.privmsg(replyto, "Message not specified. For help type: " + font.blue + self.network.help_character + command.split(maxsplit=1)[0])
                 return
                 return
 
 
+            if destination == connection.get_nickname():
+                connection.privmsg(replyto, "I just love talking to myself.")
+                return
+
             # Send the message if user has owner status in the home channel.
             # 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 self.channels[self.network.home_channel].is_owner(event.source.nick):
-                if destination == connection.get_nickname():
-                    connection.privmsg(replyto, "I just love talking to myself.")
-                    return
                 if command.split(maxsplit=1)[0] == "act":
                 if command.split(maxsplit=1)[0] == "act":
                     connection.action(destination, message)
                     connection.action(destination, message)
                 else:
                 else:

+ 12 - 8
rotbot/commands/common.py

@@ -125,8 +125,10 @@ class GameHelpers():
         total_messages = queries.get_user_total_messages(self, user.id)
         total_messages = queries.get_user_total_messages(self, user.id)
         total_actions = queries.get_user_total_actions(self, user.id)
         total_actions = queries.get_user_total_actions(self, user.id)
         total_notices = queries.get_user_total_notices(self, user.id)
         total_notices = queries.get_user_total_notices(self, user.id)
-        total_cursewords_added = queries.get_user_total_curseword_added(self, user.id)
-        total_curseadjectives_added = queries.get_user_total_curseadjective_added(self, user.id)
+        total_cursewords_added = queries.get_user_total_cursewords_added(self, user.id)
+        total_curseadjectives_added = queries.get_user_total_curseadjectives_added(self, user.id)
+        total_cursewords_banned = queries.get_user_total_cursewords_banned(self, user.id)
+        total_curseadjectives_banned = queries.get_user_total_curseadjectives_banned(self, user.id)
         gamestats = queries.get_user_gamestats(self, user.id)
         gamestats = queries.get_user_gamestats(self, user.id)
         xp_spent = gamestats[0]
         xp_spent = gamestats[0]
         level = gamestats[1]
         level = gamestats[1]
@@ -153,14 +155,16 @@ class GameHelpers():
         # Karma.
         # Karma.
         if total_xp == 0:
         if total_xp == 0:
             total_xp = 0.01
             total_xp = 0.01
-        join_karma = total_joins / total_xp   # High value should have negative impact.
+        join_karma = total_joins / total_xp
         print('join_karma:' + str(join_karma) + ' = joins:' + str(total_joins) + ' / total_xp:' + str(total_xp))
         print('join_karma:' + str(join_karma) + ' = joins:' + str(total_joins) + ' / total_xp:' + str(total_xp))
-        kick_karma = (total_kicks + total_kicked) / total_xp  # High value should have negative impact.
+        kick_karma = (total_kicks + total_kicked) / total_xp
         print('kick_karma:' + str(kick_karma) + ' = (given:' + str(total_kicks) + ' + received:' + str(total_kicked) + ') / total_xp:' + str(total_xp))
         print('kick_karma:' + str(kick_karma) + ' = (given:' + str(total_kicks) + ' + received:' + str(total_kicked) + ') / total_xp:' + str(total_xp))
-        shout_karma =  total_notices / total_xp # High value should have negative impact.
+        shout_karma =  total_notices / total_xp
         print('shout_karma:' + str(shout_karma) + ' =  total_notices:' + str(total_notices) + ' + / total_xp:' + str(total_xp))
         print('shout_karma:' + str(shout_karma) + ' =  total_notices:' + str(total_notices) + ' + / total_xp:' + str(total_xp))
-        curse_add_karma = ((total_cursewords_added + total_curseadjectives_added) * 10 ) / total_xp  # High value should have positive impact.
+        curse_add_karma = ((total_cursewords_added + total_curseadjectives_added) * 10) / total_xp
         print('curse_add_karma:' + str(curse_add_karma) + ' = ((total_cursewords_added:' + str(total_cursewords_added) + ' + total_curseadjectives_added:' + str(total_curseadjectives_added) + ') * 10 ) / total_xp:'+ str(total_xp))
         print('curse_add_karma:' + str(curse_add_karma) + ' = ((total_cursewords_added:' + str(total_cursewords_added) + ' + total_curseadjectives_added:' + str(total_curseadjectives_added) + ') * 10 ) / total_xp:'+ str(total_xp))
+        curse_ban_karma = ((total_cursewords_banned + total_curseadjectives_banned) * 50) / total_xp
+        print('curse_ban_karma:' + str(curse_ban_karma) + ' = ((total_cursewords_banned:' + str(total_cursewords_banned) + ' + total_curseadjectives_banned:' + str(total_curseadjectives_banned) + ') * 10 ) / total_xp:'+ str(total_xp))
         wealth_karma = (coin * 50.1) / total_xp
         wealth_karma = (coin * 50.1) / total_xp
         print('wealth_karma:' + str(wealth_karma) + ' = (coin:' + str(coin) + ' * 50) / total_xp:' + str(total_xp))
         print('wealth_karma:' + str(wealth_karma) + ' = (coin:' + str(coin) + ' * 50) / total_xp:' + str(total_xp))
         charity_karma = (coin_given * 10.1) / total_xp
         charity_karma = (coin_given * 10.1) / total_xp
@@ -173,8 +177,8 @@ class GameHelpers():
                 elite_karma_bonus += 1
                 elite_karma_bonus += 1
                 print(elite_karma_bonus)
                 print(elite_karma_bonus)
             i += 1
             i += 1
-        karma =  float(karma_correction) + float(curse_add_karma) + float(charity_karma) + elite_karma_bonus - float(join_karma) - float(kick_karma) - float(shout_karma) - float(wealth_karma)
-        print('karma: ' + str(karma) + ' =  float(karma_correction:' + str(karma_correction) + ') + float(curse_karma:' + str(curse_add_karma) + ') + float(charity_karma:' + str(charity_karma) + ') + elite_karma_bonus:' + str(elite_karma_bonus) + ' - float(join_karma:' + str(join_karma) + ') - float(kick_karma:' + str(kick_karma) + ') - float(shout_karma:' + str(shout_karma) + ') - float(wealth_karma:' + str(wealth_karma) + ')')
+        karma =  float(karma_correction) + float(charity_karma) + elite_karma_bonus + float(curse_add_karma) - float(curse_ban_karma) - float(join_karma) - float(kick_karma) - float(shout_karma) - float(wealth_karma)
+        print('karma: ' + str(karma) + ' =  karma_correction:' + str(karma_correction) + ' + charity_karma:' + str(charity_karma) + ' + elite_karma_bonus:' + str(elite_karma_bonus) + ' + curse_karma:' + str(curse_add_karma) + ' - curse_ban_karma:' + str(curse_ban_karma) + ' - join_karma:' + str(join_karma) + ' - kick_karma:' + str(kick_karma) + ' - shout_karma:' + str(shout_karma) + ' - wealth_karma:' + str(wealth_karma))
 
 
         return level, xp, xp_spent, total_xp, karma, coin, coin_spent, coin_given, ap, ap_spent
         return level, xp, xp_spent, total_xp, karma, coin, coin_spent, coin_given, ap, ap_spent
 
 

+ 2 - 2
rotbot/commands/games.py

@@ -22,7 +22,7 @@ def do_command(self, connection, event, user, channel):
 
 
     # Do noting if the games channel function is off and it's a channel message.
     # Do noting if the games channel function is off and it's a channel message.
     if event.target != connection.get_nickname():   # Command issued to channel.
     if event.target != connection.get_nickname():   # Command issued to channel.
-        if not queries.get_channel_setting_game_commands(self, channel.id):   # Games are turned off in channel settigns.
+        if not queries.get_channel_setting_games_commands(self, channel.id):   # Games are turned off in channel settigns.
             return  # Do nothing.
             return  # Do nothing.
 
 
     if command == 'cmd' or command == 'cmds' or command == 'commands':
     if command == 'cmd' or command == 'cmds' or command == 'commands':
@@ -88,7 +88,7 @@ def do_command(self, connection, event, user, channel):
                 return
                 return
 
 
             while xp > int(level * 2.7) and ap > 0 and upgrade_count > 0:
             while xp > int(level * 2.7) and ap > 0 and upgrade_count > 0:
-                queries.levelup_user(self, user.id, int(level * 2.7))
+                queries.levelup_user(self, user.id, int((level + 1) * 2.7))
                 level, xp, xp_spent, total_xp, karma, coin, coin_spent, coin_given, ap, ap_spent = GameHelpers.get_info(self, user)
                 level, xp, xp_spent, total_xp, karma, coin, coin_spent, coin_given, ap, ap_spent = GameHelpers.get_info(self, user)
 
 
             if upgrade_count < 0:
             if upgrade_count < 0:

+ 2 - 2
rotbot/commands/statistics.py

@@ -54,8 +54,8 @@ def do_command(self, connection, event, user, channel):
                     connection.privmsg(replyto, '%sStatistics on channel %s%s%s:%s %schannel/%s' % (font.grey, font.red, command.split()[1], font.grey, font.reset, self.webgui['base_url'], channel_slug))
                     connection.privmsg(replyto, '%sStatistics on channel %s%s%s:%s %schannel/%s' % (font.grey, font.red, command.split()[1], font.grey, font.reset, self.webgui['base_url'], channel_slug))
             else:   # Argument does not match a channel.
             else:   # Argument does not match a channel.
                 user_slug = queries.get_user_slug(self, command.split()[1])
                 user_slug = queries.get_user_slug(self, command.split()[1])
-                if user:
-                    connection.privmsg(replyto, '%sStatistics on nickname %s%s%s:%s %s/user/$s' % (font.grey, font.red, command.split()[1], font.grey, font.reset, self.webgui['base_url'], user_slug))
+                if user_slug:
+                    connection.privmsg(replyto, '%sStatistics on nickname %s%s%s:%s %suser/%s' % (font.grey, font.red, command.split()[1], font.grey, font.reset, self.webgui['base_url'], user_slug))
                 else:   # Argument does not match a channel or user.
                 else:   # Argument does not match a channel or user.
                     connection.privmsg(replyto, 'I have not had the pleasure of being aquinted with: %s%s' % (font.red, command.split()[1]))
                     connection.privmsg(replyto, 'I have not had the pleasure of being aquinted with: %s%s' % (font.red, command.split()[1]))
 
 

+ 0 - 17
rotbot/common/font.py

@@ -3,24 +3,7 @@ bold = "\x02"
 underline = "\x1F"
 underline = "\x1F"
 italic = "\x1D"
 italic = "\x1D"
 reverse = "\x16" 	# swap background and foreground colors ("reverse video")
 reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-
 blue = "\x0302"
 blue = "\x0302"
 green = "\x0303"
 green = "\x0303"
 red = "\x0304"
 red = "\x0304"
 grey = "\x0314"
 grey = "\x0314"
-
-
-# def bold:
-#     return '\x02'
-# def italic:
-#     return '\x1D'
-# def underline:
-#     return '\x1F'
-# def reverse:
-#     return '\x16' 	# swap background and foreground colors ("reverse video")
-# def reset:
-#     return '\x0F'
-# def blue:
-#     return '\x0302'
-# def green:
-#     retrun '\x0303'

+ 16 - 0
rotbot/common/language.py

@@ -0,0 +1,16 @@
+from common import log
+
+def add_adjective_a(self, former, latter):  # Adds the word "a" or "an" in fornt of a random adjective and in betweet two parts of a sentance.
+    adjective = queries.random_adjective(self)  # Get random adjective.
+
+    # Apply English grammar.
+    if adjective[0] == 'a':
+        former = former + 'an'
+    else:
+        former = former + 'a'
+
+    # Don't fail if there are no adjectives.
+    if adjective:
+        return '%s a %s %s' % (former, adjective, latter)
+    else:
+        return '%s a %s' % (former, latter)

+ 38 - 25
rotbot/common/networkservices.py

@@ -1,36 +1,47 @@
+from . import log
+
 class NickServ():
 class NickServ():
     def recover_nick(connection, password):
     def recover_nick(connection, password):
+        log.info('Recovering nickname.')
         connection.privmsg('NickServ', 'IDENTIFY %s %s' % (self.network.nickname, password)) # Identify with NickServ.
         connection.privmsg('NickServ', 'IDENTIFY %s %s' % (self.network.nickname, password)) # Identify with NickServ.
         connection.privmsg('NickServ', 'RECOVER %s %s' % (self.network.nickname, password))  # Recover control of nickname via NickServ.
         connection.privmsg('NickServ', 'RECOVER %s %s' % (self.network.nickname, password))  # Recover control of nickname via NickServ.
         connection.privmsg('NickServ', 'GHOST %s %s' % (self.network.nickname, password))  # Recover control of nickname via NickServ, old style.
         connection.privmsg('NickServ', 'GHOST %s %s' % (self.network.nickname, password))  # Recover control of nickname via NickServ, old style.
         connection.nick(connection.nickname)    # Set original nickname. Should have happened during the nickServ recover, this fails when still connecting. So this creates a loop to successfully recover via NickServ.
         connection.nick(connection.nickname)    # Set original nickname. Should have happened during the nickServ recover, this fails when still connecting. So this creates a loop to successfully recover via NickServ.
 
 
 class ChanServ():
 class ChanServ():
-    def invite(connection, channel):
-        connection.privmsg("ChanServ", "INVITE " + channel)
+    def invite(connection, channel_name):
+        log.info('Requesting ChanServ to invite me to %s' % channel_name)
+        connection.privmsg("ChanServ", "INVITE " + channel_name)
 
 
-    def getkey(connection, channel):
-        connection.privmsg("ChanServ", "GETKEY " + channel)
+    def getkey(connection, channel_name):
+        log.info('Requesting ChanServ password for channel %s' % channel_name)
+        connection.privmsg("ChanServ", "GETKEY " + channel_name)
 
 
-    def ban(connection, channel, user, reason):
-        connection.privmsg("ChanServ", "BAN " + channel + " " + user + " " + reason)
+    def ban(connection, channel_name, user_name, reason):
+        log.info('Requesting ChanServ to ban %s from %s for %s' % (user_name, channel_name, reason))
+        connection.privmsg("ChanServ", "BAN " + channel_name + " " + user_name + " " + reason)
 
 
-    def tempban(connection, channel, user, duration, reason):
-        connection.privmsg("ChanServ", "BAN " + channel + " +" + duration + " " + user + " " + reason)
+    def tempban(connection, channel_name, user_name, duration, reason):
+        log.info('Requesting ChanServ to ban %s for %s in %s %s for %s' % (user_name, reason, channel_name, duration))
+        connection.privmsg("ChanServ", "BAN " + channel_name + " +" + duration + " " + user_name + " " + reason)
 
 
-    def unban(connection, channel, user):
-        connection.privmsg("ChanServ", "UNBAN " + channel + " " + user)
+    def unban(connection, channel_name, user_name):
+        log.info('Requesting ChanServ to ubnan %s from %s.' %(user_name, channel_name))
+        connection.privmsg("ChanServ", "UNBAN " + channel_name + " " + user_name)
 
 
-    def akick_add(connection, channel, user):
-        connection.privmsg("ChanServ", "AKICK " + channel + " ADD " + user)
+    def akick_add(connection, channel_name, user_name):
+        log.info('Requesting ChanServ to add %s to the auto kick list of %s.' % (user_name, channel_name))
+        connection.privmsg("ChanServ", "AKICK " + channel_name + " ADD " + user_name)
 
 
-    def akick_del(connection, channel, user):
-        connection.privmsg("ChanServ", "AKICK " + channel + " DEL " + user)
+    def akick_del(connection, channel_name, user_name):
+        log.info('Requesting ChanServ to remove %s to the auto kick list of %s.' % (user_name, channel_name))
+        connection.privmsg("ChanServ", "AKICK " + channel_name + " DEL " + user_name)
 
 
-    def kick(connection, channel, user, reason):
-        connection.privmsg("ChanServ", "KICK " + channel + " " + user + " " + reason)
+    def kick(connection, channel_name, user_name, reason):
+        log.info('Requesting ChanServ to kick %s from %s.' % (user_name, channel_name))
+        connection.privmsg("ChanServ", "KICK " + channel_name + " " + user_name + " " + reason)
 
 
-    def give_mode(connection, channel, user, mode):
+    def give_mode(connection, channel_name, user_name, mode):
         if mode[1] == "q":
         if mode[1] == "q":
             modename = "OWNER"
             modename = "OWNER"
         if mode[1] == "a":
         if mode[1] == "a":
@@ -41,11 +52,13 @@ class ChanServ():
             modename = "HALFOP"
             modename = "HALFOP"
         if mode[1] == "v":
         if mode[1] == "v":
             modename = "VOICE"
             modename = "VOICE"
-        connection.privmsg("ChanServ", modename + " " + channel + " " + user)
-
-    def take_all_modes(connection, channel, user):
-        connection.privmsg("ChanServ", "DEVOICE " + channel + " " + user)
-        connection.privmsg("ChanServ", "DEHALFOP " + channel + " " + user)
-        connection.privmsg("ChanServ", "DEOP " + channel + " " + user)
-        connection.privmsg("ChanServ", "DEPROTECT " + channel + " " + user)
-        connection.privmsg("ChanServ", "DEOWNER " + channel + " " + user)
+        log.info('Requesting ChanServ grant %s to %s on %s' % (modename, user_name, channel_name))
+        connection.privmsg("ChanServ", modename + " " + channel_name + " " + user_name)
+
+    def take_all_modes(connection, channel_name, user_name):
+        log.info('Requesting ChanServ strip %s of all modes in %s.' % (user_name, channel_name))
+        connection.privmsg("ChanServ", "DEVOICE " + channel_name + " " + user_name)
+        connection.privmsg("ChanServ", "DEHALFOP " + channel_name + " " + user_name)
+        connection.privmsg("ChanServ", "DEOP " + channel_name + " " + user_name)
+        connection.privmsg("ChanServ", "DEPROTECT " + channel_name + " " + user_name)
+        connection.privmsg("ChanServ", "DEOWNER " + channel_name + " " + user_name)

+ 74 - 8
rotbot/common/queries.py

@@ -117,9 +117,11 @@ def create_or_get_and_update_last_event(self, table, event_type, channel_name=No
     return record
     return record
 
 
 
 
-def get_owners(self):
-    return self.db.all('SELECT * FROM rotbot_owner')
+# def get_owners(self):
+#     return self.db.all('SELECT * FROM rotbot_owner')
 
 
+def is_owner(self, hostmask):
+    return self.db.one('SELECT id FROM rotbot_owner WHERE hostmask=%(hostmask)s', hostmask=hostmask)
 
 
 # Channel
 # Channel
 def get_channel_id(self, channel_name):
 def get_channel_id(self, channel_name):
@@ -131,12 +133,31 @@ def get_channel_slug(self, channel_name):
 def get_channel_setting_statistic_commands(self, channel_id):
 def get_channel_setting_statistic_commands(self, channel_id):
     return self.db.one('SELECT statistic_commands FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
     return self.db.one('SELECT statistic_commands FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
 
 
-def get_channel_setting_game_commands(self, channel_id):
+def get_channel_setting_games_commands(self, channel_id):
     return self.db.one('SELECT games FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
     return self.db.one('SELECT games FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
 
 
+def get_channel_setting_chat(self, channel_id):
+    return self.db.one('SELECT chat FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
+
 def get_autojoin_channels(self):
 def get_autojoin_channels(self):
     return self.db.all('SELECT name FROM rotbot_channel WHERE network_id=%(network_id)s AND autojoin=True', network_id=self.network.id)
     return self.db.all('SELECT name FROM rotbot_channel WHERE network_id=%(network_id)s AND autojoin=True', network_id=self.network.id)
 
 
+def get_channel_last_greet(self, channel_id):
+    return self.db.one('SELECT last_greet FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
+
+def update_channel_last_greet(self, channel_id):
+    return self.db.run('UPDATE rotbot_channel SET last_greet=NOW() WHERE id=%(channel_id)s', channel_id=channel_id)
+
+def get_channel_last_lame(self, channel_id):
+    return self.db.one('SELECT last_lame FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
+
+def update_channel_last_lame(self, channel_id):
+    return self.db.run('UPDATE rotbot_channel SET last_greet=NOW() WHERE id=%(channel_id)s', channel_id=channel_id)
+
+def get_channel_key(self, channel_name):
+    channel_id = get_channel_id(self, channel_name)     # Inperfect, make a index of the channel_name field.
+    return self.db.one('SELECT key FROM rotbot_channel WHERE channel_id=%(channel_id)', channel_id=channel_id)
+
 def save_channel_key(self, channel_name, channel_key):
 def save_channel_key(self, channel_name, channel_key):
     channel_id = get_channel_id(self, channel_name)     # Inperfect, make a index of the channel_name field.
     channel_id = get_channel_id(self, channel_name)     # Inperfect, make a index of the channel_name field.
     self.db.run('UPDATE key FROM rotbot_channel WHERE channel_id=%(channel_id)', channel_id=channel_id)
     self.db.run('UPDATE key FROM rotbot_channel WHERE channel_id=%(channel_id)', channel_id=channel_id)
@@ -187,21 +208,65 @@ def get_user_total_notices(self, user_id):
     recordset = self.db.all('SELECT amount FROM rotbot_notice WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
     recordset = self.db.all('SELECT amount FROM rotbot_notice WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
     return total_amount_in_recordset(recordset)
     return total_amount_in_recordset(recordset)
 
 
-def get_user_total_curseword_added(self, user_id):
+def get_user_total_cursewords_added(self, user_id):
     recordset = self.db.all('SELECT id FROM rotbot_curseword WHERE irc_user_id=%(user_id)s ', user_id=user_id)
     recordset = self.db.all('SELECT id FROM rotbot_curseword WHERE irc_user_id=%(user_id)s ', user_id=user_id)
     return recordset.count(recordset)
     return recordset.count(recordset)
 
 
-def get_user_total_curseadjective_added(self, user_id):
+def get_user_total_curseadjectives_added(self, user_id):
     recordset = self.db.all('SELECT id FROM rotbot_curseadjective WHERE irc_user_id=%(user_id)s', user_id=user_id)
     recordset = self.db.all('SELECT id FROM rotbot_curseadjective WHERE irc_user_id=%(user_id)s', user_id=user_id)
     return recordset.count(recordset)
     return recordset.count(recordset)
 
 
+def get_user_total_cursewords_banned(self, user_id):
+    recordset = self.db.all('SELECT id FROM rotbot_curseword WHERE banned=True AND irc_user_id=%(user_id)s ', user_id=user_id)
+    return recordset.count(recordset)
+
+def get_user_total_curseadjectives_banned(self, user_id):
+    recordset = self.db.all('SELECT id FROM rotbot_curseadjective WHERE banned=True AND irc_user_id=%(user_id)s', user_id=user_id)
+    return recordset.count(recordset)
+
+def get_user_last_greet(self, user_id):
+    return self.db.one('SELECT last_greet FROM rotbot_user WHERE id=%(user_id)s', user_id=user_id)
+
+def update_user_last_greet(self, user_id):
+    return self.db.run('UPDATE rotbot_user SET last_greet=NOW() WHERE id=%(user_id)s', user_id=user_id)
+
+def get_user_last_lame(self, user_id):
+    return self.db.one('SELECT last_lame FROM rotbot_user WHERE id=%(user_id)s', user_id=user_id)
+
+def update_user_last_lame(self, user_id):
+    return self.db.run('UPDATE rotbot_user SET last_lame=NOW() WHERE id=%(user_id)s', user_id=user_id)
+
+
+# Userchannel
+def get_user_channel_joins(self, user_id, channel_id):
+    return self.db.one('SELECT amount FROM rotbot_join WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id)
+
+def get_user_channel_kicks(self, user_id, channel_id):
+    return self.db.one('SELECT amount FROM rotbot_kick WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id)
+
 
 
 # Chat
 # Chat
 def random_curse(self):
 def random_curse(self):
-    adjective = self.db.one('SELECT word FROM rotbot_curseadjective ORDER BY RANDOM() LIMIT 1')
-    curse = self.db.one('SELECT word FROM rotbot_curseword ORDER BY RANDOM() LIMIT 1')
+    adjective = self.db.one('SELECT word FROM rotbot_curseadjective WHERE banned=False ORDER BY RANDOM() LIMIT 1')
+    curse = self.db.one('SELECT word FROM rotbot_curseword WHERE banned=False ORDER BY RANDOM() LIMIT 1')
+
+    # Try to hint the user of my capabilities.
+    if not adjective:
+        log.notice('No adjectives in the database, please add some for more colourfull language.')
+    if not curse:
+        log.notice('No curses in the database, please add some for more colourfull language.')
+
     return '%s %s' % (adjective, curse)
     return '%s %s' % (adjective, curse)
 
 
+def random_adjective(self):
+    adjective = self.db.one('SELECT word FROM rotbot_curseadjective ORDER BY RANDOM() LIMIT 1')
+
+    # Try to hint the user of my capabilities.
+    if not adjective:
+        log.notice('No adjectives in database, please add some for more colourfull language.')
+
+    return self.db.one('SELECT word FROM rotbot_curseadjective ORDER BY RANDOM() LIMIT 1')
+
 def get_curse(self, word):
 def get_curse(self, word):
     return self.db.one('SELECT * FROM rotbot_curseword WHERE LOWER(word)=LOWER(%(word)s)')
     return self.db.one('SELECT * FROM rotbot_curseword WHERE LOWER(word)=LOWER(%(word)s)')
 
 
@@ -246,6 +311,7 @@ def punish_user(self, user_id, coin, karma):
     self.db.run('UPDATE website_users SET coin=coin-%(coin)s, karma_correction=karma_correction-%(karma)s WHERE id=%(user_id)s', coin=coin, karma=karma, user_id=user_id)
     self.db.run('UPDATE website_users SET coin=coin-%(coin)s, karma_correction=karma_correction-%(karma)s WHERE id=%(user_id)s', coin=coin, karma=karma, user_id=user_id)
 
 
 def payday(self, coin):
 def payday(self, coin):
+    log.info('Game payday: %s coin.' % coin)
     self.db.run('UPDATE rotbot_user SET coin=coin+%(coin)s WHERE network_id=%(network_id)s AND level>0', coin=coin, network_id=self.network.id)
     self.db.run('UPDATE rotbot_user SET coin=coin+%(coin)s WHERE network_id=%(network_id)s AND level>0', coin=coin, network_id=self.network.id)
 
 
 def cointransfer(self, sender_id, receiver_id, coin):
 def cointransfer(self, sender_id, receiver_id, coin):
@@ -254,8 +320,8 @@ def cointransfer(self, sender_id, receiver_id, coin):
     coin = random.uniform(0.1, 0.3)
     coin = random.uniform(0.1, 0.3)
     payday(self, coin)
     payday(self, coin)
 
 
-# Common.
 
 
+# Common.
 def total_amount_in_recordset(recordset):
 def total_amount_in_recordset(recordset):
     amount = 0
     amount = 0
     for record in recordset:
     for record in recordset:

+ 4 - 21
rotbot/events/common.py

@@ -4,16 +4,19 @@ from common import queries, userstatus, log
 
 
 class Inform():
 class Inform():
     def owners(self, connection, message):
     def owners(self, connection, message):
+        log.info('Informing owners: %s' % message)
         if self.network.home_channel in self.channels:
         if self.network.home_channel in self.channels:
             for owner in self.channels[self.network.home_channel].owners():
             for owner in self.channels[self.network.home_channel].owners():
                 connection.privmsg(owner, message)
                 connection.privmsg(owner, message)
 
 
     def notice_owners(self, connection, message):
     def notice_owners(self, connection, message):
+        log.info('Notifying owners: %s' % message)
         if self.network.home_channel in self.channels:
         if self.network.home_channel in self.channels:
             for owner in self.channels[self.network.home_channel].owners():
             for owner in self.channels[self.network.home_channel].owners():
                 connection.notice(owner, message)
                 connection.notice(owner, message)
 
 
     def operators(self, connection, message):
     def operators(self, connection, message):
+        log.info('Informing operators: %s' % message)
         if self.homechannel in self.channels:
         if self.homechannel in self.channels:
             for user in self.channels[self.homechannel].owners():
             for user in self.channels[self.homechannel].owners():
                 connection.privmsg(user, message)
                 connection.privmsg(user, message)
@@ -23,6 +26,7 @@ class Inform():
                 connection.privmsg(user, message)
                 connection.privmsg(user, message)
 
 
     def home_channel(self, connection, message):
     def home_channel(self, connection, message):
+        log.info('Informing home channel: %s' % message)
         connection.privmsg(self.network.home_channel, message)
         connection.privmsg(self.network.home_channel, message)
 
 
 # class Protectees():
 # class Protectees():
@@ -96,24 +100,3 @@ class Inform():
 #         else:
 #         else:
 #             return "Aggression channel function = " + behaviour + ": " + protectee + " is atlast halfop in " + self.homechannel + "."
 #             return "Aggression channel function = " + behaviour + ": " + protectee + " is atlast halfop in " + self.homechannel + "."
 #
 #
-# class Lastact():
-#     def update(self, name, type, channel=False, lastact=False, auxiliary=False):
-#
-#         # Create records if not present.
-#         if channel:
-#             queries.create_ifnot_onrecord(self, "channels", channel)
-#         queries.create_ifnot_onrecord(self, "users", name)
-#
-#         # Update record.
-#         self.db.run("UPDATE users SET last_act_type=%s, last_act_datetime=%s, last_act_channel=%s, last_act=%s, last_act_auxiliary=%s WHERE name=%s AND network=%s",  (type, str(datetime.now()), channel, lastact, auxiliary, name, self.network))
-#
-#         # Set user back from away, if user is active.
-#         if type not in ["nick", "kick", "part", "quit"]:
-#             self.db.run("UPDATE users SET away=FALSE WHERE name=%s AND network=%s", (name, self.network, ))
-#
-# class MessageStatistics():
-#     def update(self, event, type):
-#         if not self.db.one('SELECT id FROM rotbot_' + type + ' WHERE network_id=%(network_id)s AND channel_id=%(channel_id)s AND user_id=%(user_id)s', network_id=self.network.id, channel_id=channel.id ,user_id=user.id):  # Not on record.
-#             self.db.run('INSERT INTO rotbot_' + type + ' (network_id, channel_id, user_id, amount) VALUES (%(network_id)s, %(channel_id)s, %(user_id)s, 1)', network_id=self.network.id, channel_id=channel.id ,user_id=user.id)   # Create record.
-#         else:   # On record.
-#             self.db.run('UPDATE rotbot_' + type + ' SET amount = amount +1 WHERE network_id=%(network_id)s AND channel_id=%(channel_id)s AND user_id=%(user_id)s', network_id=self.network.id, channel_id=channel.id ,user_id=user.id)  # Increment record.

+ 54 - 50
rotbot/events/on_action.py

@@ -1,60 +1,64 @@
-from common import queries #userstatus, font, queries
+from common import queries, userstatus, font#, queries
 #from events.common import Replyto, Lastact, MessageStatistics
 #from events.common import Replyto, Lastact, MessageStatistics
 
 
 def process_event(self, connection, event):
 def process_event(self, connection, event):
-    # Let's not log all actions.
+    # Let's not log all actions. log.info(event) # Log to console.
 
 
     # Get and update resources.
     # Get and update resources.
-    user = queries.create_or_get_and_update_last_event(self, 'user', 'ca', channel_name=event.target, user_name=event.source.nick)
+    slapper = queries.create_or_get_and_update_last_event(self, 'user', 'ca', channel_name=event.target, user_name=event.source.nick)
+    slapped = queries.create_or_get_and_update_last_event(self, 'user', 'ca', channel_name=event.target, user_name=event.arguments[0].split(" ")[1])
+
+
     if event.target != connection.get_nickname():   # Channel action.
     if event.target != connection.get_nickname():   # Channel action.
         channel = queries.create_or_get_and_update_last_event(self, 'channel', 'ca', channel_name=event.target, user_name=event.source.nick)
         channel = queries.create_or_get_and_update_last_event(self, 'channel', 'ca', channel_name=event.target, user_name=event.source.nick)
-        queries.update_message_statistics(self, 'message', channel.id, user.id)   # Update message statistics
-
-
-    # # Stop if channelfunction chat if off.
-    # if not self.db.one("SELECT chat FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'"):
-    #     return
-    #
-    # # Slap guard.
-    # if event.arguments[0].lower().startswith("slaps ") and not event.target == connection.get_nickname():   # Channel action that stats with "slaps ".
-    #
-    #     # Stop if chat channel function is off.
-    #     if not self.db.one("SELECT chat FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'"):
-    #         return
-    #
-    #     # Only protect the worty.
-    #     if not userstatus.atleast_voiced(self, event.arguments[0].split(" ")[1], self.homechannel) and not userstatus.atleast_oper(self, event.arguments[0].split(" ")[1], self.homechannel): # Insufficient rights.
-    #         if event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
-    #             Replyto.name(connection, event)
-    #         return
-    #     if userstatus.atleast_voiced(self, event.source.nick, self.homechannel):   # Slapper has atleast voice in home channel.
-    #         if not self.channels[self.homechannel].is_owner(event.arguments[0].split(" ")[1]):  # Slappee is not owner.
-    #             if event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
-    #                 Replyto.name(connection, event)
-    #             return
-    #         if self.channels[self.homechannel].is_owner(event.source.nick) and  self.channels[self.homechannel].is_owner(event.arguments[0].split(" ")[1]): # Slapper and slappee are owner.
-    #             if event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
-    #                 Replyto.name(connection, event)
-    #             return
-    #
-    #     # Respond.
-    #     if " with a " in event.arguments[0]:
-    #         if event.arguments[0].split(" with a ", maxsplit=1)[1]:
-    #             if event.arguments[0].split(" ")[1].lower() == connection.get_nickname().lower(): # Bot slapped
-    #                 connection.action(event.target, "Takes the " + event.arguments[0].split(" with a ", maxsplit=1)[1] + " like a robot.")
-    #             else:
-    #                 connection.action(event.target, "swiftly jumps in front of " + red + event.arguments[0].split(" ")[1] + reset + " to block the " + event.arguments[0].split(" with a ", maxsplit=1)[1])
-    #
-    #         elif event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
-    #             connection.action(event.target, "bites " + red + event.source.nick + reset + " furiously.")
-    #         else:
-    #             connection.action(event.target, "swiftly jumps in front of " + red + event.arguments[0].split(" ")[1] + reset + " to block the slap.")
-    #     elif len(event.arguments[0].split(" ")) > 1:
-    #         if event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
-    #             connection.action(event.target, "bites " + red + event.source.nick + reset + " furiously.")
-    #         else:
-    #             connection.action(event.target, "swiftly jumps in front of " + red + event.arguments[0].split(" ")[1] + reset + " to block the slap.")
-    #
+        queries.update_message_statistics(self, 'action', channel.id, slapper.id)   # Update message statistics
+
+    # Stop if chat setting is disabled.
+    if not queries.get_channel_setting_chat(self, channel.id):
+        return
+
+    # Slaps
+    if event.arguments[0].lower().startswith('slaps ') and not event.target == connection.get_nickname():   # Channel action that stats with "slaps ".
+        takeitlikeaman = False
+        takeoffense = False
+        protect = False
+        joinin = False
+        if event.arguments[0].split(" ")[1].lower() == connection.get_nickname(): # Bot slapped
+            if userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):   # Slapper has atleast voice in home channel.
+                takeitlikeaman = True
+            else:   # Bot slapped by a pleb.
+                takeoffense = True
+
+        elif userstatus.atleast_voiced(self, event.arguments[0].split(" ")[1], self.network.home_channel):    # Only protect the worthy.
+            if not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):   # But not from the worthy
+                protect = True
+            else: # Worthy slappning the worthy.
+                pass
+
+        elif userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):   # Join the worthy.
+            if not userstatus.atleast_voiced(self, event.arguments[0].split(" ")[1], self.network.home_channel):    # But not against teh worthy.
+                joinin = True
+
+        if " with a " in event.arguments[0]:    # Slapping with utensil.
+            utensil = event.arguments[0].split(" with a ", maxsplit=1)[1]
+            if takeitlikeaman == True:
+                connection.action(event.target, "takes the " + utensil + " like a robot.")
+            elif takeoffense == True:
+                connection.action(event.target, "is covered in %s bruises and shame." % utensil)
+            elif protect == True:
+                connection.action(event.target, "swiftly jumps in front of " + font.red + event.arguments[0].split(" ")[1] + font.reset + " to block the " + utensil)
+            elif joinin == True:
+                connection.action(event.target, 'takes another %s and joins in slapping %s%s%s profusely.' % (utensil, font.red, event.arguments[0].split(" ")[1], font.reset))
+        else:   # Slapping without utensil.
+            if takeitlikeaman == True:
+                connection.action(event.target, "stands proud, presenting his cheek to %s%s" % (font.red, event.source.nick))
+            elif takeoffense == True:
+                connection.action(event.target, 'cries.')
+            elif protect == True:
+                connection.action(event.target, "swiftly jumps in front of " + font.red + event.arguments[0].split(" ")[1] + font.reset + " to block the slap.")
+            elif joinin == True:
+                connection.action(event.target, 'checks his hand and joins in slapping %s%s%s profusely.' % (font.red, event.arguments[0].split(" ")[1], font.reset))
+
     # # Respond to own name.
     # # Respond to own name.
     # elif connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned, not by the bot itself.
     # elif connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned, not by the bot itself.
     #     Replyto.name(connection, event)
     #     Replyto.name(connection, event)

+ 2 - 2
rotbot/events/on_error.py

@@ -5,5 +5,5 @@ def process_event(self, connection, event):
     log.notice(str(event))  # Log to console.
     log.notice(str(event))  # Log to console.
 
 
     # Forward error.
     # Forward error.
-    connection.privmsg(self.network.home_channel, 'ERROR: %s' %s (event))
-    Inform.notice_owners(self, connection, 'Received error from server: %s' % (event))
+    Inform.home_channel(self, connection, 'ERROR: %s' % event)
+    Inform.notice_owners(self, connection, 'Received error from server: %s' % event)

+ 1 - 0
rotbot/events/on_invite.py

@@ -9,5 +9,6 @@ def process_event(self, connection, event):
 
 
     if event.target == connection.get_nickname(): # Bot invited.
     if event.target == connection.get_nickname(): # Bot invited.
         Inform.operators(self, connection, 'Received invitation to %s %s %s form %s %s %s.' % (font.red, event.arguments[0], font.reset, font.red, event.source.nick, font.reset))
         Inform.operators(self, connection, 'Received invitation to %s %s %s form %s %s %s.' % (font.red, event.arguments[0], font.reset, font.red, event.source.nick, font.reset))
+        Inform.home_channel(self, connection, 'Received invitation to %s %s %s form %s %s %s.' % (font.red, event.arguments[0], font.reset, font.red, event.source.nick, font.reset))
         connection.privmsg(event.source.nick, 'Ask an operator of %s%s%s to make me join.' % (font.red, self.network.home_channel, font.reset))
         connection.privmsg(event.source.nick, 'Ask an operator of %s%s%s to make me join.' % (font.red, self.network.home_channel, font.reset))
         connection.invite(event.source.nick, self.network.home_channel)
         connection.invite(event.source.nick, self.network.home_channel)

+ 56 - 50
rotbot/events/on_join.py

@@ -1,3 +1,4 @@
+import datetime
 from common import log, queries, font, userstatus
 from common import log, queries, font, userstatus
 
 
 def process_event(self, connection, event):
 def process_event(self, connection, event):
@@ -8,60 +9,65 @@ def process_event(self, connection, event):
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cj', channel_name=event.target, user_name=event.source.nick)
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cj', channel_name=event.target, user_name=event.source.nick)
     queries.increment_join(self, channel.id, user.id)
     queries.increment_join(self, channel.id, user.id)
 
 
-    # Stop if the bot joined the channel.
-    if event.source == self.connection.get_nickname():
-        return
-
-    # Promote user if usermask is in database.
-    owners = queries.get_owners(self)
-    print('Event source: ', event.source)
-    if event.source in owners:
-        connection.mode(event.target, "+aohv %s %s %s %s" % (event.source.nick, event.source.nick, event.source.nick, event.source.nick))
-        curse = queries.random_curse(self)
-        if curse:
-            connection.privmsg(event.target, 'Welcome back %s%s%s, you %s.' % (font.red, event.source, font.reset, curse))
-
-    # Promote user if owner in home channel.
-    if userstatus.is_owner(self, event.source.nick, self.network.home_channel):
-        connection.mode(event.target, '+aohv %s %s %s %s' % (event.source.nick, event.source.nick, event.source.nick, event.source.nick))
-
-
     if event.source.nick == connection.get_nickname():  # The bot joined a channel.
     if event.source.nick == connection.get_nickname():  # The bot joined a channel.
-        # connection.who(self.homechannel)    # Get whoreplies for users of homechannel.
+        log.info('Joined %s' % event.target)
         if self.channels[event.target].has_key():   # Passworded channel.
         if self.channels[event.target].has_key():   # Passworded channel.
             if event.target in self.channelkeys:    # New key used to join channel.
             if event.target in self.channelkeys:    # New key used to join channel.
+                log.info('Saving channel key for %s.' %s)
                 self.db.run('UPDATE rotbot_channels SET key=%(key)s WHERE id=%(id)s', key=self.channelkeys[event.target], id=channel.id)    # Save new key to DB.
                 self.db.run('UPDATE rotbot_channels SET key=%(key)s WHERE id=%(id)s', key=self.channelkeys[event.target], id=channel.id)    # Save new key to DB.
-        # if event.target == self.homechannel:    # Home channel.
-        #     connection.who(connection.get_nickname())   # get whoreply to add bot to protectees.
-       # return  # Do not greet myself.
+        return   # Stop if the bot joined the channel.
+
+    # Greeting conditions.
+    timeout = 10    # Amount of minutes to let pass before greeting again.
+    joins = queries.get_user_channel_joins(self, user.id, channel.id)
+    chan_lastgreet = queries.get_channel_last_greet(self, channel.id)
+    user_lastgreet = queries.get_user_last_greet(self, user.id)
+    greet = False
+    amount_greet = False
+    if not chan_lastgreet:
+        chan_lastgreet = datetime.datetime.now() - datetime.timedelta(minutes=timeout+1)
+    if not user_lastgreet:
+        user_lastgreet = datetime.datetime.now() - datetime.timedelta(minutes=timeout+1)
+    if chan_lastgreet < datetime.datetime.now() - datetime.timedelta(minutes=timeout) and user_lastgreet < datetime.datetime.now() - datetime.timedelta(minutes=timeout):    # User or channel have not had greet message in the last timeout minutes, there is a curse available
+        if joins % 200 == 0:    # Has joined 200, or a multiple of 200 times. (Also 0 but the join has already been saved.)
+            amount_greet = True
+        elif userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):  # User has atleast voice in home channel.
+            greet = True
 
 
+    # Promotion conditions.
+    promote = False
+    if queries.is_owner(self, event.source):  # Usermask in database.
+        promote = True
+    elif userstatus.is_owner(self, event.source.nick, self.network.home_channel):   # Owner of homechannel
+        promote = True
 
 
-    # # Stop if greeting is not wanted.
-    # joingreeting = self.db.one("SELECT join_greeting FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
-    # stopgreet = self.db.one("SELECT stopgreet FROM joins WHERE channel='" + event.target + "' AND channel_network='" + self.network + "' AND \"user\"='" + event.source.nick + "' AND user_network='" + self.network + "'")
-    # if not joingreeting or stopgreet:
-    #     return
+    # Promote.
+    if promote:
+        log.info('Promoting %s in %s' % (event.source.nick, event.target))
+        connection.mode(event.target, "+aohv %s %s %s %s" % (event.source.nick, event.source.nick, event.source.nick, event.source.nick))
 
 
-    # # Show greeting.
-    # joins = self.db.one("SELECT joins FROM joins WHERE channel='" + event.target + "' AND channel_network='" + self.network + "' AND \"user\"='" + event.source.nick + "' AND user_network='" + self.network + "'")
-    # if not self.db.one("SELECT join_greeting FROM channels WHERE name='" + event.target + "' AND network ='" + self.network + "'"): # Do not greet users joining the channel.
-    #     return
-    # if joins == 1:
-    #     message = "Welcome to " + font.red + event.target + font.reset + ", " + font.red + event.source.nick + font.reset + ". For a list of command type " + blue + self.cmdchar + "cmd" + font.reset + "."
-    # if joins == 3:
-    #     message = "Welcome back in " + font.red + event.target + font.reset + ", " + font.red + event.source.nick + font.reset + ". To turn of greetings, type " + blue + "!stopgreet" + font.reset + "."
-    # if joins == 5:
-    #     if self.channels[event.target].has_key():   # Channel has a password.
-    #         message = "Welcome back again " + font.red + event.source.nick + font.reset + ". To automaticly join this channel type " + blue + "/ns ajoin " + font.reset + "ADD " + font.red + event.target + font.reset + italic + " password"
-    #     else:   # Channel does not have a password.
-    #         message = "Welcome back again " + font.red + event.source.nick + font.reset + ". To automaticly join this channel type " + blue + "/ns ajoin " + font.reset + "ADD " + font.red + event.source.nick + " " + event.target
-    # if joins < 100 and str(joins)[-1:] == "0":
-    #     message = font.red + event.source.nick + font.reset + " you have joined " + font.red + event.target + font.reset + " " + str(joins) + " times!"
-    # if joins < 1000 and str(joins)[-2:] == "00" or joins < 1000 and str(joins)[-2:] == "50":
-    #     message = "Epic! " + font.red + event.source.nick + font.reset + " you have joined " + font.red + event.target + font.reset + " " + str(joins) + " times!"
-    # if joins < 10000 and str(joins)[-2:] == "00":
-    #     message = "AMAZING! " + font.red + event.source.nick + font.reset + " you have joined " + font.red + event.target + font.reset + " " + str(joins) + " times!"
-    # try:
-    #     connection.privmsg(event.target, message)
-    # except:
-    #     pass
+    # Greet.
+    if greet or amount_greet:
+        curse = queries.random_curse(self)
+        if not curse:
+            return
+    if amount_greet:
+        log.info('Greeting %s in %s' % (event.source.nick, event.target))
+        adjective = queries.random_adjective(self)
+        if adjective[0].lower() == 'a':
+            adjective = 'n ' + adjective
+        else:
+            adjective = ' ' + adjective
+        if adjective:
+            connection.privmsg(event.target, 'Welcome back %s, I have seen you join here a%s %s times.' % (event.source.nick, adjective, joins))
+            connection.action(self.network.home_channel, ' has seen %s%s%s join %s%s%s a%s %s%s%s times.' % (font.red, event.source.nick, font.reset, font.red, event.target, font.reset, adjective, font.green, joins, font.reset))
+        else:
+            connection.privmsg(event.target, 'Welcome back %s, have seen you join here an amazing %s times.' % (event.source.nick, joins))
+            Inform.home_channel(self, connection, '%s%s%s has joined %s%s%s %s%s%s times.' % (font.red, event.source.nick, font.reset, font.red, event.target, font.reset, font.green, joins, font.reset))
+        queries.update_channel_last_greet(self, channel.id)
+        queries.update_user_last_greet(self, user.id)
+    elif greet:
+        log.info('Greeting %s in %s' % (event.source.nick, event.target))
+        connection.privmsg(event.target, 'Welcome back %s, you %s.' % (event.source.nick, curse))
+        queries.update_channel_last_greet(self, channel.id)
+        queries.update_user_last_greet(self, user.id)

+ 1 - 0
rotbot/events/on_keyset.py

@@ -3,4 +3,5 @@ from common import log, queries
 def process_event(self, connection, event):
 def process_event(self, connection, event):
     log.info(event) # Log to console.
     log.info(event) # Log to console.
 
 
+    queries.save_channel_key(self, channel.name, event.arguments[0])
     Inform.owners(self, connection, "keyset " + font.green + event.arguments[0] + reset.reset + " from " + font.red + event.source)
     Inform.owners(self, connection, "keyset " + font.green + event.arguments[0] + reset.reset + " from " + font.red + event.source)

+ 22 - 18
rotbot/events/on_kick.py

@@ -1,5 +1,5 @@
 #from common.networkservices import ChanServ
 #from common.networkservices import ChanServ
-from common import log, queries #userstatus, do_everything_to, log, font, queries
+from common import log, queries, language, userstatus#, do_everything_to, log, font, queries
 #from events.common import Aggressiveness, Lastact
 #from events.common import Aggressiveness, Lastact
 
 
 def process_event(self, connection, event):
 def process_event(self, connection, event):
@@ -14,29 +14,33 @@ def process_event(self, connection, event):
     # Record kick event in database.
     # Record kick event in database.
     queries.increment_kick(self, channel.id, kicker.id, kicked.id)
     queries.increment_kick(self, channel.id, kicker.id, kicked.id)
 
 
-    if kicked.name == connection.get_nickname() or kicked.name == self.network.nickname:
+    if event.arguments[0] == connection.get_nickname(): # Bot kicked from channel.
+        log.notice('I just got kicked from: %s' % event.target)
         connection.action(self.network.home_channel, 'just got kicked from %s%s %sby %s%s' % (font.red, event.target, font.reset, font.red, event.source.nick))
         connection.action(self.network.home_channel, 'just got kicked from %s%s %sby %s%s' % (font.red, event.target, font.reset, font.red, event.source.nick))
         connection.privmsg(event.source.nick, 'Sorry you needed to kick me. Bot\'s should serve those who enjoy it, without annoying anyone. Any channelOP can use the !settings command to change my settings.')
         connection.privmsg(event.source.nick, 'Sorry you needed to kick me. Bot\'s should serve those who enjoy it, without annoying anyone. Any channelOP can use the !settings command to change my settings.')
         temp_key = queries.create_tempchannelkey(self, channel.id)
         temp_key = queries.create_tempchannelkey(self, channel.id)
         connection.privmsg(event.source.nick, 'Here is a temp 10 minute link for %s%s%s:%s %schannelsettings/%s' % (event.target, font.red, event.target, font.reset, self.webgui['base_ur'], temp_key))
         connection.privmsg(event.source.nick, 'Here is a temp 10 minute link for %s%s%s:%s %schannelsettings/%s' % (event.target, font.red, event.target, font.reset, self.webgui['base_ur'], temp_key))
         connection.privmsg(event.source.nick, 'Good bye. If you have any complaints, suggestions or want me back in %s%s%s contact an operator of: %s%s' % (font.red, event.target, font.reset, font.red, self.network.home_channel))
         connection.privmsg(event.source.nick, 'Good bye. If you have any complaints, suggestions or want me back in %s%s%s contact an operator of: %s%s' % (font.red, event.target, font.reset, font.red, self.network.home_channel))
+        return
+
+    if self.channel[event.target].has_user(event.arguments[0]): # User resides in homechannel.
+        if userstatus.is_owner(self, event.arguments[0], event.target) or queries.is_owner(self, hostmask) or event.arguments[0] == conntection.get_nickname():    # Owner or bot kicked.
+            log.info('Kicking %s from %s for kicking %s.' % (event.sourcenick, event.target, event.arguments[0]))
+            if reason:
+                do_everything_to.kick(connection, event.target, event.source.nick, 'Revenge: %s' % reason)
+            else:
+                do_everything_to.kick(connection, event.target, event.source.nick, 'Revenge')
+
+        # Mock home channel users in home channel.
+        kicks = queries.get_user_channel_kicks(self, kicked.id, channel.id)
+        if reason:
+            reson_fill = ' for %s%s%s'
+        else:
+            reason_fill = ''
+        message = language.add_adjective_a('mocks %s%s%s for getting kicked out of %s%s%s%s, which makes ' % (font.red, event.arguments[0], font.reset, font.red, event.target, font.reset, reason_fill), ' %s times.' % kicks)
+        connection.action(self.network.home_channel, message)
+
 
 
-    # # Update protectees if needed.
-    # if channel == self.homechannel: # Kicked from home channel
-    #     if event.source.nick in self.protectees:    # Protectee kicked.
-    #         del self.protectees[event.source.nick]  # Remove old nick from list.
-    #
-    # # Do nothing more when user is not protected.
-    # if not userstatus.atleast_halfop(self, kicked, self.homechannel) and not kicked == connection.get_nickname():
-    #     return
-    #
-    # # Report.
-    # if not channel == self.homechannel: # Not kicked from homechannel.
-    #     if reason:
-    #         connection.privmsg(self.homechannel, red + kicked + reset + " has been kicked from " + red + channel + reset + " by " + red + kicker + reset + ": " + green + reason)
-    #     else:
-    #         connection.privmsg(self.homechannel, red + kicked + reset + " has been kicked from " + red + channel + reset + " by " + red + kicker + reset + ".")
-    #
     # # React.
     # # React.
     # print("Reacting to kick")
     # print("Reacting to kick")
     # behaviour = self.db.one("SELECT aggressiveness FROM channels WHERE name='" + channel + "' AND network='" + self.network + "'")
     # behaviour = self.db.one("SELECT aggressiveness FROM channels WHERE name='" + channel + "' AND network='" + self.network + "'")

+ 0 - 6
rotbot/events/on_nick.py

@@ -10,10 +10,4 @@ def process_event(self, connection, event):
 
 
     # Keep preferred nick.
     # Keep preferred nick.
     if event.source.nick == connection.nickname:    # Preffered nick being changed.
     if event.source.nick == connection.nickname:    # Preffered nick being changed.
-        log.info("Assuming original nick.")
         NickServ.recover_nick(connection, self.password)
         NickServ.recover_nick(connection, self.password)
-
-    # # Update protectees.
-    # if event.source.nick in self.protectees:    # Protectee chaning nick.
-    #     del self.protectees[event.source.nick]  # Remove old nick from list.
-    #     connection.who(event.target)    # Get whorepy to add new nick to protectees.

+ 2 - 2
rotbot/events/on_nicknameinuse.py

@@ -1,7 +1,7 @@
 from common.networkservices import NickServ
 from common.networkservices import NickServ
 
 
 def process_event(self, connection, event):
 def process_event(self, connection, event):
-    log.info('Nickname %s in use, attempting to recover: %s' % (self.network.nickname, connection.nickname))    # Log to console.
+    log.info('Nickname %s in use: %s' % (self.network.nickname, connection.nickname))    # Log to console.
 
 
-    connection.nick(connection.nickname + ''.join(random.choice(string.digits) for _ in range(3)))    # Take temporary nick. In this state recovering via NickServ won't work without changing nickname.
+    connection.nick(connection.nickname + ''.join(random.choice(string.digits) for _ in range(3)))    # Take temporary nick.
     NickServ.recover_nick(connection, self.network.password)    # Recover nick.
     NickServ.recover_nick(connection, self.network.password)    # Recover nick.

+ 0 - 4
rotbot/events/on_part.py

@@ -6,7 +6,3 @@ def process_event(self, connection, event):
     # Get and update resources.
     # Get and update resources.
     channel = queries.create_or_get_and_update_last_event(self, 'channel', 'cp', channel_name=event.target, user_name=event.source.nick)
     channel = queries.create_or_get_and_update_last_event(self, 'channel', 'cp', channel_name=event.target, user_name=event.source.nick)
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cp', channel_name=event.target, user_name=event.source.nick)
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cp', channel_name=event.target, user_name=event.source.nick)
-
-#   # Update protectees.
-#   if event.target == self.homechannel and event.source.nick in self.protectees:    # Protectee parted home channel.
-#        del self.protectees[event.source.nick] # Delete from protectees.

+ 27 - 13
rotbot/events/on_privnotice.py

@@ -25,33 +25,47 @@ def process_event(self, connection, event):
     elif event.source.nick == "NickServ":   # Message from NickServ.
     elif event.source.nick == "NickServ":   # Message from NickServ.
         if event.arguments[0].startswith("This nickname is registered"):
         if event.arguments[0].startswith("This nickname is registered"):
             connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password)) # Identify with NickServ. Also doing it on_welcome, but if there is a netsplit or so and there is no welcome, but a need to login, this is needed.
             connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password)) # Identify with NickServ. Also doing it on_welcome, but if there is a netsplit or so and there is no welcome, but a need to login, this is needed.
-        if event.arguments[0].startswith("You are already identified."):
             return
             return
-
-            # Nick \x02RotBot\x02 isn't registered.
-        if event.arguments[0].endswith(' is not a registered nickname.') or event.arguments[0].startswith('Nick ') and event.arguments[0].endswith(' isn\'t registered.') or event.arguments[0] == 'Your nick isn\'t registered.': # Username from database is not registered.
-            connection.privmsg('NickServ', 'register %s spamtBK@xs4all.nl' % (self.network.password)) # Register with NickServ.
-            connection.privmsg(self.network.home_channel, 'Regisring %s%s%s with %sNickServ%s.' % (font.red, self.network.nickname, font.reset, font.red, font.reset))  # Recover control of nickname via NickServ, old style.
+        elif event.arguments[0].endswith(' is not a registered nickname.') or event.arguments[0].startswith('Nick ') and event.arguments[0].endswith(' isn\'t registered.') or event.arguments[0] == 'Your nick isn\'t registered.': # Username from database is not registered.
             log.info('Registerring 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)
-        if event.arguments[0].startswith('You must have been using this nick for at least 30 seconds to register.'):
+            Inform.operator('Regisring %s%s%s with %sNickServ%s.' % (font.red, self.network.nickname, font.reset, font.red, font.reset))
+            connection.privmsg('NickServ', 'register %s spamtBK@xs4all.nl' % (self.network.password)) # Register with NickServ.
+            return
+        elif event.arguments[0].startswith('Nickname ') and event.arguments[0].endswith(' registered.'):
+            Inform.home_channel(seld, connection, 'Registerred nickname %s%s%s with NickServ, adjusting settigns.' % font.red, self.network.nickname, font.reset)
+            connection.privmsg('NickServ', 'ACCESS LIST')
+            connection.privmsg('NickServ', 'AJOIN ADD %s' % (self.network.home_channel, queries.get_channel_key(self, self.network.home_channel)))
+            connection.privmsg('NickServ', 'SET AUTOOP ON')
+            connection.privmsg('NickServ', 'SET HIDE EMAIL ON')
+            connection.privmsg('NickServ', 'SET KILL QUICK')
+            connection.privmsg('NickServ', 'SET SECURE ON')
+            connection.privmsg('NickServ', 'SET URL %snetwork/%s' % (self.webgui['base_url'], self.network.slug))
+
+            return
+        elif event.arguments[0].startswith('You must have been using this nick for at least 30 seconds to register.'):
+            log.info('Waiting 31 seconds to register with NickServ.')
             asyncio.run(register_later(self.connection, 31))
             asyncio.run(register_later(self.connection, 31))
+            return
+        elif event.arguments[0].startswith("You are already identified."):
+            return
     elif event.source.nick == "ChanServ":
     elif event.source.nick == "ChanServ":
         if event.arguments[0].startswith("Key for channel ") and len(event.arguments[0]) > 5:   # Received channel key.
         if event.arguments[0].startswith("Key for channel ") and len(event.arguments[0]) > 5:   # Received channel key.
+            log.info('Saving channel password received from NickServ for: %s' % event.arguments[0].split(' ')[3])
             queries.save_channel_key(self, event.arguments[0].split(' ')[3], event.arguments[0].split(' ')[5][:-1])
             queries.save_channel_key(self, event.arguments[0].split(' ')[3], event.arguments[0].split(' ')[5][:-1])
             connection.join(event.arguments[0].split(' ')[3], event.arguments[0].split(' ')[5][:-1])
             connection.join(event.arguments[0].split(' ')[3], event.arguments[0].split(' ')[5][:-1])
             Inform.owners(self, connection, "Received " + red + event.arguments[0].split(" ")[3] + reset + " key: " + event.arguments.split(" ")[5][:-1])
             Inform.owners(self, connection, "Received " + red + event.arguments[0].split(" ")[3] + reset + " key: " + event.arguments.split(" ")[5][:-1])
-        if event.arguments[0] == "Password authentication required for that command.":  # Not authenticated with NisckServ.
-            Inform.notice_owners(self, connection, "Not authenticated with NickServ. See " + blue + self.helpchar + "recovernick " + reset + "and " + blue + self.helpchar + "registernick" + reset + ".")
+            returnZZ
+        elif event.arguments[0] == "Password authentication required for that command.":  # Not authenticated with NisckServ.
+            connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password))
+            Inform.notice_owners(self, connection, "Not authenticated with NickServ.")
             return
             return
-        if event.arguments[0].startswith("You have been unbanned from ") or event.arguments[0].endswith(" autokick list is empty.") or event.arguments[0].startswith("You are already in ") or event.arguments[0] == "Syntax: UNBAN channel [nick]" or event.arguments[0] == "/msg ChanServ HELP UNBAN for more information":
+        elif event.arguments[0].startswith("You have been unbanned from ") or event.arguments[0].endswith(" autokick list is empty.") or event.arguments[0].startswith("You are already in ") or event.arguments[0] == "Syntax: UNBAN channel [nick]" or event.arguments[0] == "/msg ChanServ HELP UNBAN for more information":
             return
             return
         # if event.arguments[0].startswith("Channel ") and event.arguments[0].endswith(" has no key."):
         # if event.arguments[0].startswith("Channel ") and event.arguments[0].endswith(" has no key."):
         #     return
         #     return
     if event.source.nick != "Global":
     if event.source.nick != "Global":
         Inform.notice_owners(self, connection, 'Notice from %s %s %s %s: %s %s' % (font.red, font.red, event.source.nick, font.grey, font.reset, event.arguments[0]))
         Inform.notice_owners(self, connection, 'Notice from %s %s %s %s: %s %s' % (font.red, font.red, event.source.nick, font.grey, font.reset, event.arguments[0]))
 
 
-async def say_after(connection, seconds):
+async def register_later(connection, seconds):
     await asyncio.sleep(seconds)
     await asyncio.sleep(seconds)
     connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password))
     connection.privmsg('NickServ', 'identify %s %s' % (self.network.nickname, self.network.password))

+ 24 - 22
rotbot/events/on_pubmsg.py

@@ -8,7 +8,6 @@ def process_event(self, connection, event):
     # Get and update resources.
     # Get and update resources.
     channel = queries.create_or_get_and_update_last_event(self, 'channel', 'cm', channel_name=event.target, user_name=event.source.nick)
     channel = queries.create_or_get_and_update_last_event(self, 'channel', 'cm', channel_name=event.target, user_name=event.source.nick)
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cm', channel_name=event.target, user_name=event.source.nick)
     user = queries.create_or_get_and_update_last_event(self, 'user', 'cm', channel_name=event.target, user_name=event.source.nick)
-
     queries.update_message_statistics(self, 'message', channel.id, user.id)   # Update message statistics
     queries.update_message_statistics(self, 'message', channel.id, user.id)   # Update message statistics
 
 
     commands.public.do_command(self, connection, event, user, channel)
     commands.public.do_command(self, connection, event, user, channel)
@@ -16,28 +15,31 @@ def process_event(self, connection, event):
     commands.statistics.do_command(self, connection, event, user, channel)
     commands.statistics.do_command(self, connection, event, user, channel)
     commands.games.do_command(self, connection, event, user, channel)
     commands.games.do_command(self, connection, event, user, channel)
 
 
-    # # Stop if channelfunction chat if off.
-    # if not self.db.one("SELECT chat FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'"):
-    #     return
-    #
+    # Stop if channelfunction chat if off.
+    if not queries.get_channel_setting_chat(self, channel.id):
+        return
+
     # if connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned
     # if connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned
     #     if event.arguments[0].startswith(self.cmdchar):
     #     if event.arguments[0].startswith(self.cmdchar):
     #         return  # Stop if it's a command.
     #         return  # Stop if it's a command.
     #     Replyto.name(connection, event)
     #     Replyto.name(connection, event)
-    #
-    # # Character lame.
-    # elif event.arguments[0] == len(event.arguments[0]) * event.arguments[0][0]:   # Trigger exclusively same character.
-    #
-    #     # Do not say KKK.
-    #     if event.arguments[0] == "kk":
-    #         return
-    #
-    #     # Stop if lamed recently.
-    #     lastlame = self.db.one("SELECT last_lame FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
-    #     if lastlame and lastlame > datetime.datetime.now() - datetime.timedelta(minutes=2):    # In the last 2 minutes.
-    #         return
-    #
-    #     # Update lastlame.
-    #     self.db.run("UPDATE channels SET last_lame='" + str(datetime.datetime.now()) + "' WHERE name='" + event.target + "' AND network='" + self.network + "'")
-    #
-    #     connection.privmsg(event.target, event.arguments[0] + event.arguments[0][:1])
+
+    # Character lame.
+    elif event.arguments[0] == len(event.arguments[0]) * event.arguments[0][0]:   # Trigger exclusively same character.
+
+        # Stop if lamed recently.
+        timeout = 10    # Timeout in minutes.
+        chan_lastlame = queries.get_channel_last_lame(self, channel.id)
+        user_lastlame = queries.get_user_last_lame(self, user.id)
+        if chan_lastlame and chan_lastlame > datetime.datetime.now() - datetime.timedelta(minutes=timeout) or user_lastlame and user_lastlame > datetime.datetime.now() - datetime.timedelta(minutes=timeout):  # Lamed channel or user recently.
+            return
+
+        # Do not say KKK.
+        if event.arguments[0] == "kk":
+            return
+
+        connection.privmsg(event.target, event.arguments[0] + event.arguments[0][:1])
+
+        # Update lastlame.
+        queries.update_channel_last_lame(self, channel_id)
+        queries.update_user_last_lame(self, user_id)

+ 4 - 1
rotbot/events/on_welcome.py

@@ -1,7 +1,7 @@
 from common import log, do_everything_to, queries
 from common import log, do_everything_to, queries
 
 
 def process_event(self, connection, event):
 def process_event(self, connection, event):
-    log.info(event)    # Handy for debugging. Keep this.
+    log.info(event)    # Log event.
     self.db.run("UPDATE rotbot_host SET connection_succeeds = connection_succeeds + 1 WHERE id=%s", [self.network.id])
     self.db.run("UPDATE rotbot_host SET connection_succeeds = connection_succeeds + 1 WHERE id=%s", [self.network.id])
 
 
     # Identify with NickServ.
     # Identify with NickServ.
@@ -14,5 +14,8 @@ def process_event(self, connection, event):
 
 
     # Join channels with the autojoin setting.
     # Join channels with the autojoin setting.
     channels = queries.get_autojoin_channels(self)  # Get channels with autojoin setting.
     channels = queries.get_autojoin_channels(self)  # Get channels with autojoin setting.
+    log.info('Joining autojoin channels: %s' % channels)
     for channel in channels:
     for channel in channels:
         connection.join(channel)    # Join channels with autojoin function.
         connection.join(channel)    # Join channels with autojoin function.
+
+    connection.privmsg('NickServ', 'ACCESS LIST')   # Request access list from NickServ.

+ 3 - 1
rotbot/events/on_whoreply.py

@@ -1,3 +1,5 @@
+from common import log
+
 def process_event(self, connection, event):
 def process_event(self, connection, event):
+    log.info(event)
     #Protectees.update(self,  event.arguments[4], event.arguments[1], event.arguments[2])
     #Protectees.update(self,  event.arguments[4], event.arguments[1], event.arguments[2])
-    pass

+ 2 - 2
website/rotbot/forms.py

@@ -49,11 +49,11 @@ class OwnerForm(ModelForm):
         model=Owner
         model=Owner
         fields='__all__'
         fields='__all__'
         labels={
         labels={
-            'source': '<i class="fingerprint icon"></i>Owner host',
+            'hostmask': '<i class="fingerprint icon"></i>Owner hostmask',
         }
         }
         layout = [
         layout = [
             ('Two Fields',
             ('Two Fields',
-                ('Field', 'source'),
+                ('Field', 'hostmask'),
                 ('Field', 'DELETE'),
                 ('Field', 'DELETE'),
             )
             )
         ]
         ]

+ 63 - 0
website/rotbot/migrations/0005_auto_20191121_0048.py

@@ -0,0 +1,63 @@
+# Generated by Django 2.2.6 on 2019-11-20 23:48
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('rotbot', '0004_auto_20191119_0418'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='owner',
+            old_name='source',
+            new_name='hostmask',
+        ),
+        migrations.AddField(
+            model_name='channel',
+            name='last_changesetting_datetime',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='channel',
+            name='last_changesetting_ircuser',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='channel',
+            name='last_changesetting_webuser',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='channel',
+            name='last_greet',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='channel',
+            name='last_lame',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='last_greet',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='last_lame',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+        migrations.AlterField(
+            model_name='curseadjective',
+            name='word',
+            field=models.CharField(max_length=16, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='curseword',
+            name='word',
+            field=models.CharField(max_length=16, unique=True),
+        ),
+    ]

+ 19 - 4
website/rotbot/models.py

@@ -7,7 +7,7 @@ class Owner(models.Model):
         'Network',
         'Network',
         on_delete=models.CASCADE,
         on_delete=models.CASCADE,
     )
     )
-    source = models.CharField(
+    hostmask = models.CharField(
         max_length=50,
         max_length=50,
         unique=True,
         unique=True,
     )
     )
@@ -209,6 +209,14 @@ class Channel(models.Model):
         null=True,
         null=True,
         blank=True,
         blank=True,
     )
     )
+    last_greet = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
+    last_lame = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
 
 
 
 
     class Meta:
     class Meta:
@@ -313,7 +321,14 @@ class User(models.Model):
     no_chat = models.BooleanField(
     no_chat = models.BooleanField(
         default=False,
         default=False,
     )
     )
-
+    last_greet = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
+    last_lame = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
 
 
     class Meta:
     class Meta:
         unique_together = ['network', 'name']
         unique_together = ['network', 'name']
@@ -426,7 +441,7 @@ class Kick(models.Model):
 
 
 class CurseWord(models.Model):
 class CurseWord(models.Model):
     word = models.CharField(
     word = models.CharField(
-        max_length=15,
+        max_length=16,
         unique=True,
         unique=True,
     )
     )
     created = models.DateField(
     created = models.DateField(
@@ -453,7 +468,7 @@ class CurseWord(models.Model):
 
 
 class CurseAdjective(models.Model):
 class CurseAdjective(models.Model):
     word = models.CharField(
     word = models.CharField(
-        max_length=15,
+        max_length=16,
         unique=True,
         unique=True,
     )
     )
     created = models.DateField(
     created = models.DateField(

+ 1 - 0
website/rotbot/templates/rotbot/add_curseword.html

@@ -1,6 +1,7 @@
 {% extends "base.html" %}
 {% extends "base.html" %}
 {% load semanticui %}
 {% load semanticui %}
 {% block content %}
 {% block content %}
+  {{ description }}
   <form class= "ui form" method="post" action="{% url 'rotbot:add_curseword' %}">
   <form class= "ui form" method="post" action="{% url 'rotbot:add_curseword' %}">
     {% csrf_token %}
     {% csrf_token %}
     <div class="ui horizontal basic segments">
     <div class="ui horizontal basic segments">

+ 2 - 2
website/rotbot/templates/rotbot/index.html

@@ -84,7 +84,7 @@
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
-  {% if perms.rotbot.add_curseword %}
+  {#% if perms.rotbot.add_curseword %#}
     <a href="{% url 'rotbot:add_curseword' %}" class="ui inverted right floated button"><i class="book dead icon"></i>Add curseword</a>
     <a href="{% url 'rotbot:add_curseword' %}" class="ui inverted right floated button"><i class="book dead icon"></i>Add curseword</a>
-  {% endif %}
+  {#% endif %#}
 {% endblock %}
 {% endblock %}