async def update_leaderboard(): # Gets a list of users and scores (as tuple in descending order) users = [(data.leaderboard[key]['nick'], data.leaderboard[key]['score']) for key in data.leaderboard] users.sort(key=lambda tuple: tuple[1], reverse=True) # Checks if the leaderboard has already been posted if "leaderboard_message_id" not in data.state and os.getenv( "LEADERBOARD_MESSAGE_ID") == None: # Creates new leaderboard logger.info("Make new leaderboard message") embed = get_embed(users) await builtins.leaderboard_channel.send(embed=embed) leaderboard_id = leaderboard_channel.last_message_id builtins.leaderboard_message = await builtins.leaderboard_channel.fetch_message( leaderboard_id) data.state['leaderboard_message_id'] = leaderboard_id data.update_state() else: # Edits and existing one logger.info("Edit leaderboard message") embed = get_embed(users) await builtins.leaderboard_message.edit(embed=embed) data.update_leaderboard()
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)
def main(): load_dotenv() sys.stdout.flush() logger.info(f'Starting Food Flex v{__version__}') data.init_firebase() static.load() bot.loop.create_task(check_time_periods()) bot.run(os.getenv('TOKEN'))
def on_snapshot(doc_snapshot, changes, read_time): global leaderboard, weekly_data, voting_map, state for doc in doc_snapshot: logger.info(u'Received document snapshot: {}'.format(doc.id)) if doc.id == current_leaderboard_ref.get().id: leaderboard = doc.to_dict() elif doc.id == weekly_data_ref.get().id: weekly_data = doc.to_dict() elif doc.id == voting_map_ref.get().id: voting_map = doc.to_dict() elif doc.id == state_ref.get().id: state = doc.to_dict()
async def on_ready(): global main_channel, leaderboard_channel, guild, admin_role logger.debug('Finding text channels...') builtins.main_channel = bot.get_channel(int(os.getenv('MAIN_CHANNEL_ID'))) builtins.leaderboard_channel = bot.get_channel(int(os.getenv('LEADERBOARD_CHANNEL_ID'))) try: builtins.leaderboard_message = await builtins.leaderboard_channel.fetch_message(int(os.getenv("LEADERBOARD_MESSAGE_ID"))) except: logger.warning("No leaderboard message") if "leaderboard_message_id" not in data.state: builtins.leaderboard_message = None else: builtins.leaderboard_message = await builtins.leaderboard_channel.fetch_message(data.state['leaderboard_message_id']) builtins.guild = bot.get_guild(int(os.getenv('SERVER_ID'))) builtins.admin_role = guild.get_role(int(os.getenv('ADMIN_ROLE_ID'))) logger.info('Food Flex is online!')
async def on_message(message): # don't respond to our own messages await bot.process_commands(message) if message.author.bot: return # ignore messages in any channel but the main one if message.channel != builtins.main_channel: return if data.state['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.state['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)
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('Creating new weekly document') week_number = datetime.datetime.now().isocalendar()[1] data.create_new_weekly_document(week_number) data.weekly_data = {} data.update_weekly_document() data.voting_map = {} data.update_voting_map()
def build_voting_map(): counter = 0 logger.debug('Building voting_map map...') # ensure voting_map is empty if len(voting_map) != 0: logger.warn('voting_map map has not been cleared, clearing now') voting_map.clear() # assign a letter to every person who has submitted for user_id in weekly_data: if weekly_data[user_id]['submitted']: assigned_letter = chr(ord('A') + counter) counter += 1 logger.debug( f'Assigned letter \'{assigned_letter}\' to user_id \'{user_id}\'' ) voting_map[assigned_letter] = user_id logger.info(f'Map built, {len(voting_map)} letter(s)') db.collection(u'weekly-data').document(u'voting-map').set(voting_map)
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.weekly_data: if data.weekly_data[user]['submitted']: tuple = (data.weekly_data[user]['nick'], data.weekly_data[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()
async def process_submission(message): user_id = str(message.author.id) logger.debug(f'Processing submission, msg id {user_id}') if data.weekly_data != None and user_id in data.weekly_data: logger.info('Submission invalid') try: url = message.attachments[0].proxy_url except IndexError: url = '' loggger.warn('Submission does not have an image attached') data.weekly_data[user_id][u'image_url'] = url await message.channel.send(random.choice(static.quotes['rude'])) logger.info('Submission overwritten') else: try: url = message.attachments[0].proxy_url except IndexError: url = '' loggger.warn('Submission does not have an image attached') data.weekly_data[user_id] = { u'nick': message.author.display_name, u'submitted': True, u'image_url': url, u'voted': False, u'votes': 0 } await message.channel.send(random.choice(static.quotes['rude'])) logger.info('Submission valid') data.update_weekly_document()
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')
async def voting_period(): logger.info('// Now in VOTING period //') logger.info('Creating voting key...') # we need to build voting_map map first data.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.weekly_data[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')
def update_weekly_document(): current_week_id = db.collection(u'weekly-data').document( u'current-week').get().to_dict()['id'] current_week = u'week-' + current_week_id db.collection(u'weekly-data').document(current_week).set(weekly_data) logger.info(f'{current_week} document updated')
def update_voting_map(): db.collection(u'weekly-data').document(u'voting-map').set(voting_map) logger.info('Voting map updated')
def update_leaderboard(): current_leaderboard = db.collection(u'leaderboard').document( u'current-leaderboard').get().to_dict()['id'] db.collection(u'leaderboard').document(current_leaderboard).set( leaderboard) logger.info('Leaderboard updated')
def create_new_weekly_document(week_number): name = u'week-' + str(week_number) db.collection(u'weekly-data').document(name).set({}) current_week = {'id': str(week_number)} db.collection(u'weekly-data').document(u'current-week').set(current_week) logger.info(f'Week {week_number} document created')
def update_state(): db.collection(u'weekly-data').document(u'state').set(state) logger.info('State updated')
def build_state(): data = {'period': ''} db.collection(u'weekly-data').document(u'state').set(data) logger.info('State built')