예제 #1
0
def launch(markov_instance, parent_location, stats_instance):
    global markov, derpy_stats, run_failure

    common.console_print("Discord Client version " + version, console_prefix)
    config.load(parent_location)
    markov = markov_instance
    derpy_stats = stats_instance
    discord_commands.pass_data(
        markov, config,
        stats_instance)  # We'll probably do something better eventually
    discord_commands.load_custom_commands(False, parent_location)

    if config.bot_token == '':
        common.console_print("Token is not present. Cannot login to Discord.",
                             console_prefix)
        run_failure = True
        return

    try:
        asyncio.set_event_loop(discord_client.loop)
        discord_client.loop.run_until_complete(
            discord_client.start(config.bot_token))
    except KeyboardInterrupt:
        discord_client.loop.run_until_complete(discord_client.logout())
        pending = asyncio.Task.all_tasks(loop=discord_client.loop)
        gathered = asyncio.gather(*pending, loop=discord_client.loop)
        try:
            gathered.cancel()
            discord_client.loop.run_until_complete(gathered)
            gathered.exception()
        except:
            pass
예제 #2
0
def get_statistics(print_to_console, return_formatted):
    """
    Gets a dict of various statistics and returns them.
    
    print: If True, we print the statistics to console as well.
    """

    update_stats()
    stats = {}
    stats['line_count'] = line_count
    stats['word_count'] = word_count
    stats['unique_word_count'] = unique_word_count
    stats['state_size'] = model.state_size
    stats['context_count'] = context_count

    output = []
    output.append("I know " + str(line_count) +
                  " lines containing a total of " + str(word_count) +
                  " words.")
    output.append(str(unique_word_count) + " of those words are unique.")
    output.append("We are currently using a state size of " +
                  str(model.state_size) + " which generated " +
                  str(context_count) + " contexts.")

    if print_to_console:
        for entry in output:
            common.console_print(entry, console_prefix)

    if return_formatted:
        return "\n".join(output)

    return stats
예제 #3
0
def commands():
    common.console_print("Entering command mode...", console_prefix)

    while not shutting_down:
        command = input('>> ')

        if command is "":
            continue

        split_command = command.split()
        command_target = split_command.pop(0)
        sub_command = ' '.join(split_command)

        if "markov" in command_target:
            markov.incoming_console_command(sub_command)

        if command == "client status":
            chat_client.still_running(True)

        if command == "client reload":
            client_load(True)

        if command == "client logout":
            chat_client.logout()

        if command == "client shutdown":
            chat_client.shutdown()

        if command == "shutdown":
            shutdown()

        if command == "reload markov":
            markov_load(True)
예제 #4
0
async def on_channel_update(before, after):
    if after.name != before.name:
        if before.name in config.discord_channels and after.name not in config.discord_channels:
            config.discord_channels.append(after.name)

        if before.name in config.discord_markov_channels and after.name not in config.discord_markov_channels:
            config.discord_markov_channels.append(after.name)

        common.console_print(
            "Channel #" + before.name + " has changed to #" + after.name,
            console_prefix)
예제 #5
0
def shutdown():
    global shutting_down
    shutting_down = True
    common.console_print("Shutting everything down...", console_prefix)

    if not markov.shutting_down:
        markov.shutdown()

    chat_client.shutdown()
    common.console_print("Good night!", console_prefix)
    raise SystemExit
예제 #6
0
def shutdown():
    """ 
    Let's do a clean shutdown here.
    """

    global model, shutting_down
    shutting_down = True
    save()
    del model
    common.console_print("DerpyMarkov is shutting down now.", console_prefix)
    return True
예제 #7
0
def incoming_console_command(command):
    if not accepting_input():
        return

    if command == 'shutdown':
        shutdown()

    if command == 'statistics':
        get_statistics(True, False)

    if command == 'version':
        common.console_print("derpymarkov " + version, console_prefix)
예제 #8
0
def save():
    """
    Writes the current lines to file. If no changes have been detected since
    last save we don't need to do anything.
    """
    global unsaved

    if not unsaved:
        return

    common.console_print("Saving lines...", console_prefix)

    if os.path.exists(config.main_dictionary_file) and not os.path.isfile(config.main_dictionary_file):
        common.console_print("Error! " + config.main_dictionary_filename + " exists but is not a valid file. Cannot save lines.", console_prefix)
        return

    if not os.path.exists(config.main_dictionary_file):
        os.makedirs(config.absolute_dictionary_directory, exist_ok = True)
        common.console_print(config.main_dictionary_filename + " was not found. Creating new file...", console_prefix)

    with threading.Lock():
        with open(config.main_dictionary_file, '+w', encoding = "utf8") as text:
            text.write('\n'.join(sorted(lines)))
            text.close()

    common.console_print("Lines saved!", console_prefix)
    unsaved = False
예제 #9
0
async def on_message(message):
    reply = None
    markov_learn = True
    private_channel = False

    if message.author.bot or message.author == discord_client.user:
        return

    if message.content is "" or message.content is None:
        return

    if discordpy_legacy:
        private_channel = message.channel.is_private
    else:
        private_channel = isinstance(message.channel,
                                     discord.abc.PrivateChannel)

    if private_channel:
        if config.markov_learn_pm:
            markov_learn = True

        common.console_print(
            "Direct Message from " + message.author.name + ": " +
            message.content, console_prefix)
    else:
        if message.channel.name not in config.discord_channels:
            return
        if message.channel.name not in config.discord_markov_channels:
            markov_learn = False

        common.console_print(
            "Message from #" + message.channel.name + ": " + message.content,
            console_prefix)

    split_content = message.clean_content.split()
    command_check = split_content.pop(0)

    if config.command_alias == command_check:
        reply = discord_commands.get_commands(message, split_content)
    else:
        if markov is not None:
            reply = markov.incoming_message(message.clean_content,
                                            discord_client.user.name,
                                            markov_learn)

    if reply is not "" and reply is not None:
        if config.chat_to_console:
            if private_channel:
                common.console_print(
                    "Direct Message to " + message.author + ": " + reply,
                    console_prefix)
            else:
                common.console_print(
                    "Message to #" + message.channel.name + ": " + reply,
                    console_prefix)

        if isinstance(reply, str):
            await discord_client.send_message(message.channel, reply)
        else:
            await discord_client.send_message(message.channel, embed=reply)
예제 #10
0
def activate(reload):
    """
    Load and initialize everything then get markov running.
    """

    global model, lines, main_dictionary_file, shutting_down, doing_chain

    shutting_down = False
    doing_chain = False

    if reload:
        reload()

    common.console_print("DerpyMarkov version " + version, console_prefix)
    common.console_print("Loading main dictionary...", console_prefix)
    input_text = common.text_file_read(config.main_dictionary_file)

    if input_text == '':
        input_text = 'derp'

    model = derpymodel.DerpyText(input_text, state_size=config.state_size1)
    lines = generate_lines_from_model(True)
    get_statistics(True, False)
    common.console_print(
        "Normal reply rate is " + str(config.reply_rate) +
        " and bot name reply rate is " + str(config.bot_name_reply_rate) + ".",
        console_prefix)
    common.console_print(
        "The save interval is " + str(config.save_interval) + " seconds.",
        console_prefix)
    del input_text
    setup_commands()
예제 #11
0
def markov_load(reload):
    global markov

    if not use_markov:
        return

    common.console_print("Loading markov...", console_prefix)

    if reload:
        importlib.reload(markov)
    else:
        markov_package = config.get('Markov', 'markov_package')
        markov_module = config.get('Markov', 'markov_module')
        markov = importlib.import_module('modules.' + markov_package + '.' +
                                         markov_module)

    markov.activate(reload)
예제 #12
0
def client_load(reload):
    global chat_client, client_thread

    common.console_print("Loading chat client...", console_prefix)

    if reload:
        chat_client.shutdown()
        importlib.reload(chat_client)
    else:
        if use_discord_client:
            chat_client = importlib.import_module(
                'clients.discord_client.discord_client')

    client_thread = None
    client_thread = Thread(target=chat_client.launch,
                           args=([markov, script_location, derpy_stats]))
    client_thread.start()
예제 #13
0
def load_config():
    global config

    defaults_present = False
    common.load_config_file(script_location + '/config/defaults.cfg', config)

    if len(config.sections()) is not 0:
        defaults_present = True

    common.load_config_file(script_location + '/config/config.cfg', config)

    if not defaults_present and len(config.sections()) is 0:
        common.console_print(
            "Both configuration files config.cfg and defaults.cfg are missing or empty! D:",
            console_prefix)
        common.console_print("We can't function like this...", console_prefix)
        shutdown()
예제 #14
0
async def on_message(message):
    reply = None
    markov_learn = False
    bot_mentioned = discord_client.user in message.mentions

    if message.author.bot and config.ignore_bots:
        return

    if message.author == discord_client.user:
        return

    if message.content is "" or message.content is None:
        return

    if discordpy_legacy:
        is_private = message.channel.is_private
    else:
        is_private = isinstance(message.channel, discord.abc.PrivateChannel)

    if is_private:
        markov_learn = config.markov_learn_dm
        bot_mentioned = True
        common.console_print(
            "Direct Message from " + message.author.name + ": " +
            message.content, console_prefix)
    else:
        if not config.discord_all_channels and message.channel.name not in config.discord_channels:
            return

        if config.discord_markov_all_channels or message.channel.name in config.discord_markov_channels:
            markov_learn = True

        common.console_print(
            "Message from #" + message.channel.name + ": " + message.content,
            console_prefix)

    split_content = message.clean_content.split()
    command_check = split_content.pop(0)

    if config.command_alias == command_check:
        reply = discord_commands.get_commands(message, split_content)
    else:
        if markov is not None:
            if config.raw_to_markov:
                markov_text = message.content
            else:
                markov_text = message.clean_content

            reply = markov.incoming_message(markov_text,
                                            discord_client.user.name,
                                            bot_mentioned, markov_learn)

    if reply is not "" and reply is not None:
        if config.clean_output:
            reply = utils.clean_mentions(reply, discord_client)

        if config.chat_to_console:
            if is_private:
                common.console_print(
                    "Direct Message to " + message.author.name + ": " + reply,
                    console_prefix)
            else:
                common.console_print(
                    "Message to #" + message.channel.name + ": " + reply,
                    console_prefix)

        if isinstance(reply, str):
            if discordpy_legacy:
                await discord_client.send_message(message.channel, reply)
            else:
                await message.channel.send(reply)
        else:
            if discordpy_legacy:
                await discord_client.send_message(message.channel, embed=reply)
            else:
                await message.channel.send(embed=reply)
예제 #15
0
async def on_ready():
    global ready

    common.console_print(" We have logged in to Discord!", console_prefix)
    common.console_print("  Name: " + discord_client.user.name, console_prefix)
    common.console_print("  ID: " + str(discord_client.user.id),
                         console_prefix)

    try:
        await discord_client.change_presence(game=discord.Game(
            name=config.discord_playing))
        common.console_print("  Playing: " + config.discord_playing,
                             console_prefix)
    except:
        common.console_print(
            "  Could not set 'Playing' status for some reason.",
            console_prefix)
        common.console_print(" ", console_prefix)

    ready = True
예제 #16
0
def still_running(print):
    if print:
        common.console_print(
            "Client still running! Logged in? " + str(logged_in()),
            console_prefix)
    return True
예제 #17
0
def shutdown():
    if logged_in:
        logout()
    common.console_print("Shutting down client...", console_prefix)
예제 #18
0
def logout():
    future = asyncio.run_coroutine_threadsafe(discord_client.close(),
                                              discord_client.loop)
    common.console_print("Logging out...", console_prefix)
예제 #19
0
def shutdown():
    global shutting_down
    shutting_down = True
    common.console_print("Shutting everything down...", console_prefix)

    if not markov.shutting_down:
        markov.shutdown()

    chat_client.shutdown()
    common.console_print("Good night!", console_prefix)
    raise SystemExit


stats_module_load()
common.console_print("DerpyBot version " + version, console_prefix)

#These try commands check if config files are present, because if \config\config.cfg file is not present program will crash.
try:
    fh = open(script_location + '/config/config.cfg', 'r')
    # check to see if config exists
except FileNotFoundError:
    common.console_print("'\config\config.cfg' not found!!! Shutting down...")
    exit()
# Inform user config does not exist, then stops the program

try:
    fh = open(script_location + '\modules\derpymarkov\config\config.cfg', 'r')
    # check to see if config exists
except FileNotFoundError:
    common.console_print(
예제 #20
0
    if markov is not None:
        if not markov.shutting_down:
            markov.shutdown()

    if chat_client is not None:
        chat_client.shutdown()

    common.console_print("Good night!", console_prefix)
    raise SystemExit


load_config()
use_discord_client = config.getboolean('Config',
                                       'use_discord_client',
                                       fallback=True)
use_markov = config.getboolean('Config', 'use_markov', fallback=True)
stats_module_load()
common.console_print("DerpyBot version " + version, console_prefix)
markov_load(False)
client_load(False)

while not chat_client.ready and not chat_client.run_failure:
    time.sleep(0.1)

status_thread = Thread(target=client_status, args=[])
status_thread.start()
derpy_stats.add_new_set('derpybot')
derpy_stats.update_stats('derpybot', 'start_time', datetime.datetime.now())
commands()