<commit_before>'use strict';

const util = require('util');
const path = require('path');
const fs = require('fs');
const SQLite = require('sqlite3').verbose();
const Bot = require('botkit');
const linker = require('./linking/linker');
const Help = require('./help');

var SRBot = function Constructor(settings) {
    this.controller = Bot.slackbot({
        debug: false,
        storage: undefined
    });

    this.settings = settings;
    this.settings.debug = settings.debug || false;
    this.settings.name = settings.name || 'srbot';

    this.settings.config = JSON.parse(fs.readFileSync(
        path.resolve(process.cwd(), 'config.json'),
        'utf8')
    );

    this.settings.token = this.settings.token || this.settings.config.keys.slack;

    this.dbPath = settings.dbPath || path.resolve(process.cwd(), 'data', 'srdata.db');

    this.user = null;
    this.db = null;

};

//util.inherits(SRBot, Bot.slackbot);

module.exports = SRBot;

SRBot.prototype.run = function () {
    this.controller.spawn({
        token: this.settings.token
    }).startRTM();

    var self = this;

    // on start
    this.controller.on('rtm_open', function (bot, message) {
        self.connectDb();
        self.firstRunCheck(bot, message);
        console.log('SRBot has started.');
    });

    this.controller.on(['message_received', 'direct_mention', 'direct_message', 'mention', 'ambient'], function (bot, message) {

        // just try all the things srbot can do for each message, and if it
        // works, that's great.

        if (message.text) {

            console.log('Received a message in scope, with body:\n  ' + message.text);

            var help = new Help(self.settings.config.help);
            help.getResponse(message.text, function (result) {
                if (result) {
                    bot.reply(message, result);
                }
            });

            linker.getResponse(message.text, function (result) {
                if (result) {
                    bot.reply(message, result);
                }
            });
        }
    });
};

SRBot.prototype.connectDb = function () {
    if (!fs.existsSync(this.dbPath)) {
                process.exit(1);
    }
    this.db = new SQLite.Database(this.dbPath);
    console.log('Opened databse connection.');
};

SRBot.prototype.firstRunCheck = function (bot, message) {
    var self = this;
    self.db.get('SELECT value FROM info WHERE name = "lastrun" LIMIT 1', function (err, record) {
        if (err) {
            return
        }

        var currentTime = (new Date()).toJSON();

        if (!record) {
            // no record found, so must be first run
            console.log('Running srbot for the first time. Saving meta-information.');
            console.log('Replying to slack with welcome message.');
            bot.reply(message, this.settings.config.firstRunMessage);
            return self.db.run('INSERT INTO info(name, value) VALUES("lastrun", ?)', currentTime);
        }

        // update new last run time
        console.log('srbot has run before. Updating meta-information.');
        self.db.run('UPDATE info SET value = ? WHERE name = "lastrun"', currentTime);
    });
};
<commit_msg>tie in all previous changes<commit_after>'use strict';

const util = require('util');
const path = require('path');
const fs = require('fs.extra');
const SQLite = require('sqlite3').verbose();
const Bot = require('botkit');
const winston = require('winston');

const linker = require('./linking/linker');
const Train = require('./nlp/train');
const Brain = require('./nlp/brain');

var SRBot = function Constructor(settings) {
    this.controller = Bot.slackbot({
        debug: false,
        storage: undefined
    });

    this.settings = settings;
    this.settings.debug = settings.debug || false;
    this.settings.name = settings.name || 'srbot';

    this.settings.config = JSON.parse(fs.readFileSync(
        path.resolve(process.cwd(), 'config.json'),
        'utf8')
    );

    this.settings.token = this.settings.token || this.settings.config.keys.slack;

    this.dbPath = settings.dbPath || path.resolve(process.cwd(), 'data', 'srdata.db');

    this.brain = new Brain();
    this.teach = null;

    this.user = null;
    this.db = null;

};

//util.inherits(SRBot, Bot.slackbot);

module.exports = SRBot;

SRBot.prototype.run = function () {
    this.controller.spawn({
        token: this.settings.token
    }).startRTM();

    var self = this;

    // on start
    this.controller.on('rtm_open', function (bot, message) {
        self.connectDb();
        self.firstRunCheck(bot, message);
        winston.log('info', 'Setting up the natural language parsing.');
        self.setUpNlp();
        winston.log('info', 'srbot has started.');
    });

    this.controller.on(['message_received', 'direct_mention', 'direct_message', 'mention', 'ambient'], function (bot, message) {
        if (message.text) {
            linker.getResponse(message.text, function (result) {
                if (result) {
                    winston.log('info', 'The linker received a message.');
                    bot.reply(message, result);
                }
            });
        }
    });

    this.controller.on(['message_received', 'direct_mention', 'direct_message', 'mention'], function (bot, message) {
        if (message.text) {
            if (message.text.toLowerCase() === 'start training') {
                winston.log('info', 'Training started.');
                Train(self.brain, bot, message);
            } else {
                try {
                    var interpretation = self.brain.interpret(message.text);
                    winston.log('info', 'srbot heard: ' + message.text);
                    winston.log('info', 'srbot interpreted it as: ' + interpretation.guess);
                    if (interpretation.guess) {
                        winston.log('info', 'Invoking skill: ' + interpretation.guess);
                        self.brain.invoke(interpretation.guess, interpretation, bot, message);
                    } else {
                        //bot.reply(message, 'Not sure what you said there.');
                        winston.log('info', 'srbot could not interpret the message: ' + message.text);
                    }
                } catch (err) {
                    winston.log('error', err);
                }
            }
        }
    });
};

SRBot.prototype.connectDb = function () {
    if (!fs.existsSync(this.dbPath)) {
        winston.log('alert', 'The database does not exist.');
        process.exit(1);
    }
    this.db = new SQLite.Database(this.dbPath);
    winston.log('info', 'Opened databse connection.');
};

SRBot.prototype.firstRunCheck = function (bot, message) {
    var self = this;
    self.db.get('SELECT value FROM info WHERE name = "lastrun" LIMIT 1', function (err, record) {
        if (err) {
            return
        }

        var currentTime = (new Date()).toJSON();

        if (!record) {
            // no record found, so must be first run
            winston.log('info', 'Running srbot for the first time. Saving meta-information.');
            winston.log('info', 'Replying to slack with welcome message.');
            bot.reply(message, this.settings.config.firstRunMessage);
            return self.db.run('INSERT INTO info(name, value) VALUES("lastrun", ?)', currentTime);
        }

        // update new last run time
        winston.log('info', 'srbot has run before. Updating meta-information.');
        self.db.run('UPDATE info SET value = ? WHERE name = "lastrun"', currentTime);
    });
};

SRBot.prototype.setUpNlp = function () {
    var customPhrasesText;
    var customPhrases;
    try {
        customPhrasesText = fs.readFileSync(path.resolve(process.cwd(), 'customphrase.json')).toString();
    } catch (err) {
        throw new Error('Could not find the customphrase json file.');
    }
    try {
        customPhrases = JSON.parse(customPhrasesText);
    } catch (err) {
        throw new Error('customphrase.json was not valid json. This needs fixing.');
    }

    winston.log('info', 'Teaching custom phrases.');
    this.teach = this.brain.teach.bind(this.brain);
    eachKey(customPhrases, this.teach);
    this.brain.think();
};

var eachKey = function (object, callback) {
    Object.keys(object).forEach(function (key) {
        callback(key, object[key]);
    });
};

{'fraction_non_alphanumeric': 0.1449154560609669, 'fraction_numerical': 0.0009526077637532746, 'mean_word_length': 2.291144200626959, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1141570', 'n_tokens_mistral': 2476, 'n_tokens_neox': 2392, 'n_words': 572}