async def bots(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ online_bots = [] offline_bots = [] total_bots = 0 for user in pld.msg.guild.members: if user.bot: total_bots += 1 name = f'{user.name}#{user.discriminator}' offline_bots.append(name) if str( user.status) == 'offline' else online_bots.append(name) if total_bots == 0: response = GenericResponse( 'No bots were found on that server.').error() else: guild_icon = str(pld.msg.guild.icon_url ) if pld.msg.guild.icon_url else discord.Embed.Empty icon_color = await get_image_colors(guild_icon) response = discord.Embed(color=icon_color) response.set_author(name=f'Bots on {pld.msg.guild.name}', icon_url=guild_icon) response.add_field(name='Online', value='\n- ' + '\n- '.join(sorted(online_bots))) response.add_field(name='Offline', value='\n- ' + '\n- '.join(sorted(offline_bots) or ['None'])) await pld.msg.channel.send(embed=response)
async def permissions(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ allowed_list = [] disallowed_list = [] if pld.msg.mentions: user_q = pld.msg.mentions[0] else: user_q = pld.msg.author response = GenericResponse(f'{user_q.name}\'s Permissions').info() for permission in user_q.guild_permissions: if permission[1]: allowed_list.append(permission[0].replace('_', ' ').title()) else: disallowed_list.append(permission[0].replace('_', ' ').title()) if len(allowed_list) == 0: allowed_list = ['None'] if len(disallowed_list) == 0: disallowed_list = ['None'] response.add_field(name='Allowed', value='```yml\n - ' + '\n - '.join(sorted(allowed_list)) + '\n```') response.add_field(name='Disallowed', value='```yml\n - ' + '\n - '.join(sorted(disallowed_list)) + '\n```') in_ch = GenericResponse('Permission list sent to you.').ok() await pld.msg.author.send(embed=response) await pld.msg.channel.send(embed=in_ch)
async def impersonate(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: if pld.msg.mentions: target = pld.msg.mentions[0] else: target = discord.utils.find( lambda x: x.name.lower() == ' '.join(pld.args).lower(), pld.msg.guild.members) else: target = pld.msg.author if target: if os.path.exists(f'chains/{target.id}.json.gz'): chain_data = load(target.id) if chain_data: chain_function = functools.partial(markovify.Text.from_dict, deserialize(chain_data)) with ThreadPoolExecutor() as threads: try: chain = await cmd.bot.loop.run_in_executor( threads, chain_function) sentence_function = functools.partial( chain.make_short_sentence, 500) sentence = await cmd.bot.loop.run_in_executor( threads, sentence_function) except (KeyError, ValueError, AttributeError): sentence = None if not sentence: not_enough_data = '😖 I could not think of anything... I need more chain items!' response = discord.Embed(color=0xBE1931, title=not_enough_data) else: response = discord.Embed(color=0xbdddf4) response.set_author(name=target.name, icon_url=user_avatar(target)) response.add_field(name='💭 Hmm... something like...', value=sentence) else: response = GenericResponse( f'{target.name}\'s chain has no data.').error() else: response = discord.Embed(color=0x696969) prefix = cmd.db.get_prefix(pld.settings) title = f'🔍 Chain Data Not Found For {target.name}' value = f'You can make one with `{prefix}collectchain @{target.name} #channel`!' response.add_field(name=title, value=value) else: response = GenericResponse('No user targeted.').error() await pld.msg.channel.send(embed=response)
async def listincidents(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.msg.author.permissions_in(pld.msg.channel).manage_messages: icore = get_incident_core(cmd.db) identifier, incidents = None, None page = pld.args[-1] if len(pld.args) in [1, 3] else 1 if len(pld.args) >= 2: identifier = pld.args[0].lower() if (pld.msg.mentions or identifier == 'variant') and identifier in identifiers: if identifier == 'moderator': mod = pld.msg.mentions[0] incidents = await icore.get_all_by_mod(pld.msg.guild.id, mod.id) response = discord.Embed(color=0x226699) incident_list, page = parse_incidents(incidents, page) response.add_field(name=f'🗃️ Incidents initiated by {mod.name}', value=incident_list) elif identifier == 'target': target = pld.msg.mentions[0] incidents = await icore.get_all_by_target(pld.msg.guild.id, target.id) response = discord.Embed(color=0x226699) incident_list, page = parse_incidents(incidents, page) response.add_field(name=f'🗃️ Incidents for {target.name}', value=incident_list) else: variant = pld.args[1].lower() if variant in variants: incidents = await icore.get_all_by_variant(pld.msg.guild.id, variant) response = discord.Embed(color=0x226699) response.add_field(name='Details', value=f'```\nPage {page}\n```') incident_list, page = parse_incidents(incidents, page) response.add_field(name=f'🗃️ {identifier.title()} incidents', value=incident_list) else: response = GenericResponse('Invalid variant.').error() else: response = GenericResponse('Invalid identifier.').error() else: incidents = await icore.get_all(pld.msg.guild.id) response = discord.Embed(color=0x226699) incident_list, page = parse_incidents(incidents, page) response.add_field(name='🗃️ All incidents', value=incident_list) if not incidents and (identifier in identifiers or not identifier): if identifier: response = GenericResponse(f'No incidents found for that {identifier}.').error() else: response = GenericResponse('This server has no incidents.').error() else: response = GenericResponse('Access Denied. Manage Messages needed.').denied() await pld.msg.channel.send(embed=response)
async def rolepopulation(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ guild_icon = str(pld.msg.guild.icon_url ) if pld.msg.guild.icon_url else discord.Embed.Empty if pld.args: rl_qry = ' '.join(pld.args) role_search = discord.utils.find( lambda x: x.name.lower() == rl_qry.lower(), pld.msg.guild.roles) if role_search: counter = len(role_search.members) response = discord.Embed(color=role_search.color) response.set_author(name=pld.msg.guild.name, icon_url=guild_icon) response.add_field(name=f'{role_search.name} Population', value=f'```py\n{counter}\n```') else: response = GenericResponse(f'{rl_qry} not found.').not_found() else: role_dict = {} for role in pld.msg.guild.roles: if role.id != pld.msg.guild.id: role_key = role.name role_count = len(role.members) role_dict.update({role_key: role_count}) sorted_roles = sorted(role_dict.items(), key=operator.itemgetter(1), reverse=True) output = [] for srole in sorted_roles[:15]: output.append([ srole[0], srole[1], f'{str(percentify(srole[1], len(pld.msg.guild.members)))}%' ]) out_text = boop(output) stats_block = f'```py\nShowing {len(output)} roles out of {len(pld.msg.guild.roles) - 1}\n```' response = discord.Embed(color=0x3B88C3) response.set_author(name=pld.msg.guild.name, icon_url=guild_icon) response.add_field(name='Statistics', value=stats_block, inline=False) response.add_field(name='Role Population', value=f'```haskell\n{out_text}\n```', inline=False) await pld.msg.channel.send(embed=response)
async def help(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: cmd_name = ''.join(pld.args).lower() if cmd_name in cmd.bot.modules.alts: cmd_name = cmd.bot.modules.alts[cmd_name] if cmd_name in cmd.bot.modules.commands: pfx = cmd.db.get_prefix(pld.settings) command = cmd.bot.modules.commands[cmd_name] usage = command.usage.replace('{pfx}', pfx).replace('{cmd}', command.name) title = f'📄 [{command.category.upper()}] {command.name.upper()} Usage and Information' response = discord.Embed(color=0x1B6F5F, title=title) response.add_field(name='Usage Example', value=f'`{usage}`', inline=False) response.add_field(name='Command Description', value=f'```\n{command.desc}\n```', inline=False) if command.alts: response.add_field( name='Command Aliases', value=f'```\n{", ".join(command.alts)}\n```') else: response = GenericResponse('Command not found.').not_found() else: response = discord.Embed(color=0x1B6F5F) response.set_author(name=SIGMA_TITLE, icon_url=user_avatar(cmd.bot.user), url=cmd.bot.cfg.pref.website) invite_url = f'https://discordapp.com/oauth2/authorize?client_id={cmd.bot.user.id}&scope=bot&permissions=8' support_text = f'**Add Me**: [Link]({invite_url})' support_text += f' | **Commands**: [Link]({cmd.bot.cfg.pref.website}/commands)' support_text += f' | **Support**: [Link]({SUPPORT_URL})' support_text += f'\nWanna help? **Patreon**: [Link]({PATREON_URL}) | **PayPal**: [Link]({PAYPAL_URL})' response.add_field(name='Help', value=support_text) response.set_thumbnail(url=user_avatar(cmd.bot.user)) response.set_footer( text='© by Lucia\'s Cipher. Released under the GPLv3 license.', icon_url=LUCIA_IMAGE) await pld.msg.channel.send(embed=response)
async def poll(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if not pld.args: out_content = GenericResponse('Nothing inputted.').error() await pld.msg.channel.send(embed=out_content) return all_qry = ' '.join(pld.args) if all_qry.endswith(';'): all_qry = all_qry[:-1] poll_name = all_qry.split('; ')[0] choice_qry = '; '.join(all_qry.split('; ')[1:]) if choice_qry.endswith(';'): choice_qry = choice_qry[:-1] poll_choices = choice_qry.split('; ') if len(poll_choices) < 2: out_content = GenericResponse('Not enough arguments.').error() await pld.msg.channel.send(embed=out_content) return if len(poll_choices) > 9: out_content = GenericResponse('Maximum is 9 choices.').error() await pld.msg.channel.send(embed=out_content) return icon_list_base = '🍏 🍎 🍐 🍊 🍋 🍌 🍉 🍇 🍓 🍈 🍒 🍑 🍍 🍅 🍆 🌶 🌽 🍠 🍞 🍗 🍟 🍕 🍺 🍷 🍬 🍙'.split( ) choice_text = '' emoji_list = [] for option in poll_choices: emoji = icon_list_base.pop(secrets.randbelow(len(icon_list_base))) emoji_list.append(emoji) choice_text += f'\n{emoji} - {option}' out_content = discord.Embed(color=pld.msg.author.color) out_content.set_author(name=f'{pld.msg.author.name}\'s Poll', icon_url=user_avatar(pld.msg.author)) out_content.description = poll_name out_content.add_field(name='Choices', value=choice_text) out_content.set_footer( text=f'[{secrets.token_hex(3)}] React with your vote below!') poll_message = await pld.msg.channel.send(embed=out_content) for emoji in emoji_list: await poll_message.add_reaction(emoji=emoji)
async def oserverbots(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: lookup = ' '.join(pld.args) try: gld = await cmd.bot.get_guild(int(lookup)) except ValueError: gld = discord.utils.find( lambda u: u.name.lower() == lookup.lower(), cmd.bot.guilds) if gld: online_bots, offline_bots = [], [] total_bots = len([u for u in gld.members if u.bot]) for user in gld.members: if user.bot: name = f'{user.name}#{user.discriminator}' offline_bots.append(name) if str( user.status) == 'offline' else online_bots.append(name) if total_bots == 0: response = GenericResponse( 'No bots were found on that server.').error() else: guild_icon = str( pld.msg.guild.icon_url ) if pld.msg.guild.icon_url else discord.Embed.Empty response = discord.Embed( color=await get_image_colors(guild_icon)) response.set_author(name=f'Bots on {gld.name}', icon_url=guild_icon) response.add_field(name='Online', value='\n- ' + '\n- '.join(sorted(online_bots))) response.add_field( name='Offline', value='\n- ' + '\n- '.join(sorted(offline_bots) or ['None'])) else: response = GenericResponse('Guild not found.').not_found() else: response = GenericResponse('Nothing inputted.').error() await pld.msg.channel.send(embed=response)
async def inrole(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: try: lookup, state, page = parse_args(pld.args) except IndexError: response = GenericResponse('Bad input. See usage example.').error() await pld.msg.channel.send(embed=response) return if lookup: role_search = discord.utils.find(lambda x: x.name.lower() == lookup, pld.msg.guild.roles) if role_search: members = [] for member in pld.msg.guild.members: if role_search in member.roles: if state: if member.status.name == state: members.append([member.name, member.top_role.name]) else: members.append([member.name, member.top_role.name]) if members: count = len(members) members, page = PaginatorCore.paginate(sorted(members), page) response = discord.Embed(color=role_search.color) state = state if state else 'Any' value = f'```py\nShowing 10 of {count} users. Status: {state}. Page {page}\n```' members_table = boop(members, ['Name', 'Top Role']) response.add_field(name='📄 Details', value=value, inline=False) response.add_field(name='👥 Members', value=f'```hs\n{members_table}\n```', inline=False) else: response = GenericResponse(f'No users have the {role_search.name} role.').not_found() else: response = GenericResponse(f'{lookup} not found.').not_found() else: response = GenericResponse('Missing role name.').error() else: response = GenericResponse('Nothing inputted.').error() await pld.msg.channel.send(embed=response)
async def foodrecipe(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if cmd.cfg.api_key: if pld.args: search = ' '.join(pld.args) url = f'http://food2fork.com/api/search?key={cmd.cfg.api_key}&q={search}' async with aiohttp.ClientSession() as session: async with session.get(url) as data: search_data = await data.read() search_data = json.loads(search_data) count = search_data['count'] if count == 0: response = GenericResponse('No results.').not_found() else: info = search_data['recipes'][0] title = info['title'] source = info['publisher'] source_url = info['source_url'] image_url = info['image_url'] publisher_url = info['publisher_url'] response = discord.Embed(color=0xee5b2f) response.set_author(name=source, url=publisher_url, icon_url='https://i.imgur.com/RH8LNdQ.png') response.add_field(name=title, value='[Recipe Here](' + source_url + ')') response.set_thumbnail(url=image_url) else: response = GenericResponse('Nothing inputted.').error() else: response = GenericResponse('The API Key is missing.').error() await pld.msg.channel.send(embed=response)
async def weather(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if cmd.cfg.secret_key: if pld.args: search, unit = get_unit_and_search(pld.args) if search: geo_parser = Nominatim( user_agent=f'Apex Sigma Derivate {cmd.bot.user.id}') try: location = geo_parser.geocode(search) except Exception as e: response = GenericResponse( f'Geocoder {str(e).lower()}.').error() else: if location: lat = location.latitude lon = location.longitude req_url = f'https://api.darksky.net/forecast/{cmd.cfg.secret_key}/{lat},{lon}?units={unit}' async with aiohttp.ClientSession() as session: async with session.get(req_url) as data: search_data = await data.read() data = json.loads(search_data) curr = data['currently'] icon = curr['icon'] forecast = data['daily']['summary'] unit = data['flags'][ 'units'] if unit == 'auto' else unit dis, deg = get_dis_and_deg(unit, forecast) forecast_title = f'{icons[icon]["icon"]} {curr["summary"]}' response = discord.Embed(color=icons[icon]['color'], title=forecast_title) response.description = f'Location: {location}' response.add_field(name='📄 Forecast', value=forecast, inline=False) info_title = '🌡 Temperature' info_text = f'Current: {round(curr["temperature"], 2)}{deg}' info_text += f'\nFeels Like: {round(curr["apparentTemperature"], 2)}{deg}' info_text += f'\nDew Point: {round(curr["dewPoint"], 2)}{deg}' response.add_field(name=info_title, value=info_text) wind_title = '💨 Wind' wind_text = f'Speed: {round(curr["windSpeed"], 2)} {dis}/H' wind_text += f'\nGust: {round(curr["windGust"], 2)} {dis}/H' wind_text += f'\nBearing: {curr["windBearing"]}°' response.add_field(name=wind_title, value=wind_text) other_title = '📉 Other' other_text = f'Humidity: {round(curr["humidity"] * 100, 2)}%' other_text += f'\nPressure: {round(curr["pressure"], 2)}mbar' if 'visibility' in curr: other_text += f'\nVisibility: {round(curr["visibility"], 2)} {dis}' else: other_text += '\nVisibility: Unknown' response.add_field(name=other_title, value=other_text) else: response = GenericResponse( 'Location not found.').not_found() else: response = GenericResponse('Missing location.').error() else: response = GenericResponse('Nothing inputted.').error() else: response = GenericResponse('The API Key is missing.').error() await pld.msg.channel.send(embed=response)
async def unqueue(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: if pld.msg.author.voice: same_bound = True if pld.msg.guild.voice_client: if pld.msg.guild.voice_client.channel.id != pld.msg.author.voice.channel.id: same_bound = False if same_bound: if pld.msg.guild.voice_client: queue = cmd.bot.music.get_queue(pld.msg.guild.id) if not queue.empty(): try: order_num = int(pld.args[0]) if order_num >= 1: order_num -= 1 queue_list = await cmd.bot.music.listify_queue( queue) queue_size = len(queue_list) if order_num <= queue_size - 1: item = queue_list[order_num] is_mod = pld.msg.author.guild_permissions.manage_guild is_req = item.requester.id == pld.msg.author.id if is_mod or is_req: queue_list.remove(item) new_queue = Queue() for list_item in queue_list: await new_queue.put(list_item) cmd.bot.music.queues.update( {pld.msg.guild.id: new_queue}) response = GenericResponse( f'Removed {item.title}.').ok() requester = f'{pld.msg.author.name}#{pld.msg.author.discriminator}' response.set_author(name=requester, icon_url=user_avatar( pld.msg.author)) else: auth_deny_desc = f'Sorry, {pld.msg.author.name}. To remove a song you need to be' auth_deny_desc += ' the person who requested it, or have the Manage Server' auth_deny_desc += f' permission on {pld.msg.guild.name}.' response = discord.Embed(color=0xBE1931) response.add_field(name='⛔ Access Denied', value=auth_deny_desc) else: response = GenericResponse( 'Input out of range.').error() except ValueError: response = GenericResponse( 'Invalid input. Numbers only.').error() else: response = GenericResponse( 'The queue is empty.').error() else: response = GenericResponse( 'I am not connected to any channel.').error() else: response = GenericResponse( 'You are not in my voice channel.').error() else: response = GenericResponse( 'You are not in a voice channel.').error() else: response = GenericResponse('Nothing inputted.').error() await pld.msg.channel.send(embed=response)
async def queue(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ page_num = False if len(pld.args) == 1: if pld.args[0].isdigit(): page_num = int(pld.args[0]) if pld.args and not page_num: if pld.msg.author.voice: same_bound = True if pld.msg.guild.voice_client: if pld.msg.guild.voice_client.channel.id != pld.msg.author.voice.channel.id: same_bound = False if same_bound: lookup = ' '.join(pld.args) if '/watch?' in lookup: lookup = lookup.split('&')[0] playlist_url = False init_response = discord.Embed(color=0xFFCC66, title='💽 Processing URL...') elif '/playlist?' in lookup: playlist_url = True init_response = discord.Embed(color=0xFFCC66, title='💽 Processing playlist. This might take a long time...') else: if lookup.startswith('http'): playlist_url = True else: playlist_url = False init_response = discord.Embed(color=0xFFCC66, title='💽 Searching...') init_res_msg = await pld.msg.channel.send(embed=init_response) extracted_info = await cmd.bot.music.extract_info(lookup) if extracted_info: if '_type' in extracted_info: if extracted_info['_type'] == 'playlist': if not playlist_url: song_item = extracted_info['entries'][0] playlist = False else: song_item = None playlist = True else: song_item = extracted_info playlist = False else: song_item = extracted_info playlist = False if playlist: pl_title = extracted_info['title'] entries = extracted_info['entries'] for song_entry in entries: if song_entry: queue_item = QueueItem(pld.bot, pld.msg.author, song_entry) queue_container = cmd.bot.music.get_queue(pld.msg.guild.id) await queue_container.put(queue_item) final_resp = discord.Embed(color=0xFFCC66, title=f'💽 Added {len(entries)} songs from {pl_title}.') else: if song_item: queue_item = QueueItem(pld.bot, pld.msg.author, song_item) queue_container = cmd.bot.music.get_queue(pld.msg.guild.id) await queue_container.put(queue_item) duration = str(datetime.timedelta(seconds=int(song_item.get('duration', 0)))) requester = f'{pld.msg.author.name}#{pld.msg.author.discriminator}' final_resp = discord.Embed(color=0x66CC66) final_resp.add_field(name='✅ Added To Queue', value=song_item.get('title', "No Title")) if 'thumbnail' in song_item: final_resp.set_thumbnail(url=song_item.get('thumbnail')) final_resp.set_author(name=requester, icon_url=user_avatar(pld.msg.author)) final_resp.set_footer(text=f'Duration: {duration}') else: final_resp = GenericResponse('Addition returned a null item.').not_found() try: await init_res_msg.edit(embed=final_resp) except discord.NotFound: pass else: final_resp = GenericResponse('No results.').not_found() try: await init_res_msg.edit(embed=final_resp) except discord.NotFound: pass else: if not pld.args: response = GenericResponse('You are not in my voice channel.').error() await pld.msg.channel.send(embed=response) else: if not pld.args: response = GenericResponse('You are not in a voice channel.').error() await pld.msg.channel.send(embed=response) else: music_queue = cmd.bot.music.get_queue(pld.msg.guild.id) if not music_queue.empty(): music_list_all = await cmd.bot.music.listify_queue(music_queue) stats_desc = f'There are **{len(music_list_all)}** songs in the queue.' if pld.msg.guild.id in cmd.bot.music.currents: curr = cmd.bot.music.currents[pld.msg.guild.id] stats_desc += f'\nCurrently playing: [{curr.title}]({curr.url})' list_desc_list = [] boop_headers = ['#', 'Title', 'Requester', 'Duration'] order_num = 0 page = page_num if page_num else 1 music_list, page = PaginatorCore.paginate(music_list_all, page, 5) for item in music_list: order_num += 1 duration = str(datetime.timedelta(seconds=item.duration)) title = item.title if ' - ' in title: title = ' - '.join(title.split('-')[1:]).strip() title = shorten(title, 20, '...') req = shorten(item.requester.name, 9, '...') list_desc_list.append([order_num, title, req, duration]) list_desc = boop(list_desc_list, boop_headers) list_title = f'Queued Items on Page {page}' response = discord.Embed(color=0x3B88C3) guild_icon = str(pld.msg.guild.icon_url) if pld.msg.guild.icon_url else discord.Embed.Empty response.set_author(name=pld.msg.guild.name, icon_url=guild_icon) response.add_field(name='Current Music Queue', value=stats_desc, inline=False) response.add_field(name=list_title, value=f'```bat\n{list_desc}\n```', inline=False) else: response = discord.Embed(color=0x3B88C3, title='🎵 The queue is empty.') await pld.msg.channel.send(embed=response)
async def commands(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: lookup = pld.args[0].lower() command_items = cmd.bot.modules.commands command_list = [] for command in command_items: command = command_items[command] category = command.category.lower() if category == lookup: if pld.msg.guild: permission = ServerCommandPermissions(command, pld.msg) await permission.check_perms() else: permission = None command_list.append([command, permission]) if command_list: module_list = sorted(command_list, key=lambda x: x[0].name) module_count = len(module_list) page = pld.args[1] if len(pld.args) > 1 else 1 module_list, page = PaginatorCore.paginate(module_list, page, 30) output = '' for module_item, module_perm in module_list: if module_perm: if module_perm.permitted: output += f'\n- {module_item.name}' else: output += f'\n- ⛔ {module_item.name}' else: output += f'\n- {module_item.name}' if module_item.alts: output += f' [{", ".join(module_item.alts)}]' if output: title_text = f'```py\nThere are {module_count} commands.\n```' response = discord.Embed(color=0x1B6F5F) response.add_field(name=f'{lookup.upper()} Commands', value=title_text, inline=False) response.add_field(name=f'Commands List | Page {page}', value=f'```yml\n{output}\n```', inline=False) else: response = GenericResponse( f'No commands on page {page}.').not_found() else: response = GenericResponse('Module not found.').not_found() else: pfx = cmd.db.get_prefix(pld.settings) command_list = cmd.bot.modules.commands module_list = [] for command in command_list: command = command_list[command] category = command.category.upper() if category not in module_list: module_list.append(category) module_list = sorted(module_list) output = '' for module_item in module_list: output += f'\n- {module_item}' module_list_out = f'```py\nThere are {len(module_list)} modules.\n```' response = discord.Embed(color=0x1B6F5F) response.add_field(name='Modules', value=module_list_out, inline=False) response.add_field(name='Module List', value=f'```yml\n{output}\n```', inline=False) response.set_footer( text= f'Type {pfx}{cmd.name} [module] to see commands in that module.') await pld.msg.channel.send(embed=response)
async def jisho(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ jisho_q = ' '.join(pld.args) async with aiohttp.ClientSession() as session: async with session.get( 'http://jisho.org/api/v1/search/words?keyword=' + jisho_q) as data: rq_text = await data.text() rq_data = await data.read() rq_json = json.loads(rq_data) if rq_text.find('503 Service Unavailable') != -1: response = GenericResponse( 'Jisho responded with 503 Service Unavailable.').error() await pld.msg.channel.send(embed=response) return request = rq_json # check if response contains data or nothing was found if request['data']: request = request['data'][0] else: response = GenericResponse( f'Sorry, couldn\'t find anything matching `{jisho_q}`').not_found( ) await pld.msg.channel.send(embed=response) return output = '' starter = '' # if the word doesn't have kanji, print out the kana alone try: starter += f"{request['japanese'][0]['word']} [{request['japanese'][0]['reading']}]" except KeyError: try: starter += f"{request['japanese'][0]['reading']}" except KeyError: pass wk_lvls = [] for tag in request['tags']: if tag.find('wanikani') != -1: wk_lvls.append(tag[8:]) if len(request['senses']) > 5: definitons_len = 5 else: definitons_len = len(request['senses']) for i in range(0, definitons_len): etc = [] if 'english_definitions' in request['senses'][i]: output += f"\n{i + 1}. {'; '.join(request['senses'][i]['english_definitions'])}" if request['senses'][i]['parts_of_speech']: parts_of_speech = '' for part_of_speech in request['senses'][i]['parts_of_speech']: if part_of_speech: parts_of_speech += part_of_speech + ', ' etc.append(parts_of_speech[:-2]) if request['senses'][i]['tags']: try: etc.append('; '.join(request['senses'][i]['tags'])) except IndexError: pass except KeyError: pass if request['senses'][i]['see_also']: etc.append( f"See also {', '.join(request['senses'][i]['see_also'])}") if request['senses'][i]['info']: etc.append('; '.join(request['senses'][i]['info'])) # attaching definition tags if etc: if etc[0]: etc_string = ', '.join(etc) output += f'\n| *{etc_string}*' if len(request['senses']) > 5: hidden = len(request['senses']) - 5 if hidden == 1: output += f'\n\n- {hidden} definition is hidden' else: output += f'\n\n- {hidden} definitions are hidden' other_forms = '' if len(request['japanese']) > 1: other_forms = '' for i in range(1, len(request['japanese'])): if 'word' in request['japanese'][i]: other_forms += request['japanese'][i]['word'] + '、' search_url = f'http://jisho.org/search/{jisho_q.replace(" ", "%20")}' jisho_icon = 'https://i.imgur.com/X1fCJLV.png' response = discord.Embed(color=0xF9F9F9) response.set_author(name='Jisho.org', url=search_url, icon_url=jisho_icon) response.add_field(name=f'{starter if starter else jisho_q}', value=output) if other_forms: footer_text = f'Other forms: {other_forms[:-1]}' if request['is_common']: footer_text += ' | Common Word' if wk_lvls: footer_text += f" | Wanikani Level {', '.join(wk_lvls)}" response.set_footer(text=footer_text) await pld.msg.channel.send(embed=response)
async def impersonate_local(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ target, limit, beginning = parse_args(pld) if target: if os.path.exists(f'chains/{target.id}.json.gz'): chain_data = await cmd.bot.threader.execute(load, (target.id, )) if chain_data: chain_json = await cmd.bot.threader.execute( deserialize, (chain_data, )) chain = await cmd.bot.threader.execute( markovify.Text.from_dict, (chain_json, )) try: if beginning: sentence_func = chain.make_sentence_with_start sentence_args = ( beginning, False, ) else: sentence_func = chain.make_short_sentence sentence_args = (limit, ) sentence = await cmd.bot.threader.execute( sentence_func, sentence_args) except (KeyError, ValueError, AttributeError): sentence = None except markovify.text.ParamError: if not beginning: sentence = None else: ender = 'word' if len( beginning.split()) == 1 else 'phrase' error_title = f'😖 I could not think of anything with that {ender}.' response = discord.Embed(color=0xBE1931, title=error_title) await pld.msg.channel.send(embed=response) return if not sentence: not_enough_data = '😖 I could not think of anything... I need more chain items!' response = discord.Embed(color=0xBE1931, title=not_enough_data) else: response = discord.Embed(color=0xbdddf4) response.set_author(name=target.name, icon_url=user_avatar(target)) response.add_field(name='💭 Hmm... something like...', value=ensure_length(sentence)) else: response = GenericResponse( f'{target.name}\'s chain has no data.').error() else: response = discord.Embed(color=0x696969) prefix = cmd.db.get_prefix(pld.settings) title = f'🔍 Chain Data Not Found For {target.name}' value = f'You can make one with `{prefix}collectchain @{target.name} #channel`!' response.add_field(name=title, value=value) else: response = GenericResponse('No user targeted.').error() await pld.msg.channel.send(embed=response)
async def wftrials(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: username = '******'.join(pld.args) trials_url = f'https://api.trials.wf/api/player/pc/{username}/completed' async with aiohttp.ClientSession() as session: async with session.get(trials_url) as data: trial_data = await data.read() trial_data = json.loads(trial_data) if len(trial_data) == 0: response = GenericResponse( f'User {username} Not Found.').not_found() else: # noinspection PyBroadException try: username_proper = get_usercaps(username, trial_data) raidlist_url = f'https://trials.wf/player/?user={username_proper}' # LoR lor_deaths = 0 lor_kills = 0 lor_time_total = 0 lor_time_short = 0 lor_count = 0 lor_won = 0 lor_failed = 0 # LoR NM lornm_deaths = 0 lornm_kills = 0 lornm_time_total = 0 lornm_time_short = 0 lornm_count = 0 lornm_won = 0 lornm_failed = 0 # JV jv_deaths = 0 jv_kills = 0 jv_time_total = 0 jv_time_short = 0 jv_count = 0 jv_won = 0 jv_failed = 0 # Calculate Data for trial in trial_data: if trial['type'] == 'lor': lor_deaths += trial['deaths'] lor_kills += trial['kills'] lor_time_total += convert_to_seconds(trial['time']) if lor_time_short == 0: lor_time_short = convert_to_seconds(trial['time']) else: if lor_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': lor_time_short = convert_to_seconds( trial['time']) lor_count += 1 if trial['objective'] == 'VICTORY': lor_won += 1 elif trial['objective'] == 'FAILED': lor_failed += 1 elif trial['type'] == 'lornm': lornm_deaths += trial['deaths'] lornm_kills += trial['kills'] lornm_time_total += convert_to_seconds(trial['time']) lornm_count += 1 if trial['objective'] == 'VICTORY': lornm_won += 1 elif trial['objective'] == 'FAILED': lornm_failed += 1 if lornm_time_short == 0: lornm_time_short = convert_to_seconds( trial['time']) else: if lornm_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': lornm_time_short = convert_to_seconds( trial['time']) elif trial['type'] == 'jv': jv_deaths += trial['deaths'] jv_kills += trial['kills'] jv_time_total += convert_to_seconds(trial['time']) jv_count += 1 if trial['objective'] == 'VICTORY': jv_won += 1 elif trial['objective'] == 'FAILED': jv_failed += 1 if jv_time_short == 0: jv_time_short = convert_to_seconds(trial['time']) else: if jv_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': jv_time_short = convert_to_seconds( trial['time']) # Total total_deaths = lor_deaths + lornm_deaths + jv_deaths total_kills = lor_kills + lornm_kills + jv_kills total_time_total = lor_time_total + lornm_time_total + jv_time_total total_time_short = 0 short_times = [lor_time_short, lornm_time_short, jv_time_short] for short_time in short_times: if total_time_short == 0: total_time_short = short_time else: if total_time_short > short_time: total_time_short = short_time total_count = lor_count + lornm_count + jv_count total_won = lor_won + lornm_won + jv_won total_failed = lor_failed + lornm_failed + jv_failed # Make Descriptions try: lor_desc = f'Total: {lor_count}' lor_desc += f'\nWin/Lose: {lor_won}/{lor_failed}' lor_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lor_time_total))}' lor_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(lor_time_total // lor_count)))}' lor_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lor_time_short))}' lor_desc += f'\nKills: {lor_kills}' lor_desc += f'\nAverage Kills: {lor_kills // lor_count}' lor_desc += f'\nDeaths: {lor_deaths}' lor_desc += f'\nAverage Deaths: {lor_deaths // lor_count}' except ZeroDivisionError: lor_desc = 'Invalid Data' try: lornm_desc = f'Total: {lornm_count}' lornm_desc += f'\nWin/Lose: {lornm_won}/{lornm_failed}' lornm_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lornm_time_total))}' lornm_avg_sec = lornm_time_total // lornm_count lornm_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=lornm_avg_sec))}' lornm_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lornm_time_short))}' lornm_desc += f'\nKills: {lornm_kills}' lornm_desc += f'\nAverage Kills: {lornm_kills // lornm_count}' lornm_desc += f'\nDeaths: {lornm_deaths}' lornm_desc += f'\nAverage Deaths: {lornm_deaths // lornm_count}' except ZeroDivisionError: lornm_desc = 'Invalid Data' try: jv_desc = f'Total: {jv_count}' jv_desc += f'\nWin/Lose: {jv_won}/{jv_failed}' jv_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=jv_time_total))}' jv_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(jv_time_total // jv_count)))}' jv_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=jv_time_short))}' jv_desc += f'\nKills: {jv_kills}' jv_desc += f'\nAverage Kills: {jv_kills // jv_count}' jv_desc += f'\nDeaths: {jv_deaths}' jv_desc += f'\nAverage Deaths: {jv_deaths // jv_count}' except ZeroDivisionError: jv_desc = 'Invalid Data' try: total_desc = f'Total: {total_count}' total_desc += f'\nWin/Lose: {total_won}/{total_failed}' total_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=total_time_total))}' total_desc += '\nAverage Time: ' total_desc += f'{str(datetime.timedelta(seconds=(total_time_total // total_count)))}' total_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=total_time_short))}' total_desc += f'\nKills: {total_kills}' total_desc += f'\nAverage Kills: {total_kills // total_count}' total_desc += f'\nDeaths: {total_deaths}' total_desc += f'\nAverage Deaths: {total_deaths // total_count}' except ZeroDivisionError: total_desc = 'Invalid Data' response = discord.Embed(color=0xa12626) response.set_thumbnail(url='https://i.imgur.com/pf89nIk.png') response.set_author(name=username_proper, icon_url='https://i.imgur.com/n0EESkn.png', url=raidlist_url) response.add_field(name='Law of Retribution', value=lor_desc) response.add_field(name='Nightmare LoR', value=lornm_desc) response.add_field(name='Jordas Verdict', value=jv_desc) response.add_field(name='Total Trials', value=total_desc) except Exception: response = GenericResponse( f'Stats for {username} were found but contained errors.' ).warn() await pld.msg.channel.send(embed=response)