1
0
Fork 0
mirror of https://gitlab.jonasled.de/jonasled/discordbot synced 2024-11-16 06:52:17 +01:00
This commit is contained in:
Jonas Leder 2020-09-30 10:26:16 +02:00
parent edb27b5c14
commit 6b51adfa66

596
bot.py
View file

@ -14,8 +14,8 @@ from asyncio import sleep
from io import BytesIO from io import BytesIO
polls = {} polls = {}
player = None #the Player for the music Bot player = None # the Player for the music Bot
playerServer = None #The Server the player is active at the moment playerServer = None # The Server the player is active at the moment
audioPlayer = None audioPlayer = None
playerQue = [] playerQue = []
titleQue = [] titleQue = []
@ -27,7 +27,7 @@ bot = commands.Bot(command_prefix=prefix)
dbconnection = connect('database.db') dbconnection = connect('database.db')
dbcursor = dbconnection.cursor() dbcursor = dbconnection.cursor()
try: #try to create the database tables, if it fails they were created previosly try: # try to create the database tables, if it fails they were created previosly
sql = "CREATE TABLE MESSAGES(user LONG, server LONG, textXP LONG, reactionXP LONG, vcXP LONG)" sql = "CREATE TABLE MESSAGES(user LONG, server LONG, textXP LONG, reactionXP LONG, vcXP LONG)"
sql2 = "CREATE TABLE VcActive (user LONG, startTime LONG)" sql2 = "CREATE TABLE VcActive (user LONG, startTime LONG)"
sql3 = "CREATE TABLE poll (pollID LONG, reaction STRING, calls LONG)" sql3 = "CREATE TABLE poll (pollID LONG, reaction STRING, calls LONG)"
@ -37,22 +37,24 @@ try: #try to create the database tables, if it fails they were created previosly
except: except:
pass pass
@bot.event #print the username and id to the console and change the game status
@bot.event # print the username and id to the console and change the game status
async def on_ready(): async def on_ready():
print('Logged in as') print('Logged in as')
print(bot.user.name) print(bot.user.name)
print(bot.user.id) print(bot.user.id)
print('------') print('------')
if(activity == 0): if (activity == 0):
await bot.change_presence(activity=discord.Game(name=name, start=datetime.fromtimestamp(gameStartTime))) await bot.change_presence(activity=discord.Game(name=name, start=datetime.fromtimestamp(gameStartTime)))
if(activity == 1): if (activity == 1):
await bot.change_presence(activity=discord.Streaming(name=name, url=url)) await bot.change_presence(activity=discord.Streaming(name=name, url=url))
if(activity == 2): if (activity == 2):
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=name)) await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=name))
if(activity == 3): if (activity == 3):
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=name)) await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=name))
#
#
# #
# _ __ ___ __ __ _ __ ___ ___ ___ ___ __ _ __ _ ___ # _ __ ___ __ __ _ __ ___ ___ ___ ___ __ _ __ _ ___
# | '_ \ / _ \\ \ /\ / / | '_ ` _ \ / _ \/ __|/ __| / _` | / _` | / _ \ # | '_ \ / _ \\ \ /\ / / | '_ ` _ \ / _ \/ __|/ __| / _` | / _` | / _ \
@ -62,40 +64,50 @@ async def on_ready():
# |___/ # |___/
@bot.event @bot.event
async def on_message(message):#this will run on every message async def on_message(message): # this will run on every message
if (message.guild == None) and "time" in message.content: #this is for fun, if the user sends the bot private a message with time in it, send him the current time if (
current_time = datetime.now().strftime("%H:%M:%S")#get the time as string message.guild == None) and "time" in message.content: # this is for fun, if the user sends the bot private a message with time in it, send him the current time
await message.author.send("Current time: " + current_time)#send the current time to the user as DM current_time = datetime.now().strftime("%H:%M:%S") # get the time as string
return#don't execute the rest (will fail in the next step) await message.author.send("Current time: " + current_time) # send the current time to the user as DM
return # don't execute the rest (will fail in the next step)
try: try:
if (len(allowOnServer) > 0) and message.guild.id not in allowOnServer:#check if whitelist is enabled and Server on list if (len(
return#don't execute the rest allowOnServer) > 0) and message.guild.id not in allowOnServer: # check if whitelist is enabled and Server on list
return # don't execute the rest
except: except:
pass pass
print(str(message.author) + " sent: " + str(message.content) + ", latency: " + str(bot.latency) + " ms, Bot: " + str(message.author.bot)) #print some information about the message to the console print(
if(message.author.bot) or (message.author.id == bot.user.id): #check if the bot has written the message, if yes stop parsing it str(message.author) + " sent: " + str(message.content) + ", latency: " + str(bot.latency) + " ms, Bot: " + str(
message.author.bot)) # print some information about the message to the console
if (message.author.bot) or (
message.author.id == bot.user.id): # check if the bot has written the message, if yes stop parsing it
return return
try: try:
res = dbcursor.execute("SELECT textXP FROM MESSAGES WHERE user=? AND server = ?", [message.author.id, message.guild.id]) #try to get the current textXP of the user res = dbcursor.execute("SELECT textXP FROM MESSAGES WHERE user=? AND server = ?",
[message.author.id, message.guild.id]) # try to get the current textXP of the user
result = res.fetchone() result = res.fetchone()
if (result == None): if (result == None):
dbcursor.execute("INSERT INTO MESSAGES VALUES (?, ?, ?, 0, 0)", [message.author.id, message.guild.id, messageXP]) #if Bot can't find the user in the Database create a new entry dbcursor.execute("INSERT INTO MESSAGES VALUES (?, ?, ?, 0, 0)", [message.author.id, message.guild.id,
messageXP]) # if Bot can't find the user in the Database create a new entry
else: else:
messages = result[0] + messageXP messages = result[0] + messageXP
dbcursor.execute("UPDATE MESSAGES SET textXP = ? WHERE user = ? AND server = ?", [messages, message.author.id, message.guild.id]) #update the textXP value in the Database dbcursor.execute("UPDATE MESSAGES SET textXP = ? WHERE user = ? AND server = ?",
[messages, message.author.id, message.guild.id]) # update the textXP value in the Database
except: except:
pass pass
dbconnection.commit() #write the database changes to disk dbconnection.commit() # write the database changes to disk
if message.content.startswith(prefix): #check if the message starts with the prefix, if yes process the command if message.content.startswith(prefix): # check if the message starts with the prefix, if yes process the command
await bot.process_commands(message) await bot.process_commands(message)
if "<@!" + str(bot.user.id) + ">" in message.content: if "<@!" + str(bot.user.id) + ">" in message.content:
if (message.content[:3] == "hi ") or (message.content[-3:] == " hi"): if (message.content[:3] == "hi ") or (message.content[-3:] == " hi"):
await message.channel.send("Hello <@!" + str(message.author.id) + "> To get a list of my commands enter " + prefix + "help.") await message.channel.send(
"Hello <@!" + str(message.author.id) + "> To get a list of my commands enter " + prefix + "help.")
# _ _ _ _
# _ _ _ _
# | | (_) | | | | # | | (_) | | | |
# _ __ ___ __ _ ___ | |_ _ ___ _ __ __ _ __| | __| | # _ __ ___ __ _ ___ | |_ _ ___ _ __ __ _ __| | __| |
# | '__| / _ \ / _` | / __|| __|| | / _ \ | '_ \ / _` | / _` | / _` | # | '__| / _ \ / _` | / __|| __|| | / _ \ | '_ \ / _` | / _` | / _` |
@ -105,27 +117,34 @@ async def on_message(message):#this will run on every message
# #
@bot.event @bot.event
async def on_raw_reaction_add(message): #this runs on every reaction async def on_raw_reaction_add(message): # this runs on every reaction
if(message.user_id == bot.user.id):#check if the bot has written the message, if yes stop parsing it if (message.user_id == bot.user.id): # check if the bot has written the message, if yes stop parsing it
return return
res = dbcursor.execute("SELECT reactionXP FROM MESSAGES WHERE user=? AND server = ?", [message.user_id, message.guild_id]) #try to get the reactionXP from the database res = dbcursor.execute("SELECT reactionXP FROM MESSAGES WHERE user=? AND server = ?",
[message.user_id, message.guild_id]) # try to get the reactionXP from the database
result = res.fetchone() result = res.fetchone()
if (result == None): if (result == None):
dbcursor.execute("INSERT INTO MESSAGES VALUES (?, ?, 0, ?, 0)", [message.user_id, message.guild_id, reactionXP]) #if bot can't find the database entry for the user create a new one dbcursor.execute("INSERT INTO MESSAGES VALUES (?, ?, 0, ?, 0)", [message.user_id, message.guild_id,
reactionXP]) # if bot can't find the database entry for the user create a new one
messages = reactionXP messages = reactionXP
else: else:
messages = result[0] + reactionXP messages = result[0] + reactionXP
dbcursor.execute("UPDATE MESSAGES SET reactionXP = ? WHERE user = ? AND server = ?", [messages, message.user_id, message.guild_id])#update the reactionXP with the new values dbcursor.execute("UPDATE MESSAGES SET reactionXP = ? WHERE user = ? AND server = ?",
[messages, message.user_id, message.guild_id]) # update the reactionXP with the new values
try: try:
polls[str(message.message_id)][0] # check if the reaction is on a poll polls[str(message.message_id)][0] # check if the reaction is on a poll
calls = dbcursor.execute("SELECT calls FROM poll WHERE pollID = ? AND reaction = ?", [message.message_id, str(message.emoji)]).fetchone()[0]# if yes update the database and add 1 vote calls = dbcursor.execute("SELECT calls FROM poll WHERE pollID = ? AND reaction = ?",
dbcursor.execute("UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ?", [calls + 1, message.message_id, str(message.emoji)]) [message.message_id, str(message.emoji)]).fetchone()[
0] # if yes update the database and add 1 vote
dbcursor.execute("UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ?",
[calls + 1, message.message_id, str(message.emoji)])
except: except:
pass pass
dbconnection.commit() #write the database changes to disk dbconnection.commit() # write the database changes to disk
# _ _ # _ _
# | | (_) # | | (_)
# _ __ ___ __ _ ___ | |_ _ ___ _ __ _ __ ___ _ __ ___ ___ __ __ ___ # _ __ ___ __ _ ___ | |_ _ ___ _ __ _ __ ___ _ __ ___ ___ __ __ ___
@ -138,14 +157,18 @@ async def on_raw_reaction_add(message): #this runs on every reaction
@bot.event @bot.event
async def on_raw_reaction_remove(message): async def on_raw_reaction_remove(message):
try: try:
polls[str(message.message_id)][0] #check if the message is a poll polls[str(message.message_id)][0] # check if the message is a poll
calls = dbcursor.execute("SELECT calls FROM poll WHERE pollID = ? AND reaction = ?", [message.message_id, str(message.emoji)]).fetchone()[0]#if yes update the database and remove 1 vote calls = dbcursor.execute("SELECT calls FROM poll WHERE pollID = ? AND reaction = ?",
dbcursor.execute("UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ?", [calls - 1, message.message_id, str(message.emoji)]) [message.message_id, str(message.emoji)]).fetchone()[
0] # if yes update the database and remove 1 vote
dbcursor.execute("UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ?",
[calls - 1, message.message_id, str(message.emoji)])
except: except:
pass pass
dbconnection.commit()# write the database changes to disk dbconnection.commit() # write the database changes to disk
# _ _ _ _ _
# _ _ _ _ _
# (_) | | | | | | | | # (_) | | | | | | | |
# __ __ ___ _ ___ ___ ___ | |__ __ _ | |_ _ _ _ __ __| | __ _ | |_ ___ # __ __ ___ _ ___ ___ ___ | |__ __ _ | |_ _ _ _ __ __| | __ _ | |_ ___
# \ \ / / / _ \ | | / __| / _ \ / __|| '_ \ / _` || __| | | | || '_ \ / _` | / _` || __| / _ \ # \ \ / / / _ \ | | / __| / _ \ / __|| '_ \ / _` || __| | | | || '_ \ / _` | / _` || __| / _ \
@ -155,38 +178,52 @@ async def on_raw_reaction_remove(message):
# |_| # |_|
@bot.event @bot.event
async def on_voice_state_update(member, before, after):#this runs on every voice chat update (user joins, leaves, go afk, moves, ...) async def on_voice_state_update(member, before,
if member.bot or (member.id == bot.user.id): #check if the bot is the user, if yes stop parsing it after): # this runs on every voice chat update (user joins, leaves, go afk, moves, ...)
if member.bot or (member.id == bot.user.id): # check if the bot is the user, if yes stop parsing it
return return
if not before.afk and after.afk:#check if the user moved from not afk to afk if not before.afk and after.afk: # check if the user moved from not afk to afk
print(str(member) + " is now AFK") print(str(member) + " is now AFK")
result = dbcursor.execute("SELECT startTime FROM VcActive WHERE user=?", [member.id]).fetchone()[0]#if yes, get the join time from the database result = dbcursor.execute("SELECT startTime FROM VcActive WHERE user=?", [member.id]).fetchone()[
dbcursor.execute("DELETE FROM VcActive WHERE user=?", [member.id])#delete the entrie from the voicechat in the database 0] # if yes, get the join time from the database
xp = (time() - result) / minutesPerVcXP#calculate the xp dbcursor.execute("DELETE FROM VcActive WHERE user=?",
result = dbcursor.execute("SELECT vcXP FROM MESSAGES WHERE user=? AND server = ?", [member.id, member.guild.id]).fetchone()[0]#update the user database and set the new Voice XP [member.id]) # delete the entrie from the voicechat in the database
dbcursor.execute("UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ?", [result + round(xp), member.id, member.guild.id]) xp = (time() - result) / minutesPerVcXP # calculate the xp
dbconnection.commit() #write the changes to the database result = dbcursor.execute("SELECT vcXP FROM MESSAGES WHERE user=? AND server = ?",
[member.id, member.guild.id]).fetchone()[
0] # update the user database and set the new Voice XP
dbcursor.execute("UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ?",
[result + round(xp), member.id, member.guild.id])
dbconnection.commit() # write the changes to the database
return return
if before.afk and not after.afk: #check if the user moved from afk back to active if before.afk and not after.afk: # check if the user moved from afk back to active
print(str(member) + " is active again") print(str(member) + " is active again")
dbcursor.execute("INSERT INTO VcActive VALUES (?, ?)", [member.id, round(time())])#insert the current time in the table dbcursor.execute("INSERT INTO VcActive VALUES (?, ?)",
dbconnection.commit() #write the changes to database [member.id, round(time())]) # insert the current time in the table
dbconnection.commit() # write the changes to database
return return
if(after.channel == None): #check if the user left the voicechat if (after.channel == None): # check if the user left the voicechat
print(str(member) + " left the Voicechat") print(str(member) + " left the Voicechat")
result = dbcursor.execute("SELECT startTime FROM VcActive WHERE user = ?", [member.id]).fetchone()[0]#get the join time from database result = dbcursor.execute("SELECT startTime FROM VcActive WHERE user = ?", [member.id]).fetchone()[
dbcursor.execute("DELETE FROM VcActive WHERE user=?", [member.id])# delete the join time entry 0] # get the join time from database
xp = (time() - result) / 60 / minutesPerVcXP#calculate the XP dbcursor.execute("DELETE FROM VcActive WHERE user=?", [member.id]) # delete the join time entry
result = dbcursor.execute("SELECT vcXP FROM MESSAGES WHERE user=? AND server = ?", [member.id, member.guild.id]).fetchone()[0]#update the user Table and set the new voiceXP xp = (time() - result) / 60 / minutesPerVcXP # calculate the XP
dbcursor.execute("UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ?", [result + round(xp), member.id, member.guild.id]) result = dbcursor.execute("SELECT vcXP FROM MESSAGES WHERE user=? AND server = ?",
dbconnection.commit()#write the changes to disk [member.id, member.guild.id]).fetchone()[
0] # update the user Table and set the new voiceXP
dbcursor.execute("UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ?",
[result + round(xp), member.id, member.guild.id])
dbconnection.commit() # write the changes to disk
return return
elif(before.channel == None): #check if a user joins the voicechat elif (before.channel == None): # check if a user joins the voicechat
print(str(member) + " joined the Voicechat " + str(after.channel)) print(str(member) + " joined the Voicechat " + str(after.channel))
dbcursor.execute("INSERT INTO VcActive VALUES (?, ?)", [member.id, round(time())])#insert the current time in the database dbcursor.execute("INSERT INTO VcActive VALUES (?, ?)",
dbconnection.commit()#write the changes to databasr [member.id, round(time())]) # insert the current time in the database
dbconnection.commit() # write the changes to databasr
return return
# _ _
# _ _
# | | | | # | | | |
# | | ___ __ __ ___ | | # | | ___ __ __ ___ | |
# | | / _ \\ \ / / / _ \| | # | | / _ \\ \ / / / _ \| |
@ -195,51 +232,58 @@ async def on_voice_state_update(member, before, after):#this runs on every voice
# #
# #
@bot.command(brief="shows your current XP and level") @bot.command(brief="shows your current XP and level")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def level(ctx, user : discord.Member=None):#shows your current XP and level, as argument you can give a different user async def level(ctx,
if (user == None): #check if the message author submitted a different user to check, if not use the author user: discord.Member = None): # shows your current XP and level, as argument you can give a different user
if (user == None): # check if the message author submitted a different user to check, if not use the author
user = ctx.message.author user = ctx.message.author
xp = dbcursor.execute("SELECT textXP, reactionXP, vcXP FROM MESSAGES WHERE user=? AND server = ?", [user.id, ctx.message.guild.id]).fetchone()#get the xp of the user from database
unsorted = dbcursor.execute("SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ?", [ctx.message.guild.id]).fetchall() #get all users from the database (for the ranking)
ranking = [] #to this variable we will later add the users sorted xp = dbcursor.execute("SELECT textXP, reactionXP, vcXP FROM MESSAGES WHERE user=? AND server = ?",
[user.id, ctx.message.guild.id]).fetchone() # get the xp of the user from database
unsorted = dbcursor.execute("SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ?",
[ctx.message.guild.id]).fetchall() # get all users from the database (for the ranking)
while len(unsorted) > 0: #do this while we have entries in unsorted ranking = [] # to this variable we will later add the users sorted
lowest = unsorted[0]#just set the first entrie in lowest, so we can later overwrite it if we find a user with less XP
for entries in unsorted: #go through every user, calculate the XP and check if its lower than the current lowest while len(unsorted) > 0: # do this while we have entries in unsorted
if((entries[1] + entries[2] + entries[3]) <= (lowest[1] + lowest[2] + lowest[3])): lowest = unsorted[
lowest = entries#if the xp is lower, write the user to lowest 0] # just set the first entrie in lowest, so we can later overwrite it if we find a user with less XP
unsorted.remove(lowest)#after checking every user, remove the lowest from unsorted and add it to ranking for entries in unsorted: # go through every user, calculate the XP and check if its lower than the current lowest
if ((entries[1] + entries[2] + entries[3]) <= (lowest[1] + lowest[2] + lowest[3])):
lowest = entries # if the xp is lower, write the user to lowest
unsorted.remove(lowest) # after checking every user, remove the lowest from unsorted and add it to ranking
ranking.append(lowest) ranking.append(lowest)
for entries in ranking:#try to find the user in the ranking array, to get his rank. for entries in ranking: # try to find the user in the ranking array, to get his rank.
if(user.id == entries[0]): if (user.id == entries[0]):
rank = len(ranking) - ranking.index(entries) rank = len(ranking) - ranking.index(entries)
tempXP = xp[0]+xp[1]+xp[2]#the XP the user has in this level tempXP = xp[0] + xp[1] + xp[2] # the XP the user has in this level
level = 0#the current level level = 0 # the current level
levelXP = 0#the XP the user needs for the level levelXP = 0 # the XP the user needs for the level
while (tempXP > 0): #while the XP is over 0, calculate the XP needed fo this level and subtract it from tempXP while (tempXP > 0): # while the XP is over 0, calculate the XP needed fo this level and subtract it from tempXP
levelXP = base * (factor**(level)) levelXP = base * (factor ** (level))
tempXP = tempXP - levelXP tempXP = tempXP - levelXP
level = level + 1 level = level + 1
level = level - 1 #subtract one level, because the last level the user didn't reached level = level - 1 # subtract one level, because the last level the user didn't reached
username = str(user.display_name)#get the username username = str(user.display_name) # get the username
embed = discord.Embed(title="Stats of " + username , description="Rank " + str(rank) + " of " + str(len(ranking)))#make the response message embed = discord.Embed(title="Stats of " + username,
description="Rank " + str(rank) + " of " + str(len(ranking))) # make the response message
embed.set_thumbnail(url=user.avatar_url) embed.set_thumbnail(url=user.avatar_url)
embed.add_field(name="Text XP", value=xp[0]) embed.add_field(name="Text XP", value=xp[0])
embed.add_field(name="Reaction XP", value=xp[1]) embed.add_field(name="Reaction XP", value=xp[1])
embed.add_field(name="Voice XP", value=xp[2]) embed.add_field(name="Voice XP", value=xp[2])
embed.add_field(name="Total XP", value=xp[0]+xp[1]+xp[2]) embed.add_field(name="Total XP", value=xp[0] + xp[1] + xp[2])
embed.add_field(name="Level", value=level) embed.add_field(name="Level", value=level)
embed.add_field(name="Progress", value=str(round(levelXP+tempXP)) + "/" + str(round(levelXP)) + " (" + str(round((levelXP+tempXP) / levelXP * 100 )) + "%)") embed.add_field(name="Progress", value=str(round(levelXP + tempXP)) + "/" + str(round(levelXP)) + " (" + str(
round((levelXP + tempXP) / levelXP * 100)) + "%)")
await ctx.message.channel.send(embed=embed) #send the response message await ctx.message.channel.send(embed=embed) # send the response message
# _ _ _ _
# _ _ _ _
# | | | | | | | | # | | | | | | | |
# | | ___ __ _ __| | ___ _ __ | |__ ___ __ _ _ __ __| | # | | ___ __ _ __| | ___ _ __ | |__ ___ __ _ _ __ __| |
# | | / _ \ / _` | / _` | / _ \| '__|| '_ \ / _ \ / _` || '__| / _` | # | | / _ \ / _` | / _` | / _ \| '__|| '_ \ / _ \ / _` || '__| / _` |
@ -249,32 +293,39 @@ async def level(ctx, user : discord.Member=None):#shows your current XP and leve
# #
@bot.command(brief="shows the leaderboard") @bot.command(brief="shows the leaderboard")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def leaderboard(ctx): async def leaderboard(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
unsorted = dbcursor.execute("SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ?", [ctx.message.guild.id]).fetchall() #get all users from the database (for the ranking) unsorted = dbcursor.execute("SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ?",
[ctx.message.guild.id]).fetchall() # get all users from the database (for the ranking)
ranking = [] #to this variable we will later add the users sorted ranking = [] # to this variable we will later add the users sorted
while len(unsorted) > 0: #do this while we have entries in unsorted while len(unsorted) > 0: # do this while we have entries in unsorted
lowest = unsorted[0]#just set the first entrie in lowest, so we can later overwrite it if we find a user with less XP lowest = unsorted[
for entries in unsorted: #go through every user, calculate the XP and check if its lower than the current lowest 0] # just set the first entrie in lowest, so we can later overwrite it if we find a user with less XP
if((entries[1] + entries[2] + entries[3]) <= (lowest[1] + lowest[2] + lowest[3])): for entries in unsorted: # go through every user, calculate the XP and check if its lower than the current lowest
lowest = entries#if the xp is lower, write the user to lowest if ((entries[1] + entries[2] + entries[3]) <= (lowest[1] + lowest[2] + lowest[3])):
unsorted.remove(lowest)#after checking every user, remove the lowest from unsorted and add it to ranking lowest = entries # if the xp is lower, write the user to lowest
unsorted.remove(lowest) # after checking every user, remove the lowest from unsorted and add it to ranking
ranking.append(lowest) ranking.append(lowest)
while len(ranking) > 10:#remove the last user, while the length is over 10 while len(ranking) > 10: # remove the last user, while the length is over 10
ranking.remove(ranking[0]) ranking.remove(ranking[0])
badges = [":first_place: ", ":second_place: ", ":third_place: ", ":four: ", ":five: ", ":six: ", ":seven: ", ":eight: ", ":nine: ", ":keycap_ten: "]#the emoji in front of the username badges = [":first_place: ", ":second_place: ", ":third_place: ", ":four: ", ":five: ", ":six: ", ":seven: ",
message = ""#in this variable we will prepare in the next step the response ":eight: ", ":nine: ", ":keycap_ten: "] # the emoji in front of the username
for entries in reversed(ranking):#loop through every user in reverse order to get the best first and andd his statistics to message message = "" # in this variable we will prepare in the next step the response
message = message + badges[len(ranking) - ranking.index(entries) - 1] + ": <@" + str(entries[0]) + "> **Total:** " + str(entries[1] + entries[2] + entries[3]) + " XP (**Text:** " + str(entries[1]) + " + **Reaction:** " + str(entries[2]) + " + **VC:** " + str(entries[3]) + ")\n" for entries in reversed(
embed = discord.Embed(title="Leaderboard" , description=message)#make the response Box ranking): # loop through every user in reverse order to get the best first and andd his statistics to message
await ctx.message.channel.send(embed=embed)#print the ressponse box message = message + badges[len(ranking) - ranking.index(entries) - 1] + ": <@" + str(
entries[0]) + "> **Total:** " + str(entries[1] + entries[2] + entries[3]) + " XP (**Text:** " + str(
entries[1]) + " + **Reaction:** " + str(entries[2]) + " + **VC:** " + str(entries[3]) + ")\n"
embed = discord.Embed(title="Leaderboard", description=message) # make the response Box
await ctx.message.channel.send(embed=embed) # print the ressponse box
# _
# _
# (_) # (_)
# _ __ _ _ __ __ _ # _ __ _ _ __ __ _
# | '_ \ | || '_ \ / _` | # | '_ \ | || '_ \ / _` |
@ -284,16 +335,20 @@ async def leaderboard(ctx):
# |_| |___/ # |_| |___/
@bot.command(pass_context=True, brief="prints the ping time of the bot") @bot.command(pass_context=True, brief="prints the ping time of the bot")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def ping(ctx):#prints the ping and the time the bot needed to process this command async def ping(ctx): # prints the ping and the time the bot needed to process this command
now = datetime.utcnow()#get the current time now = datetime.utcnow() # get the current time
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
delta = round((now.microsecond - ctx.message.created_at.microsecond) /1000)#substract the time the message was created from the current time 8in microsecconds), convert this to millisecconds and round delta = round((
embed = discord.Embed(title=":ping_pong: | Pong!", description="```prolog\nLatency:: " + str(round(bot.latency * 1000)) + "ms\nResponse :: " + str(delta) + "ms```")#make the response, we format it as code and select prolog as language for nice cloloring now.microsecond - ctx.message.created_at.microsecond) / 1000) # substract the time the message was created from the current time 8in microsecconds), convert this to millisecconds and round
embed = discord.Embed(title=":ping_pong: | Pong!", description="```prolog\nLatency:: " + str(
round(bot.latency * 1000)) + "ms\nResponse :: " + str(
delta) + "ms```") # make the response, we format it as code and select prolog as language for nice cloloring
await ctx.message.channel.send(embed=embed)#send the prepared message await ctx.message.channel.send(embed=embed) # send the prepared message
# _ _ __ _ _
# _ _ __ _ _
# (_)(_) / _| | | | | # (_)(_) / _| | | | |
# ___ _ __ ___ ___ _ _ | |_ _ _ | |_ ___ __ __| |_ # ___ _ __ ___ ___ _ _ | |_ _ _ | |_ ___ __ __| |_
# / _ \| '_ ` _ \ / _ \ | || || _|| | | | | __| / _ \\ \/ /| __| # / _ \| '_ ` _ \ / _ \ | || || _|| | | | | __| / _ \\ \/ /| __|
@ -303,27 +358,28 @@ async def ping(ctx):#prints the ping and the time the bot needed to process this
# |__/ |___/ # |__/ |___/
@bot.command(brief="prints the text as emojies") @bot.command(brief="prints the text as emojies")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def emoji(ctx, *message: str):#emojifies the string the user give as parameter async def emoji(ctx, *message: str): # emojifies the string the user give as parameter
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
temp = "" temp = ""
for messages in message:#because every word will be formatted as parameter by discord.py, we have to make a long string again for messages in message: # because every word will be formatted as parameter by discord.py, we have to make a long string again
temp = temp + messages + " " temp = temp + messages + " "
messageNew = "" messageNew = ""
for char in temp:#process every character one by one for char in temp: # process every character one by one
char = char.lower()#convert it to lower (e.g. Aa ==> aa) char = char.lower() # convert it to lower (e.g. Aa ==> aa)
if char in "abcdefghijklmnopqrstuvwxyz":#check if the char is a letter if char in "abcdefghijklmnopqrstuvwxyz": # check if the char is a letter
messageNew = messageNew + ":regional_indicator_" + char + ":"#if yes we add to the new message the emoji of the letter messageNew = messageNew + ":regional_indicator_" + char + ":" # if yes we add to the new message the emoji of the letter
elif char in "1234567890":#if the character is a number we have to use a different emoji elif char in "1234567890": # if the character is a number we have to use a different emoji
numbers = { "0" : 'zero', "1" : 'one', "2" : 'two', "3" : 'three', "4" : 'four', "5": 'five', "6" : 'six', "7" : 'seven', "8" : 'eight', "9" : 'nine',} numbers = {"0": 'zero', "1": 'one', "2": 'two', "3": 'three', "4": 'four', "5": 'five', "6": 'six',
"7": 'seven', "8": 'eight', "9": 'nine', }
messageNew = messageNew + ":" + numbers[char] + ":" messageNew = messageNew + ":" + numbers[char] + ":"
elif char == "?":#the emoji for ? elif char == "?": # the emoji for ?
messageNew = messageNew + ":question:" messageNew = messageNew + ":question:"
elif char == "!":#the emoji for ! elif char == "!": # the emoji for !
messageNew = messageNew + ":exclamation:" messageNew = messageNew + ":exclamation:"
else:#if we can'T find a suitable emoji, just add the raw char else: # if we can'T find a suitable emoji, just add the raw char
messageNew = messageNew + char messageNew = messageNew + char
await ctx.message.channel.send(messageNew)#send the formatted message await ctx.message.channel.send(messageNew) # send the formatted message
# _ _ # _ _
@ -335,39 +391,48 @@ async def emoji(ctx, *message: str):#emojifies the string the user give as param
# | | # | |
# |_| # |_|
@bot.command(pass_context=True, brief="starts a poll", description="starts a poll, please give as first argument the question (for sentences please use \") and then the posibilities (leave empty for yes or no)") @bot.command(pass_context=True, brief="starts a poll",
@commands.cooldown(1, cooldownTime, commands.BucketType.user) description="starts a poll, please give as first argument the question (for sentences please use \") and then the posibilities (leave empty for yes or no)")
async def poll(ctx, question, *options: str):#this is a tool to create a poll @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def poll(ctx, question, *options: str): # this is a tool to create a poll
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
if len(options) <= 1:#check if options were supplied, if not add yes and no to the options if len(options) <= 1: # check if options were supplied, if not add yes and no to the options
options = list(options) options = list(options)
options.append("yes") options.append("yes")
options.append("no") options.append("no")
options = tuple(options) options = tuple(options)
if len(options) > 9:#we can only process 9 arguments at the moment (emoji 1 to 9) if len(options) > 9: # we can only process 9 arguments at the moment (emoji 1 to 9)
await ctx.message.channel.send('You cannot make a poll for more than 9 things!')#if the user added more arguments, print a error message await ctx.message.channel.send(
'You cannot make a poll for more than 9 things!') # if the user added more arguments, print a error message
return return
if len(options) == 2 and options[0] == 'yes' and options[1] == 'no':#select the reaction emojis, ✅ and ❌ for yes or no and numbers one to 9 for the rest if len(options) == 2 and options[0] == 'yes' and options[
1] == 'no': # select the reaction emojis, ✅ and ❌ for yes or no and numbers one to 9 for the rest
reactions = ['', ''] reactions = ['', '']
else: else:
reactions = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣'] reactions = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣']
description = "" description = ""
for x, option in enumerate(options):#make a dict from options and process every entry, x is the key and option the value for x, option in enumerate(
description += '\n {} {}'.format(reactions[x], option)#add to the description for every entry in otions one line with the emoji and the answer options): # make a dict from options and process every entry, x is the key and option the value
embed = discord.Embed(title=question, description=description)#prepare the response description += '\n {} {}'.format(reactions[x],
await ctx.message.channel.send("@everyone")#tag everyone, for the new survey option) # add to the description for every entry in otions one line with the emoji and the answer
react_message = await ctx.message.channel.send(embed=embed)#print the survey and save the message to a variable embed = discord.Embed(title=question, description=description) # prepare the response
polls[str(react_message.id)] = [react_message, ctx.message.author.id]#save the react message and the userid to the polls array to acces it later await ctx.message.channel.send("@everyone") # tag everyone, for the new survey
for reaction in reactions[:len(options)]:#for every reaction add an entry to the reaction database and add it to the message, that the user can click it react_message = await ctx.message.channel.send(embed=embed) # print the survey and save the message to a variable
polls[str(react_message.id)] = [react_message,
ctx.message.author.id] # save the react message and the userid to the polls array to acces it later
for reaction in reactions[:len(
options)]: # for every reaction add an entry to the reaction database and add it to the message, that the user can click it
dbcursor.execute("INSERT INTO poll VALUES (?, ?, 0)", [react_message.id, reaction]) dbcursor.execute("INSERT INTO poll VALUES (?, ?, 0)", [react_message.id, reaction])
await react_message.add_reaction(reaction) await react_message.add_reaction(reaction)
embed.set_footer(text='Poll ID: {}'.format(react_message.id))#add the poll id to the message (needed to get the results) embed.set_footer(
text='Poll ID: {}'.format(react_message.id)) # add the poll id to the message (needed to get the results)
await react_message.edit(embed=embed) await react_message.edit(embed=embed)
# _ _ _ _
# _ _ _ _
# | || | | || | # | || | | || |
# _ __ ___ | || | _ __ ___ ___ _ _ | || |_ # _ __ ___ | || | _ __ ___ ___ _ _ | || |_
# | '_ \ / _ \ | || | | '__| / _ \/ __|| | | || || __| # | '_ \ / _ \ | || | | '__| / _ \/ __|| | | || || __|
@ -377,39 +442,43 @@ async def poll(ctx, question, *options: str):#this is a tool to create a poll
# |_| # |_|
@bot.command(pass_context=True, brief="shows the result of a poll, give the poll ID as argument") @bot.command(pass_context=True, brief="shows the result of a poll, give the poll ID as argument")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def result(ctx, id):#this function prints the result of a poll async def result(ctx, id): # this function prints the result of a poll
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
poll_message = polls[str(id)][0]#get the poll message from the variable poll_message = polls[str(id)][0] # get the poll message from the variable
poll_owner = polls[str(id)][1] poll_owner = polls[str(id)][1]
if(poll_owner != ctx.message.author.id): #check if the poll owner wants the result, or someone else if (poll_owner != ctx.message.author.id): # check if the poll owner wants the result, or someone else
await ctx.message.channel.send("You can only get the results of your poll.") await ctx.message.channel.send("You can only get the results of your poll.")
return return
embed = poll_message.embeds[0]#get the embed (the content) embed = poll_message.embeds[0] # get the embed (the content)
del polls[str(id)]#delte the poll from the poll message array del polls[str(id)] # delte the poll from the poll message array
unformatted_options = [x.strip() for x in poll_message.embeds[0].description.split('\n')]#split the poll options (split every line and remove all leading and trailing spaces) unformatted_options = [x.strip() for x in poll_message.embeds[0].description.split(
'\n')] # split the poll options (split every line and remove all leading and trailing spaces)
opt_dict = {} opt_dict = {}
for options in unformatted_options:#for every option: split on the space between emoji and text and put it in a dict, with the emoji as key and the emoji + the text as value for options in unformatted_options: # for every option: split on the space between emoji and text and put it in a dict, with the emoji as key and the emoji + the text as value
options = options.split(" ", 1) options = options.split(" ", 1)
opt_dict[options[0]] = options[0] + " " + options[1] opt_dict[options[0]] = options[0] + " " + options[1]
request = dbcursor.execute("SELECT calls, reaction FROM poll WHERE pollID = ?", [id]).fetchall() #get the votes from the database request = dbcursor.execute("SELECT calls, reaction FROM poll WHERE pollID = ?",
[id]).fetchall() # get the votes from the database
description = "" description = ""
for results in request:#loop through the entries of the database and make the result for results in request: # loop through the entries of the database and make the result
description = description + "\n" + opt_dict[results[1]] + ": " + str(results[0]) + " votes" description = description + "\n" + opt_dict[results[1]] + ": " + str(results[0]) + " votes"
embed = discord.Embed(title=poll_message.embeds[0].title, description=description) # prepare the result
embed = discord.Embed(title=poll_message.embeds[0].title, description=description)#prepare the result embed.set_footer(
embed.set_footer(text='enden on ' + datetime.now().strftime("%d.%m.%Y %H:%M:%S"))#set as footer the end time of the poll text='enden on ' + datetime.now().strftime("%d.%m.%Y %H:%M:%S")) # set as footer the end time of the poll
await poll_message.edit(embed=embed)#edit the origina lmessage and print the results await poll_message.edit(embed=embed) # edit the origina lmessage and print the results
embed2 = discord.Embed(title=" ", description="You can find the result of the poll in the original message [here](" + poll_message.jump_url + ").")#This message will be printed to the end of the chat with a link to the original (where the results are) embed2 = discord.Embed(title=" ",
await ctx.message.channel.send(embed=embed2)#print the result message from one line up description="You can find the result of the poll in the original message [here](" + poll_message.jump_url + ").") # This message will be printed to the end of the chat with a link to the original (where the results are)
dbcursor.execute("DELETE FROM poll where pollID = ?", [id])#delete the entries from the poll in the database await ctx.message.channel.send(embed=embed2) # print the result message from one line up
dbconnection.commit()#write the database to disk dbcursor.execute("DELETE FROM poll where pollID = ?", [id]) # delete the entries from the poll in the database
dbconnection.commit() # write the database to disk
# _____
# _____
# |_ _| # |_ _|
# | | _ __ ___ __ _ __ _ ___ ___ # | | _ __ ___ __ _ __ _ ___ ___
# | | | '_ ` _ \ / _` |/ _` |/ _ \/ __| # | | | '_ ` _ \ / _` |/ _` |/ _ \/ __|
@ -419,47 +488,53 @@ async def result(ctx, id):#this function prints the result of a poll
# |___/ # |___/
@bot.command(pass_context=True, brief="sends a random cat image") @bot.command(pass_context=True, brief="sends a random cat image")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def cat(ctx): async def cat(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
r = get("https://api.thecatapi.com/v1/images/search?size=full") # get random cat image r = get("https://api.thecatapi.com/v1/images/search?size=full") # get random cat image
answer = loads(r.text) answer = loads(r.text)
extension = answer[0]["url"].split(".")[-1]#get the file extension extension = answer[0]["url"].split(".")[-1] # get the file extension
r = get(answer[0]["url"])#get the url to the cat r = get(answer[0]["url"]) # get the url to the cat
image_data = BytesIO(r.content)#download tthe image and load it into BytesIO image_data = BytesIO(r.content) # download tthe image and load it into BytesIO
image_data.seek(0) image_data.seek(0)
await ctx.send(file=discord.File(image_data, 'cat.' + extension))#send the cat image await ctx.send(file=discord.File(image_data, 'cat.' + extension)) # send the cat image
@bot.command(pass_context=True, brief="sends a random dog image") @bot.command(pass_context=True, brief="sends a random dog image")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def dog(ctx): async def dog(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
r = get("https://random.dog/woof.json") # get random dog image r = get("https://random.dog/woof.json") # get random dog image
answer = loads(r.text) answer = loads(r.text)
extension = answer["url"].split(".")[-1]#get the file extension extension = answer["url"].split(".")[-1] # get the file extension
r = get(answer["url"])#get the url to the dog r = get(answer["url"]) # get the url to the dog
image_data = BytesIO(r.content)#download tthe image and load it into BytesIO image_data = BytesIO(r.content) # download tthe image and load it into BytesIO
image_data.seek(0) image_data.seek(0)
await ctx.send(file=discord.File(image_data, 'dog.' + extension))#send the dog image await ctx.send(file=discord.File(image_data, 'dog.' + extension)) # send the dog image
@bot.command(pass_context=True, brief="sends a random fail gif") @bot.command(pass_context=True, brief="sends a random fail gif")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def fail(ctx): async def fail(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
r = get("https://api.giphy.com/v1/gifs/random?api_key=0UTRbFtkMxAplrohufYco5IY74U8hOes&tag=fail&pg-13") # get random fail image r = get(
"https://api.giphy.com/v1/gifs/random?api_key=0UTRbFtkMxAplrohufYco5IY74U8hOes&tag=fail&pg-13") # get random fail image
answer = loads(r.text) answer = loads(r.text)
r = get(answer["data"]["images"]["downsized_medium"]["url"])#get the url to the fail r = get(answer["data"]["images"]["downsized_medium"]["url"]) # get the url to the fail
image_data = BytesIO(r.content)#download tthe image and load it into BytesIO image_data = BytesIO(r.content) # download tthe image and load it into BytesIO
image_data.seek(0) image_data.seek(0)
await ctx.send(file=discord.File(image_data, 'fail.gif'))#send the fail image await ctx.send(file=discord.File(image_data, 'fail.gif')) # send the fail image
@bot.command(pass_context=True, brief="sends a random upload from jensmemes.tilera.xyz") @bot.command(pass_context=True, brief="sends a random upload from jensmemes.tilera.xyz")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def jensmeme(ctx): async def jensmeme(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
r = get("https://jensmemes.tilera.xyz/api/random") # get random upload r = get("https://jensmemes.tilera.xyz/api/random") # get random upload
await ctx.send(loads(r.text)["link"])#send the fail image await ctx.send(loads(r.text)["link"]) # send the fail image
# ___ ___ _ ______ _
# ___ ___ _ ______ _
# | \/ | (_) | ___ \ | | # | \/ | (_) | ___ \ | |
# | . . | _ _ ___ _ ___ | |_/ / ___ | |_ # | . . | _ _ ___ _ ___ | |_/ / ___ | |_
# | |\/| || | | |/ __|| | / __|| ___ \ / _ \ | __| # | |\/| || | | |/ __|| | / __|| ___ \ / _ \ | __|
@ -469,155 +544,166 @@ async def jensmeme(ctx):
# #
@bot.command(brief="adds a song to the playlist") @bot.command(brief="adds a song to the playlist")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def play(ctx, songURL : str): async def play(ctx, songURL: str):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
global player#import the global variables needed global player # import the global variables needed
global playerServer global playerServer
global downloadQue global downloadQue
try: try:
channel = ctx.author.voice.channel#get the current voicechat the user is in channel = ctx.author.voice.channel # get the current voicechat the user is in
except:#if we can't get the voice channel, the user is not in one ==> print an error except: # if we can't get the voice channel, the user is not in one ==> print an error
await ctx.message.channel.send("To use the music bot you have to be in a voice chat") await ctx.message.channel.send("To use the music bot you have to be in a voice chat")
return return
if(player == None):#if the music player is currently not connected to a server if (player == None): # if the music player is currently not connected to a server
await channel.connect()#connect to this chat await channel.connect() # connect to this chat
player = ctx.voice_client #save the voice client for later use player = ctx.voice_client # save the voice client for later use
playerServer = ctx.message.guild.id#save the music bot server id to variable playerServer = ctx.message.guild.id # save the music bot server id to variable
if(playerServer != ctx.message.guild.id):#check if the music bot is at the moment on this server, if not print a error message if (
await ctx.message.channel.send("The Bot is currently connected to a different channel, please wait until he is finished there") playerServer != ctx.message.guild.id): # check if the music bot is at the moment on this server, if not print a error message
await ctx.message.channel.send(
"The Bot is currently connected to a different channel, please wait until he is finished there")
return return
r = get("https://www.youtube.com/oembed?format=json&url=" + songURL)#check if video exists and get the title r = get("https://www.youtube.com/oembed?format=json&url=" + songURL) # check if video exists and get the title
if(r.status_code != 200):#if youtube doesn't respond with 200, there was an error finding the song if (r.status_code != 200): # if youtube doesn't respond with 200, there was an error finding the song
await ctx.message.channel.send("Can't find the song") await ctx.message.channel.send("Can't find the song")
return return
await ctx.message.channel.send("Adding `" + loads(r.text)["title"] + "` to que.")#print the user a status message await ctx.message.channel.send("Adding `" + loads(r.text)["title"] + "` to que.") # print the user a status message
backgroundDownloader(loads(r.text)["html"].split("src=")[1][1:].split("\"")[0], loads(r.text)["title"]) backgroundDownloader(loads(r.text)["html"].split("src=")[1][1:].split("\"")[0], loads(r.text)["title"])
@bot.command(brief="skipps the current song in playlist") @bot.command(brief="skipps the current song in playlist")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def skip(ctx): async def skip(ctx):
try: try:
channel = ctx.author.voice.channel#get the current voicechat the user is in channel = ctx.author.voice.channel # get the current voicechat the user is in
except:#if we can't get the voice channel, the user is not in one ==> print an error except: # if we can't get the voice channel, the user is not in one ==> print an error
await ctx.message.channel.send("To use the music bot you have to be in a voice chat") await ctx.message.channel.send("To use the music bot you have to be in a voice chat")
return return
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
global player# import the global variable global player # import the global variable
player.stop()#stop the player (daemon think song enden ==> plays next one) player.stop() # stop the player (daemon think song enden ==> plays next one)
await ctx.message.channel.send("Skipped current song")#print the status to the console await ctx.message.channel.send("Skipped current song") # print the status to the console
@bot.command(brief="Prints the current music que") @bot.command(brief="Prints the current music que")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def que(ctx): async def que(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
global titleQue#import the global variable global titleQue # import the global variable
message = "**Musicbot Que:**\n **[current] " + titleQue[0] + " **"#prepare the message and add the current playing first in bold message = "**Musicbot Que:**\n **[current] " + titleQue[
0] + " **" # prepare the message and add the current playing first in bold
for entries in titleQue[1:]: #scroll through the entries and add all songs to the resonse for entries in titleQue[1:]: # scroll through the entries and add all songs to the resonse
message = message + "\n" + entries message = message + "\n" + entries
await ctx.message.channel.send(message)#send the prepared message await ctx.message.channel.send(message) # send the prepared message
@bot.command(brief="stop the music bot and clear the que") @bot.command(brief="stop the music bot and clear the que")
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def stop(ctx): async def stop(ctx):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
try: try:
channel = ctx.author.voice.channel#get the current voicechat the user is in channel = ctx.author.voice.channel # get the current voicechat the user is in
except:#if we can't get the voice channel, the user is not in one ==> print an error except: # if we can't get the voice channel, the user is not in one ==> print an error
await ctx.message.channel.send("To use the music bot you have to be in a voice chat") await ctx.message.channel.send("To use the music bot you have to be in a voice chat")
return return
global player#import the global variables global player # import the global variables
global playerQue global playerQue
global titleQue global titleQue
global downloadQue global downloadQue
global playerServer global playerServer
if (playerServer != ctx.message.guild.id):#check if the music bot runns on this server if (playerServer != ctx.message.guild.id): # check if the music bot runns on this server
await ctx.message.channel.send("You can't stop the music bot on a different server.") await ctx.message.channel.send("You can't stop the music bot on a different server.")
return return
playerQue = []#delte all ques playerQue = [] # delte all ques
titleQue = [] titleQue = []
downloadQue = [] downloadQue = []
player.stop()#stop the current song player.stop() # stop the current song
await player.disconnect()#disconnect from the voice chat await player.disconnect() # disconnect from the voice chat
player = None#clear the player variable player = None # clear the player variable
playerServer = None#allow everyone to invite the music bot playerServer = None # allow everyone to invite the music bot
for files in listdir("."):#delete all mp3 files for files in listdir("."): # delete all mp3 files
if files.endswith(".mp3"): if files.endswith(".mp3"):
remove(files) remove(files)
@bot.command(brief="changes the volume of the music bot")#with this command you can change the volume of the music bot
@commands.cooldown(1, cooldownTime, commands.BucketType.user) @bot.command(
async def volume(ctx, volume : int): brief="changes the volume of the music bot") # with this command you can change the volume of the music bot
@commands.cooldown(1, cooldownTime, commands.BucketType.user)
async def volume(ctx, volume: int):
if reactOnValidCommand: await ctx.message.add_reaction("") if reactOnValidCommand: await ctx.message.add_reaction("")
try: try:
channel = ctx.author.voice.channel#get the current voicechat the user is in channel = ctx.author.voice.channel # get the current voicechat the user is in
except:#if we can't get the voice channel, the user is not in one ==> print an error except: # if we can't get the voice channel, the user is not in one ==> print an error
await ctx.message.channel.send("To use the music bot you have to be in a voice chat") await ctx.message.channel.send("To use the music bot you have to be in a voice chat")
return return
global audioPlayer#import hte global audio player global audioPlayer # import hte global audio player
if(volume < 0) or (volume > 100):#check if the volume is in a percent range if (volume < 0) or (volume > 100): # check if the volume is in a percent range
ctx.message.channel.send("Volume has to be between 0 and 100") ctx.message.channel.send("Volume has to be between 0 and 100")
else: else:
audioPlayer.volume = volume / 100#change the volume audioPlayer.volume = volume / 100 # change the volume
async def checkForNextSong():#background task, that runns every seccond and checks if the song ended async def checkForNextSong(): # background task, that runns every seccond and checks if the song ended
global player#import the global variables global player # import the global variables
global playerQue global playerQue
global playerServer global playerServer
global playing global playing
global titleQue global titleQue
global audioPlayer global audioPlayer
while True: #catch all errors (dont crash when a error occurs) while True: # catch all errors (dont crash when a error occurs)
try: try:
if(player != None) and not player.is_playing() and (len(playerQue) > 0):#check if the player is active and the song ended if (player != None) and not player.is_playing() and (
if(playing):#check if the player played previously len(playerQue) > 0): # check if the player is active and the song ended
remove(playerQue[0])#delete the last mp3 file if (playing): # check if the player played previously
playerQue.remove(playerQue[0])#remove the first entry from the que and the first title remove(playerQue[0]) # delete the last mp3 file
playerQue.remove(playerQue[0]) # remove the first entry from the que and the first title
titleQue.remove(titleQue[0]) titleQue.remove(titleQue[0])
playing = False#set playing to false playing = False # set playing to false
if(len(playerQue) == 0):#if the que is empty leave the voicechat and cleat the player variable if (len(playerQue) == 0): # if the que is empty leave the voicechat and cleat the player variable
await player.disconnect() await player.disconnect()
player = None player = None
playerServer = None#allow everyone to invite the music bot playerServer = None # allow everyone to invite the music bot
for files in listdir("."):#delete all mp3 files for files in listdir("."): # delete all mp3 files
if files.endswith(".mp3"): if files.endswith(".mp3"):
remove(files) remove(files)
else: else:
playing = True#set playing to true and play the next file playing = True # set playing to true and play the next file
print("playing " + playerQue[0]) print("playing " + playerQue[0])
audioPlayer = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(playerQue[0]))#convert the audio player to a volume audio player audioPlayer = discord.PCMVolumeTransformer(
discord.FFmpegPCMAudio(playerQue[0])) # convert the audio player to a volume audio player
player.play(audioPlayer) player.play(audioPlayer)
await sleep(1)#sleep 1 seccond and allo the bot to run different tasks await sleep(1) # sleep 1 seccond and allo the bot to run different tasks
except: except:
pass pass
def backgroundDownloader(url, title): def backgroundDownloader(url, title):
global playerQue#import the global variables global playerQue # import the global variables
global fileIndex global fileIndex
ydl_opts = { #youtube-dl arguments ydl_opts = { # youtube-dl arguments
'format': 'worstaudio/worst', 'format': 'worstaudio/worst',
'postprocessors': [{ 'postprocessors': [{
'key': 'FFmpegExtractAudio', 'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3', 'preferredcodec': 'mp3',
'preferredquality': '192', 'preferredquality': '192',
}], }],
'outtmpl': str(fileIndex) +'.%(ext)s', 'outtmpl': str(fileIndex) + '.%(ext)s',
} }
fileIndex = fileIndex + 1 #add 1 to the file index counter (used to find the mp3 files easy later and that there are no files with the same name) fileIndex = fileIndex + 1 # add 1 to the file index counter (used to find the mp3 files easy later and that there are no files with the same name)
with YoutubeDL(ydl_opts) as ydl:#download the song with the arguments from up with YoutubeDL(ydl_opts) as ydl: # download the song with the arguments from up
ydl.download([url]) ydl.download([url])
playerQue.append(str(fileIndex - 1) + ".mp3")#add the file to the que playerQue.append(str(fileIndex - 1) + ".mp3") # add the file to the que
titleQue.append(title)#add the title to the que (for que list) titleQue.append(title) # add the title to the que (for que list)
bot.loop.create_task(checkForNextSong())#start the music bot task in background
bot.run(token, bot=botAccount)#start the bot with the options in config.py bot.loop.create_task(checkForNextSong()) # start the music bot task in background
bot.run(token, bot=botAccount) # start the bot with the options in config.py