diff --git a/main.py b/main.py index 9de2475..b8d1296 100644 --- a/main.py +++ b/main.py @@ -1,19 +1,159 @@ +# I M P O R T S import discord import os +import asyncio +import youtube_dl +from discord.ext import commands + +######################################################################################################################## +# +# _____ _ _ +# / ____| | | | +# | (___ | |_ __ _ _ __| |_ _ _ _ __ +# \___ \| __/ _` | '__| __| | | | '_ \ +# ____) | || (_| | | | |_| |_| | |_) | +# |_____/ \__\__,_|_| \__|\__,_| .__/ +# | | +# |_| client = discord.Client() token = os.getenv("TOKEN") - +bot = commands.Bot(command_prefix=commands.when_mentioned_or("/"), + description="SnakieCat bot") @client.event async def on_ready(): - print('We have logged in as {0.user}'.format(client)) + print('Yeah, I am started and my name is {0.user}'.format(client)) + +######################################################################################################################### + +# MMMMMMMM MMMMMMMMUUUUUUUU UUUUUUUU SSSSSSSSSSSSSSS IIIIIIIIII CCCCCCCCCCCCC +# M:::::::M M:::::::MU::::::U U::::::U SS:::::::::::::::SI::::::::I CCC::::::::::::C +# M::::::::M M::::::::MU::::::U U::::::US:::::SSSSSS::::::SI::::::::I CC:::::::::::::::C +# M:::::::::M M:::::::::MUU:::::U U:::::UUS:::::S SSSSSSSII::::::IIC:::::CCCCCCCC::::C +# M::::::::::M M::::::::::M U:::::U U:::::U S:::::S I::::I C:::::C CCCCCC +# M:::::::::::M M:::::::::::M U:::::D D:::::U S:::::S I::::IC:::::C +# M:::::::M::::M M::::M:::::::M U:::::D D:::::U S::::SSSS I::::IC:::::C +# M::::::M M::::M M::::M M::::::M U:::::D D:::::U SS::::::SSSSS I::::IC:::::C +# M::::::M M::::M::::M M::::::M U:::::D D:::::U SSS::::::::SS I::::IC:::::C +# M::::::M M:::::::M M::::::M U:::::D D:::::U SSSSSS::::S I::::IC:::::C +# M::::::M M:::::M M::::::M U:::::D D:::::U S:::::S I::::IC:::::C +# M::::::M MMMMM M::::::M U::::::U U::::::U S:::::S I::::I C:::::C CCCCCC +# M::::::M M::::::M U:::::::UUU:::::::U SSSSSSS S:::::SII::::::IIC:::::CCCCCCCC::::C +# M::::::M M::::::M UU:::::::::::::UU S::::::SSSSSS:::::SI::::::::I CC:::::::::::::::C +# M::::::M M::::::M UU:::::::::UU S:::::::::::::::SS I::::::::I CCC::::::::::::C +# MMMMMMMM MMMMMMMM UUUUUUUUU SSSSSSSSSSSSSSS IIIIIIIIII CCCCCCCCCCCCC + +ytdl_format_options = { + 'format': 'bestaudio/best', + 'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s', + 'restrictfilenames': True, + 'noplaylist': True, + 'nocheckcertificate': True, + 'ignoreerrors': False, + 'logtostderr': False, + 'quiet': True, + 'no_warnings': True, + 'default_search': 'auto', + 'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes +} + +ffmpeg_options = { + 'options': '-vn' +} + +ytdl = youtube_dl.YoutubeDL(ytdl_format_options) + +class YTDLSource(discord.PCMVolumeTransformer): + def __init__(self, source, *, data, volume=0.5): + super().__init__(source, volume) + + self.data = data + + self.title = data.get('title') + self.url = data.get('url') + + @classmethod + async def from_url(cls, url, *, loop=None, stream=False): + loop = loop or asyncio.get_event_loop() + data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream)) + + if 'entries' in data: + # take first item from a playlist + data = data['entries'][0] + + filename = data['url'] if stream else ytdl.prepare_filename(data) + return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data) + + +class Music(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.command() + async def join(self, ctx, *, channel: discord.VoiceChannel): + """Joins a voice channel""" + if ctx.voice_client is not None: + return await ctx.voice_client.move_to(channel) + + await channel.connect() + + @commands.command() + async def play(self, ctx, *, url): + """Streams from a url (same as yt, but doesn't predownload)""" + + async with ctx.typing(): + player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True) + ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None) + + await ctx.send('Ok, (beep boop) I am turning on {}'.format(player.title)) + + @commands.command() + async def volume(self, ctx, volume: int): + """Changes the player's volume""" + + if ctx.voice_client is None: + return await ctx.send("Not connected to a voice channel.") + + ctx.voice_client.source.volume = volume / 100 + await ctx.send("Now volume is {}%".format(volume)) + + @commands.command() + async def stop(self, ctx): + """Stops and disconnects the bot from voice""" + await ctx.voice_client.disconnect() + + @play.before_invoke + async def ensure_voice(self, ctx): + if ctx.voice_client is None: + if ctx.author.voice: + await ctx.author.voice.channel.connect() + else: + await ctx.send("You are not connected to a voice channel.") + raise commands.CommandError("Author not connected to a voice channel.") + elif ctx.voice_client.is_playing(): + ctx.voice_client.stop() + +######################################################################################################################## + +# +# /$$ /$$ /$$ +# | $$ | $$ |__/ +# /$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$$ /$$ /$$ /$$ /$$$$$$ /$$$$$$ /$$ /$$$$$$$ /$$$$$$ +#|_ $$_/ /$$__ $$| $$ /$$/|_ $$_/ |____ $$| $$__ $$ /$$_____/| $$ | $$ | $$ /$$__ $$ /$$__ $$| $$| $$__ $$ /$$__ $$ +# | $$ | $$$$$$$$ \ $$$$/ | $$ /$$$$$$$| $$ \ $$| $$$$$$ | $$ | $$ | $$| $$$$$$$$| $$ \__/| $$| $$ \ $$| $$ \ $$ +# | $$ /$$| $$_____/ >$$ $$ | $$ /$$ /$$__ $$| $$ | $$ \____ $$| $$ | $$ | $$| $$_____/| $$ | $$| $$ | $$| $$ | $$ +# | $$$$/| $$$$$$$ /$$/\ $$ | $$$$/ | $$$$$$$| $$ | $$ /$$$$$$$/| $$$$$/$$$$/| $$$$$$$| $$ | $$| $$ | $$| $$$$$$$ +# \___/ \_______/|__/ \__/ \___/ \_______/|__/ |__/|_______/ \_____/\___/ \_______/|__/ |__/|__/ |__/ \____ $$ +# /$$ \ $$ +# | $$$$$$/ +# \______/ @client.event async def on_message(message): if message.author == client.user: return - if message.content.startswith('$hello'): + if message.content.startswith('hello'): await message.channel.send('Hello!') if message.content.startswith('aboba'): @@ -22,4 +162,12 @@ async def on_message(message): if message.content.startswith('ABOBA'): await message.channel.send(':regional_indicator_a: :regional_indicator_b: :regional_indicator_o: :regional_indicator_b: :regional_indicator_a:') -client.run(token) \ No newline at end of file + +######################################################################################################################## +# ____ __ ___ __ +# / __ \/ / / / | / / +# / /_/ / / / / |/ / +# / _, _/ /_/ / /| / +#/_/ |_|\____/_/ |_/ + +client.run(token)