async def _send_to_queue(self, ctx, video_url): if ctx.author.voice is None: raise NerpyException("Not connected to a voice channel.") if not ctx.author.voice.channel.permissions_for(ctx.guild.me).connect: raise NerpyException("Missing permission to connect to channel.") video_infos = fetch_yt_infos(video_url) if "_type" in video_infos: await self.bot.sendc( ctx, "Please use the playlist command for playlists.") await ctx.send_help(ctx.command) else: video_title = video_infos["title"] video_thumbnail = video_infos["thumbnails"][0]["url"] self.bot.log.info( f"{ctx.guild.name} requesting {video_title} to play") emb = Embed( title="Added Song to Queue!", color=Color(value=int("0099ff", 16)), description=f"[{video_title}]({video_url})", ) emb.set_thumbnail(url=video_thumbnail) # song = QueuedSong(self.bot.get_channel(606539392319750170), volume, self._fetch) song = QueuedSong(ctx.author.voice.channel, self._fetch, video_url, video_title) await self.bot.audio.play(ctx.guild.id, song) await self.bot.sendc(ctx, "", emb)
async def create( self, ctx, name: clean_content, tag_type: TagTypeConverter, *content: clean_content, ): """create tag content""" with self.bot.session_scope() as session: if Tag.exists(name, ctx.guild.id, session): raise NerpyException("tag already exists!") async with ctx.typing(): with self.bot.session_scope() as session: self.bot.log.info( f"creating tag {ctx.guild.name}/{name} started") _tag = Tag( Name=name, Author=str(ctx.author), Type=tag_type, CreateDate=datetime.utcnow(), Count=0, Volume=100, GuildId=ctx.guild.id, ) Tag.add(_tag, session) session.flush() self._add_tag_entries(session, _tag, content) self.bot.log.info(f"creating tag {ctx.guild.name}/{name} finished") await self.bot.sendc(ctx, f"tag {name} created!")
def download(url: str): """download audio content (maybe transform?)""" req = urllib.request.Request( url, headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36" }, ) split = os.path.splitext(url) if split[1] is not None and split[1] != "": dlfile = os.path.join(DL_DIR, f"{str(uuid.uuid4())}{split[1]}") with urllib.request.urlopen(req) as response, open(dlfile, "wb") as out_file: shutil.copyfileobj(response, out_file) else: video = fetch_yt_infos(url) song = Song(**video) dlfile = lookup_file(song.idn) if dlfile is None: _ = YTDL.download([song.webpage_url]) dlfile = lookup_file(song.idn) if dlfile is None: raise NerpyException(f"could not find a download in: {url}") return convert(dlfile)
async def send(self, guild_id, cur_chan, msg, emb=None, file=None, files=None, delete_after=None): with self.session_scope() as session: def_chan = DefaultChannel.get(guild_id, session) if def_chan is not None: chan = self.get_channel(def_chan.ChannelId) if chan is not None: return await chan.send(msg, embed=emb, file=file, files=files, delete_after=delete_after) if not cur_chan.permissions_for(cur_chan.guild.me).send_messages: raise NerpyException( "Missing permission to send message to channel.") await cur_chan.send(msg, embed=emb, file=file, files=files, delete_after=delete_after)
async def weather(self, ctx, *, query: str): """outputs weather information""" url = ( f"http://api.openweathermap.org/data/2.5/weather?q={query}&appid={self.config['openweather']}&units=metric" ) async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() conditions = [] for w in data["weather"]: conditions.append(w["main"]) sunrise = datetime.datetime.fromtimestamp( int(data["sys"]["sunrise"])).strftime("%H:%M") sunset = datetime.datetime.fromtimestamp( int(data["sys"]["sunset"])).strftime("%H:%M") emb = discord.Embed() emb.add_field( name=":earth_africa: " + fmt.bold("location"), value=f"""[{data['name']}, {data['sys']['country']}](https://openweathermap.org/city/{data['id']})""", ) emb.add_field( name=":thermometer: " + fmt.bold("temperature"), value=f"{data['main']['temp']}°C", ) emb.add_field( name=":cloud: " + fmt.bold("condition"), value=str.join(", ", conditions), ) emb.add_field( name=":sweat_drops: " + fmt.bold("humidity"), value=f"{data['main']['humidity']}%", ) emb.add_field( name=":wind_chime: " + fmt.bold("wind"), value=f"{data['wind']['speed']} m/s", ) emb.add_field( name="🔆 " + fmt.bold("min-max"), value= f"{data['main']['temp_min']}°C - {data['main']['temp_max']}°C", ) emb.add_field(name=":city_sunrise: " + fmt.bold("sunrise"), value=f"{sunrise} UTC") emb.add_field(name=":city_sunset: " + fmt.bold("sunset"), value=f"{sunset} UTC") emb.set_footer( text="Powered by openweathermap.org", icon_url= f"http://openweathermap.org/img/w/{data['weather'][0]['icon']}.png", ) await self.bot.sendc(ctx, "", emb)
async def imdb_search(self, query_type, query: str): emb = None rip = "" search_url = f"http://www.omdbapi.com/?apikey={self.config['omdb']}&type={query_type}&s={query}" async with aiohttp.ClientSession() as session: async with session.get(search_url) as search_response: if search_response.status != 200: err = f"The api-webserver responded with a code:{search_response.status} - {search_response.reason}" raise NerpyException(err) search_result = await search_response.json() if search_result["Response"] == "True": id_url = ( f"http://www.omdbapi.com/?apikey={self.config['omdb']}&i=" + search_result["Search"][0]["imdbID"]) async with session.get(id_url) as id_response: if id_response.status != 200: err = f"The api-webserver responded with a code:{id_response.status} - {id_response.reason}" raise NerpyException(err) id_result = await id_response.json() emb = discord.Embed(title=id_result["Title"]) emb.description = id_result["Plot"] emb.set_thumbnail(url=id_result["Poster"]) emb.add_field(name=fmt.bold("Released"), value=id_result["Released"]) emb.add_field(name=fmt.bold("Genre"), value=id_result["Genre"]) emb.add_field(name=fmt.bold("Runtime"), value=id_result["Runtime"]) emb.add_field(name=fmt.bold("Country"), value=id_result["Country"]) emb.add_field(name=fmt.bold("Language"), value=id_result["Language"]) emb.add_field(name=fmt.bold("Director"), value=id_result["Director"]) emb.add_field(name=fmt.bold("Actors"), value=id_result["Actors"]) emb.set_footer( text="Powered by https://www.omdbapi.com/") else: rip = fmt.inline("No movie found with this search query") return rip, emb
async def delete(self, ctx, name: clean_content): """delete a tag?""" self.bot.log.info(f"trying to delete {name} from {ctx.guild.id}") with self.bot.session_scope() as session: if not Tag.exists(name, ctx.guild.id, session): raise NerpyException("tag doesn't exist!") Tag.delete(name, ctx.guild.id, session) await self.bot.sendc(ctx, "tag deleted!")
async def xkcd(self, ctx): """random xkcd comic""" url = "https://xkcd.com/" urlend = "info.0.json" async with aiohttp.ClientSession() as session: async with session.get(url + urlend) as xkcd_id: if xkcd_id.status != 200: err = f"The api-webserver responded with a code: {xkcd_id.status} - {xkcd_id.reason}" raise NerpyException(err) result = await xkcd_id.json() async with session.get( f"{url}{randint(0, result['num'])}/{urlend}") as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc(ctx, data["img"])
async def tag(self, ctx): """sound and text tags""" if ctx.invoked_subcommand is None: args = str(ctx.message.clean_content).split(" ") if len(args) > 2: raise NerpyException("Command not found!") elif len(args) <= 1: await ctx.send_help(ctx.command) else: await self._send(ctx, args[1])
async def _play_music(self, ctx): """Play your favorite Music from Youtube and many more!""" if ctx.invoked_subcommand is None: args = str(ctx.message.clean_content).split(" ") if len(args) > 2: raise NerpyException("Command not found!") elif len(args) <= 1: await ctx.send_help(ctx.command) else: await self._send_to_queue(ctx, args[1])
async def summoner(self, ctx, region: RegionConverter, *, summoner_name: str): """get information about the summoner""" rank = tier = lp = wins = losses = "" auth_header = {"X-Riot-Token": self.config["riot"]} summoner_url = self._get_url(region, LeagueCommand.SUMMONER_BY_NAME, summoner_name) async with aiohttp.ClientSession( headers=auth_header) as summoner_session: async with summoner_session.get(summoner_url) as summoner_response: data = await summoner_response.json() if "status" in data: # if query is successfull there is no status key raise NerpyException( "Could not get data from API. Please report to Bot author." ) else: summoner_id = data.get("id") name = data.get("name") level = data.get("summonerLevel") icon_id = data.get("profileIconId") rank_url = self._get_url(region, LeagueCommand.RANK_POSITIONS, summoner_id) async with aiohttp.ClientSession( headers=auth_header) as rank_session: async with rank_session.get(rank_url) as rank_response: data = await rank_response.json() played_ranked = len(data) > 0 if played_ranked: rank = data[0].get("rank") tier = data[0].get("tier") lp = data[0].get("leaguePoints") wins = data[0].get("wins") losses = data[0].get("losses") ver = await self._get_latest_version() emb = discord.Embed(title=name) emb.set_thumbnail( url= f"http://ddragon.leagueoflegends.com/cdn/{ver}/img/profileicon/{icon_id}.png" ) emb.description = f"Summoner Level: {level}" if played_ranked: emb.add_field(name="rank", value=f"{tier} {rank}") emb.add_field(name="league points", value=lp) emb.add_field(name="wins", value=wins) emb.add_field(name="losses", value=losses) await self.bot.sendc(ctx, "", emb=emb)
async def volume(self, ctx, name: clean_content, vol): """adjust the volume of a sound tag (WIP)""" self.bot.log.info(f"set volume of {name} to {vol} from {ctx.guild.id}") with self.bot.session_scope() as session: if not Tag.exists(name, ctx.guild.id, session): raise NerpyException("tag doesn't exist!") with self.bot.session_scope() as session: _tag = Tag.get(name, ctx.guild.id, session) _tag.Volume = vol await self.bot.sendc(ctx, f"changed volume of {name} to {vol}")
async def eightball(self, ctx, *, question: str): """ Ask 8 ball a question Question must end with a question mark. """ if not question.endswith("?") or question == "?": raise NerpyException("That doesn't look like a question.") mention = ctx.message.author.mention await self.bot.sendc( ctx, f"{mention} asked me: {question}\n\n{choice(self.ball)}`")
async def yomomma(self, ctx): """random yomomma joke""" url = "http://api.yomomma.info" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc(ctx, data["joke"])
async def chuck(self, ctx): """random chuck norris joke.""" url = "http://api.icndb.com/jokes/random" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc(ctx, data["value"]["joke"])
async def catfact(self, ctx): """random cat command are legit""" url = "https://catfact.ninja/fact" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc(ctx, data["fact"])
async def bunny(self, ctx): """why do i have a random bunny gif command???""" url = "https://api.bunnies.io/v2/loop/random/?media=gif" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc(ctx, data["media"]["gif"])
async def add(self, ctx, name: clean_content, *content: clean_content): """add an entry to an existing tag""" with self.bot.session_scope() as session: if not Tag.exists(name, ctx.guild.id, session): raise NerpyException("tag doesn't exists!") async with ctx.typing(): with self.bot.session_scope() as session: _tag = Tag.get(name, ctx.guild.id, session) self._add_tag_entries(session, _tag, content) self.bot.log.info(f"added entry to tag {ctx.guild.name}/{name}.") await self.bot.sendc(ctx, f"Entry added to tag {name}!")
async def _send(self, ctx, tag_name): self.bot.log.info(f"{ctx.guild.name} requesting {tag_name} tag") with self.bot.session_scope() as session: _tag = Tag.get(tag_name, ctx.guild.id, session) if _tag is None: raise NerpyException("No such tag found") if TagType(_tag.Type) is TagType.sound: if ctx.author.voice is None: raise NerpyException("Not connected to a voice channel.") if not ctx.author.voice.channel.permissions_for( ctx.guild.me).connect: raise NerpyException( "Missing permission to connect to channel.") # song = QueuedSong(self.bot.get_channel(606539392319750170), _tag_volume, self._fetch) song = QueuedSong(ctx.author.voice.channel, self._fetch, tag_name) await self.bot.audio.play(ctx.guild.id, song) else: random_entry = _tag.get_random_entry() await self.bot.sendc(ctx, random_entry.TextContent)
async def quote(self, ctx): """random quote""" url = "http://quotesondesign.com/wp-json/posts?filter[orderby]=rand" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() await self.bot.sendc( ctx, fmt.strip_tags(data[0]["content"]) + " - " + data[0]["title"])
async def _defch_set(self, ctx, chan: discord.TextChannel): if not chan.permissions_for(chan.guild.me).send_messages: raise NerpyException("Missing permission to send message to channel.") with self.bot.session_scope() as session: def_ch = DefaultChannel.get(ctx.guild.id, session) if def_ch is None: def_ch = DefaultChannel(GuildId=ctx.guild.id, CreateDate=datetime.utcnow(), Author=ctx.author.name) session.add(def_ch) def_ch.ModifiedDate = datetime.utcnow() def_ch.ChannelId = chan.id await ctx.send(f"Default response channel set to {chan.mention}.")
async def _prefix_set(self, ctx, *, new_pref): if " " in new_pref: raise NerpyException("Spaces not allowed in prefixes") with self.bot.session_scope() as session: pref = GuildPrefix.get(ctx.guild.id, session) if pref is None: pref = GuildPrefix(GuildId=ctx.guild.id, CreateDate=datetime.utcnow(), Author=ctx.author.name) session.add(pref) pref.ModifiedDate = datetime.utcnow() pref.Prefix = new_pref await ctx.send(f"new prefix is now set to '{new_pref}'.")
async def roti(self, ctx, num: int = None): """ rules of the internet if no <num> is provided, a random rule will display """ if num: if num not in self.rotis: raise NerpyException( "Sorry 4chan pleb, no rules found with this number") rule = num else: rule = choice(list(self.rotis.keys())) await self.bot.sendc(ctx, f"Rule {rule}: {self.rotis[rule]}")
async def choose(self, ctx, *choices): """ Chooses between multiple choices. To denote multiple choices, you should use double quotes. """ choices_str = ", ".join(choices) if len(choices) < 2: raise NerpyException("Not enough choices to pick from.") mention = ctx.message.author.mention await self.bot.sendc( ctx, f"{mention} asked me to choose between: {choices_str}\n\nI choose {choice(choices)}" )
async def trump(self, ctx): """random trump tweet""" url = "https://api.whatdoestrumpthink.com/api/v1/quotes/random" trump_pic = "https://www.tolonews.com/sites/default/files/styles/principal_article_image/public/Trumpppp.jpg" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() emb = discord.Embed(title="Donald Trump") emb.description = data["message"] emb.set_thumbnail(url=trump_pic) await self.bot.sendc(ctx, "", emb=emb)
async def imgur(self, ctx, *, query): """may the meme be with you""" url = f"https://api.imgur.com/3/gallery/search/viral?q={query}" async with aiohttp.ClientSession( headers={"Authorization": f"Client-ID {self.config['imgur']}" }) as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() if data["success"] is True and len(data["data"]) > 0: meme = data["data"][0]["link"] else: meme = "R.I.P. memes" await self.bot.sendc(ctx, meme)
def session_scope(self): """Provide a transactional scope around a series of operations.""" session = self.SESSION() error = None try: yield session session.commit() except SQLAlchemyError as exc: session.rollback() error = exc finally: session.close() if error is not None: self.log.error(error) raise NerpyException( "There was an error with the database. Please report to Bot Author!" )
async def urban(self, ctx, *, query): """urban legend""" url = f"http://api.urbandictionary.com/v0/define?term={query}" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() emb = discord.Embed(title=f'"{query}" on Urban Dictionary:') if len(data["list"]) > 0: item = data["list"][0] emb.description = item["definition"] emb.set_author(name=item["author"]) emb.url = item["permalink"] else: emb.description = "no results - R.I.P. memes" await self.bot.sendc(ctx, "", emb)
async def lyrics(self, ctx, *, query): """genius lyrics""" url = f"http://api.genius.com/search?q={query}&access_token={self.config['genius']}" async with aiohttp.ClientSession() as session: async with session.get(url) as response: if response.status != 200: err = f"The api-webserver responded with a code: {response.status} - {response.reason}" raise NerpyException(err) data = await response.json() emb = discord.Embed(title=f'"{query}" on genius.com:') if len(data["response"]["hits"]) > 0: item = data["response"]["hits"][0].get("result") emb.description = item.get("full_title") emb.set_thumbnail( url=item.get("header_image_thumbnail_url")) emb.url = item.get("url") else: emb.description = "R.I.P. memes" await self.bot.sendc(ctx, "", emb=emb)
def setup(bot): """adds this module to the bot""" if "wow" in bot.config: bot.add_cog(WorldofWarcraft(bot)) else: raise NerpyException("Config not found.")