예제 #1
0
async def process_submission(message):
    user_id = str(message.author.id)
    logger.debug(f'Processing submission, msg id {user_id}')

    if user_id in data.participants:
        logger.info('Submission invalid')

    else:
        try:
            url = message.attachments[0].proxy_url
        except IndexError:
            url = ''
            loggger.warn('Submission does not have an image attached')

        data.participants[user_id] = {
            'nick': message.author.display_name,
            'submitted': True,
            'image_url': url,
            'voted': False,
            'votes': 0
        }

        await message.channel.send(random.choice(static.quotes['rude']))
        logger.info('Submission valid')
        data.save_state()
예제 #2
0
def load():
    global token, server_id, command_prefix, admin_ids, main_channel_id, leaderboard_channel_id, data_root
    logger.info('Loading config...')
    try:
        with open(CONFIG_PATH) as file:
            try:
                config = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {CONFIG_PATH}')

            try:
                token = config['token']
                server_id = config['server_id']
                command_prefix = config['command_prefix']
                admin_ids = config['admin_ids']
                main_channel_id = config['main_channel_id']
                leaderboard_channel_id = config['leaderboard_channel_id']
                data_root = config['data_root'] if 'data_root' in config.keys() else '.'
                logger.debug('↳ Config loaded')
            except KeyError:
                fatal(f'↳ Cannot find required keys in {CONFIG_PATH}\
                      \nSee README.md for required structure')
    except OSError:
        logger.warn(f'↳ Cannot open {CONFIG_PATH}')
        env = Env()
        token = env('TOKEN')
        server_id = env.int('SERVER_ID')
        command_prefix = env('COMMAND_PREFIX')
        admin_ids = list(map(lambda x: int(x), env.list('ADMIN_IDS')))
        main_channel_id = env.int('MAIN_CHANNEL_ID')
        leaderboard_channel_id = env.int('LEADERBOARD_CHANNEL_ID')
        data_root = env('DATA_ROOT') if 'DATA_ROOT' in os.environ else '.'
        logger.debug('↳ Config loaded from environment')
예제 #3
0
async def log_and_dm(title, reason, person):
    embed = discord.Embed(
        title=title,
        description=reason,
        colour=0xff0000)
    await person.send(embed=embed)
    logger.info(reason + ', ' + title)
예제 #4
0
def load_state():
    global participants, voting_map, period, mode

    logger.debug('Loading state...')
    try:
        with open(STATE_PATH, 'r') as file:
            try:
                data = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {STATE_PATH}')
            try:
                participants = data['participants']
                voting_map = data['voting_map']
                period = data['period']
                mode = data['mode']
                logger.info('↳ Using existing state file')
            except KeyError:
                fatal(f'↳ Cannot find required keys in {STATE_PATH}')
    except OSError:
        participants = {}
        voting_map = {}
        period = DEFAULT_PERIOD
        mode = DEFAULT_MODE
        logger.info('↳ No existing state file, starting with blank state')
        save_state()
예제 #5
0
async def on_message(message):
    # don't respond to our own messages
    if message.author.bot:
        return

    await bot.process_commands(message)

    # ignore messages in any channel but the main one
    if message.channel != main_channel:
        return

    now = datetime.datetime.now()
    hour = int(now.strftime('%H'))
    minute = int(now.strftime('%M'))

    if data.period == 'submissions' and len(message.attachments) > 0:
        logger.info(
            f'Submission from \'{message.author.display_name}\' ({str(message.author.id)})'
        )
        await submissions.process_submission(message)

    elif data.period == 'voting' and len(message.clean_content) == 1:
        logger.info(
            f'Vote \'{message.clean_content}\' from \'{message.author.display_name}\' ({str(message.author.id)})'
        )
        await voting.check_vote(message)
예제 #6
0
async def on_ready():
    global main_channel, leaderboard_channel
    logger.debug('Finding text channels...')

    builtins.main_channel = bot.get_channel(config.main_channel_id)
    builtins.leaderboard_channel = bot.get_channel(config.leaderboard_channel_id)

    logger.info('Food Flex is online!')
예제 #7
0
def main():
    logger.info(f'Starting Food Flex v{__version__}')
    static.load()
    data.load_state()
    data.load_leaderboard()

    print_state_info()

    logger.info('Starting bot...')
    bot.loop.create_task(check_time_periods())
    bot.run(config.token)
예제 #8
0
def change_period(new_period, manual_change=False):
    global period, mode

    if manual_change:
        mode = 'manual'
    else:
        mode = 'automatic'

    logger.info(f'Period \'{period}\' -> \'{new_period}\' ({mode})')

    period = new_period
    save_state()
예제 #9
0
def save_leaderboard():
    global leaderboard, leaderboard_message_id

    logger.debug('Saving leaderboard...')
    try:
        os.makedirs(DATA_PATH, exist_ok=True)
        with open(LEADERBOARD_PATH, 'w') as file:
            json.dump({
                'leaderboard': leaderboard,
                'leaderboard_message_id': leaderboard_message_id
                }, file, indent=2)
            logger.info('Leaderboard saved')
    except OSError:
        fatal(f'↳ Could not save to {STATE_PATH}')
예제 #10
0
async def submission_period():
    logger.info('// Now in SUBMISSIONS period //')
    activity = discord.Activity(
        name=static.strings['submission_open_activity'],
        type=discord.ActivityType.watching)
    await bot.change_presence(status=discord.Status.online, activity=activity)
    embed = discord.Embed(title=static.strings['submission_open_title'],
                          description=static.strings['submission_open'],
                          colour=0xff0000)
    await main_channel.send(embed=embed)

    logger.debug('Clearing participants & voting_map')
    data.participants.clear()
    data.voting_map.clear()
    data.save_state()
예제 #11
0
def save_state():
    global participants, voting_map, period, mode

    logger.debug('Saving state...')

    try:
        os.makedirs(DATA_PATH, exist_ok=True)
        with open(STATE_PATH, 'w') as file:
            json.dump({
                'participants': participants,
                'voting_map': voting_map,
                'period': period,
                'mode': mode
                }, file, indent=2)
            logger.info('State saved')
    except OSError:
        fatal(f'↳ Could not save to {STATE_PATH}')
예제 #12
0
def load_leaderboard():
    global leaderboard, leaderboard_message_id

    logger.debug('Loading leaderboard...')
    try:
        with open(LEADERBOARD_PATH) as file:
            try:
                data = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {LEADERBOARD_PATH}')
            try:
                leaderboard = data['leaderboard']
                leaderboard_message_id = data['leaderboard_message_id']
                logger.info('↳ Using existing leaderboard file')
            except KeyError:
                fatal(f'↳ Cannot find required keys in {LEADERBOARD_PATH}')
    except OSError:
        leaderboard = {}
        leaderboard_message_id = None
        logger.info('↳ No existing leaderboard file, starting with blank')
        save_leaderboard()
예제 #13
0
async def results_period():
    logger.info('// Now in RESULTS period //')
    activity = discord.Activity(name='for shit food',
                                type=discord.ActivityType.watching)
    await bot.change_presence(status=discord.Status.idle, activity=activity)

    logger.info('Preparing reuslts...')
    # Get list of users (tuples) who submitted (nick, votes)
    users = []
    for user in data.participants:
        if data.participants[user]['submitted']:
            tuple = (data.participants[user]['nick'],
                     data.participants[user]['votes'])
            users.append(tuple)
    users.sort(key=lambda tuple: tuple[1], reverse=True)

    # Get the winner(s) as a string
    winner_message = await get_winner()

    embed = discord.Embed(title='Results', description='', colour=0xff0000)
    embed.set_author(name=winner_message)

    # Add users to embed
    for user in users:
        votes = 'Votes: ' + str(user[1])
        embed.add_field(name=user[0], value=votes, inline=False)

    await main_channel.send(embed=embed)
    logger.info('Results posted')
    await leaderboard.update_leaderboard()
예제 #14
0
def load():
    global quotes, strings
    logger.debug('Loading quotes & strings...')
    try:
        with open(QUOTES_PATH) as file:
            try:
                quotes = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {QUOTES_PATH}')
    except OSError:
        fatal(f'↳ Cannot open {QUOTES_PATH}')

    try:
        with open(STRINGS_PATH) as file:
            try:
                strings = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {STRINGS_PATH}')
    except OSError:
        fatal(f'↳ Cannot open {STRINGS_PATH}')

    logger.info('↳ Quotes & strings loaded')
예제 #15
0
def load():
    global token, server_id, command_prefix, admin_ids, main_channel_id, leaderboard_channel_id
    logger.info('Loading config...')
    try:
        with open(CONFIG_PATH) as file:
            try:
                config = json.load(file)
            except json.decoder.JSONDecodeError:
                fatal(f'↳ Cannot parse {CONFIG_PATH}')

            try:
                token = config['token']
                server_id = config['server_id']
                command_prefix = config['command_prefix']
                admin_ids = config['admin_ids']
                main_channel_id = config['main_channel_id']
                leaderboard_channel_id = config['leaderboard_channel_id']
                logger.debug('↳ Config loaded')
            except KeyError:
                fatal(f'↳ Cannot find required keys in {CONFIG_PATH}\
                      \nSee README.md for required structure')
    except OSError:
        fatal(f'↳ Cannot open {CONFIG_PATH}')
예제 #16
0
async def voting_period():
    logger.info('// Now in VOTING period //')
    logger.info('Creating voting key...')

    # we need to build voting_map map first
    build_voting_map()

    logger.debug('Creating (url, letter) pairs for submissions...')
    submissions = []
    # create (image_url, letter) pair list
    for letter in data.voting_map:
        user_id = data.voting_map[letter]
        image_url = data.participants[user_id]['image_url']
        submissions.append((image_url, letter))

    # sort submissions by alphabetical key
    submissions.sort(key=lambda tuple: tuple[1], reverse=False)

    logger.debug('Generating images...')
    # process images
    image_objects = []
    for (image_url, letter) in submissions:
        buffer = images.process_image(image_url, letter)
        image_objects.append(discord.File(buffer, filename=f'{letter}.png'))

    # announce voting is open
    await main_channel.send(static.strings['voting_open_title'])

    logger.debug('Uploading images...')
    # upload images
    for image in image_objects:
        await main_channel.send(file=image)

    # remind people how to vote and change presence
    await main_channel.send(static.strings['voting_open_footer'])

    activity = discord.Activity(name='people vote on shit food',
                                type=discord.ActivityType.watching)
    await bot.change_presence(status=discord.Status.online, activity=activity)
    logger.info('Done, voting key posted')
예제 #17
0
def set_mode(new_mode):
    global mode

    logger.info(f'Mode \'{mode}\' -> \'{new_mode}\'')
    mode = new_mode
    save_state()
예제 #18
0
def print_state_info():
    logger.info(
        f'period=\'{data.period}\', mode=\'{data.mode}\' people={len(data.participants)}'
    )