polarobot/main.py

202 lines
8.8 KiB
Python

# Polarobot is a discord bot designed mainly to play music
# Copyright (C) 2022 Louis Lacoste
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
# Also add information on how to contact you by electronic and paper mail.
import os
import sys
import re
import random
import discord
from discord.ext import commands
from discord.utils import get
import youtube_dl
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
intents = discord.Intents().all()
client = discord.Client(intents=intents)
bot = commands.Bot(command_prefix="!p ", intents=intents)
# YT related code
youtubeUrlRegex = "https?:\/\/(www\.)?(youtu|youtube)\.(com|be)"
def is_a_youtube_url(url: str):
return bool(re.match(youtubeUrlRegex, url))
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'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 = {
'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'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 = ""
@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=False))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['formats'][0]['url']#data['title'] if stream else ytdl.prepare_filename(data)
return filename
def random_playing_gif():
gifList = ["https://media.tenor.com/Ra6rkhDtYPwAAAAd/anime-dj.gif",
"https://media.tenor.com/7o_Y0qCQaJQAAAAM/howan-anime.gif",
"https://media.tenor.com/_OA-44hy1-4AAAAM/anime-music.gif",
"https://media.tenor.com/rJpCgvQJgsEAAAAj/music.gif",
"https://media.tenor.com/sEKdNnp9tmoAAAAM/music-dog.gif",
"https://media.tenor.com/6z00WD2k8foAAAAM/boombox-jamming.gif"]
return random.choice(gifList)
@bot.event
async def on_ready():
print("Starting")
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.playing, name='PolaroBot | !p to call'))
for guild in bot.guilds:
for channel in guild.text_channels :
if str(channel) == "just-botting" :
embedUp = discord.Embed(title="🤖PolaroBot est dans la place", description="Prêt à vous régaler")
embedUp.set_image(url="https://media.tenor.com/dOoTf5typPAAAAAS/roll-out-optimus.gif")
await channel.send(embed=embedUp)
print('Active in {}\n Member Count : {}'.format(guild.name,guild.member_count))
def restart_bot():
os.execv(sys.executable, ['python'] + sys.argv)
@bot.command(aliases=['reboot'])
async def restart(ctx):
"""Reboot bot"""
bot.current_ctx = ctx
print("Rebooting")
await leave(ctx)
embedDeco = discord.Embed(title="🤖PolaroBot Statut",
description="PolaroBot redémarre : Patientez quelques secondes.. ", color=0xF1D50E)
await ctx.send(embed=embedDeco)
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.playing, name='PolaroBot redémarre...'))
restart_bot()
@bot.command(name='play_song', help='To play song')
async def play(ctx,url):
try :
server = ctx.message.guild
voice_channel = server.voice_client
if voice_channel == None:
await join(ctx)
voice_channel = server.voice_client
async with ctx.typing():
if is_a_youtube_url(url):
url_source = await YTDLSource.from_url(url, loop=bot.loop)
voice_channel.play(discord.FFmpegPCMAudio(url_source, **ffmpeg_options))
embedPlaying = discord.Embed(
title="🤖PolaroBot joue", description=f"Je sais jouer de musique frère ! {url}")
embedPlaying.set_image(url=random_playing_gif())
else:
embedPlaying = discord.Embed(title="🤖PolaroBot veut casser ta gueule",
description=f"FREROT ?! C'EST QUOI {url} ? C'EST DE LA MERDE 💩💩💩 ! ")
embedPlaying.set_image(
url="https://media.tenor.com/wQH1Lm24wLwAAAAM/de-la-merde-jean.gif")
await ctx.send(embed=embedPlaying)
except Exception as err:
await ctx.send(f"The bot is not connected to a voice channel. Error : {err}")
@bot.command(name='pause_song', help='This command pauses the song')
async def pause(ctx):
voice_client = bot.voice_client
await print("Pausing song")
await print(await voice_client.is_playing())
try:
if await voice_client.is_playing():
embedMessage = discord.Embed(title="🤖PolaroBot mets en pause", description="""Okay ça part en pause chef
Tu voudras une grande frite avec ?""")
embedMessage.set_image("https://media.tenor.com/58MHehmspf8AAAAM/saddam-hussein-adobada.gif")
await ctx.send(embed=embedMessage)
await voice_client.pause()
else:
embedMessage=embed=discord.Embed(title="🤖PolaroBot ne joue rien", description="""Qu'est-ce qu'tu veux mettre en pause là ?
Sois chill mec :peace:""")
embedMessage.set_image("https://media4.giphy.com/media/lqM68D2hniKxm9gHwj/giphy.gif")
await ctx.send(embed=embedMessage)
except Exception as err:
await print(err)
@bot.command(name='resume_song', help='Resumes the song')
async def resume(ctx):
voice_client = bot.voice_client
await voice_client.resume()
if await voice_client.is_paused():
embedMessage=discord.Embed(title="🤖PolaroBot relance la musique", description="""Okay letz go""")
embedMessage.set_image("https://media.tenor.com/q54lr7rrbPgAAAAC/okay-lets-go.gif")
await ctx.send(embed=embedMessage)
await voice_client.resume()
else:
embedMessage=discord.Embed(title="🤖PolaroBot relance la musique", description="""Je jouais rien poto
Pour lancer un son qui groove un max (comme *Alphonse Brown*) : !p play_song \"url_youtube\"""")
embedMessage.set_image("https://media.tenor.com/VaCWeSBvjHMAAAAi/dog-animal.gif")
await ctx.send(embed=embedMessage)
@bot.command(name="join",help="Pour demander au bot de rejoindre le canal vocal")
async def join(ctx):
if not ctx.message.author.voice:
embedMessage = discord.Embed(
title="🤖PolaroBot ne peut pas se connecter", description=f"T'es dans canal vocal ?")
else:
channel = ctx.author.voice.channel
bot.voice_client = await channel.connect()
embedMessage = discord.Embed(
title="🤖PolaroBot connecté", description=f"PolaroBot connecté au canal de {ctx.author}")
await ctx.send(embed=embedMessage)
@bot.command(name="leave", help="Pour faire quitter le canal vocal au bot")
async def leave(ctx):
voice_client = ctx.message.guild.voice_client
if voice_client and voice_client.is_connected():
embedMessage = discord.Embed(title="🤖PolaroBot se barre", description="Salut mon srab, je m'envole vers d'autres cieux")
await voice_client.disconnect()
else:
embedMessage = discord.Embed(title="🤖PolaroBot n'est pas connecté", description="""Ben déso gros mais je suis pas là...
Faut consulter si tu me vois partout....""")
await ctx.send(embed=embedMessage)
@bot.event
async def on_command_error(ctx, error):
channel = ctx.message.channel
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("Missing required argument: {}".format(error.param))
elif isinstance(error, commands.BadArgument):
ctx.send(channel, "Could not parse commands argument.")
bot.run(TOKEN)