async def cooldowns(self, ctx): """List your remaining cooldowns..""" conf = await self.configglobalcheck(ctx) userconf = await self.configglobalcheckuser(ctx.author) cd = await userconf.cooldowns() jobcd = await conf.cooldowns() if cd["workcd"] is None: workcd = "None" else: time = int(datetime.datetime.utcnow().timestamp()) - cd["workcd"] if time < jobcd["workcd"]: workcd = humanize_timedelta(seconds=jobcd["workcd"] - time) else: workcd = "Ready to use." if cd["crimecd"] is None: crimecd = "Ready to use." else: time = int(datetime.datetime.utcnow().timestamp()) - cd["crimecd"] if time < jobcd["crimecd"]: crimecd = humanize_timedelta(seconds=jobcd["crimecd"] - time) else: crimecd = "Ready to use." if await self.walletdisabledcheck(ctx): robcd = "Disabled." elif cd["robcd"] is None: robcd = "Ready to use." else: time = int(datetime.datetime.utcnow().timestamp()) - cd["robcd"] if time < jobcd["robcd"]: robcd = humanize_timedelta(seconds=jobcd["robcd"] - time) else: robcd = "Ready to use." msg = "Work Cooldown: `{}`\nCrime Cooldown: `{}`\nRob Cooldown: `{}`".format( workcd, crimecd, robcd) await ctx.maybe_send_embed(msg)
async def settings(self, ctx): """Current unbelievaboat settings.""" conf = await self.configglobalcheck(ctx) cooldowns = await conf.cooldowns() workcd = humanize_timedelta(seconds=cooldowns["workcd"]) robcd = humanize_timedelta(seconds=cooldowns["robcd"]) crimecd = humanize_timedelta(seconds=cooldowns["crimecd"]) cooldowns = "Work Cooldown: `{}`\nCrime Cooldown: `{}`\nRob Cooldown: `{}`".format( workcd, crimecd, robcd) embed = discord.Embed(colour=ctx.author.colour, title="Unbelievaboat Settings") embed.add_field( name="Using Default Replies?", value="Yes" if await conf.defaultreplies() else "No", inline=True, ) payouts = await conf.payouts() crimepayout = f"**Max**: {payouts['crime']['max']}\n**Min**: {payouts['crime']['min']}" workpayout = f"**Max**: {payouts['work']['max']}\n**Min**: {payouts['work']['min']}" embed.add_field(name="Work Payouts", value=workpayout, inline=True) embed.add_field(name="Crime Payouts", value=crimepayout, inline=True) failrates = await conf.failrates() embed.add_field( name="Fail Rates", value= f"**Crime**: {failrates['crime']}%\n**Rob**: {failrates['rob']}%", inline=True, ) fines = await conf.fines() embed.add_field( name="Fines", value=f"**Max**: {fines['max']}\n**Min**: {fines['min']}", inline=True) embed.add_field(name="Cooldown Settings", value=cooldowns, inline=True) await ctx.send(embed=embed)
async def settings(self, ctx: commands.Context): """Display current settings.""" global_section = SettingDisplay("Global Settings") global_section.add( "Update check interval", humanize_timedelta(seconds=await self.config.frequency()), ) global_section.add( "Next check in", humanize_timedelta(timedelta=self.next_check - datetime.datetime.now()), ) global_section.add( "Check Red-DiscordBot update", "Enabled" if await self.config.check_red_discordbot() else "Disabled", ) if self.docker_commit: global_section.add( "Check Docker image update", "Enabled" if await self.config.check_pcx_docker() else "Disabled", ) global_section.add( "Docker image check type", "New features only" if await self.config.pcx_docker_feature_only() else "All updates", ) await ctx.send(str(global_section))
async def do_autoevents(self): events = filter(lambda e: e.key not in self.started_events, self.events) for event in events: for gid, data in (await self.config.all_guilds()).items(): guild = self.bot.get_guild(gid) if guild is None: continue for key, aep in data.get('pingroles', {}).items(): if event.start_from_now_sec() > aep['offset'] * 60 \ or str((key, event.key, gid)) in await self.config.sent(): continue if not self.event_matches_autoevent(event, aep): continue async with self.config.sent() as sent: sent[str((key, event.key, gid))] = time.time() index = GROUPS.index(event.group) channel = guild.get_channel(aep['channels'][index]) if channel is None: continue role = guild.get_role(aep['roles'][index]) ment = role.mention if role else "" offsetstr = "now" if aep['offset']: offsetstr = f"<t:{int(event.open_datetime.timestamp())}:R>" try: timestr = humanize_timedelta(timedelta=event.close_datetime - event.open_datetime) await channel.send(f"{event.name_and_modifier} starts {offsetstr}!" f" It will be active for {timestr}. {ment}", allowed_mentions=discord.AllowedMentions(roles=True)) except Exception: logger.exception("Failed to send AEP in channel {}".format(channel.id)) for uid, data in (await self.config.all_users()).items(): user = self.bot.get_user(uid) if user is None: continue for aed in data.get('dmevents', []): if event.start_from_now_sec() > aed['offset'] * 60 \ or str((aed['key'], event.key, uid)) in await self.config.sent(): continue if not self.event_matches_autoevent(event, aed): continue async with self.config.sent() as sent: sent[str((aed['key'], event.key, uid))] = time.time() offsetstr = "now" if aed['offset']: offsetstr = f"<t:{int(event.open_datetime.timestamp())}:R>" timestr = humanize_timedelta(timedelta=event.close_datetime - event.open_datetime) try: await user.send(f"{event.clean_dungeon_name} starts {offsetstr}!" f" It will be active for {timestr}.") except Exception: logger.exception("Failed to send AED to user {}".format(user.id))
async def settings(self, ctx): """Current lifestyle settings.""" conf = await self.configglobalcheck(ctx) data = await conf.all() cooldowns = data["cooldowns"] workcd = humanize_timedelta(seconds=cooldowns["workcd"]) robcd = humanize_timedelta(seconds=cooldowns["robcd"]) crimecd = humanize_timedelta(seconds=cooldowns["crimecd"]) slutcd = humanize_timedelta(seconds=cooldowns["slutcd"]) cooldownmsg = "Work Cooldown: `{}`\nCrime Cooldown: `{}`\nSlut Cooldown: `{}`\nRob Cooldown: `{}`".format( workcd, crimecd, slutcd, robcd ) embed = discord.Embed(colour=ctx.author.colour, title="Lifestyle Settings") embed.add_field( name="Using Default Replies?", value="Yes" if data["defaultreplies"] else "No", inline=True, ) payouts = data["payouts"] slutpayout = f"**Max**: {humanize_number(payouts['s**t']['max'])}\n**Min**: {humanize_number(payouts['s**t']['min'])}" crimepayout = f"**Max**: {humanize_number(payouts['crime']['max'])}\n**Min**: {humanize_number(payouts['crime']['min'])}" workpayout = f"**Max**: {humanize_number(payouts['work']['max'])}\n**Min**: {humanize_number(payouts['work']['min'])}" embed.add_field(name="Work Payouts", value=workpayout, inline=True) embed.add_field(name="Crime Payouts", value=crimepayout, inline=True) embed.add_field(name="S**t Payouts", value=slutpayout, inline=True) failrates = data["failrates"] embed.add_field( name="Fail Rates", value=f"**Crime**: {failrates['crime']}%\n**S**t**: {failrates['s**t']}%\n**Rob**: {failrates['rob']}%", inline=True, ) bankfine = data["fine"] bailamounts = data["bailamounts"] embed.add_field( name="Bail Amounts", value=f"**Max**: {humanize_number(bailamounts['max'])}%\n**Min**: {humanize_number(bailamounts['min'])}%\n**Bank Fee**: {humanize_number(bankfine)}%", inline=True, ) embed.add_field(name="Cooldown Settings", value=cooldownmsg, inline=True) briefcasesettings = data["disable_briefcase"] embed.add_field( name="Briefcase Settings", value="Disabled." if not briefcasesettings else f"**Max Balance**: {humanize_number(data['briefcase_max'])}\n**Withdraw Cooldown**: {humanize_timedelta(seconds=cooldowns['withdrawcd'])}\n**Deposit Cooldown**: {humanize_timedelta(seconds=cooldowns['depositcd'])}", inline=True, ) minbet = humanize_number(data["betting"]["min"]) maxbet = humanize_number(data["betting"]["max"]) betstats = f"**Max**: {maxbet}\n**Min**: {minbet}" embed.add_field(name="Betting Info", value=betstats) roulette = data["roulette_toggle"] game_stats = f"**Roulette**: {'Enabled' if roulette else 'Disabled'}" embed.add_field(name="Games", value=game_stats) await ctx.send(embed=embed)
async def freecredits_times(self, ctx): """Display remaining time for all options""" if await bank.is_global(): amounts = await self.config.all() times = await self.config.user(ctx.author).all() now = datetime.now().astimezone().replace(microsecond=0) strings = "" if amounts["hour"]: td = now - datetime.fromisoformat(times["hour"]) strings += ( self.friendly["hour"] + ": " + (humanize_timedelta(timedelta=(timedelta(hours=1) - td)) if td.seconds < 3600 else "Available Now!") + "\n") for k, v in self.settings.items(): if amounts[k]: td = now - (datetime.fromisoformat(times[k])) strings += ( self.friendly[k] + ": " + (humanize_timedelta(timedelta=(timedelta(days=v) - td)) if td.days < v else "Available Now!") + "\n") if strings == "": await ctx.send("No freecredit options have been configured yet" ) else: await ctx.send(strings) else: amounts = await self.config.guild(ctx.guild).all() times = await self.config.member(ctx.author).all() now = datetime.now().astimezone().replace(microsecond=0) strings = "" if amounts["hour"]: td = now - (datetime.fromisoformat(times["hour"])) strings += ( self.friendly["hour"] + ": " + (humanize_timedelta(timedelta=(timedelta(hours=1) - td)) if td.seconds < 3600 else "Available Now!") + "\n") for k, v in self.settings.items(): if amounts[k]: td = now - (datetime.fromisoformat(times[k])) strings += ( self.friendly[k] + ": " + (humanize_timedelta(timedelta=(timedelta(days=v) - td)) if td.days < v else "Available Now!") + "\n") if strings == "": await ctx.send("No freecredit options have been configured yet" ) else: await ctx.send(strings)
async def settings(self, ctx): """Current unbelievaboat settings.""" conf = await self.configglobalcheck(ctx) data = await conf.all() cooldowns = data["cooldowns"] workcd = humanize_timedelta(seconds=cooldowns["workcd"]) robcd = humanize_timedelta(seconds=cooldowns["robcd"]) crimecd = humanize_timedelta(seconds=cooldowns["crimecd"]) cooldownmsg = "Work Cooldown: `{}`\nCrime Cooldown: `{}`\nRob Cooldown: `{}`".format( workcd, crimecd, robcd) embed = discord.Embed(colour=ctx.author.colour, title="Unbelievaboat Settings") embed.add_field( name="Using Default Replies?", value="Yes" if data["defaultreplies"] else "No", inline=True, ) payouts = data["payouts"] crimepayout = f"**Max**: {humanize_number(payouts['crime']['max'])}\n**Min**: {humanize_number(payouts['crime']['min'])}" workpayout = f"**Max**: {humanize_number(payouts['work']['max'])}\n**Min**: {humanize_number(payouts['work']['min'])}" embed.add_field(name="Work Payouts", value=workpayout, inline=True) embed.add_field(name="Crime Payouts", value=crimepayout, inline=True) failrates = data["failrates"] embed.add_field( name="Fail Rates", value= f"**Crime**: {failrates['crime']}%\n**Rob**: {failrates['rob']}%\n**Interest Fee**: {data['interest']}%", inline=True, ) fines = data["fines"] embed.add_field( name="Fines", value= f"**Max**: {humanize_number(fines['max'])}\n**Min**: {humanize_number(fines['min'])}", inline=True, ) embed.add_field(name="Cooldown Settings", value=cooldownmsg, inline=True) walletsettings = data["disable_wallet"] embed.add_field( name="Wallet Settings", value="Disabled." if not walletsettings else f"**Max Balance**: {humanize_number(data['wallet_max'])}\n**Withdraw Cooldown**: {humanize_timedelta(seconds=cooldowns['withdrawcd'])}\n**Deposit Cooldown**: {humanize_timedelta(seconds=cooldowns['depositcd'])}", inline=True, ) minbet = humanize_number(data["betting"]["min"]) maxbet = humanize_number(data["betting"]["max"]) betstats = f"**Max**: {maxbet}\n**Min**: {minbet}" embed.add_field(name="Betting Information", value=betstats) roulette = data["roulette_toggle"] game_stats = f"**Roulette**: {'Enabled' if roulette else 'Disabled'}" embed.add_field(name="Games", value=game_stats) await ctx.send(embed=embed)
async def slowmode( self, ctx, *, interval: commands.TimedeltaConverter( minimum=timedelta(seconds=0), maximum=timedelta(hours=6), default_unit="seconds") = timedelta(seconds=0), ): """Changes channel's slowmode setting. Interval can be anything from 0 seconds to 6 hours. Use without parameters to disable. """ modplus = ctx.bot.get_cog("ModPlus") if not await modplus.action_check(ctx, "editchannel"): return seconds = interval.total_seconds() await ctx.channel.edit(slowmode_delay=seconds) if seconds > 0: await ctx.send( _("Slowmode interval is now {interval}.").format( interval=humanize_timedelta(timedelta=interval))) else: await ctx.send(_("Slowmode has been disabled.")) await modplus.notify('editchannel', f"{ctx.channel} has slowmode enabled.")
async def time(self, ctx: commands.Context, reminder_id: int, *, time: str): """Modify the time of an existing reminder.""" users_reminders = await self.get_user_reminders(ctx.message.author.id) old_reminder = self._get_reminder(users_reminders, reminder_id) if not old_reminder: await self._send_non_existent_msg(ctx, reminder_id) return try: time_delta = parse_timedelta(time, minimum=timedelta(minutes=1)) if not time_delta: await ctx.send_help() return except commands.BadArgument as ba: await reply(ctx, str(ba)) return future = int(current_time.time() + time_delta.total_seconds()) future_text = humanize_timedelta(timedelta=time_delta) new_reminder = old_reminder.copy() new_reminder.update(FUTURE=future, FUTURE_TEXT=future_text) async with self.config.reminders() as current_reminders: current_reminders.remove(old_reminder) current_reminders.append(new_reminder) message = f"Reminder with ID# **{reminder_id}** will remind you in {future_text} from now (<t:{future}:f>)" if "REPEAT" in new_reminder and new_reminder["REPEAT"]: message += f", repeating every {humanize_timedelta(seconds=new_reminder['REPEAT'])} thereafter." else: message += "." await reply(ctx, message)
async def time(self, ctx: commands.Context, reminder_id: int, *, time: str): """Modify the time of an existing reminder.""" users_reminders = await self.get_user_reminders(ctx.message.author.id) old_reminder = self._get_reminder(users_reminders, reminder_id) if not old_reminder: await self._send_non_existant_msg(ctx, reminder_id) return try: time_delta = parse_timedelta(time, minimum=timedelta(minutes=1)) if not time_delta: await ctx.send_help() return except commands.BadArgument as ba: await self._send_message(ctx, str(ba)) return seconds = time_delta.total_seconds() future = int(current_time.time() + seconds) future_text = humanize_timedelta(timedelta=time_delta) new_reminder = old_reminder.copy() new_reminder.update(FUTURE=future, FUTURE_TEXT=future_text) async with self.config.reminders() as current_reminders: current_reminders.remove(old_reminder) current_reminders.append(new_reminder) await self._send_message( ctx, f"Reminder with ID# **{reminder_id}** has been edited successfully, " f"and will now remind you {future_text} from now.", )
async def time(self, ctx: commands.Context, reminder_id: int, *, time: str): """Modify the time of an existing reminder.""" users_reminders = await self.get_user_reminders(ctx.message.author.id) edit_reminder = self.get_reminder(users_reminders, reminder_id) if not edit_reminder: await self.send_non_existant_msg(ctx, reminder_id) return try: time_delta = parse_timedelta(time, minimum=timedelta(minutes=1)) if not time_delta: await ctx.send_help() return except commands.BadArgument as ba: await self.send_message(ctx, str(ba)) return seconds = time_delta.total_seconds() future = int(current_time.time() + seconds) future_text = humanize_timedelta(timedelta=time_delta) reminder = { "USER_REMINDER_ID": reminder_id, "USER_ID": edit_reminder["USER_ID"], "REMINDER": edit_reminder["REMINDER"], "FUTURE": future, "FUTURE_TEXT": future_text, } async with self.config.reminders() as current_reminders: current_reminders.remove(edit_reminder) current_reminders.append(reminder) await self.send_message( ctx, "Reminder with ID# **{}** has been edited successfully, and will now remind you {} from now." .format(reminder_id, future_text), )
async def autoroom_settings(self, ctx: commands.Context): """Display current settings.""" member_channel = self._get_current_voice_channel(ctx.message.author) if not member_channel or not await self._is_autoroom(member_channel): hint = await ctx.send( error("{}, you are not in an AutoRoom.".format( ctx.message.author.mention))) await delete(ctx.message, delay=5) await delete(hint, delay=5) return room_owners = await self._get_room_owners(member_channel) room_settings = SettingDisplay("Room Settings") room_settings.add( "Owner" if len(room_owners) == 1 else "Owners", ", ".join([owner.display_name for owner in room_owners]), ) base_member_role = await self._get_base_member_role(ctx.guild) mode = "???" if base_member_role in member_channel.overwrites: mode = ("Public" if member_channel.overwrites[base_member_role].connect else "Private") room_settings.add("Mode", mode) room_settings.add("Bitrate", "{}kbps".format(member_channel.bitrate // 1000)) room_settings.add( "Channel Age", humanize_timedelta(timedelta=datetime.datetime.utcnow() - member_channel.created_at), ) await ctx.send(room_settings)
async def gamemodes(self, ctx, profile: str, platform: str = "uplay"): """R6 Gamemode Statistics. Valid platforms are psn, xbl and uplay.""" if platform not in self.platforms: return await ctx.send("Not a valid platform.") data = await self.request_data(ctx, "gamemodes", player=profile, platform=self.platforms[platform]) if data is None: return embeds = [] async with ctx.typing(): for gm in data.gamemode_stats: embed = discord.Embed( colour=ctx.author.colour, title="{} statistics for {}".format( gm.replace("_", " ").title(), profile), ) for stat in data.gamemode_stats[gm]: if stat == "playtime": embed.add_field( name=f"{stat.replace('_', ' ').title()}", value=humanize_timedelta( seconds=data.gamemode_stats[gm][stat]), ) else: embed.add_field( name=f"{stat.replace('_', ' ').title()}", value=data.gamemode_stats[gm][stat], ) embeds.append(embed) await menu(ctx, embeds, DEFAULT_CONTROLS)
async def autoroom_settings(self, ctx: commands.Context): """Display current settings.""" autoroom_channel, autoroom_info = await self._get_autoroom_channel_and_info( ctx, check_owner=False) if not autoroom_info: return room_settings = SettingDisplay("Room Settings") room_settings.add( "Owner", autoroom_info["owner"].display_name if autoroom_info["owner"] else "???", ) mode = "???" for member_role in autoroom_info["member_roles"]: if member_role in autoroom_channel.overwrites: mode = ("Public" if autoroom_channel.overwrites[member_role].connect else "Private") break room_settings.add("Mode", mode) room_settings.add("Bitrate", f"{autoroom_channel.bitrate // 1000}kbps") room_settings.add( "Channel Age", humanize_timedelta(timedelta=datetime.datetime.utcnow() - autoroom_channel.created_at), ) await ctx.send(str(room_settings))
async def general(self, ctx, profile, platform="uplay"): """General R6 Stats. Valid platforms are psn, xbl and uplay.""" if platform not in self.platforms: return await ctx.send("Not a valid platform.") data = await self.request_data(ctx, "generic", player=profile, platform=self.platforms[platform]) if data is None: return async with ctx.typing(): embed = discord.Embed( title="General R6S Stats for {}".format(profile), color=ctx.author.colour) for stat in data.general_stats: if stat != "playtime": embed.add_field(name=stat.replace("_", " ").title(), value=data.general_stats[stat]) else: embed.add_field( name=stat.replace("_", " ").title(), value=str( humanize_timedelta( seconds=int(data.general_stats[stat]))), ) await ctx.send(embed=embed)
async def list(self, ctx: commands.Context): """Show a list of all of your reminders.""" author = ctx.message.author to_send = await self.get_user_reminders(author.id) if not to_send: await self.send_message(ctx, "You don't have any upcoming reminders.") else: embed = discord.Embed( title="Reminders for {}".format(author.name), color=await ctx.embed_color(), ) embed.set_thumbnail(url=author.avatar_url) current_timestamp = int(current_time.time()) count = 0 for reminder in to_send: count += 1 delta = reminder["FUTURE"] - current_timestamp embed.add_field( name="#{} - {}".format( count, "In {}".format(humanize_timedelta( seconds=delta)) if delta > 0 else "Now!", ), value=reminder["TEXT"], inline=False, ) await author.send(embed=embed) if ctx.message.guild is not None: await self.send_message(ctx, "Check your DMs for a full list!")
async def profile(self, ctx, profile, platform="uplay"): """General R6 Stats. Valid platforms are psn, xbl and uplay.""" if platform not in self.platforms: return await ctx.send("Not a valid platform.") data = await self.request_data(ctx, "generic", player=profile, platform=self.platforms[platform]) if data is None: return async with ctx.typing(): picture = await self.config.member(ctx.author).picture() if picture: image = await self.stats.profilecreate(data) await ctx.send(file=image) else: embed = discord.Embed( colour=ctx.author.color, title="R6 Profile for {}".format(profile)) embed.set_thumbnail(url=data.avatar_url_256) embed.add_field(name="Level:", value=data.level) embed.add_field( name="Timeplayed:", value=str( humanize_timedelta( seconds=int(data.general_stats["playtime"]))), ) embed.add_field(name="Total Wins:", value=data.general_stats["wins"]) embed.add_field(name="Total Losses:", value=data.general_stats["losses"]) embed.add_field(name="Draws:", value=data.general_stats["draws"]) embed.add_field(name="Lootbox %:", value=data.lootbox_probability) embed.add_field(name="Kills:", value=data.general_stats["kills"]) embed.add_field(name="Deaths:", value=data.general_stats["deaths"]) embed.add_field(name="KDR:", value=data.general_stats["kd"]) try: wlr = (round( data.general_stats["wins"] / data.general_stats["games_played"], 2) * 100) except ZeroDivisionError: wlr = 0 embed.add_field(name="Total W/LR %:", value=wlr) try: rwlr = (round( data.queue_stats["ranked"]["wins"] / data.queue_stats["ranked"]["games_played"], 2, ) * 100) except ZeroDivisionError: rwlr = 0 embed.add_field(name="Total Ranked W/LR:", value=rwlr) await ctx.send(embed=embed)
async def multiple_choice(self, ctx: Context, tag: str, *, question_and_options: str): """Poll a multiple choice question through people's custom status The amount of options are set by the author. The questions and all answers must be separated by ;""" if self.attempts_mass_mention(ctx.message.content.lower()): final_msg = "Nice try." elif "#" in tag: final_msg = self.HASH_ERROR else: options = [ x.strip() for x in question_and_options.split(";") if x.strip() ] question = options.pop( 0) # Extract the questions from the answers. option_count = len(options) if option_count == 0: final_msg = self.MC_NO_OPTIONS elif option_count == 1: final_msg = self.MC_ONE_OPTION else: hashtag = tag.lower() seconds = await self.config.guild(ctx.guild).poll_seconds() mc_str = "\n".join( (f"**{n}** - {v}" for n, v in enumerate(options, start=1))) await ctx.send( self.MC_POLL_START.format( q=question, ht=hashtag, time=humanize_timedelta(seconds=seconds), lst=mc_str)) await asyncio.sleep(seconds - 10) await ctx.send("10 seconds left!") await asyncio.sleep(10) results = Counter({v: 0 for v in range(1, option_count + 1)}) for vote in self.get_votes_by_hashtag(ctx, hashtag): vote_number = int(vote) if vote.isdigit() else 0 if 0 < vote_number <= option_count: results[vote_number] += 1 if not results: final_msg = self.NO_RESPONSE else: width = len(str(len(results))) line_list = [] for n, (answer_n, count) in enumerate(results.most_common(), start=1): answer = options[answer_n - 1] to_append = "`{n:0{w}d}` **{opt}** - {x} vote{s}".format( n=n, w=width, opt=answer, x=count, s=self.plural(count)) line_list.append(to_append) final_msg = self.POLL_END + "\n".join(line_list) await ctx.send(final_msg)
async def heartbeat(self, ctx: commands.Context): """Manage Heartbeat settings.""" if not ctx.invoked_subcommand: msg = ("Heartbeat: {}\n" "Frequency: {}").format( "Enabled" if await self.config.url() else "Disabled (no URL set)", humanize_timedelta(seconds=await self.config.frequency()), ) await ctx.send(box(msg))
def finalise_embed(self, e: discord.Embed) -> discord.Embed: """Make embeds look nicer - limit to two columns and set the footer to boot time""" # needed because otherwise they are otherwise too squashed together so tabulate breaks # doesn't look great on mobile but is fully bearable, more than ugly text wrapping # oh, don't mention the ugly code please :P # it works... emb = e.to_dict() fields = emb.get("fields", []) if len(fields) > 2: # needs multi rows data: list[list[EmbedField]] = [] temp: list[EmbedField] = [] for field in fields: temp.append(field) if len(temp) == 2: data.append(temp) temp = [] if len(temp) != 0: # clear up stragglers data.append(temp) empty_field: EmbedField = { "inline": True, "name": ZERO_WIDTH, "value": ZERO_WIDTH } fields = [] for row in data: while len(row) < 3: row.append(empty_field) fields.extend(row) # else it's 2 or less columns so doesn't need special treatment emb["fields"] = fields e = discord.Embed.from_dict(emb) # and footer is just a nice touch, thanks max for the idea of uptime there sys_uptime = humanize_timedelta(seconds=up_for()) bot_uptime = humanize_timedelta(timedelta=datetime.datetime.utcnow() - self.bot.uptime) e.set_footer( text=f"System uptime: {sys_uptime}\nBot uptime: {bot_uptime}") return e
async def shop(self, ctx, start_level: int = None): """Friendlier menu for displaying the animals available at the store.""" async with self.lock: data = await self.conf.user(ctx.author).all() animals = data["animals"] bought = data["bought"] animal = data["animal"] if animal in ["", "P"]: return await ctx.send("Finish starting your evolution first") embed_list = [] for x in range(1, max(list(map(int, animals.keys()))) + 1): embed = discord.Embed( title=f"{animal.title()} Shop", description=f"Level {str(x)}", color=0xD2B48C, ) embed.add_field(name="You currently own", value=animals.get(str(x), 0)) current = int(bought.get(str(x), 0)) embed.add_field(name="You have bought", value=current) embed.add_field(name="Price", value=humanize_number( self.utils.get_total_price(int(x), current, 1))) last = 0 chances = [] try: for chance, value in self.utils.levels[int(x)].items(): chances.append( f"{str(chance-last)}% chance to gain {str(value)}") last = chance except KeyError: chances = ["100% chance to gain 1000"] embed.add_field(name="Income", value="\n".join(chances)) embed.add_field( name="Credit delay", value=humanize_timedelta(timedelta=timedelta( seconds=self.utils.delays[int(x)])), ) embed_list.append(embed) highest_level = max( [int(a) for a in animals.keys() if int(animals[a]) > 0]) highest_level -= 3 if start_level and not (animals.get(str(start_level), False) is False): highest_level = start_level highest_level -= 1 if highest_level < 0: highest_level = 0 controls = copy.deepcopy(DEFAULT_CONTROLS) controls["\N{MONEY BAG}"] = self.utils.shop_control_callback await menu(ctx, embed_list, controls, page=highest_level)
async def poll_duration(self, ctx: Context, duration: POLL_TIMEDELTA_CONVERTER): """Set the duration of polls The duration must be at least 15 seconds and at most 30 minutes""" await self.config.guild(ctx.guild ).poll_seconds.set(duration.total_seconds()) await ctx.send( self.POLL_TIME_SET.format(humanize_timedelta(timedelta=duration)))
async def operator(self, ctx, profile, operator: str, platform="uplay"): """R6 Operator Stats. Valid platforms are psn, xbl and uplay.""" if operator in self.foreignops: operator = self.foreignops[operator] if platform not in self.platforms: return await ctx.send("Not a valid platform.") data = await self.request_data(ctx, "operator", player=profile, platform=self.platforms[platform]) if data is None: return ops = [] for operators in data.operators: ops.append(operators["name"].lower()) if operator.lower() not in ops: return await ctx.send( "No statistics found for the current operator or the operator is invalid." ) ind = ops.index(operator) async with ctx.typing(): picture = await self.config.member(ctx.author).picture() if picture: image = await self.stats.operatorstatscreate( data, ind, profile) await ctx.send(file=image) else: data = data.operators[ind] embed = discord.Embed( colour=ctx.author.colour, title="{} Statistics for {}".format( operator.title(), profile), ) embed.set_thumbnail(url=data["badge_image"]) embed.add_field(name="Kills:", value=data["kills"]) embed.add_field(name="Deaths:", value=data["deaths"]) embed.add_field(name="Wins:", value=data["wins"]) embed.add_field(name="Losses:", value=data["losses"]) embed.add_field(name="KDR:", value=data["kd"]) embed.add_field( name="Playtime:", value=str( humanize_timedelta(seconds=int(data["playtime"])))) embed.add_field(name="Headshots:", value=data["headshots"]) embed.add_field( name="W/LR %:", value=round(data["wins"] / (data["wins"] + data["losses"]), 2)) try: for ability in data["abilities"]: embed.add_field(name=ability["ability"], value=ability["value"]) except KeyError: pass await ctx.send(embed=embed)
async def parse_llnode_stat(stats: node.NodeStats, stat_name: str): stat = getattr(stats, stat_name) if isinstance(stat, int) and stat_name.startswith("memory_"): stat = humanize.naturalsize(stat, binary=True) if stat_name == "uptime": stat = chat.humanize_timedelta(seconds=stat / 1000) if "load" in stat_name: stat = f"{round(stat*100, 2)} %" return stat
async def status(self, ctx: commands.Context, service: ServiceConverter): """ Check for the status of a variety of services, eg Discord. """ if time_until := self.service_cooldown.handle(ctx.author.id, service.name): message = "Status updates for {} are on cooldown. Try again in {}.".format( service.friendly, humanize_timedelta(seconds=time_until)) return await ctx.send(message, delete_after=time_until)
def __init__(self, retry_after, *, message=None): self.retry_after = int(retry_after) if message is None: message = _("This command is on cooldown. Try again in {delay}.") message = message.format(delay=humanize_timedelta( seconds=self.retry_after ) if self.retry_after >= 1 else _("1 second")) super().__init__(message)
async def updatenotify(self, ctx: commands.Context): """Manage UpdateNotify settings.""" if not ctx.invoked_subcommand: msg = ( "Update check interval: {}\n" "Next check in: {}\n" "Check Red-DiscordBot update: {}" ).format( humanize_timedelta(seconds=await self.config.frequency()), humanize_timedelta( seconds=(self.next_check - datetime.datetime.now()).total_seconds() ), "Enabled" if await self.config.check_red_discordbot() else "Disabled", ) if self.docker_version: msg += "\nCheck Docker image update: {}".format( "Enabled" if await self.config.check_pcx_docker() else "Disabled" ) await ctx.send(box(msg))
async def freecredits_quarterly(self, ctx): """Get some free currency every quarter (122 days)""" if await bank.is_global(): free = await self.config.quarter() if free > 0: last = datetime.fromisoformat(await self.config.user(ctx.author ).quarter()) now = datetime.now().astimezone().replace(microsecond=0) if (now - last).days >= 122: await bank.deposit_credits(ctx.author, free) await self.config.user(ctx.author ).quarter.set(now.isoformat()) await ctx.send("You have been given {} {}".format( free, (await bank.get_currency_name()))) else: await ctx.send( "Sorry, you still have {} until your next quarterly bonus" .format( humanize_timedelta(timedelta=(timedelta(days=122) - (now - last))))) else: free = await self.config.guild(ctx.guild).quarter() if free > 0: last = datetime.fromisoformat(await self.config.member(ctx.author ).quarter()) now = datetime.now().astimezone().replace(microsecond=0) if (now - last).days >= 122: await bank.deposit_credits(ctx.author, free) await self.config.member(ctx.author ).quarter.set(now.isoformat()) await ctx.send("You have been given {} {}".format( free, (await bank.get_currency_name(ctx.guild)))) else: await ctx.send( "Sorry, you still have {} until your next quarterly bonus" .format( humanize_timedelta(timedelta=(timedelta(days=122) - (now - last)))))
async def settings(self, ctx: commands.Context): """Display current settings.""" global_section = SettingDisplay("Global Settings") global_section.add( "Heartbeat", "Enabled" if await self.config.url() else "Disabled (no URL set)", ) global_section.add( "Frequency", humanize_timedelta(seconds=await self.config.frequency())) await ctx.send(str(global_section))
async def uptime(self, ctx: commands.Context): """Shows [botname]'s uptime.""" name = ctx.bot.user.name since = ctx.bot.uptime.strftime("%H:%M:%S UTC | %Y-%m-%d") delta = datetime.datetime.utcnow() - self.bot.uptime uptime_str = humanize_timedelta( timedelta=delta) or ("Less than one second.") emb = discord.Embed(colour=await ctx.embed_color()) emb.add_field(name=f"{name} has been up for:", value=uptime_str) emb.set_footer(text=f"Since: {since}") await ctx.send(embed=emb)