async def pay(self, ctx: Context, amount: int, *, member: Member): """Give coins to someone You can't give money to yourself or any bots. Transfer amount should be more than 0. """ if member == ctx.author or member.bot: return await ctx.send(t(ctx, "other_users_only")) if amount <= 0: return await ctx.send(t(ctx, "at_least_one")) user, _ = await User.get_or_create(id=ctx.author.id) if user.balance < amount: return await ctx.send( t( ctx, "not_enough_funds", coins=user.balance, missing=amount - user.balance, ) ) embed = Embed( ctx, title=t(ctx, "title"), description=t(ctx, "confirmation", amount=amount, member=member.mention), ) message = await ctx.send(embed=embed) await message.add_reaction("✅") try: await self.bot.wait_for( "reaction_add", timeout=30, check=lambda r, u: u == ctx.message.author and str(r.emoji) == "✅", ) except TimeoutError: embed.description = t(ctx, "cancelled") return await message.edit(embed=embed) target_user, _ = await User.get_or_create(id=member.id) user.balance -= amount target_user.balance += amount await user.save() await target_user.save() try: await message.clear_reactions() except Forbidden: pass embed.description = t(ctx, "success", amount=amount, member=member.mention) await message.edit(embed=embed)
async def pay(self, ctx: Context, amount: int, *, member: Member): """Give coins to someone You can't give money to yourself or any bots. Transfer amount should be more than 0. """ if member == ctx.author or member.bot: return await ctx.send("You can give money to other users only.") if amount <= 0: return await ctx.send("You need to pay at least 1 coin.") user, _ = await User.get_or_create(id=ctx.author.id) if user.balance < amount: return await ctx.send( f"Not enough funds, you have " f"{user.balance} coins ({amount - user.balance} missing).") embed = Embed( ctx, title="Transfer", description=f"You are about to give **{amount}** " f"coin(s) to {member.mention}, are you sure?", ) message = await ctx.send(embed=embed) await message.add_reaction("✅") try: await self.bot.wait_for( "reaction_add", timeout=30, check=lambda r, u: u == ctx.message.author and str(r.emoji) == "✅", ) except TimeoutError: embed.description = "Transfer cancelled." return await message.edit(embed=embed) target_user, _ = await User.get_or_create(id=member.id) user.balance -= amount target_user.balance += amount await user.save() await target_user.save() try: await message.clear_reactions() except Forbidden: pass embed.description = f"Transferred **{amount}** coin(s) " f"to {member.mention}" await message.edit(embed=embed)
async def warn(self, ctx: Context, member: Member, *, reason: str): """Warn someone Warns do not give any punishments apart fron an entry in the warn list. """ guild, _ = await Guild.get_or_create(id=ctx.guild.id) user, _ = await User.get_or_create(id=member.id) warn = await Warn.create(moderator=ctx.author.id, guild=guild, user=user, reason=reason) embed = Embed(ctx, title=f"Warn [{warn.id}]", color=member.color) embed.description = t(ctx, "message", member=member.mention, reason=reason) await ctx.send(embed=embed) try: await member.send( t(ctx, "dm_message", guild=ctx.guild, reason=reason)) except (Forbidden, HTTPException, AttributeError): pass
async def mute(self, ctx: Context, member: Member, time: Timedelta, *, reason: str = None): """Mute someone Muting someone gives them the mute role specified by the muterole command and removes the role after the specified time has passed. Note: Mutes are checked every 10 seconds, so times are not perfect. """ mute = await Mute.filter(user__id=member.id, guild__id=ctx.guild.id, active=True).first() if mute: mute.end += time await mute.save() return await ctx.send( t(ctx, "message_extended", member=member, time=time)) # NOTE: Extensions don't add a mute entry, they just make the # active mute longer. # return await ctx.send(f"{member.name} is already muted.") user, _ = await User.get_or_create(id=member.id) guild, _ = await Guild.get_or_create(id=ctx.guild.id) if not guild.mute_role: return await ctx.send(t(ctx, "no_mute_role", guild=ctx.guild)) mute = await Mute.create( moderator=ctx.author.id, user=user, guild=guild, reason=reason, end=datetime.utcnow() + time, ) mute_role = ctx.guild.get_role(guild.mute_role) # TODO: Check if member has lower permissions required to mute them await member.add_roles( mute_role, reason=f"Muted by {ctx.author} for {time}, reason: {reason}") embed = Embed(ctx, title=f"Mute [{mute.id}]", color=member.color) embed.set_thumbnail(url=member.avatar_url) embed.description = t(ctx, "message", member=member.mention, time=time, reason=reason) await ctx.send(embed=embed) try: await member.send( t(ctx, "dm_message", guild=ctx.guild, time=time, reason=reason)) except (Forbidden, HTTPException, AttributeError): pass
async def studio(self, ctx: Context, *, name: str): """Studio info from AniList""" query = """ query ($name: String) { Studio (search: $name, sort: SEARCH_MATCH) { name siteUrl isAnimationStudio media (sort: POPULARITY_DESC, perPage: 10) { nodes { title {romaji} coverImage {extraLarge} siteUrl popularity favourites } } } } """ studio = (await anilist(query, {"name": name}))["data"]["Studio"] embed = Embed( ctx, title=studio["name"], url=studio["siteUrl"], footer="Via AniList" ) embed.set_thumbnail(url=studio["media"]["nodes"][0]["coverImage"]["extraLarge"]) if studio["isAnimationStudio"]: embed.description = t(ctx, "animation_studio") # TODO: Observe, if this breaks when isAnimationStudio=False. most_popular = [t(ctx, "most_popular_header")] for i in studio["media"]["nodes"]: most_popular.append( t( ctx, "most_popular_item", popularity=i["popularity"], favorites=i["favourites"], title=i["title"]["romaji"], url=i["siteUrl"], ) ) embed.add_field( name=t(ctx, "most_popular_title"), value="\n".join(most_popular) ) await ctx.send(embed=embed)
async def studio(self, ctx: Context, *, name: str): """Studio info from AniList""" query = """ query ($name: String) { Studio (search: $name, sort: SEARCH_MATCH) { name siteUrl isAnimationStudio media (sort: POPULARITY_DESC, perPage: 10) { nodes { title {romaji} coverImage {extraLarge} siteUrl popularity favourites } } } } """ studio = (await anilist(query, {"name": name}))["data"]["Studio"] embed = Embed(ctx, title=studio["name"], url=studio["siteUrl"], footer="Via AniList") embed.set_thumbnail( url=studio["media"]["nodes"][0]["coverImage"]["extraLarge"]) if studio["isAnimationStudio"]: embed.description = "Animation Studio" # TODO: Observe, if this breaks when isAnimationStudio=False. most_popular = ["Popularity ⭐ Favorites ❤"] for i in studio["media"]["nodes"]: most_popular.append(f"{i['popularity']} ⭐ {i['favourites']} ❤️ " f"[{i['title']['romaji']}]({i['siteUrl']}) ") embed.add_field(name="Most popular productions", value="\n".join(most_popular)) await ctx.send(embed=embed)
async def warn(self, ctx: Context, member: Member, *, reason: str): """Warn someone Warns do not give any punishments apart fron an entry in the warn list. """ guild, _ = await Guild.get_or_create(id=ctx.guild.id) user, _ = await User.get_or_create(id=member.id) warn = await Warn.create(moderator=ctx.author.id, guild=guild, user=user, reason=reason) embed = Embed(ctx, title=f"Warn [{warn.id}]", color=member.color) embed.description = f"Warned {member.mention}, reason: *{reason}*" await ctx.send(embed=embed) try: await member.send(f"You have been warned in **{ctx.guild.name}**, " f"reason: *{warn.reason}*") except (Forbidden, HTTPException, AttributeError): pass
async def daily(self, ctx: Context, member: Member = None): """Daily coin reward Mention someone to give your them your reward. Can be used once every 23 hours. Streak gives you more coins over time, but will be lost after 2 days of inactivity. """ if member and member.bot: return await ctx.send("You can't give points to a bot!") user, _ = await User.get_or_create(id=ctx.author.id) def hours_til_next_daily() -> int: return ceil( (user.next_daily.timestamp() - datetime.utcnow().timestamp()) / 3600) if not user.daily_available: try: await ctx.send( f"Your next daily will be available in " f"**{hours_til_next_daily()} hour(s)**. Current streak: " f"**{user.daily_streak}**.") except Forbidden: pass return expired = "(lost streak)" if user.daily_streak_expired else "" if user.daily_streak_expired: user.daily_streak = 1 else: user.daily_streak += 1 bonus = floor(sqrt(user.daily_streak) * 20) user.last_daily = datetime.utcnow() if member: target_user, _ = await User.get_or_create(id=member.id) else: target_user = user target_user.balance += 100 + bonus await user.save() if user != target_user: await target_user.save() embed = Embed(ctx, title="Daily", color=ctx.author.color) if user == target_user: embed.description = ( f"You received **{100 + bonus}** daily points\n" f"Streak: **{user.daily_streak}** {expired}\n" f"Come back in **{hours_til_next_daily()} hour(s)** " f"to continue your streak!") else: embed.description = ( f"You gave your **{100 + bonus}** daily points " f"to {member.mention}\n" f"Streak: **{user.daily_streak}** {expired}\n" f"Come back in **{hours_til_next_daily()} hour(s)** " f"to continue your streak!") try: await ctx.send(embed=embed) except Forbidden: pass
async def daily(self, ctx: Context, member: Member = None): """Daily coin reward Mention someone to give your them your reward. Can be used once every 23 hours. Streak gives you more coins over time, but will be lost after 2 days of inactivity. """ if member and member.bot: return await ctx.send(t(ctx, "cannot_give_to_bot")) user, _ = await User.get_or_create(id=ctx.author.id) def hours_til_next_daily() -> int: return ceil( (user.next_daily.timestamp() - datetime.utcnow().timestamp()) / 3600 ) if not user.daily_available: try: await ctx.send( t( ctx, "next_daily", remaining=hours_til_next_daily(), streak=user.daily_streak, ) ) except Forbidden: pass return expired = t(ctx, "lost_streak") if user.daily_streak_expired else "" if user.daily_streak_expired: user.daily_streak = 1 else: user.daily_streak += 1 bonus = floor(sqrt(user.daily_streak) * 20) user.last_daily = datetime.utcnow() if member: target_user, _ = await User.get_or_create(id=member.id) else: target_user = user target_user.balance += 100 + bonus await user.save() if user != target_user: await target_user.save() embed = Embed(ctx, title=t(ctx, "title"), color=ctx.author.color) if user == target_user: embed.description = t( ctx, "received_daily", amount=100 + bonus, streak=user.daily_streak, expired=expired, remaining=hours_til_next_daily(), ) else: embed.description = t( ctx, "received_daily", amount=100 + bonus, member=member.mention, streak=user.daily_streak, expired=expired, remaining=hours_til_next_daily(), ) try: await ctx.send(embed=embed) except Forbidden: pass
image_name = image_url.split("/")[-1] embed = Embed( ctx, title=t(ctx, "title"), footer="Via trace.moe", description=t(ctx, "searching", image=image_name), color=Color.blue(), ) message = await ctx.send(embed=embed) search = await trace(image_url) if "errors" in search.keys(): embed.description = ( "Error while loading image. Try posting the " "image directly in chat or check if you used " "a valid URL." ) return await message.edit(embed=embed) embed.description = "" for result in search["docs"]: if result["is_adult"]: continue embed.description += t( ctx, "entry", title=result["title_romaji"], id=result["anilist_id"], episode=result["episode"],