<commit_before># Copyright (c) 2013-2014 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from getpass import getpass
import logging
import re
import sqlite3


class Configurator(object):
    """Handles the configuration settings in the database."""

    def __init__(self, db_conn):
        self.db_conn = db_conn
        self.logger = logging.getLogger("GorillaBot")

    def configure(self):
        """Provide the user with prompts to interact with the configuration of the bot."""
        ans = ''
        while ans not in ["0", "1", "2", "3", "4"]:
            data = self.get_settings()
            if data is not None and len(data) > 0:
                print("Existing configurations:")
                for row in data:
                    print('\t' + row[0])
                print("\n[0] Load configuration\n[1] Create new configuration\n[2] View "
                      "configuration\n[3] Remove configuration\n[4] Exit")
                ans = input("")
                if ans == "0":
                    return self.load_settings()
                elif ans == "1":
                    return self.create_new()
                elif ans == "2":
                    self.view()
                elif ans == "3":
                    self.delete()
                elif ans == "4":
                    return False
                ans = ''
            else:
                ans = ''
                while ans not in ["0", "1"]:
                    print("\n[0] Create new configuration\n[1] Exit")
                    ans = input("")
                    if ans == "0":
                        return self.create_new()
                    elif ans == "1":
                        return False

    def get_settings(self):
        """Retrieve existing configurations, or create the table if it does not exist."""
        cursor = self.db_conn.cursor()
        try:
            cursor.execute('''SELECT name FROM settings''')
        except sqlite3.OperationalError as e:
            # No settings table exists in the DB, so create one
            cursor.execute('''CREATE TABLE settings
                              (name TEXT NOT NULL PRIMARY KEY,
                               host TEXT NOT NULL,
                               port INTEGER NOT NULL,
                               nick TEXT NOT NULL,
                               realname TEXT NOT NULL,
                               ident TEXT NOT NULL,
                               password TEXT,
                               wait BOOLEAN NOT NULL CHECK(wait IN(0,1)))''')
            self.db_conn.commit()
            cursor.close()
            data = None
        else:
            data = cursor.fetchall()
            cursor.close()
        finally:
            # Create channels, users, and users_to_channels tables
            cursor = self.db_conn.cursor()
            cursor.execute('''CREATE TABLE IF NOT EXISTS channels
                              (chan_id INTEGER PRIMARY KEY,
                               name TEXT NOT NULL UNIQUE,
                               joined BOOLEAN NOT NULL CHECK(joined IN(0,1)),
                               setting TEXT,
                               FOREIGN KEY(setting) REFERENCES settings(name) ON DELETE CASCADE)
                               ''')
            cursor.execute('''CREATE TABLE IF NOT EXISTS users
                              (user_id INTEGER PRIMARY KEY,
                               nick TEXT NOT NULL UNIQUE,
                               user TEXT,
                               host TEXT,
                               botop BOOLEAN NOT NULL CHECK(botop IN(0,1)))''')
            cursor.execute('''CREATE TEMP TABLE users_to_channels
                              (user_id INTEGER,
                               chan_id INTEGER,
                               FOREIGN KEY(user_id) REFERENCES users(user_id) ON DELETE CASCADE,
                               FOREIGN KEY(chan_id) REFERENCES channels(chan_id) ON DELETE CASCADE)
                               ''')
            self.db_conn.commit()
            cursor.close()
        return data

    def create_new(self):
        """Create a new configuration."""
        verify = ''
        while verify != 'y':
            print('\n')
            name = ""
            while name == "":
                name = input("Unique name for this configuration: ")
            host = self.prompt("Host", "chat.freenode.net")
            port = self.prompt("Port", 6667)
            nick = self.prompt("Nick", "GorillaBot")
            realname = self.prompt("Ident", "GorillaBot")
            ident = self.prompt("Realname", "GorillaBot")
            chans = self.prompt("Chans")
            botop = self.prompt("Bot operator(s)", '')
            password = self.prompt("Server password", hidden=True)
            wait = ""
            while wait != 'y' and wait != 'n':
                wait = self.prompt("Wait to join before entering channels? [y/n]", 'n')
                wait.lower()
            wait = 0 if wait == 'n' else 1
            chans = re.split(',? ', chans)
            botop = re.split(',? ', botop)
            self.display((name, host, port, nick, realname, ident, password, wait), chans, botop)
            verify = input('Is this configuration correct? [y/n]: ').lower()
        self.save_config((name, host, port, nick, realname, ident, chans, botop, password, wait))
        return name

    def load_settings(self):
        """Show a given configuration, and allow the user to modify it if needed."""
        while True:
            name, data, channels, botops = self.view()
            cursor = self.db_conn.cursor()
            cursor.execute('''DROP TABLE IF EXISTS users''')
            self.db_conn.commit()
            cursor.close()
            self.verify(data, channels, botops)
            return name

    def view(self):
        """Open a configuration for viewing."""
        while True:
            configuration = input("Please choose an existing configuration: ")
            cursor = self.db_conn.cursor()
            cursor.execute("SELECT * FROM settings WHERE name = ?",
                                (configuration,))
            data = cursor.fetchone()
            cursor.close()
            if data is not None:
                cursor = self.db_conn.cursor()<commit_msg>Fix bug where bot operator wasn't being persisted<commit_after># Copyright (c) 2013-2014 <NAME>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from getpass import getpass
import logging
import re
import sqlite3


class Configurator(object):
    """Handles the configuration settings in the database."""

    def __init__(self, db_conn):
        self.db_conn = db_conn
        self.logger = logging.getLogger("GorillaBot")

    def configure(self):
        """Provide the user with prompts to interact with the configuration of the bot."""
        ans = ''
        while ans not in ["0", "1", "2", "3", "4"]:
            data = self.get_settings()
            if data is not None and len(data) > 0:
                print("Existing configurations:")
                for row in data:
                    print('\t' + row[0])
                print("\n[0] Load configuration\n[1] Create new configuration\n[2] View "
                      "configuration\n[3] Remove configuration\n[4] Exit")
                ans = input("")
                if ans == "0":
                    return self.load_settings()
                elif ans == "1":
                    return self.create_new()
                elif ans == "2":
                    self.view()
                elif ans == "3":
                    self.delete()
                elif ans == "4":
                    return False
                ans = ''
            else:
                ans = ''
                while ans not in ["0", "1"]:
                    print("\n[0] Create new configuration\n[1] Exit")
                    ans = input("")
                    if ans == "0":
                        return self.create_new()
                    elif ans == "1":
                        return False

    def get_settings(self):
        """Retrieve existing configurations, or create the table if it does not exist."""
        cursor = self.db_conn.cursor()
        try:
            cursor.execute('''SELECT name FROM settings''')
        except sqlite3.OperationalError as e:
            # No settings table exists in the DB, so create one
            cursor.execute('''CREATE TABLE settings
                              (name TEXT NOT NULL PRIMARY KEY,
                               host TEXT NOT NULL,
                               port INTEGER NOT NULL,
                               nick TEXT NOT NULL,
                               realname TEXT NOT NULL,
                               ident TEXT NOT NULL,
                               password TEXT,
                               wait BOOLEAN NOT NULL CHECK(wait IN(0,1)))''')
            self.db_conn.commit()
            cursor.close()
            data = None
        else:
            data = cursor.fetchall()
            cursor.close()
        finally:
            # Create channels, users, and users_to_channels tables
            cursor = self.db_conn.cursor()
            cursor.execute('''CREATE TABLE IF NOT EXISTS channels
                              (chan_id INTEGER PRIMARY KEY,
                               name TEXT NOT NULL UNIQUE,
                               joined BOOLEAN NOT NULL CHECK(joined IN(0,1)),
                               setting TEXT,
                               FOREIGN KEY(setting) REFERENCES settings(name) ON DELETE CASCADE)
                               ''')
            cursor.execute('''CREATE TABLE IF NOT EXISTS users
                              (user_id INTEGER PRIMARY KEY,
                               nick TEXT NOT NULL UNIQUE,
                               user TEXT,
                               host TEXT,
                               botop BOOLEAN NOT NULL CHECK(botop IN(0,1)))''')
            cursor.execute('''CREATE TEMP TABLE users_to_channels
                              (user_id INTEGER,
                               chan_id INTEGER,
                               FOREIGN KEY(user_id) REFERENCES users(user_id) ON DELETE CASCADE,
                               FOREIGN KEY(chan_id) REFERENCES channels(chan_id) ON DELETE CASCADE)
                               ''')
            self.db_conn.commit()
            cursor.close()
        return data

    def create_new(self):
        """Create a new configuration."""
        verify = ''
        while verify != 'y':
            print('\n')
            name = ""
            while name == "":
                name = input("Unique name for this configuration: ")
            host = self.prompt("Host", "chat.freenode.net")
            port = self.prompt("Port", 6667)
            nick = self.prompt("Nick", "GorillaBot")
            realname = self.prompt("Ident", "GorillaBot")
            ident = self.prompt("Realname", "GorillaBot")
            chans = self.prompt("Chans")
            botop = self.prompt("Bot operator(s)", '')
            password = self.prompt("Server password", hidden=True)
            wait = ""
            while wait != 'y' and wait != 'n':
                wait = self.prompt("Wait to join before entering channels? [y/n]", 'n')
                wait.lower()
            wait = 0 if wait == 'n' else 1
            chans = re.split(',? ', chans)
            botop = re.split(',? ', botop)
            self.display((name, host, port, nick, realname, ident, password, wait), chans, botop)
            verify = input('Is this configuration correct? [y/n]: ').lower()
        self.save_config((name, host, port, nick, realname, ident, chans, botop, password, wait))
        return name

    def load_settings(self):
        """Show a given configuration, and allow the user to modify it if needed."""
        while True:
            name, data, channels, botops = self.view()
            cursor = self.db_conn.cursor()
            cursor.execute('''DROP TABLE IF EXISTS users''')
            self.db_conn.commit()
            cursor.close()
            cursor = self.db_conn.cursor()
            cursor.execute('''CREATE TABLE users
                              (user_id INTEGER PRIMARY KEY,
                               nick TEXT NOT NULL UNIQUE,
                               user TEXT,
                               host TEXT,
                               botop BOOLEAN NOT NULL CHECK(botop IN(0,1)))''')
            if botops != ['']:
                for op in botops:
                    cursor.execute('''INSERT INTO users VALUES (NULL, ?, NULL, NULL, 1)''', (op,))
            self.db_conn.commit()
            cursor.close()
            self.verify(data, channels, botops)
            return name

    def view(self):
        """Open a configuration for viewing."""
        while True:
            configuration = input("Please choose an existing configuration: ")
            cursor = self.db_conn.cursor()
            cursor.execute("SELECT * FROM settings WHERE name = ?",
                                (configuration,))
            data = cursor.fetchone()
            cursor.close()
            if data is not None:
                cursor = self.db_conn.cursor()
{'fraction_non_alphanumeric': 0.09301564443280749, 'fraction_numerical': 0.006087582640570793, 'mean_word_length': 1.5045901639344261, 'pattern_counts': {'":': 16, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4839229', 'n_tokens_mistral': 3819, 'n_tokens_neox': 3613, 'n_words': 1327}