async def print_results(self, ctx, results): msg = ctx.message nbs = '' discord_fmt = nbs + '```py\n{}\n```' is_interactive = self.settings["OUTPUT_REDIRECT"] == "pages" res_len = len(discord_fmt.format(results)) if is_interactive and res_len > self.settings["PAGES_LENGTH"]: single_msg = not self.settings["MULTI_MSG_PAGING"] page = self.pagify_interactive_results(ctx, results, single_msg=single_msg) self.bot.loop.create_task(page) elif res_len > 2000: if self.settings["OUTPUT_REDIRECT"] == "pm": await self.bot.send_message(msg.channel, 'Content too big. Check your PMs') enough_paper = self.settings["PM_PAGES"] for page in pagify(results, ['\n', ' '], shorten_by=12): await self.bot.send_message(msg.author, discord_fmt.format(page)) enough_paper -= 1 if not enough_paper: await self.bot.send_message(msg.author, "**Too many pages! Think of the trees!**") return elif self.settings["OUTPUT_REDIRECT"] == "console": await self.bot.send_message(msg.channel, 'Content too big. Check your console') print(results) else: await self.bot.send_message(msg.channel, 'Content too big. Writing to file') with open(self.output_file, 'w') as f: f.write(results) open_cmd = self.settings["OPEN_CMD"] if open_cmd: subprocess.Popen([open_cmd, self.output_file]) else: await self.bot.send_message(msg.channel, discord_fmt.format(results))
async def discover_server(self, author: discord.User): output = "" servers = sorted(self.bot.servers, key=lambda s: s.name) for i, server in enumerate(servers, 1): output += "{}: {}\n".format(i, server.name) output += "Select a server to add to the sync list by number, " 'or enter "-1" to stop adding servers' for page in pagify(output, delims=["\n"]): dm = await self.bot.send_message(author, box(page)) message = await self.bot.wait_for_message(channel=dm.channel, author=author, timeout=15) if message is not None: try: message = int(message.content.strip()) if message == -1: return -1 else: server = servers[message - 1] except (ValueError, IndexError): await self.bot.send_message(author, "That wasn't a valid choice") return None else: return server else: await self.bot.say("You took too long, try again later") return None
async def penis(self, ctx, *users: discord.Member): """Detects user's penis length This is 100% accurate. Enter multiple users for an accurate comparison!""" if not users: await self.bot.send_cmd_help(ctx) return dongs = {} msg = "" state = random.getstate() for user in users: random.seed(user.id) dongs[user] = "8{}D".format("=" * random.randint(0, 30)) random.setstate(state) dongs = sorted(dongs.items(), key=lambda x: x[1]) for user, dong in dongs: msg += "**{}'s size:**\n{}\n".format(user.display_name, dong) for page in pagify(msg): await self.bot.say(page)
async def racfaudit_top(self, ctx, count: int): """Show top N members in family.""" await self.bot.type() try: member_models = await self.family_member_models() except ClashRoyaleAPIError as e: await self.bot.say(e.status_message) return author = ctx.message.author if not author.server_permissions.manage_roles: count = min(count, 10) member_models = sorted(member_models, key=lambda x: x['trophies'], reverse=True) results = member_models[:count] out = [] for index, member in enumerate(results, 1): out.append('{:<4} {:>4} {:<8} {}'.format( index, member['trophies'], member['clan']['name'][5:], member['name'] )) for page in pagify('\n'.join(out)): await self.bot.say(box(page, lang='py'))
async def _global_leaderboard(self, top: int=10): """Prints out the global leaderboard Defaults to top 10""" if top < 1: top = 10 bank_sorted = sorted(self.bank.get_all_accounts(), key=lambda x: x.balance, reverse=True) bank_sorted = [a for a in bank_sorted if a.member] # exclude users who left unique_accounts = [] for acc in bank_sorted: if not self.already_in_list(unique_accounts, acc): unique_accounts.append(acc) if len(unique_accounts) < top: top = len(unique_accounts) topten = unique_accounts[:top] highscore = "" place = 1 for acc in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += ("{} |{}| ".format(acc.member, acc.server) ).ljust(23 - len(str(acc.balance))) highscore += str(acc.balance) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("There are no accounts in the bank.")
async def list(self, ctx, user: discord.Member = None): """ Print out a user's game list (sends as a DM) user: (Optional) If given, list a user's game library, otherwise list the message user's library """ author = ctx.message.author if not user: user = author game_list = get_games() if check_key(user.id) and game_list.get(user.id, False): message = pagify(", ".join(sorted(game_list[user.id])), [', ']) await self.bot.say( "Please check your DM for the full list of games, {}.".format( author.mention)) await self.bot.send_message(author, "{}'s games:".format(user.mention)) for page in message: await self.bot.send_message(author, (box(page))) else: await self.bot.say( "{}, you do not have any games. Add one using `[p]game add <game_name>` and/or link your Steam profile with `[p]game steamlink <steam_id>`." .format(user.mention))
async def karmaboard(self, top: int=10): """Prints out the karma leaderboard Defaults to top 10. Use negative numbers to reverse the leaderboard.""" reverse=True if top == 0: top = 10 elif top < 0: reverse=False top = -top self.karma = dataIO.load_json(KARMA_PATH) members_sorted = sorted(self._get_all_members(), key=lambda x: x.karma, reverse=reverse) if len(members_sorted) < top: top = len(members_sorted) topten = members_sorted[:top] highscore = "" place = 1 for member in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += ("{} | ".format(member.name) ).ljust(18 - len(str(member.karma))) highscore += str(member.karma) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("No one has any karma �")
async def _server_leaderboard(self, ctx, top: int = 10): """Prints out the server's leaderboard Defaults to top 10""" # Originally coded by Airenkun - edited by irdumb server = ctx.message.server if top < 1: top = 10 bank_sorted = sorted(self.bank.get_server_accounts(server), key=lambda x: x.balance, reverse=True) bank_sorted = [a for a in bank_sorted if a.member] # exclude users who left if len(bank_sorted) < top: top = len(bank_sorted) topten = bank_sorted[:top] highscore = "" place = 1 for acc in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += (str(acc.member.display_name) + " ").ljust(23 - len(str(acc.balance))) highscore += str(acc.balance) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): #Adding info site. siteInfo = "\nFull rankings at https://ren.injabie3.moe/economy" sleepTime = 60 msgId = await self.bot.say(box(page, lang="py") + siteInfo) await asyncio.sleep(sleepTime) await self.bot.delete_message(msgId) else: await self.bot.say("There are no accounts in the bank.")
async def partycrash(self, ctx, idnum=None): """Lists servers and generates invites for them""" owner = ctx.message.author if idnum: server = discord.utils.get(self.bot.servers, id=idnum) if server: await self._confirm_invite(server, owner, ctx) else: await self.bot.say("I'm not in that server") else: msg = "" servers = sorted(self.bot.servers, key=lambda s: s.name) for i, server in enumerate(servers, 1): msg += "{}: {}\n".format(i, server.name) msg += "\nTo post an invite for a server just type its number." for page in pagify(msg, delims=["\n"]): await self.bot.say(box(page)) await asyncio.sleep(1.5) # Just in case for rate limits msg = await self.bot.wait_for_message(author=owner, timeout=15) if msg is not None: try: msg = int(msg.content.strip()) server = servers[msg - 1] except ValueError: await self.bot.say("You must enter a number.") except IndexError: await self.bot.say("Index out of range.") else: try: await self._confirm_invite(server, owner, ctx) except discord.Forbidden: await self.bot.say("I'm not allowed to make an invite" " for {}".format(server.name)) else: await self.bot.say("Response timed out.")
async def discover_server(self, author: discord.User): shared_servers = [] for server in self.bot.servers: x = server.get_member(author.id) if x is not None: shared_servers.append(server) if len(shared_servers) == 1: return shared_servers[0] output = "" servers = sorted(shared_servers, key=lambda s: s.name) for i, server in enumerate(servers, 1): output += "{}: {}\n".format(i, server.name) output += "\npick the server to make a report in by its number." for page in pagify(output, delims=["\n"]): dm = await self.bot.send_message(author, box(page)) message = await self.bot.wait_for_message(channel=dm.channel, author=author, timeout=45) if message is not None: try: message = int(message.content.strip()) server = servers[message - 1] except (ValueError, IndexError): await self.bot.send_message(author, "That wasn't a valid choice") return None else: return server else: await self.bot.say("You took too long, try again later") return None
async def _global_leaderboard(self, top: int=10): """Prints out the global leaderboard Defaults to top 10""" if top < 1: top = 10 bank_sorted = sorted(self.bank.get_all_accounts(), key=lambda x: x.balance, reverse=True) unique_accounts = [] for acc in bank_sorted: if not self.already_in_list(unique_accounts, acc): unique_accounts.append(acc) if len(unique_accounts) < top: top = len(unique_accounts) topten = unique_accounts[:top] highscore = "" place = 1 for acc in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += ("{} |{}| ".format(acc.name, acc.server.name) ).ljust(23 - len(str(acc.balance))) highscore += str(acc.balance) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("There are no accounts in the bank.")
async def whisper(self, ctx, user: discord.User, text): """Whisper to someone using the bot Same as dming But you use the bot !""" author = ctx.message.author channel = ctx.message.channel try: await self.bot.delete_message(ctx.message) except: raise Exception( "Bruh i don't have delete messages perms delete your messaqe") prefix = "Ayoo Matey you Getting a Message from {} ({})".format( author.name, author.id) payload = "{}\n\n``` ***```{}```***".format(prefix, text) try: for page in pagify(payload, delims=[" ", "\n"], shorten_by=10): await self.bot.send_message(user, box(page)) except discord.errors.Forbidden: log.debug( "I CAN'T F*****G SEND MSGS TO {} FFS DID HE BLOCK Me ! Or maybe he just has that teng where randoms can't msg :thinking: o well ¯\_(ツ)_/¯" .format(user)) except (discord.errors.NotFound, discord.errors.InvalidArgument): log.debug("{} *404* Dis bitch not found~".format(user)) else: reply = await self.bot.say( "Whisper Mcfucking *** Delivered*** https://goo.gl/3qCxR4 ") await asyncio.sleep(5) await self.bot.delete_message(reply)
async def _blacklist_list(self, ctx): """Lists currently blacklisted channels.""" channel = ctx.message.channel if channel.is_private: if channel.id in self.settings["BLACKLIST"]: return await self.bot.say("This channel is blacklisted.") else: return await self.bot.say("This channel is not blacklisted.") else: if self.settings["BLACKLIST"]: is_owner = ctx.message.author.id == self.bot.settings.owner channels = [] for c in self.settings["BLACKLIST"]: channel = discord.utils.get(self.bot.get_all_channels() if is_owner else ctx.message.server.channels, id=c) if channel: channels.append(channel) else: if is_owner: channels.append("Unknown ({})".format(c)) if channels: for page in pagify("Blacklist: {}".format(", ".join( channels)), [", "]): return await self.bot.say("```{}```".format( page.strip(", "))) return await self.bot.say("The blacklist is empty.")
async def mention(self, ctx, name: str): server = ctx.message.server author = ctx.message.author channel = ctx.message.channel self.init_settings(server) name = name.lower() if name not in self.raffles[server.id]: return await self.bot.say("No such raffle.") r = self.raffles[server.id][name] entries = r.registered members = [] for e in entries: x = server.get_member(e) if x is not None: members.append(x) output = "" if channel.permissions_for(author).mention_everyone: for member in members: output += "{0.mention} , ".format(member) else: for member in members: output += "\n{0.id}: {0.display_name}".format(member) for page in pagify(output, delims=["\n", ","]): await self.bot.say(page)
async def leaderboard(self, ctx, top=10): """Displays the win/loss leaderboard""" server = ctx.message.server if top < 1: top = 10 entries_sorted = sorted(self.arena.get_entries(server), key=lambda x: x.wins, reverse=True) entries_sorted = [a for a in entries_sorted if a.member] if len(entries_sorted) < top: top = len(entries_sorted) topentries = entries_sorted[:top] highscore = "Wins Losses\n".rjust(23) place = 1 for acc in topentries: highscore += str(place).ljust(len(str(top)) + 1) highscore += ( str(acc.member.display_name) + " ").ljust(23 - len(str(acc.wins) + " " + str(acc.losses))) highscore += str(acc.wins) + " " + str(acc.losses) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("There are no accounts in the leaderboard")
async def todo(self, cmd): '''Make your own ToDo list and manage it''' if cmd.invoked_subcommand is None: try: user = str(cmd.message.author) index = 0 if len(self.config[user]) != 0: msg = '' for i in self.config[user]: msg += '*{0}*: {1}\n'.format(index, i) index += 1 page_index = 1 pages = pagify(msg) for page in pages: nick = cmd.message.author.nick or cmd.message.author.name embed = discord.Embed(description=page) embed.title = '{}\'s ToDo of {} things'.format( nick, len(self.config[user])) embed.colour = discord.Colour.green() embed.set_footer( text='Part {}'.format(page_index), icon_url='https://yamahi.eu/favicon.ico') await self.bot.say(embed=embed) page_index += 1 else: await self.bot.say('You have nothing to do! :D') except KeyError: await self.bot.say('You have nothing to do! :D') except: await self.bot.say('An error happened?!')
async def emojis(self, ctx: Context, embed=False): """Show all emojis available on server.""" server = ctx.message.server if embed: emoji_list = [ emoji for emoji in server.emojis if not emoji.managed ] emoji_lists = grouper(25, emoji_list) for emoji_list in emoji_lists: em = discord.Embed() for emoji in emoji_list: if emoji is not None: em.add_field(name=str(emoji), value="`:{}:`".format(emoji.name)) await self.bot.say(embed=em) else: out = [] for emoji in server.emojis: # only include in list if not managed by Twitch if not emoji.managed: emoji_str = str(emoji) out.append("{} `:{}:`".format(emoji_str, emoji.name)) for page in pagify("\n".join(out), shorten_by=12): await self.bot.say(page)
async def listclones(self, ctx): """Lists the current autorooms""" server = ctx.message.server if server.id not in self.settings: self.initial_config(server.id) channels = self.settings[server.id]['channels'] if len(channels) == 0: return await self.bot.say("No autorooms set for this server") fix_list = [] output = "Current Auto rooms\nChannel ID: Channel Name" for c in channels: channel = discord.utils.find( lambda m: m.id == c, server.channels ) if channel is None: fix_list.append(c) else: output += "\n{}: {}".format(c, channel.name) for page in pagify(output, delims=["\n", ","]): await self.bot.send_message(ctx.message.author, box(page)) for c in fix_list: channels.remove(c) self.save_json
async def opensource(self, ctx, channel): """Makes you able to communicate with other channels. This is cross-server. Type only the channel name or the ID.""" author = ctx.message.author author_channel = ctx.message.channel def check(m): try: return channels[int(m.content)] except: return False channels = self.bot.get_all_channels() channels = [ c for c in channels if c.name.lower() == channel or c.id == channel ] channels = [c for c in channels if c.type == discord.ChannelType.text] if not channels: await self.bot.say("No channels found. Remember to type just " "the channel name, no `#`.") return if len(channels) > 1: msg = "Multiple results found.\nChoose a server:\n" for i, channel in enumerate(channels): msg += "{} - {} ({})\n".format(i, channel.server, channel.id) for page in pagify(msg): await self.bot.say(page) choice = await self.bot.wait_for_message(author=author, timeout=30, check=check, channel=author_channel) if choice is None: await self.bot.say("You haven't chosen anything.") return channel = channels[int(choice.content)] else: channel = channels[0] rift = OpenRift(source=author_channel, destination=channel) self.open_rifts[author] = rift await self.bot.say( "A source has been opened! Everything you say " "will be relayed to that channel.\n" "Responses will be relayed here.\nType `exit` to quit.") msg = "" while msg == "" or msg is not None: msg = await self.bot.wait_for_message(author=author, channel=author_channel) if msg is not None and msg.content.lower() != "exit": try: await self.bot.send_message(channel, msg.content) except: await self.bot.say("Couldn't send your message.") else: break del self.open_rifts[author] await self.bot.say("Source closed.")
async def calendar_list(self, ctx, max_results=5): """List events on a calendar.""" credentials = ServiceAccountCredentials.from_json_keyfile_name( SERVICE_KEY_JSON, scopes=SCOPES) http = credentials.authorize(httplib2.Http()) service = discovery.build('calendar', 'v3', http=http) now = dt.datetime.utcnow().isoformat() + 'Z' await self.bot.say( "Getting the upcoming {} events:".format(max_results)) eventsResult = service.events().list( calendarId=RACF_CALENDAR_ID, timeMin=now, maxResults=max_results, singleEvents=True, orderBy='startTime').execute() events = eventsResult.get('items', []) if not events: await self.bot.say("No upcoming events found.") out = [] for event in events: start = event['start'].get('dateTime', event['start'].get('date')) out.append(start) out.append(event['summary']) for page in pagify('\n'.join(out), shorten_by=24): await self.bot.say(page)
async def send_trade_list(self, channel, items): o = [] def sort_items(item): R = dict(Common=1, Rare=2, Epic=3, Legendary=4) return R.get(item.rarity), item.get_card, item.give_card items = sorted(items, key=sort_items) for item in items: time = dt.datetime.utcfromtimestamp(item.timestamp) d = item._asdict() d.update( dict(give_card_emoji=self.get_emoji(item.give_card), get_card_emoji=self.get_emoji(item.get_card), r=item.rarity[0].upper(), s='\u2800', time_span=format_timespan(time))) o.append( "Give: {give_card_emoji} Get: {get_card_emoji} `{s}{r} #{clan_tag:<9} {time_span}{s}`" .format(**d)) if not len(o): await self.bot.send_message( channel, "No items found matching your request.") return first_message = None for page in pagify("\n".join(o)): msg = await self.bot.send_message(channel, page) if first_message is None: first_message = msg return first_message
async def _server_leaderboard(self, ctx, top: int=10): """Prints out the server's leaderboard Defaults to top 10""" # Originally coded by Airenkun - edited by irdumb server = ctx.message.server if top < 1: top = 10 bank_sorted = sorted(self.bank.get_server_accounts(server), key=lambda x: x.balance, reverse=True) if len(bank_sorted) < top: top = len(bank_sorted) topten = bank_sorted[:top] highscore = "" place = 1 for acc in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += (acc.name + " ").ljust(23 - len(str(acc.balance))) highscore += str(acc.balance) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("There are no accounts in the bank.")
async def listroles(self, ctx: Context, *roles): """List all the roles on the server.""" server = ctx.message.server if server is None: return out = [] out.append("__List of roles on {}__".format(server.name)) roles_to_list = [] if len(roles): roles_to_list = [ r for r in server.roles if r.name.lower() in [r2.lower() for r2 in roles] ] else: roles_to_list = server.roles out_roles = {} for role in roles_to_list: out_roles[role.id] = {'role': role, 'count': 0} for member in server.members: for role in member.roles: if role in roles_to_list: out_roles[role.id]['count'] += 1 for role in server.role_hierarchy: if role in roles_to_list: out.append("**{}** ({} members)".format( role.name, out_roles[role.id]['count'])) for page in pagify("\n".join(out), shorten_by=12): await self.bot.say(page)
async def trigger_set_list(self): """List all active triggers.""" msg = '' if not (self.triggers['text_triggers'] or self.triggers['user_triggers']): await self.bot.say('There are no active triggers.') return if self.triggers['text_triggers']: msg += 'These are the active text triggers:\n' for text, emojis in self.triggers['text_triggers'].items(): emojis_str = " ".join( str(self._lookup_emoji(emoji)) for emoji in emojis) if not emojis_str: continue msg += '`{text}`: {emojis}\n'.format(text=text, emojis=emojis_str) if self.triggers['user_triggers']: msg += 'These are the active user triggers:\n' for user_id, emojis in self.triggers['user_triggers'].items(): user = discord.utils.get(self.bot.get_all_members(), id=user_id) emojis_str = " ".join( str(self._lookup_emoji(emoji)) for emoji in emojis) if user is None or not emojis_str: continue msg += '`{user}`: {emojis}\n'.format(user=str(user), emojis=emojis_str) for page in pagify(msg): await self.bot.say(page)
async def rlmention(self, ctx, *roles: discord.Role): """ mentions all of the users who are a part of at least one of the roles Will not mention by @ everyone, requires being a mod or the ability to manage messages You really should only use this on roles people opt into, but I'm also not going to try and enforce that. Use this responsibly. It's not my problem if you don't. """ _roles = set(r for r in roles if not r.is_everyone) if len(_roles) == 0: return await self.bot.say( "Hmm, you either didn't give me any roles, " "or all of the roles you gave " "me are not eligible for " "this command.") mentions = [ m.mention for m in ctx.message.server.members if not _roles.isdisjoint(m.roles) ] mention_str = ("Mass mention authorized by {} for members in " "one or more of the following roles: {}\n\n").format( ctx.message.author.mention, ", ".join(r.name for r in _roles)) mention_str += " ".join(mentions) for page in pagify(mention_str, delims=["\n", " "]): await self.bot.say(page)
async def list(self, ctx): """List all the current filtered words. Sends to DMs.""" server = ctx.message.server author = ctx.message.author if server.id not in self.settings: self.settings[server.id] = self.defaults msg = "Filterping is currently {}.\nCurrent filter list:\n".format( "ENABLED" if self.settings[server.id]["ENABLED"] else "disabled") items = [] for m in self.settings[server.id]["FILTER"].keys(): pings = [] for p in self.settings[server.id]["FILTER"][m]: p_member = server.get_member(p) if p_member is not None: pings.append(p_member.name) items.append("{}: pings {}".format( m, ", ".join(pings) if len(pings) > 0 else "nobody")) msg += "\n".join(items) if len(self.settings[server.id]["FILTER"].keys()) > 0: try: for page in pagify(msg, delims=["\n"], shorten_by=8): await self.bot.send_message(author, page) await self.bot.say("Sent to DMs.") except discord.Forbidden: await self.bot.say("I can't send DMs to you.") else: await self.bot.say("This server has no filters set up.")
async def _on_command_error(self, error, ctx: commands.Context): """Fires when a command error occurs.""" if not self.log_channels or not isinstance(error, commands.CommandInvokeError): return destinations = [c for c in self.bot.get_all_channels() if c.id in self.log_channels] destinations += [c for c in self.bot.private_channels if c.id in self.log_channels] error_title = "Exception in command `{}`".format(ctx.command.qualified_name) log = "".join(traceback.format_exception(type(error), error, error.__traceback__)) embed = discord.Embed(title=error_title, colour=discord.Colour.red(), timestamp=ctx.message.timestamp) embed.add_field(name="Invoker", value="{0.mention}\n({0})\nID: {0.id}".format(ctx.message.author)) embed.add_field(name="Content", value=ctx.message.content) channel = ctx.message.channel if channel.is_private: _channel_disp = "Private channel" else: _channel_disp = "{0.mention}\n({0})\nID: {0.id}".format(channel) embed.add_field(name="Channel", value=_channel_disp) if not channel.is_private: embed.add_field(name="Server", value="{0.name}\nID: {0.id}".format(ctx.message.server)) for channel in destinations: try: await self.bot.send_message(channel, embed=embed) except discord.errors.Forbidden: # If bot can't embed msg = ("Invoker: {}\n" "Content: {}\n" "Channel: {}".format(str(ctx.message.author), ctx.message.content, _channel_disp)) if not channel.is_private: msg += "\nServer : {}".format(ctx.message.server.name) await self.bot.send_message(channel, box(msg)) for page in pagify(log): await self.bot.send_message(channel, box(page, lang="py"))
async def _send_list(self, repo_name=None): """Lists installable cogs""" retlist = [] if repo_name and repo_name in self.repos: msg = "Available cogs:\n" for cog in sorted(self.repos[repo_name].keys()): if 'url' == cog: continue data = self.get_info_data(repo_name, cog) if data: retlist.append([cog, data.get("SHORT", "")]) else: retlist.append([cog, '']) else: msg = "Available repos:\n" for repo_name in sorted(self.repos.keys()): data = self.get_info_data(repo_name) if data: retlist.append([repo_name, data.get("SHORT", "")]) else: retlist.append([repo_name, ""]) col_width = max(len(row[0]) for row in retlist) + 2 for row in retlist: msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n" for page in pagify(msg, delims=['\n'], shorten_by=8): await self.bot.say(box(page))
async def _server_leaderboard(self, ctx, top: int=10): """Prints out the server's leaderboard Defaults to top 10""" # Originally coded by Airenkun - edited by irdumb server = ctx.message.server if top < 1: top = 10 bank_sorted = sorted(self.bank.get_server_accounts(server), key=lambda x: x.balance, reverse=True) bank_sorted = [a for a in bank_sorted if a.member] # exclude users who left if len(bank_sorted) < top: top = len(bank_sorted) topten = bank_sorted[:top] highscore = "" place = 1 for acc in topten: highscore += str(place).ljust(len(str(top)) + 1) highscore += (str(acc.member.display_name) + " ").ljust(23 - len(str(acc.balance))) highscore += str(acc.balance) + "\n" place += 1 if highscore != "": for page in pagify(highscore, shorten_by=12): await self.bot.say(box(page, lang="py")) else: await self.bot.say("There are no accounts in the bank.")
async def _send_list(self, repo_name=None): """Lists installable modules""" retlist = [] if repo_name and repo_name in self.repos: msg = "Available modules:\n" for cog in sorted(self.repos[repo_name].keys()): if 'url' == cog: continue data = self.get_info_data(repo_name, cog) if data and data.get("HIDDEN") is True: continue if data: retlist.append([cog, data.get("SHORT", "")]) else: retlist.append([cog, '']) else: if self.repos: msg = "Available repos:\n" for repo_name in sorted(self.repos.keys()): data = self.get_info_data(repo_name) if data: retlist.append([repo_name, data.get("SHORT", "")]) else: retlist.append([repo_name, ""]) else: await self.bot.say("You haven't added a repository yet.\n" "Start now! {}".format(REPOS_LIST)) return col_width = max(len(row[0]) for row in retlist) + 2 for row in retlist: msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n" msg += "\nRepositories list: {}".format(REPOS_LIST) for page in pagify(msg, delims=['\n'], shorten_by=8): await self.bot.say(box(page))
async def ownerkeenlog_users(self, ctx, *args): """Show debug""" parser = KeenLogger.parser() try: p_args = parser.parse_args(args) except SystemExit: await send_cmd_help(ctx) return await self.bot.type() server = ctx.message.server s = self.message_search.server_messages(server, p_args) results = [{ "author_id": doc.author.id, "channel_id": doc.channel.id, "timestamp": doc.timestamp, "rng_index": None, "rng_timestamp": None, "doc": doc } for doc in s.scan()] p = pprint.PrettyPrinter(indent="4") out = p.pformat(results) for page in pagify(out, shorten_by=80): await self.bot.say(box(page, lang='py'))
async def print_results(self, ctx, results): msg = ctx.message discord_fmt = '```py\n{}\n```' if len(discord_fmt.format(results)) > 2000: if self.settings["OUTPUT_REDIRECT"] == "pm": await self.bot.send_message(msg.channel, 'Content too big. Check your PMs') enough_paper = 20 for page in pagify(results, ['\n', ' '], shorten_by=12): await self.bot.send_message(msg.author, discord_fmt.format(page)) enough_paper -= 1 if not enough_paper: await self.bot.send_message( msg.author, "**Too many pages! Think of the trees!**") return elif self.settings["OUTPUT_REDIRECT"] == "console": await self.bot.send_message( msg.channel, 'Content too big. Check your console') print(results) else: await self.bot.send_message( msg.channel, 'Content too big. Writing to file') with open(self.output_file, 'w') as f: f.write(results) open_cmd = self.settings["OPEN_CMD"] if open_cmd: subprocess.Popen([open_cmd, self.output_file]) else: await self.bot.send_message(msg.channel, discord_fmt.format(results))
def page_results(self, results, single_msg=True): nbs = '' discord_fmt = nbs + '```py\n{}\n```' prompt = (" Output too long. Navigate pages with ({}close/next)" .format('' if single_msg else 'prev/')) pages = [p for p in pagify(results, ['\n', ' '], page_length=self.settings["PAGES_LENGTH"])] # results is not a generator, so no reason to keep this as one pages = [discord_fmt.format(p) + 'pg. {}/{}' .format(c + 1, len(pages)) for c, p in enumerate(pages)] pages[0] += prompt return pages
async def show(self, ctx, trigger_name : str): """Shows all responses of a trigger""" trigger = self.get_trigger_by_name(trigger_name) if trigger: payload = self.elaborate_payload(trigger.responses, truncate=9999) if payload: payload = "\n\n".join(payload) if len(payload) > 2000: for page in pagify(payload, delims=[" "]): await self.bot.whisper(page) else: await self.bot.say(payload) else: await self.bot.say("That trigger has no responses.") else: await self.bot.say("That trigger doesn't exist.")
async def _send_list(self, repo_name=None): """Lists installable cogs Repositories list: https://twentysix26.github.io/Red-Docs/red_cog_approved_repos/""" retlist = [] if repo_name and repo_name in self.repos: msg = "Available cogs:\n" for cog in sorted(self.repos[repo_name].keys()): if 'url' == cog: continue data = self.get_info_data(repo_name, cog) if data and data.get("HIDDEN") is True: continue if data: retlist.append([cog, data.get("SHORT", "")]) else: retlist.append([cog, '']) else: if self.repos: msg = "Available repos:\n" for repo_name in sorted(self.repos.keys()): data = self.get_info_data(repo_name) if data: retlist.append([repo_name, data.get("SHORT", "")]) else: retlist.append([repo_name, ""]) else: await self.bot.say("You haven't added a repository yet.\n" "Start now! {}".format(REPOS_LIST)) return col_width = max(len(row[0]) for row in retlist) + 2 for row in retlist: msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n" msg += "\nRepositories list: {}".format(REPOS_LIST) for page in pagify(msg, delims=['\n'], shorten_by=8): await self.bot.say(box(page))
async def _list(self, ctx, trigger_type="local"): """Lists local / global triggers Defaults to local""" server = ctx.message.server results = [] if trigger_type == "local": for trigger in self.triggers: if trigger.server == server.id: results.append(trigger) elif trigger_type == "global": for trigger in self.triggers: if trigger.server is None: results.append(trigger) else: await self.bot.say("Invalid type.") return if results: results = ", ".join([r.name for r in results]) for page in pagify(results, delims=[" ", "\n"]): await self.bot.say("```\n{}\n```".format(page.lstrip(" "), results)) else: await self.bot.say("I couldn't find any trigger of that type.")
async def riftopen(self, ctx, channel): """Makes you able to communicate with other channels through Red This is cross-server. Type only the channel name or the ID.""" author = ctx.message.author author_channel = ctx.message.channel def check(m): try: return channels[int(m.content)] except: return False channels = self.bot.get_all_channels() channels = [c for c in channels if c.name.lower() == channel or c.id == channel] channels = [c for c in channels if c.type == discord.ChannelType.text] if not channels: await self.bot.say("No channels found. Remember to type just " "the channel name, no `#`.") return if len(channels) > 1: msg = "Multiple results found.\nChoose a server:\n" for i, channel in enumerate(channels): msg += "{} - {} ({})\n".format(i, channel.server, channel.id) for page in pagify(msg): await self.bot.say(page) choice = await self.bot.wait_for_message(author=author, timeout=30, check=check, channel=author_channel) if choice is None: await self.bot.say("You haven't chosen anything.") return channel = channels[int(choice.content)] else: channel = channels[0] rift = OpenRift(source=author_channel, destination=channel) self.open_rifts[author] = rift await self.bot.say("A rift has been opened! Everything you say " "will be relayed to that channel.\n" "Responses will be relayed here.\nType " "`exit` to quit.") msg = "" while msg == "" or msg is not None: msg = await self.bot.wait_for_message(author=author, channel=author_channel) if msg is not None and msg.content.lower() != "exit": try: await self.bot.send_message(channel, msg.content) except: await self.bot.say("Couldn't send your message.") else: break del self.open_rifts[author] await self.bot.say("Rift closed.")
async def update(self, ctx): """Updates cogs""" tasknum = 0 num_repos = len(self.repos) min_dt = 0.5 burst_inc = 0.1/(NUM_THREADS) touch_n = tasknum touch_t = time() def regulate(touch_t, touch_n): dt = time() - touch_t if dt + burst_inc*(touch_n) > min_dt: touch_n = 0 touch_t = time() return True, touch_t, touch_n return False, touch_t, touch_n + 1 tasks = [] for r in self.repos: task = partial(self.update_repo, r) task = self.bot.loop.run_in_executor(self.executor, task) tasks.append(task) base_msg = "Downloading updated cogs, please wait... " status = ' %d/%d repos updated' % (tasknum, num_repos) msg = await self.bot.say(base_msg + status) updated_cogs = [] new_cogs = [] deleted_cogs = [] failed_cogs = [] error_repos = {} installed_updated_cogs = [] for f in as_completed(tasks): tasknum += 1 try: name, updates, oldhash = await f if updates: if type(updates) is dict: for k, l in updates.items(): tl = [(name, c, oldhash) for c in l] if k == 'A': new_cogs.extend(tl) elif k == 'D': deleted_cogs.extend(tl) elif k == 'M': updated_cogs.extend(tl) except UpdateError as e: name, what = e.args error_repos[name] = what edit, touch_t, touch_n = regulate(touch_t, touch_n) if edit: status = ' %d/%d repos updated' % (tasknum, num_repos) msg = await self._robust_edit(msg, base_msg + status) status = 'done. ' for t in updated_cogs: repo, cog, _ = t if self.repos[repo][cog]['INSTALLED']: try: await self.install(repo, cog, no_install_on_reqs_fail=False) except RequirementFail: failed_cogs.append(t) else: installed_updated_cogs.append(t) for t in updated_cogs.copy(): if t in failed_cogs: updated_cogs.remove(t) if not any(self.repos[repo][cog]['INSTALLED'] for repo, cog, _ in updated_cogs): status += ' No updates to apply. ' if new_cogs: status += '\nNew cogs: ' \ + ', '.join('%s/%s' % c[:2] for c in new_cogs) + '.' if deleted_cogs: status += '\nDeleted cogs: ' \ + ', '.join('%s/%s' % c[:2] for c in deleted_cogs) + '.' if updated_cogs: status += '\nUpdated cogs: ' \ + ', '.join('%s/%s' % c[:2] for c in updated_cogs) + '.' if failed_cogs: status += '\nCogs that got new requirements which have ' + \ 'failed to install: ' + \ ', '.join('%s/%s' % c[:2] for c in failed_cogs) + '.' if error_repos: status += '\nThe following repos failed to update: ' for n, what in error_repos.items(): status += '\n%s: %s' % (n, what) msg = await self._robust_edit(msg, base_msg + status) if not installed_updated_cogs: return patchnote_lang = 'Prolog' shorten_by = 8 + len(patchnote_lang) for note in self.patch_notes_handler(installed_updated_cogs): if note is None: continue for page in pagify(note, delims=['\n'], shorten_by=shorten_by): await self.bot.say(box(page, patchnote_lang)) await self.bot.say("Cogs updated. Reload updated cogs? (yes/no)") answer = await self.bot.wait_for_message(timeout=15, author=ctx.message.author) if answer is None: await self.bot.say("Ok then, you can reload cogs with" " `{}reload <cog_name>`".format(ctx.prefix)) elif answer.content.lower().strip() == "yes": registry = dataIO.load_json(os.path.join("data", "red", "cogs.json")) update_list = [] fail_list = [] for repo, cog, _ in installed_updated_cogs: if not registry.get('cogs.' + cog, False): continue try: self.bot.unload_extension("cogs." + cog) self.bot.load_extension("cogs." + cog) update_list.append(cog) except: fail_list.append(cog) msg = 'Done.' if update_list: msg += " The following cogs were reloaded: "\ + ', '.join(update_list) + "\n" if fail_list: msg += " The following cogs failed to reload: "\ + ', '.join(fail_list) await self.bot.say(msg) else: await self.bot.say("Ok then, you can reload cogs with" " `{}reload <cog_name>`".format(ctx.prefix))