Răsfoiți Sursa

rotbot refactoring

tBKwtWS 6 ani în urmă
părinte
comite
96f4ceaeb6

+ 3 - 2
rotbot/bot.py

@@ -93,7 +93,8 @@ class PyRot(irc.bot.SingleServerIRCBot):
         events.on_privnotice.process_event(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):
         events.on_keyset.process_event(self, connection, event)
@@ -141,7 +142,7 @@ def main():
 
     ### SETTINGS
     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': '',
     }
 

+ 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])
                 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.
             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":
                     connection.action(destination, message)
                 else:

+ 12 - 8
rotbot/commands/common.py

@@ -125,8 +125,10 @@ class GameHelpers():
         total_messages = queries.get_user_total_messages(self, user.id)
         total_actions = queries.get_user_total_actions(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)
         xp_spent = gamestats[0]
         level = gamestats[1]
@@ -153,14 +155,16 @@ class GameHelpers():
         # Karma.
         if total_xp == 0:
             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))
-        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))
-        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))
-        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))
+        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
         print('wealth_karma:' + str(wealth_karma) + ' = (coin:' + str(coin) + ' * 50) / total_xp:' + str(total_xp))
         charity_karma = (coin_given * 10.1) / total_xp
@@ -173,8 +177,8 @@ class GameHelpers():
                 elite_karma_bonus += 1
                 print(elite_karma_bonus)
             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
 

+ 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.
     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.
 
     if command == 'cmd' or command == 'cmds' or command == 'commands':
@@ -88,7 +88,7 @@ def do_command(self, connection, event, user, channel):
                 return
 
             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)
 
             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))
             else:   # Argument does not match a channel.
                 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.
                     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"
 italic = "\x1D"
 reverse = "\x16" 	# swap background and foreground colors ("reverse video")
-
 blue = "\x0302"
 green = "\x0303"
 red = "\x0304"
 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():
     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', '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.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():
-    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":
             modename = "OWNER"
         if mode[1] == "a":
@@ -41,11 +52,13 @@ class ChanServ():
             modename = "HALFOP"
         if mode[1] == "v":
             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
 
 
-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
 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):
     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)
 
+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):
     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):
     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)
@@ -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)
     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)
     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)
     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
 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)
 
+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):
     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)
 
 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)
 
 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)
     payday(self, coin)
 
-# Common.
 
+# Common.
 def total_amount_in_recordset(recordset):
     amount = 0
     for record in recordset:

+ 4 - 21
rotbot/events/common.py

@@ -4,16 +4,19 @@ from common import queries, userstatus, log
 
 class Inform():
     def owners(self, connection, message):
+        log.info('Informing owners: %s' % message)
         if self.network.home_channel in self.channels:
             for owner in self.channels[self.network.home_channel].owners():
                 connection.privmsg(owner, message)
 
     def notice_owners(self, connection, message):
+        log.info('Notifying owners: %s' % message)
         if self.network.home_channel in self.channels:
             for owner in self.channels[self.network.home_channel].owners():
                 connection.notice(owner, message)
 
     def operators(self, connection, message):
+        log.info('Informing operators: %s' % message)
         if self.homechannel in self.channels:
             for user in self.channels[self.homechannel].owners():
                 connection.privmsg(user, message)
@@ -23,6 +26,7 @@ class Inform():
                 connection.privmsg(user, message)
 
     def home_channel(self, connection, message):
+        log.info('Informing home channel: %s' % message)
         connection.privmsg(self.network.home_channel, message)
 
 # class Protectees():
@@ -96,24 +100,3 @@ class Inform():
 #         else:
 #             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
 
 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.
-    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.
         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.
     # 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)

+ 2 - 2
rotbot/events/on_error.py

@@ -5,5 +5,5 @@ def process_event(self, connection, event):
     log.notice(str(event))  # Log to console.
 
     # 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.
         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.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
 
 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)
     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.
-        # 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 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.
-        # 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):
     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)

+ 22 - 18
rotbot/events/on_kick.py

@@ -1,5 +1,5 @@
 #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
 
 def process_event(self, connection, event):
@@ -14,29 +14,33 @@ def process_event(self, connection, event):
     # Record kick event in database.
     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.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)
         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))
+        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.
     # print("Reacting to kick")
     # 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.
     if event.source.nick == connection.nickname:    # Preffered nick being changed.
-        log.info("Assuming original nick.")
         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
 
 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.

+ 0 - 4
rotbot/events/on_part.py

@@ -6,7 +6,3 @@ def process_event(self, connection, event):
     # 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)
     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.
         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.
-        if event.arguments[0].startswith("You are already identified."):
             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.')
-        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))
+            return
+        elif event.arguments[0].startswith("You are already identified."):
+            return
     elif event.source.nick == "ChanServ":
         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])
             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])
-        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
-        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
         # if event.arguments[0].startswith("Channel ") and event.arguments[0].endswith(" has no key."):
         #     return
     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]))
 
-async def say_after(connection, seconds):
+async def register_later(connection, seconds):
     await asyncio.sleep(seconds)
     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.
     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)
-
     queries.update_message_statistics(self, 'message', channel.id, user.id)   # Update message statistics
 
     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.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 event.arguments[0].startswith(self.cmdchar):
     #         return  # Stop if it's a command.
     #     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
 
 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])
 
     # Identify with NickServ.
@@ -14,5 +14,8 @@ def process_event(self, connection, event):
 
     # Join channels with the autojoin setting.
     channels = queries.get_autojoin_channels(self)  # Get channels with autojoin setting.
+    log.info('Joining autojoin channels: %s' % channels)
     for channel in channels:
         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):
+    log.info(event)
     #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
         fields='__all__'
         labels={
-            'source': '<i class="fingerprint icon"></i>Owner host',
+            'hostmask': '<i class="fingerprint icon"></i>Owner hostmask',
         }
         layout = [
             ('Two Fields',
-                ('Field', 'source'),
+                ('Field', 'hostmask'),
                 ('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',
         on_delete=models.CASCADE,
     )
-    source = models.CharField(
+    hostmask = models.CharField(
         max_length=50,
         unique=True,
     )
@@ -209,6 +209,14 @@ class Channel(models.Model):
         null=True,
         blank=True,
     )
+    last_greet = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
+    last_lame = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
 
 
     class Meta:
@@ -313,7 +321,14 @@ class User(models.Model):
     no_chat = models.BooleanField(
         default=False,
     )
-
+    last_greet = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
+    last_lame = models.DateTimeField(
+        null=True,
+        blank=True,
+    )
 
     class Meta:
         unique_together = ['network', 'name']
@@ -426,7 +441,7 @@ class Kick(models.Model):
 
 class CurseWord(models.Model):
     word = models.CharField(
-        max_length=15,
+        max_length=16,
         unique=True,
     )
     created = models.DateField(
@@ -453,7 +468,7 @@ class CurseWord(models.Model):
 
 class CurseAdjective(models.Model):
     word = models.CharField(
-        max_length=15,
+        max_length=16,
         unique=True,
     )
     created = models.DateField(

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

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

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

@@ -84,7 +84,7 @@
       </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>
-  {% endif %}
+  {#% endif %#}
 {% endblock %}