2020-04-02 11:40:56 +02:00
import discord
from discord . ext import commands
from discord . utils import get
from discord import FFmpegPCMAudio
from os import system
import sqlite3
import youtube_dl
import os
from time import sleep , time
from datetime import datetime , timedelta
from config import *
polls = { }
bot = commands . Bot ( command_prefix = prefix )
2020-04-02 11:43:03 +02:00
conn = sqlite3 . connect ( ' database.db ' )
2020-04-02 11:40:56 +02:00
c = conn . cursor ( )
try :
sql = " CREATE TABLE MESSAGES(user LONG, server LONG, textXP LONG, reactionXP LONG, vcXP LONG) "
sql2 = " CREATE TABLE VcActive (user LONG, startTime LONG) "
sql3 = " CREATE TABLE poll (pollID LONG, reaction STRING, calls LONG) "
c . execute ( sql )
c . execute ( sql2 )
c . execute ( sql3 )
except :
pass
@bot.event
async def on_ready ( ) :
print ( ' Logged in as ' )
print ( bot . user . name )
print ( bot . user . id )
print ( ' ------ ' )
await bot . change_presence ( activity = discord . Game ( name = " Discord " ) )
@bot.event
async def on_message ( message ) :
print ( str ( message . author ) + " sent: " + str ( message . content ) + " , latency: " + str ( bot . latency ) + " ms, Bot: " + str ( message . author . bot ) )
if ( message . author . bot ) or ( message . author . id == bot . user . id ) :
return
res = c . execute ( " SELECT textXP FROM MESSAGES WHERE user=? AND server = ? " , [ message . author . id , message . guild . id ] )
result = res . fetchone ( )
if ( result == None ) :
c . execute ( " INSERT INTO MESSAGES VALUES (?, ?, ?, 0, 0) " , [ message . author . id , message . guild . id , messageXP ] )
messages = messageXP
else :
messages = result [ 0 ] + messageXP
c . execute ( " UPDATE MESSAGES SET textXP = ? WHERE user = ? AND server = ? " , [ messages , message . author . id , message . guild . id ] )
conn . commit ( )
if message . content . startswith ( prefix ) :
await bot . process_commands ( message )
@bot.event
async def on_raw_reaction_add ( message ) :
if ( message . user_id == bot . user . id ) :
return
res = c . execute ( " SELECT reactionXP FROM MESSAGES WHERE user=? AND server = ? " , [ message . user_id , message . guild_id ] )
result = res . fetchone ( )
if ( result == None ) :
c . execute ( " INSERT INTO MESSAGES VALUES (?, ?, 0, ?, 0) " , [ message . user_id , message . guild_id , reactionXP ] )
messages = reactionXP
else :
messages = result [ 0 ] + reactionXP
c . execute ( " UPDATE MESSAGES SET reactionXP = ? WHERE user = ? AND server = ? " , [ messages , message . user_id , message . guild_id ] )
try :
polls [ str ( message . message_id ) ]
calls = c . execute ( " SELECT calls FROM poll WHERE pollID = ? AND reaction = ? " , [ message . message_id , str ( message . emoji ) ] ) . fetchone ( ) [ 0 ]
c . execute ( " UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ? " , [ calls + 1 , message . message_id , str ( message . emoji ) ] )
except :
pass
conn . commit ( )
@bot.event
async def on_raw_reaction_remove ( message ) :
try :
polls [ str ( message . message_id ) ]
calls = c . execute ( " SELECT calls FROM poll WHERE pollID = ? AND reaction = ? " , [ message . message_id , str ( message . emoji ) ] ) . fetchone ( ) [ 0 ]
c . execute ( " UPDATE poll SET calls = ? WHERE pollID = ? AND reaction = ? " , [ calls - 1 , message . message_id , str ( message . emoji ) ] )
except :
pass
conn . commit ( )
@bot.event
async def on_voice_state_update ( member , before , after ) :
print ( member . avatar_url )
if member . bot or ( member . id == bot . user . id ) :
return
if not before . afk and after . afk :
print ( str ( member ) + " is now AFK " )
result = c . execute ( " SELECT startTime FROM VcActive WHERE user=? " , [ member . id ] ) . fetchone ( ) [ 0 ]
c . execute ( " DELETE FROM VcActive WHERE user=? " , [ member . id ] )
xp = ( time ( ) - result ) / minutesPerVcXP
result = c . execute ( " SELECT vcXP FROM MESSAGES WHERE user=? AND server = ? " , [ member . id , member . guild . id ] ) . fetchone ( ) [ 0 ]
c . execute ( " UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ? " , [ result + round ( xp ) , member . id , member . guild . id ] )
conn . commit ( )
return
if before . afk and not after . afk :
print ( str ( member ) + " is active again " )
c . execute ( " INSERT INTO VcActive VALUES (?, ?) " , [ member . id , round ( time ( ) ) ] )
conn . commit ( )
return
if ( after . channel == None ) :
print ( str ( member ) + " left the Voicechat " )
print ( member . id )
result = c . execute ( " SELECT startTime FROM VcActive WHERE user = ? " , [ member . id ] ) . fetchone ( ) [ 0 ]
c . execute ( " DELETE FROM VcActive WHERE user=? " , [ member . id ] )
xp = ( time ( ) - result ) / 60 / minutesPerVcXP
result = c . execute ( " SELECT vcXP FROM MESSAGES WHERE user=? AND server = ? " , [ member . id , member . guild . id ] ) . fetchone ( ) [ 0 ]
c . execute ( " UPDATE MESSAGES SET vcXP = ? WHERE user = ? AND server = ? " , [ result + round ( xp ) , member . id , member . guild . id ] )
conn . commit ( )
return
elif ( before . channel == None ) :
print ( str ( member ) + " joined the Voicechat " + str ( after . channel ) )
c . execute ( " INSERT INTO VcActive VALUES (?, ?) " , [ member . id , round ( time ( ) ) ] )
conn . commit ( )
return
@bot.command ( brief = " shows your current XP and level " )
async def level ( ctx , user : str = None ) :
message = ctx . message
user_ = user
user = message . author
if ( user_ != None ) :
user_ = user_ . replace ( " <@! " , " " ) . replace ( " > " , " " )
for members in bot . get_all_members ( ) :
if ( str ( members . id ) == user_ ) :
user = members
temp = c . execute ( " SELECT textXP, reactionXP, vcXP FROM MESSAGES WHERE user=? AND server = ? " , [ user . id , message . guild . id ] ) . fetchone ( )
messages = temp [ 0 ]
reaction = temp [ 1 ]
voice = temp [ 2 ]
unsorted_ = c . execute ( " SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ? " , [ message . guild . id ] ) . fetchall ( )
unsorted = [ ]
for entries in unsorted_ :
unsorted . append ( [ entries [ 0 ] , ( entries [ 1 ] + entries [ 2 ] + entries [ 3 ] ) ] )
ranking = [ ]
lowest = unsorted [ 0 ]
while len ( unsorted ) > 0 :
for i in range ( 0 , len ( unsorted ) ) :
if ( unsorted [ i ] [ 1 ] < = lowest [ 1 ] ) :
lowest = unsorted [ i ]
unsorted . remove ( lowest )
ranking . append ( lowest )
if ( len ( unsorted ) > 0 ) :
lowest = unsorted [ 0 ]
tempXP = messages + reaction + voice
level = 0
levelXP = 0
while ( tempXP > 0 ) :
levelXP = base * ( factor * * ( level ) )
tempXP = tempXP - levelXP
level = level + 1
level = level - 1
for entries in reversed ( ranking ) :
if ( user . id == entries [ 0 ] ) :
rank = len ( ranking ) - ranking . index ( entries )
username = str ( user . name )
embed = discord . Embed ( title = " Stats of " + username , description = " Rank " + str ( rank ) + " of " + str ( len ( ranking ) ) )
embed . set_thumbnail ( url = user . avatar_url )
embed . add_field ( name = " Text XP " , value = messages )
embed . add_field ( name = " Reaction XP " , value = reaction )
embed . add_field ( name = " Voice XP " , value = voice )
embed . add_field ( name = " Total XP " , value = messages + reaction + voice )
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 ) ) + " % ) " )
await message . channel . send ( embed = embed )
@bot.command ( brief = " shows the leaderboard " )
async def leaderboard ( ctx ) :
unsorted_ = c . execute ( " SELECT user, textXP, reactionXP, vcXP FROM MESSAGES WHERE server = ? " , [ ctx . message . guild . id ] ) . fetchall ( )
unsorted = [ ]
for entries in unsorted_ :
unsorted . append ( [ entries [ 0 ] , ( entries [ 1 ] + entries [ 2 ] + entries [ 3 ] ) , entries [ 1 ] , entries [ 2 ] , entries [ 3 ] ] )
ranking = [ ]
lowest = unsorted [ 0 ]
while len ( unsorted ) > 0 :
for i in range ( 0 , len ( unsorted ) ) :
if ( unsorted [ i ] [ 1 ] < = lowest [ 1 ] ) :
lowest = unsorted [ i ]
unsorted . remove ( lowest )
ranking . append ( lowest )
if ( len ( unsorted ) > 0 ) :
lowest = unsorted [ 0 ]
message = " "
while len ( ranking ) > 10 :
ranking . remove ( ranking [ 0 ] )
badges = [ " :first_place: " , " :second_place: " , " :third_place: " , " :four: " , " :five: " , " :six: " , " :seven: " , " :eight: " , " :nine: " , " :keycap_ten: " ]
for entries in reversed ( ranking ) :
message = message + badges [ len ( ranking ) - ranking . index ( entries ) - 1 ] + " : <@ " + str ( entries [ 0 ] ) + " > **Total:** " + str ( entries [ 1 ] ) + " XP (**Text:** " + str ( entries [ 2 ] ) + " + **Reaction:** " + str ( entries [ 3 ] ) + " + **VC:** " + str ( entries [ 4 ] ) + " ) \n "
embed = discord . Embed ( title = " Leaderboard " , description = message )
await ctx . message . channel . send ( embed = embed )
@bot.command ( pass_context = True , brief = " joins your current voicechat and makes a wrong sound " )
async def wrong ( ctx ) :
channel = ctx . author . voice . channel
await channel . connect ( )
voice = ctx . voice_client
voice . play ( discord . FFmpegPCMAudio ( " wrong.mp3 " ) )
while voice . is_playing ( ) :
sleep ( 0.1 )
await ctx . message . guild . voice_client . disconnect ( )
@bot.command ( pass_context = True , brief = " joins your current voicechat and makes a dock sound " )
async def duck ( ctx ) :
channel = ctx . author . voice . channel
await channel . connect ( )
voice = ctx . voice_client
voice . play ( discord . FFmpegPCMAudio ( " duck.mp3 " ) )
while voice . is_playing ( ) :
sleep ( 0.1 )
await ctx . message . guild . voice_client . disconnect ( )
@bot.command ( pass_context = True , brief = " prints the ping time of the bot " )
async def ping ( ctx ) :
now = datetime . utcnow ( )
delta = round ( ( now . microsecond - ctx . message . created_at . microsecond ) / 1000 )
embed = discord . Embed ( title = " :ping_pong: | Pong! " , description = " ```prolog \n Latency:: " + str ( round ( bot . latency * 1000 ) ) + " ms \n Response :: " + str ( delta ) + " ms``` " )
await ctx . message . channel . send ( embed = embed )
@bot.command ( brief = " prints the text as emojies " )
async def emoji ( ctx , * message : str ) :
temp = " "
for messages in message :
temp = temp + messages + " "
messageNew = " "
for char in temp :
char = char . lower ( )
if char in " abcdefghijklmnopqrstuvwxyz " :
messageNew = messageNew + " :regional_indicator_ " + char + " : "
elif char in " 1234567890 " :
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 ] + " : "
elif char == " ? " :
messageNew = messageNew + " :question: "
elif char == " ! " :
messageNew = messageNew + " :exclamation: "
else :
messageNew = messageNew + char
await ctx . message . channel . send ( messageNew )
@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) " )
async def poll ( ctx , question , * options : str ) :
if len ( options ) < = 1 :
options = list ( options )
options . append ( " yes " )
options . append ( " no " )
options = tuple ( options )
if len ( options ) > 9 :
await ctx . message . channel . send ( ' You cannot make a poll for more than 9 things! ' )
return
if len ( options ) == 2 and options [ 0 ] == ' yes ' and options [ 1 ] == ' no ' :
reactions = [ ' ✅ ' , ' ❌ ' ]
else :
reactions = [ ' 1⃣ ' , ' 2⃣ ' , ' 3⃣ ' , ' 4⃣ ' , ' 5⃣ ' , ' 6⃣ ' , ' 7⃣ ' , ' 8⃣ ' , ' 9⃣ ' ]
description = [ ]
for x , option in enumerate ( options ) :
description + = ' \n {} {} ' . format ( reactions [ x ] , option )
embed = discord . Embed ( title = question , description = ' ' . join ( description ) )
await ctx . message . channel . send ( " @everyone " )
react_message = await ctx . message . channel . send ( embed = embed )
polls [ str ( react_message . id ) ] = react_message
for reaction in reactions [ : len ( options ) ] :
c . execute ( " INSERT INTO poll VALUES (?, ?, 0) " , [ react_message . id , reaction ] )
await react_message . add_reaction ( reaction )
embed . set_footer ( text = ' Poll ID: {} ' . format ( react_message . id ) )
await react_message . edit ( embed = embed )
@bot.command ( pass_context = True , brief = " shows the result of a poll, give the poll ID as argument " )
async def result ( ctx , id ) :
poll_message = polls [ str ( id ) ]
embed = poll_message . embeds [ 0 ]
del polls [ str ( id ) ]
unformatted_options = [ x . strip ( ) for x in poll_message . embeds [ 0 ] . description . split ( ' \n ' ) ]
opt_dict = { x [ : 2 ] : x [ 3 : ] for x in unformatted_options } if unformatted_options [ 0 ] [ 0 ] == ' 1 ' \
else { x [ : 1 ] : x [ 2 : ] for x in unformatted_options }
result = { }
request = c . execute ( " SELECT calls, reaction FROM poll WHERE pollID = ? " , [ id ] ) . fetchall ( )
for results in request :
result [ results [ 1 ] ] = results [ 0 ]
description = ' \n ' . join ( [ ' {} {} : {} votes ' . format ( key , opt_dict [ key ] , result [ key ] ) for key in result . keys ( ) ] )
embed = discord . Embed ( title = poll_message . embeds [ 0 ] . title , description = description )
embed . set_footer ( text = ' enden on ' + datetime . now ( ) . strftime ( " %d . % m. % Y % H: % M: % S " ) )
await poll_message . edit ( embed = embed )
await ctx . message . channel . send ( " You can find the result on the original poll: " + poll_message . jump_url )
c . execute ( " DELETE FROM poll where pollID = ? " , [ id ] )
conn . commit ( )
bot . run ( token , bot = botAccount )