async def _from( self, ctx: context.CustomContext, *, person: Fuzzy[ CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1)) ] = None, ): """List the tags that someone made on this server""" member = person or ctx.author all_tags = await self.bot.db.fetch( "SELECT * FROM tag WHERE author = $1 AND guild_id = $2 ORDER BY uses desc", member.id, ctx.guild.id, ) pretty_tags = [] for record in all_tags: pretty_tags.append( f"`{config.BOT_PREFIX}{record['name']}` {escape_markdown(record['title'])}" ) pages = paginator.SimplePages( entries=pretty_tags, author=f"Tags from {member.display_name}", icon=member.display_avatar.url, empty_message=f"{member} hasn't made any tags on this server yet.", per_page=12, ) await pages.start(ctx)
async def list_npcs( self, ctx: CustomContext, *, person: Fuzzy[ converter.CaseInsensitiveMember, converter.CaseInsensitiveUser, FuzzySettings(weights=(5, 1)), ] = None, ): """List every NPC you or someone else has access to **Example** `{PREFIX}{COMMAND}` list all of your NPCs `{PREFIX}{COMMAND} @DerJonas` to see what NPCs someone else has access to `{PREFIX}{COMMAND} DerJonas#8036` `{PREFIX}{COMMAND} Jonas`""" member = person or ctx.author npcs = [self._npc_cache[i] for i in self._npc_access_cache[member.id]] npcs.sort(key=lambda npc: npc["id"]) pretty_npcs = [] for record in npcs: avatar = ( f"[Avatar]({record['avatar_url']})\n" if record["avatar_url"] else "" ) owner = self.bot.get_user(record["owner_id"]) owner_value = ( "\n" if not owner else f"Owner: {owner.mention} {escape_markdown(str(owner))}\n" ) pretty_npcs.append( f"**__NPC #{record['id']} - {escape_markdown(record['name'])}__**" ) pretty_npcs.append( f"{avatar}Trigger Phrase: `{escape_markdown(record['trigger_phrase'])}`" ) pretty_npcs.append(owner_value) if pretty_npcs: pretty_npcs.insert( 0, f"You can create a new NPC with `{config.BOT_PREFIX}npc create`, " f"or edit the name, avatar and/or trigger phrase of an existing one with " f"`{config.BOT_PREFIX}npc edit <npc>`.\n", ) pages = paginator.SimplePages( author=f"{member.display_name}'s NPCs", icon=member.display_avatar.url, entries=pretty_npcs, per_page=20, empty_message="This person hasn't made any NPCs yet.", ) await pages.start(ctx)
async def clear( self, ctx, amount: int, *, target: Fuzzy[CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1))] = None, ): """Purge an amount of messages in the current channel""" if amount > 500 or amount < 0: return await ctx.send( f"{config.NO} You can only clear up to 500 messages at most.") def check(message): if target: return message.author.id == target.id return True try: deleted = await ctx.channel.purge(limit=amount, check=check) except discord.Forbidden: raise exceptions.ForbiddenError(task=ForbiddenTask.MESSAGE_DELETE) await ctx.send(f"{config.YES} Deleted **{len(deleted)}** messages.", delete_after=5)
async def _from( self, ctx, *, person_or_party: Fuzzy[ CaseInsensitiveMember, CaseInsensitiveUser, PoliticalParty, FuzzySettings(weights=(5, 1, 2)), ] = None, ): """List the laws a specific person or Political Party authored""" return await self._from_person_model( ctx, model=models.Law, member_or_party=person_or_party )
async def set_channel_perms(self, ctx, *, channel: Fuzzy[ CaseInsensitiveTextChannel] = None): """Toggle Read and/or Send Messages permissions for a role or person in one of your nation's channels""" if not channel: channel = await ctx.converted_input( f"{config.USER_INTERACTION_REQUIRED} Which channel's permissions should be changed?", converter=Fuzzy[CaseInsensitiveTextChannel], return_input_on_fail=False, ) if channel.category_id not in self.bot.mk.NATION_CATEGORIES: return await ctx.send( f"{config.NO} The `{channel.name}` channel does not belong to your nation." ) user_input = await ctx.input( f"{config.USER_INTERACTION_REQUIRED} For which role *or* person should the " f"permissions in {channel.mention} be changed?") conv = Fuzzy[CaseInsensitiveRole, CaseInsensitiveMember, FuzzySettings(weights=(6, 4))] role = await conv.convert(ctx, user_input) overwrites = channel.overwrites_for(role) result = await PermissionSelectorMenu( role=role, channel=channel, overwrites=overwrites).prompt(ctx) if not result.confirmed: return await ctx.send( f"{config.NO} You didn't decide on which permission(s) to change." ) permission_to_change = result.result if permission_to_change["read"]: overwrites.read_messages = not overwrites.read_messages if permission_to_change["send"]: overwrites.send_messages = not overwrites.send_messages await channel.set_permissions(target=role, overwrite=overwrites) await ctx.send(f"{config.YES} Done.")
async def vibecheck( self, ctx, *, person: Fuzzy[CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1))] = None, ): """vibecheck""" member = person or ctx.author not_vibing = [ "https://i.kym-cdn.com/entries/icons/mobile/000/031/163/Screen_Shot_2019-09-16_at_10.22.26_AM.jpg", "https://s3.amazonaws.com/media.thecrimson.com/photos/2019/11/18/194724_1341037.png", "https://i.kym-cdn.com/photos/images/newsfeed/001/574/493/3ab.jpg", "https://i.imgflip.com/3ebtvt.jpg", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT814jrNuqJsaVVHGqWw_0snlcysLN5fLpocEYrx6hzkgXYx7RV5w&s", "https://img.buzzfeed.com/buzzfeed-static/static/2019-10/7/15/asset/c5dd65974640/sub-buzz-521-1570462442-1.png?downsize=700:*&output-format=auto&output-quality=auto", "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/12132fe4-1709-4287-9dcc-4ee9fc252a01/ddk55pz-bf72cab3-2b9e-474e-94a8-00e5f53d2baf.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzEyMTMyZmU0LTE3MDktNDI4Ny05ZGNjLTRlZTlmYzI1MmEwMVwvZGRrNTVwei1iZjcyY2FiMy0yYjllLTQ3NGUtOTRhOC0wMGU1ZjUzZDJiYWYuanBnIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.Sb6Axu0O6iZ3YmZJHg5wRe-r41iLnWVqa_ddWrtbQlo", "https://pbs.twimg.com/media/EHgYHjOX4AAuv6s.jpg", "https://pbs.twimg.com/media/EGTsxzaUwAAuBLG?format=jpg&name=900x900", "https://66.media.tumblr.com/c2fc65d9f8614dbd9bb7378983e0598e/tumblr_pxw332rEmZ1yom1s3o1_1280.png", ] vibing = [ "https://i.redd.it/ax6jb6lhdah31.jpg", "https://i.redd.it/3a6nr5b3u4x31.png", "https://i.kym-cdn.com/photos/images/original/001/599/028/bf3.jpg", "https://i.redd.it/p4e6a65i3bw31.jpg", "https://media.makeameme.org/created/congratulations-you-have-61e05e0d4b.jpg", ] passed = True if random.randrange(1, stop=100) >= 65 else False if passed: image = random.choice(vibing) pretty = "passed" else: image = random.choice(not_vibing) pretty = "not passed" embed = text.SafeEmbed( title=f"{member} has __{pretty}__ the vibe check", ) embed.set_image(url=image) await ctx.send(embed=embed)
async def whohas( self, ctx, *, role: Fuzzy[CaseInsensitiveRole, DemocracivCaseInsensitiveRole, PoliticalParty, FuzzySettings( no_choice_exception= f"{config.NO} There is no role on this or the " f"Democraciv server that matches `{{argument}}`.", weights=(5, 2, 2), ), ], ): """Detailed information about a role""" if isinstance(role, PoliticalParty): role = role.role await self.role_info(ctx, role)
async def npc(self, ctx: CustomContext, *, npc: str = ""): """What is an NPC?""" if ctx.invoked_with.lower() == "npcs": if npc: conv = Fuzzy[ converter.CaseInsensitiveMember, converter.CaseInsensitiveUser, FuzzySettings(weights=(5, 1)), ] person = await conv.convert(ctx, npc) else: person = ctx.author return await ctx.invoke(self.bot.get_command("npc list"), person=person) if npc: converted = await Fuzzy[AnyNPCConverter].convert(ctx, npc) return await ctx.invoke(self.bot.get_command("npc info"), npc=converted) p = config.BOT_PREFIX embed = text.SafeEmbed( description=f"NPCs allow you to make it look like you speak as a different character, " f"or on behalf of someone else, like an organization or group.\n\n" f"This can elevate the role-playing experience by making it clear " f"when someone talks in character, or out-of-character (OOC). " f"Political parties, newspapers, government departments or other groups can " f"use this to release official looking announcements.\n\n" f"To get started, you can create a new NPC with `{p}npc create`. NPCs are " f"not bound to any server, every NPC that you make on this server can " f"also be used in every other server I am in.\n\nServer administrators " f"can disable NPC usage on their server for any reason with " f"the `{p}server npc` command.\n\n\nSee `{p}help npcs` or " f"`{p}commands` to see every NPC-related command and learn more about them." ) embed.set_author(name="What are NPCs?", icon_url=self.bot.dciv.icon.url) embed.set_image( url="https://cdn.discordapp.com/attachments/818226072805179392/818230819835215882/npc.gif" ) await ctx.send(embed=embed)
async def transfer( self, ctx: context.CustomContext, to_person: Fuzzy[ CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1)) ], *, tag: OwnedTag, ): """Transfer a tag of yours to someone else""" if to_person == ctx.author: return await ctx.send( f"{config.NO} You cannot transfer your tag to yourself." ) await self.bot.db.execute( "UPDATE tag SET author = $1 WHERE id = $2", to_person.id, tag.id ) return await ctx.send( f"{config.YES} {to_person} is now the owner of `{config.BOT_PREFIX}{tag.name}`." )
async def avatar( self, ctx, *, person: Fuzzy[CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1))] = None, ): """View someone's avatar in detail **Example** `{PREFIX}{COMMAND}` `{PREFIX}{COMMAND} @DerJonas` `{PREFIX}{COMMAND} DerJonas` `{PREFIX}{COMMAND} DerJonas#8109` """ member: discord.Member = person or ctx.author avatar_png = member.display_avatar.with_size(4096).url embed = text.SafeEmbed() embed.set_image(url=avatar_png) embed.set_author(name=member, icon_url=avatar_png, url=avatar_png) await ctx.send(embed=embed)
async def stats( self, ctx: context.CustomContext, *, person: Fuzzy[ CaseInsensitiveMember, CaseInsensitiveUser, FuzzySettings(weights=(5, 1)) ] = None, ): """View general statistics or statistics about a specific person **Example** `{PREFIX}{COMMAND}` to view general statistics `{PREFIX}{COMMAND} DerJonas` to view statistics specific to that person""" if person: return await self._person_stats(ctx, person) total = await self.bot.db.fetch( "SELECT COUNT(name) FROM tag " "UNION ALL " "SELECT COUNT(name) FROM tag WHERE guild_id = $1 " "UNION ALL " "SELECT COUNT(name) FROM tag WHERE global = true", ctx.guild.id, ) total_total = total[0]["count"] total_local = total[1]["count"] total_global = total[2]["count"] top_global_tags = await self.bot.db.fetch( "SELECT name, uses FROM tag WHERE global = true " "ORDER BY uses DESC LIMIT 5" ) top_server_tags = await self.bot.db.fetch( "SELECT name, uses FROM tag WHERE guild_id = $1 " "ORDER BY uses DESC LIMIT 5", ctx.guild.id, ) top_local_tags = await self.bot.db.fetch( "SELECT name, uses FROM tag WHERE global = false AND guild_id = $1 " "ORDER BY uses DESC LIMIT 5", ctx.guild.id, ) embed = text.SafeEmbed( description=f"There are {total_total} tags in total, of which " f"{total_global} are global. {total_local} are from this server." ) embed.set_author(name=f"Tags on {ctx.guild.name}", icon_url=ctx.guild_icon) embed.add_field( name="Top Global Tags", value=self._fmt_stats(top_global_tags), inline=False ) embed.add_field( name="Top Tags from this Server (Global and Local)", value=self._fmt_stats(top_server_tags), inline=False, ) embed.add_field( name="Top Local Tags from this Server", value=self._fmt_stats(top_local_tags), inline=False, ) cog = self.bot.get_cog(self.bot.mk.LEGISLATURE_NAME) if cog: top_tag_creators = await self.bot.db.fetch( "SELECT author FROM tag WHERE guild_id = $1", ctx.guild.id ) value = cog.format_stats( record=top_tag_creators, record_key="author", stats_name="tags" ) top_global_tag_creators = await self.bot.db.fetch( "SELECT author FROM tag WHERE global = true" ) global_value = cog.format_stats( record=top_global_tag_creators, record_key="author", stats_name="global tags", ) embed.add_field( name="People with the most Global Tags from any Server", value=global_value, inline=False, ) embed.add_field( name="People with the most Tags from this Server", value=value, inline=False, ) await ctx.send(embed=embed)
async def send( self, ctx, to_person_or_iban_or_organization: Fuzzy[ converter.CaseInsensitiveMember, converter.CaseInsensitiveUser, BankCorporationAbbreviation, BankUUIDConverter, FuzzySettings(weights=(5, 1)), ], amount: decimal.Decimal, *, purpose: str = None, ): """Send money to a specific bank account, organization, or person on this server **Examples** `-bank send @DerJonas 9.99` `-bank send DerJonas#8036 250` `-bank send c4a3ec17-cba4-462f-bdda-05620f574dce 32.10 Thanks ;)` `-bank send GOOGLE 1000.21` assuming 'GOOGLE' is the abbreviation of an existing, published organization """ await self.is_connected_with_bank_user(ctx) currency = "" if not isinstance(to_person_or_iban_or_organization, uuid.UUID): # if IBAN, skip currency selection embed = text.SafeEmbed( title=f"{config.USER_INTERACTION_REQUIRED} Currency Selection", description= "Since you did not specify an IBAN to send the money to, " "I cannot automatically determine the currency for this " "transaction. Once you've chosen a currency, I will send the money to the recipient's " "default account for the chosen currency.\n\n" "This only works provided that the recipient have previously selected a default account " "for the chosen currency on [democracivbank.com](https://democracivbank.com).", ) view = CurrencySelector(ctx, self._currencies) msg = await ctx.send(embed=embed, view=view) currency = await view.prompt() if not currency: return await msg.delete() if isinstance(to_person_or_iban_or_organization, (discord.Member, discord.User)): to_iban = await self.resolve_iban( to_person_or_iban_or_organization.id, currency) elif isinstance(to_person_or_iban_or_organization, str): to_iban = await self.resolve_iban( to_person_or_iban_or_organization, currency) else: # is UUID to_iban = str(to_person_or_iban_or_organization) currency = await self.get_currency_from_iban(to_iban) view = PickBankAccountView(ctx, currency, amount, to_iban) msg = await ctx.send( content= f"{config.USER_INTERACTION_REQUIRED} From what bank account would you like to send " f"the money?", view=view, ) from_iban = await view.prompt() await msg.delete() if not from_iban: return pretty_amount = self.get_currency(currency).with_amount(amount) fmt = "" if isinstance(to_person_or_iban_or_organization, discord.abc.User): fmt = to_person_or_iban_or_organization.mention elif isinstance(to_person_or_iban_or_organization, str): r = await self.request(BankRoute("GET", f"account/{to_iban}/")) pretty_target = await r.json() fmt = f"**{pretty_target['corporate_holder']['name']}**" em = text.SafeEmbed( title=f"{config.USER_INTERACTION_REQUIRED} Confirm Transaction", description=f"Do you really want to send **{pretty_amount}** " f"to {fmt}?", ) v = ConfirmView(ctx) m = await ctx.send(embed=em, view=v) result = await v.prompt() await m.delete() if not result: return purpose = "Sent via the Democraciv Discord Bot" if not purpose else purpose transaction = await self.send_money(ctx.author.id, from_iban, to_iban, amount, purpose) embed = text.SafeEmbed( title= f"You sent {pretty_amount} to {transaction['safe_to_account']}", description= f"[See the transaction details here.](https://democracivbank.com/transaction/{transaction['id']})", ) embed.set_author(name=self.BANK_NAME, icon_url=self.BANK_ICON_URL) await ctx.send(embed=embed)
async def whois( self, ctx, *, person: Fuzzy[CaseInsensitiveMember, CaseInsensitiveUser, CaseInsensitiveRole, DemocracivCaseInsensitiveRole, PoliticalParty, FuzzySettings(weights=(5, 2, 1, 1, 0)), ] = None, ): """See detailed information about someone **Example** `{PREFIX}{COMMAND}` `{PREFIX}{COMMAND} Jonas - u/Jovanos` `{PREFIX}{COMMAND} @DerJonas` `{PREFIX}{COMMAND} DerJonas` `{PREFIX}{COMMAND} deRjoNAS` `{PREFIX}{COMMAND} DerJonas#8109` `{PREFIX}{COMMAND} 212972352890339328` """ def _get_roles(roles): fmt = [] for role in roles[::-1]: if not role.is_default(): fmt.append(role.mention) if not fmt: return "-" else: return ", ".join(fmt) if isinstance(person, discord.Role): return await self.role_info(ctx, person) elif isinstance(person, PoliticalParty): return await self.role_info(ctx, person.role) member = person or ctx.author embed = text.SafeEmbed() if isinstance(member, discord.User): embed.description = ":warning: This person is not here in this server." embed.add_field(name="Person", value=f"{member} {member.mention}", inline=False) embed.add_field(name="ID", value=member.id, inline=False) embed.add_field( name="Discord Registration", value=f'{member.created_at.strftime("%B %d, %Y")}', inline=True, ) if isinstance(member, discord.Member): join_pos, max_members = await self.get_member_join_position( member, ctx.guild.members) if not join_pos: join_pos = "Unknown" embed.add_field( name="Joined", value= f'{(await self.get_member_join_date(member)).strftime("%B %d, %Y")}', inline=True, ) embed.add_field(name="Join Position", value=f"{join_pos}/{max_members}", inline=True) embed.add_field( name=f"Roles ({len(member.roles) - 1})", value=_get_roles(member.roles), inline=False, ) embed.set_thumbnail(url=member.display_avatar.url) await ctx.send(embed=embed)