async def apod(self, ctx: aoi.AoiContext, *, date: dtime() = None): if not date: date = datetime.datetime.now() dt = date.strftime('%Y-%m-%d') if dt not in self.apod_cache: async with ctx.typing(): async with aiohttp.ClientSession() as sess: async with sess.get( f"https://api.nasa.gov/planetary/apod?api_key={self.bot.nasa}&" f"date={dt}") as resp: js = await resp.json() if js.get("code", None) in [404, 400, 403, 401]: self.apod_cache[dt] = (str(js["code"]), "404", "404", js["msg"]) return await ctx.send_error(js["msg"]) url = js["url"] hdurl = js.get("hdurl", url) expl = js["explanation"][:1900] title = js["title"] + " " + dt self.apod_cache[dt] = (title, hdurl, url, expl) else: title, hdurl, url, expl = self.apod_cache[dt] if title == "404": await ctx.send_error(expl) await ctx.embed( title=title, description= f"{expl}\n\n[Normal Resolution]({url}) [High Resolution]({hdurl})", image=url)
async def wxhourly(self, ctx: aoi.AoiContext, *, location: gmaps.LocationCoordinates): async with ctx.typing(): conditions = (await self.wx.lookup_hourly(location)) await ctx.paginate( fmt=f"Resolved Address: {location.location or location}```%s```\n", lst=[cond.line() for cond in conditions], n=24, title="Weather lookup", thumbnails=[c.icon for c in conditions[3::24]])
async def deletequote(self, ctx: aoi.AoiContext, quote: int): qid, user, guild = (await (await self.bot.db.conn.execute( "select id, user, guild from quotes where id=?", (quote, ))).fetchone()) if user != ctx.author.id and not ctx.author.guild_permissions.administrator: return ctx.send_error( "You must be administrator to delete quotes that aren't yours." ) await self.bot.db.conn.execute("delete from quotes where id=?", (qid, )) await self.bot.db.conn.commit()
async def warnp(self, ctx: aoi.AoiContext, warns: int, *, action: str = None): if not action: await self.bot.db.del_warnp(ctx.guild.id, warns) return await ctx.send( f"No punishment will be applied at {warns} warns") res = await self._validate_warnp(action) if res: return ctx.send_error(res) await self.bot.db.set_warnp(ctx.guild.id, warns, action) return await ctx.send_ok(f"`{action}` will be applied at {warns} warns" )
async def landsat(self, ctx: aoi.AoiContext, coords: gmaps.LocationCoordinates, date: dtime() = None): lat = coords.lat long = coords.long dt = date or datetime.datetime.now() url = f"https://api.nasa.gov/planetary/earth/imagery?" \ f"lon={long}&lat={lat}&dim=0.15&api_key={self.bot.nasa}" \ f"&date={dt.strftime('%Y-%m-%d')}" buf = io.BytesIO() async with ctx.typing(): async with aiohttp.ClientSession() as sess: async with sess.get(url) as resp: buf.write(await resp.content.read()) await ctx.embed(title=f"{lat} {long} {dt.strftime('%Y-%m-%d')}", image=buf)
async def punishmentclear(self, ctx: aoi.AoiContext, member: discord.Member, num: int = 1): punishments: List[PunishmentModel] = sorted( await self.bot.db.lookup_punishments(member.id), key=lambda punishment: punishment.time, reverse=True) if num < 1 or num > len(punishments): return ctx.send_error("Invalid warning number") p = punishments[num - 1] if "del" in ctx.flags: await self.bot.db.conn.execute( "delete from punishments where user=? and guild=? and timestamp=?", (p.user, p.guild, p.time.timestamp())) else: await self.bot.db.conn.execute( "update punishments set cleared=1,cleared_by=? where user=? and guild=? " "and timestamp=?", (ctx.author.id, p.user, p.guild, p.time.timestamp())) await self.bot.db.conn.commit() await ctx.send_ok(f"Cleared punishment #{num} for {member}")
async def addrero(self, ctx: aoi.AoiContext, message: discord.Message, *, args: str): # noqa c901 split = ctx.group_list(args.split(), 2) role_converter = commands.RoleConverter() for i in split: print(i) try: emoji: discord.PartialEmoji = await partial_emoji_convert( ctx, i[0]) role: discord.Role = await role_converter.convert(ctx, i[1]) except commands.PartialEmojiConversionFailure: return await ctx.send_error(f"Emoji {i[0]} invalid") except commands.RoleNotFound: return await ctx.send_error(f"Role {i[1]} invalid") if role >= ctx.author.top_role and ctx.guild.owner_id != ctx.author.id: raise aoi.RoleHierarchyError( f"Role {role} must be lower than your highest") if role >= ctx.me.top_role: raise aoi.RoleHierarchyError( f"Role {role} must be lower than mine") try: await message.add_reaction(emoji) except discord.Forbidden: return await ctx.send_error("I can't react to that message!") except discord.HTTPException: return await ctx.send_error(f"Emoji {i[0]} invalid") if message.id not in self._roles: self._roles[message.id] = {} if emoji.name in self._roles[message.id] or str( emoji.id) in self._roles[message.id]: return await ctx.send_error("That emoji is already being used") self._roles[message.id][str(emoji.id) if emoji.id else emoji. name] = _ReactionRoleData(role) await self._db.conn.execute( "insert into rero values (?,?,?,?,?,0,0)", (ctx.guild.id, message.channel.id, message.id, str(emoji.id) if emoji.id else emoji.name, role.id)) await self._db.conn.commit() await ctx.send_ok("Added!")
async def satellite(self, ctx: aoi.AoiContext, location: gmaps.LocationCoordinates): res = await self.wx.lookup_grid(location.lat, location.long) radar = res.radar_station[-3:] if radar in self.sat_cache: diff = (datetime.now() - self.sat_cache[radar][0]).seconds if diff < 30 * 60: img = self.sat_cache[radar][1] buf = io.BytesIO() img.save(buf, format="png") return await ctx.embed( image=buf, footer=f"Cached from {diff // 60}m{diff % 60:2} ago") del self.sat_cache[radar] urls = [ f"https://radar.weather.gov/ridge/Overlays/Topo/Short/{radar}_Topo_Short.jpg", f"https://radar.weather.gov/ridge/RadarImg/N0R/{radar}_N0R_0.gif", f"https://radar.weather.gov/ridge/Overlays/County/Short/{radar}_County_Short.gif", f"https://radar.weather.gov/ridge/Overlays/Rivers/Short/{radar}_Rivers_Short.gif", f"https://radar.weather.gov/ridge/Overlays/Highways/Short/{radar}_Highways_Short.gif", f"https://radar.weather.gov/ridge/Overlays/Cities/Short/{radar}_City_Short.gif", f"https://radar.weather.gov/ridge/Warnings/Short/{radar}_Warnings_0.gif", f"https://radar.weather.gov/ridge/Legend/N0R/{radar}_N0R_Legend_0.gif" ] imgs = [] async with ctx.typing(): async with aiohttp.ClientSession() as sess: for url in urls: async with sess.get(url) as resp: buf = io.BytesIO() buf.write(await resp.content.read()) buf.seek(0) imgs.append(Image.open(buf, "png").convert("RGBA")) composite = reduce(lambda i1, i2: Image.alpha_composite(i1, i2), imgs) self.sat_cache[radar] = (datetime.now(), composite) buf = io.BytesIO() composite.save(fp=buf, format="png") await ctx.embed(image=buf)
async def roles(self, ctx: aoi.AoiContext): def _(s): return s if len(s) < 11 else f"{s[:10]}..." if ("audit" in ctx.flags or "full" in ctx.flags) and not ctx.author.guild_permissions.manage_roles: ctx.flags = {} if "audit" in ctx.flags and "full" in ctx.flags: return await ctx.send_error("Both `--audit` and `--full` cannot be passed") if "full" in ctx.flags: r: discord.Role await ctx.paginate([f"{r.position:>3} " f"{'M' if r.mentionable else '-'}" f"{'C' if r.color.to_rgb() != (0, 0, 0) else '-'}" f"{'H' if r.hoist else '-'}|" f"{'@' if r.permissions.mention_everyone or r.permissions.administrator else '-'}" f"{'E' if r.permissions.manage_emojis or r.permissions.administrator else '-'}" f"{'c' if r.permissions.manage_channels or r.permissions.administrator else '-'}" f"{'G' if r.permissions.manage_guild or r.permissions.administrator else '-'}" f"{'N' if r.permissions.manage_nicknames or r.permissions.administrator else '-'}" f"{'W' if r.permissions.manage_webhooks or r.permissions.administrator else '-'}" f"{'I' if r.permissions.view_guild_insights or r.permissions.administrator else '-'}" f"{'R' if r.permissions.manage_roles or r.permissions.administrator else '-'}|" f"{'n' if r.permissions.change_nickname or r.permissions.administrator else '-'}" f"{'i' if r.permissions.create_instant_invite or r.permissions.administrator else '-'}" f"{'r' if r.permissions.add_reactions or r.permissions.administrator else '-'}" f"{'#' if r.permissions.external_emojis or r.permissions.administrator else '-'}?" f"{'F' if r.permissions.attach_files or r.permissions.administrator else '-'}" f"{'L' if r.permissions.embed_links or r.permissions.administrator else '-'}" f"{'h' if r.permissions.read_message_history or r.permissions.administrator else '-'}" f"{'r' if r.permissions.read_messages or r.permissions.administrator else '-'}" f"{'$' if r.permissions.send_messages or r.permissions.administrator else '-'}" f"{'T' if r.permissions.send_tts_messages or r.permissions.administrator else '-'}|" f"{'L' if r.permissions.view_audit_log or r.permissions.administrator else '-'}" f"{'K' if r.permissions.kick_members or r.permissions.administrator else '-'}" f"{'!' if r.permissions.manage_messages or r.permissions.administrator else '-'}" f"{'B' if r.permissions.ban_members or r.permissions.administrator else '-'}|" f"{'P' if r.permissions.priority_speaker or r.permissions.administrator else '-'}" f"{'s' if r.permissions.stream or r.permissions.administrator else '-'}" f"{'S' if r.permissions.speak or r.permissions.administrator else '-'}" f"{'=' if r.permissions.connect or r.permissions.administrator else '-'}" f"{'V' if r.permissions.use_voice_activation or r.permissions.administrator else '-'}" f"{'D' if r.permissions.deafen_members or r.permissions.administrator else '-'}" f"{'X' if r.permissions.mute_members or r.permissions.administrator else '-'}" f"{'<' if r.permissions.move_members or r.permissions.administrator else '-'}|" f"{'A' if r.permissions.administrator else '-'} " f"{discord.utils.escape_markdown(r.name)}" for r in ctx.guild.roles[::-1]], 20, "Role list", # THERE ARE MANY NBSP AND ZWSP HERE I PROMISE fmt="```Pos Name\n%s```\n" "M:?Mentionable??????" "H:?Hoisted??????" "C:?Colored??????" "@:?Can?@?everyone??????" "E:?Manage?emojis??????" "c:?Manage?channels??????" "G:?Manage?server??????" "N:?Manage?nicknames??????" "W:?Manage?webhooks??????" "I:?View?insights??????" "R:?Manage?roles??????" "n:?Change?nickname??????" "i:?Create?invite??????" "r:?Add?reactions??????" "#:?External?emoji??????" "F:?Attach?files??????" "L:?Embed?links??????" "h:?Message?history??????" "r:?Read?messages??????" "$:?Send?messages??????" "T:?TTS?messages??????" "L:?Audit?logs??????" "K:?Can?kick??????" "!:?Manage?Messages??????" "B:?Can?ban??????" "P:?Priority speaker??????" "s:?Stream??????" "S:?Speak??????" "=:?Connect??????" "V:?Voice?activation??????" "D:?Deafen?members??????" "X:?Mute?members??????" "<:?Move?members??????" "A:?Administrator") elif "audit" in ctx.flags: r: discord.Role await ctx.paginate([f"{r.position:>3} " f"{'M' if r.mentionable else '-'}" f"{'C' if r.color.to_rgb() != (0, 0, 0) else '-'}" f"{'H' if r.hoist else '-'}" f"{'@' if r.permissions.mention_everyone else '-'}" f"{'K' if r.permissions.kick_members or r.permissions.administrator else '-'}" f"{'B' if r.permissions.ban_members or r.permissions.administrator else '-'}" f"{'A' if r.permissions.administrator else '-'}" f"{'!' if r.permissions.manage_messages or r.permissions.administrator else '-'} " f"{_(discord.utils.escape_markdown(r.name))}" for r in ctx.guild.roles[::-1]], 20, "Role list", fmt="```Pos Name\n%s```\n" "M-Mentionable ? " "H-Hoisted ? " "C-Colored ? " "@-Can @everyone ? " "K-Can kick ? " "B-Can ban ? " "A-Administrator ? " "!-Manage Messages") else: await ctx.paginate([f"{r.position:>3} " f"{'M' if r.mentionable else '-'}" f"{'C' if r.color.to_rgb() != (0, 0, 0) else '-'}" f"{'H' if r.hoist else '-'} " f"{discord.utils.escape_markdown(r.name)}" for r in ctx.guild.roles[::-1]], 20, "Role list", fmt="```Pos Name\n%s```\n" "M-Mentionable ? " "H-Hoisted ? " "C-Colored")