Esempio n. 1
0
async def __safe_alter_config(client: bot.Overlord, path: str, value):
    parent_config = client.config.parent()

    try:
        old_value = parent_config[path]
    except KeyError:
        log.info(f'Invalid config path provided: {path}')
        await client.control_channel.send(
            res.get("messages.invalid_config_path"))
        return False

    try:
        log.warn(f'Altering raw config path {path}')
        parent_config.alter(path, value)
        if parent_config['logger']:
            logging.config.dictConfig(parent_config['logger'])
        client.update_config(parent_config.bot)
    except (InvalidConfigException, TypeError) as e:
        log.warn(
            f'Invalid config value provided: {value}, reason: {e}. Reverting.')
        parent_config.alter(path, old_value)
        if parent_config['logger']:
            logging.config.dictConfig(parent_config['logger'])
        client.update_config(parent_config.bot)
        msg = res.get("messages.error").format(e) + '\n' + res.get(
            "messages.warning").format('Config reverted')
        await client.control_channel.send(msg)
        return False

    return True
Esempio n. 2
0
def main(argv):
    # Load env variables
    load_dotenv()

    # Parse arguments
    parser = argparse.ArgumentParser(description='Overlord Discord Bot')
    parser.add_argument('-c', '--config', nargs='?', type=str, default='config.json', help='config path')
    args = parser.parse_args(argv[1:])

    # Load config
    config = ConfigView(path=args.config, schema_name="config_schema")

    # Apply logging config
    if config['logger']:
        logging.config.dictConfig(config['logger'])

    # Init database
    url = os.getenv('DATABASE_ACCESS_URL')
    if 'sqlite' in url:
        import db.queries as q
        q.MODE = q.MODE_SQLITE
    session = DBSession(url, autocommit=False)
    session.sync_table(EventType, 'name', EVENT_TYPES)
    session.sync_table(UserStatType, 'name', USER_STAT_TYPES)

    # Init bot
    discord_bot = Overlord(config.bot, session)
    discord_bot.run()

    return 0
Esempio n. 3
0
async def reload_config(client: bot.Overlord, msg: discord.Message):
    log.info(f'Reloading config')
    # Reload config
    parent_config = client.config.parent()
    new_config = ConfigView(path=parent_config.fpath(),
                            schema_name="config_schema")
    if new_config['logger']:
        logging.config.dictConfig(new_config['logger'])
    client.update_config(new_config.bot)
    log.info(f'Done')
    await client.control_channel.send(res.get("messages.done"))
Esempio n. 4
0
async def update_user_rank(client: bot.Overlord, msg: discord.Message,
                           member: discord.Member):
    async with client.sync():
        await msg.channel.send(
            res.get("messages.update_rank_begin").format(member.mention))
        await client.update_user_rank(member)
        await msg.channel.send(res.get("messages.done"))
Esempio n. 5
0
async def clear_data(client: bot.Overlord, msg: discord.Message):

    models = [
        db.MemberEvent, db.MessageEvent, db.VoiceChatEvent, db.UserStat,
        db.User, db.Role
    ]
    table_data_drop = res.get("messages.table_data_drop")

    # Tranaction begins
    async with client.sync():
        log.warn("Clearing database")
        await client.send_warning("Clearing database")
        for model in models:
            log.warn(f"Clearing table `{model.table_name()}`")
            await client.control_channel.send(
                table_data_drop.format(model.table_name()))
            client.db.query(model).delete()
            client.db.commit()
        client.set_awaiting_sync()
        log.info(f'Done')
        await client.control_channel.send(res.get("messages.done"))
Esempio n. 6
0
async def recalculate_stats(client: bot.Overlord, msg: discord.Message):
    # Tranaction begins
    async with client.sync():
        log.info(f"Recalculating all stats")
        answer = res.get("messages.user_stat_calc")
        await msg.channel.send(answer.format('all'))

        for stat_type in client.s_stats.user_stat_type_map:
            client.s_stats.reload_stat(stat_type)

        log.info(f'Done')
        await msg.channel.send(res.get("messages.done"))
Esempio n. 7
0
async def remove_rank(client: bot.Overlord, msg: discord.Message,
                      role_name: str):
    role = client.get_role(role_name)
    if role is None:
        await msg.channel.send(
            res.get("messages.rank_role_unknown").format(role_name))
        return
    ranks = client.config.ranks.role.copy().value()
    if role_name not in ranks:
        await msg.channel.send(res.get("messages.rank_unknown"))
        return
    del ranks[role_name]
    path = 'bot.ranks.role'

    if await __safe_alter_config(client, path, ranks):
        __save_config(client)
        log.info(f'Done')
        await client.control_channel.send(res.get("messages.done"))
Esempio n. 8
0
async def reload_channel_history(client: bot.Overlord, msg: discord.Message,
                                 channel: discord.TextChannel):
    permissions = channel.permissions_for(client.me)
    if not permissions.read_message_history:
        answer = res.get("messages.missing_access").format(
            channel.mention) + ' (can\'t read message history)'
        await msg.channel.send(answer)
        return

    # Tranaction begins
    async with client.sync():

        # Drop full channel message history
        log.warn(f'Dropping #{channel.name}({channel.id}) history')
        answer = res.get("messages.channel_history_drop").format(
            channel.mention)
        await msg.channel.send(answer)
        client.s_events.clear_text_channel_history(channel)

        # Load all messages
        log.warn(f'Loading #{channel.name}({channel.id}) history')
        answer = res.get("messages.channel_history_load").format(
            channel.mention)
        await msg.channel.send(answer)
        async for message in channel.history(limit=None, oldest_first=True):

            # Skip bot messages
            if message.author.bot:
                continue

            # Resolve user
            user = client.s_users.get(message.author)
            if user is None and client.config["user.leave.keep"]:
                user = client.s_users.add_user(message.author)

            # Skip users not in db
            if user is None:
                continue

            # Insert new message event
            client.s_events.create_new_message_event(user, message)

        log.info(f'Done')
        await msg.channel.send(res.get("messages.done"))
Esempio n. 9
0
async def edit_rank(client: bot.Overlord, msg: discord.Message, role_name: str,
                    weight: str, membership: str, msg_count: str,
                    vc_time: str):
    try:
        weight = int(weight)
        membership = int(membership)
        messages_count = int(msg_count)
        vc_time = int(vc_time)
    except ValueError:
        await msg.channel.send(res.get("messages.rank_arg_parse_error"))
        return
    role = client.get_role(role_name)
    if role is None:
        await msg.channel.send(
            res.get("messages.rank_role_unknown").format(role_name))
        return
    ranks = client.config.ranks.role.copy().value()
    if role_name not in ranks:
        await msg.channel.send(res.get("messages.rank_unknown"))
        return
    ranks_weights = {ranks[r]['weight']: r for r in ranks}
    if weight in ranks_weights and ranks_weights[weight] != role_name:
        await msg.channel.send(
            res.get("messages.rank_role_same_weight").format(
                ranks_weights[weight]))
        return
    ranks[role_name] = {
        "weight": weight,
        "membership": membership,
        "messages": messages_count,
        "vc": vc_time
    }
    path = 'bot.ranks.role'

    if await __safe_alter_config(client, path, ranks):
        __save_config(client)
        log.info(f'Done')
        await client.control_channel.send(res.get("messages.done"))
Esempio n. 10
0
async def update_user_ranks(client: bot.Overlord, msg: discord.Message):
    async with client.sync():
        await msg.channel.send(res.get("messages.update_ranks_begin"))
        await client.update_user_ranks()
        await msg.channel.send(res.get("messages.done"))
Esempio n. 11
0
async def sync_roles(client: bot.Overlord, msg: discord.Message):
    async with client.sync():
        await msg.channel.send(res.get("messages.sync_users_begin"))
        await client.sync_users()
        await msg.channel.send(res.get("messages.done"))
Esempio n. 12
0
async def ping(client: bot.Overlord, msg: discord.Message):
    if client.sync().locked():
        await msg.channel.send(res.get("messages.busy"))
    else:
        await msg.channel.send(res.get("messages.pong"))