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()
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')
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()
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!')
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}')
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()
async def individual_vote_reminder(): for user in data.participants: if data.participants[user]['submitted'] and \ not data.participants[user]['voted']: member = bot.get_guild(config.server_id).get_member(int(user)) if member is None: logger.warn(f'Unable to get user object for \'{user}\', skipping their vote reminder') continue embed = discord.Embed(title=static.strings['voting_dm_reminder_title'], description=static.strings['voting_dm_reminder'], colour=0xff0000) embed.set_footer(text=static.strings['voting_dm_reminder_footer']) await member.send(embed=embed) logger.debug(f'Vote reminder sent for \'{member.display_name}\' ({member.id})')
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}')
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()
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')
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}')
def build_voting_map(): counter = 0 logger.debug('Building voting_map map...') # ensure voting_map is empty if len(data.voting_map) != 0: logger.warn('voting_map map has not been cleared, clearing now') data.voting_map.clear() # assign a letter to every person who has submitted for user_id in data.participants: if data.participants[user_id]['submitted']: assigned_letter = chr(ord('A') + counter) counter += 1 logger.debug(f'Assigned letter \'{assigned_letter}\' to user_id \'{user_id}\'') data.voting_map[assigned_letter] = user_id logger.debug(f'Map built, {len(data.voting_map)} letter(s)') data.save_state()
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')
import builtins from discord.ext import commands import foodflex.util.config as config from foodflex.util.logging import logger builtins.__version__ = '2.0.1' logger.debug(f'Creating bot (cmd prefix \'{config.command_prefix}\')...') builtins.bot = commands.Bot(command_prefix=config.command_prefix) @bot.event 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!')
async def on_command_error(ctx, error): # CheckFailure is an auth error which we already log if not isinstance(error, discord.ext.commands.CheckFailure): logger.debug(f'error: {error}')