2019-06-27 22:53:26 -07:00
"""
Karl Marx 2
A bot by turtlebasket
"""
import asyncio
import json
2019-06-25 14:33:06 -07:00
import discord
from discord . ext import commands
2019-08-31 20:28:21 -07:00
from bot_utils import *
2019-06-25 14:33:06 -07:00
2019-06-28 23:25:21 -07:00
# I know, config parsing is ugly and bad, I'll get around to refactoring later TwT
with open ( ' config.json ' , ' r ' ) as json_file :
config = json . load ( json_file )
MUTE_VOTE_TIME = config [ " MUTE_VOTE_TIME " ]
MIN_MUTE_VOTERS = config [ " MIN_MUTE_VOTERS " ] # should be 3
MUTE_TIME = config [ " MUTE_TIME " ] # 10 mins
KICK_VOTE_TIME = config [ " KICK_VOTE_TIME " ]
MIN_KICK_VOTERS = config [ " MIN_KICK_VOTERS " ]
BAN_VOTE_TIME = config [ " BAN_VOTE_TIME " ]
MIN_BAN_VOTERS = config [ " MIN_BAN_VOTERS " ]
2019-08-31 20:28:21 -07:00
EMOTE_VOTE_TIME = config [ " EMOTE_VOTE_TIME " ]
MIN_EMOTE_VOTERS = config [ " MIN_EMOTE_VOTERS " ]
2019-06-25 14:33:06 -07:00
bot = commands . Bot ( command_prefix = ' >> ' )
2019-08-31 20:28:21 -07:00
bot . remove_command ( ' help ' )
2019-06-25 14:33:06 -07:00
2019-06-28 23:25:21 -07:00
# To store users who are currently being voted on
muted_users = [ ]
muting_users = [ ]
kicking_users = [ ]
banning_users = [ ]
2019-06-25 14:33:06 -07:00
@bot.event
async def on_ready ( ) :
2019-08-31 20:28:21 -07:00
await bot . change_presence ( activity = discord . Game ( name = ' >>help ' ) )
2019-06-25 14:33:06 -07:00
print ( " Bot started. " )
print ( " -------------------------- " )
2019-08-31 20:28:21 -07:00
@bot.command ( aliases = [ ' manual ' , ' commands ' ] )
async def help ( ctx ) :
2019-06-28 23:25:21 -07:00
embed = discord . Embed ( title = " How 2 Comrade " )
embed . add_field (
2019-08-31 20:28:21 -07:00
name = " >>addEmote <emoji name> " ,
value = " hold a {0} -second vote on whether or not to add a given emote (provided as a message attachment. " . format ( EMOTE_VOTE_TIME )
)
embed . add_field (
name = " >>mute <user> " ,
2019-06-28 23:37:05 -07:00
value = " Hold a {0} -second vote to mute a user for {1} minutes (minimum voters: {2} , over 50 % majority required). You can set different requirements in `config.json`. " . format ( MUTE_VOTE_TIME , int ( MUTE_TIME / 60 ) , MIN_MUTE_VOTERS )
2019-06-28 23:25:21 -07:00
)
embed . add_field (
2019-08-31 20:28:21 -07:00
name = " >>kick <user> " ,
2019-06-28 23:37:05 -07:00
value = " Kick user. The vote is up for {0} minutes, and requires that a minimum of {1} users and >50 % a pprove. " . format ( int ( KICK_VOTE_TIME / 60 ) , MIN_KICK_VOTERS )
2019-06-28 23:25:21 -07:00
)
embed . add_field (
2019-08-31 20:28:21 -07:00
name = " >>ban <user> " ,
2019-06-28 23:37:05 -07:00
value = " Ban user. By default, the vote lasts {0} minutes, and requires that there be at least {1} votes and a 50 % majority. Like the `>>mute`/`>>kick` commands, you can also tweak settings in `config.json`. " . format ( int ( BAN_VOTE_TIME / 60 ) , MIN_BAN_VOTERS )
2019-06-28 23:25:21 -07:00
)
2019-08-31 20:28:21 -07:00
embed . add_field (
name = " >>ping " ,
value = " Get bot latency. Still being implemented. "
)
2019-06-28 23:25:21 -07:00
await ctx . send ( embed = embed )
2019-06-25 14:33:06 -07:00
2019-08-31 20:28:21 -07:00
@bot.command ( aliases = [ ' addEmoji ' ] )
async def addEmote ( ctx , emote_name : str ) :
2019-06-25 14:33:06 -07:00
"""
2019-08-31 20:28:21 -07:00
command : addEmote
2019-06-27 22:53:26 -07:00
2019-08-31 20:28:21 -07:00
Hold a vote to add an emoji .
2019-06-25 14:33:06 -07:00
"""
2019-08-31 20:28:21 -07:00
filename = str ( ctx . message . attachments [ 0 ] . filename )
valid_exts = [ " .jpg " , " .jpeg " , " .png " , " .gif " ]
valid = False
for ext in valid_exts :
# print(filename.endswith(ext))
if filename . endswith ( ext ) :
valid = True
break
if not valid :
await ctx . send ( " Invalid filetype! " )
return
vote_passed = await take_vote ( ctx , " Add emoji ` {} `? " . format ( emote_name ) , EMOTE_VOTE_TIME , MIN_EMOTE_VOTERS )
2019-06-25 14:33:06 -07:00
2019-08-31 20:28:21 -07:00
# if all_in_favor > not_in_favor and all_in_favor > MIN_EMOTE_VOTERS:
if vote_passed :
file_bytes = await ctx . message . attachments [ 0 ] . read ( )
await ctx . guild . create_custom_emoji ( name = emote_name , image = file_bytes )
2019-06-25 14:33:06 -07:00
2019-08-31 20:28:21 -07:00
@bot.command ( aliases = [ ' latency ' ] )
async def ping ( ctx ) :
await ctx . send ( " Currently under construction " )
2019-06-27 22:53:26 -07:00
@bot.command ( )
async def mute ( ctx , target_user : discord . User ) :
2019-06-28 23:25:21 -07:00
if target_user in muting_users :
await ctx . send ( " There is already a mute vote on ` {} `! " . format ( target_user ) )
return
elif target_user in muted_users :
await ctx . send ( " ` {} ` is already muted! " . format ( target_user ) )
return
muting_users . append ( target_user )
2019-08-31 20:28:21 -07:00
vote_passed = await take_vote ( ctx , " Mute ` {} `? " . format ( target_user ) , MUTE_VOTE_TIME , MIN_MUTE_VOTERS )
2019-06-28 23:25:21 -07:00
muting_users . remove ( target_user )
2019-08-31 20:28:21 -07:00
if vote_passed :
2019-06-28 23:25:21 -07:00
# Add to muted_users
muted_users . append ( target_user )
2019-06-27 22:53:26 -07:00
# add temp. role for mute
muted_role = await ctx . guild . create_role ( name = " Muted " )
# edit role position to take precedence over other roles
await muted_role . edit ( position = ctx . guild . get_member ( target_user . id ) . top_role . position + 1 )
2019-06-28 23:25:21 -07:00
# change channel permissions for new role
2019-06-27 22:53:26 -07:00
for channel in ctx . guild . channels :
2019-06-28 23:25:21 -07:00
if channel is discord . TextChannel and target_user in channel . members :
await channel . set_permissions ( muted_role , read_messages = True , send_messages = False , add_reactions = False )
elif channel is discord . VoiceChannel :
await channel . set_permissions ( muted_role , connect = False )
2019-06-27 22:53:26 -07:00
2019-06-28 23:25:21 -07:00
# Give role to member
2019-06-27 22:53:26 -07:00
await ctx . guild . get_member ( target_user . id ) . add_roles ( muted_role )
2019-08-31 20:28:21 -07:00
await ctx . send ( " ** {0} , the majority has ruled that you should be muted.** See ya in {1} minutes! " . format ( target_user , int ( MUTE_TIME / 60 ) ) )
2019-06-27 22:53:26 -07:00
await asyncio . sleep ( MUTE_TIME )
await muted_role . delete ( )
2019-06-25 14:33:06 -07:00
2019-06-28 23:25:21 -07:00
# Remove from muted_users
muted_users . remove ( target_user )
2019-06-27 22:53:26 -07:00
@bot.command ( )
2019-06-28 23:25:21 -07:00
async def kick ( ctx , target_user : discord . User ) :
if target_user in kicking_users :
await ctx . send ( " There is already a kick vote on ` {} `! " . format ( target_user ) )
return
# add to kicking_users
kicking_users . append ( target_user )
2019-08-31 20:28:21 -07:00
vote_passed = await take_vote ( ctx , " Kick ` {} `? " . format ( target_user ) , KICK_VOTE_TIME , MIN_KICK_VOTERS )
2019-06-28 23:25:21 -07:00
2019-08-31 20:28:21 -07:00
if vote_passed :
await ctx . guild . kick ( target_user )
2019-06-28 23:25:21 -07:00
kicking_users . remove ( target_user )
2019-06-27 22:53:26 -07:00
2019-08-31 20:28:21 -07:00
@bot.command ( aliases = [ ' exile ' ] )
async def ban ( ctx , target_user : discord . User ) :
2019-06-28 23:25:21 -07:00
if target_user in banning_users :
await ctx . send ( " There is already a ban vote on ` {} `! " . format ( target_user ) )
return
# add to banning_users
banning_users . append ( target_user )
2019-08-31 20:28:21 -07:00
vote_passed = await take_vote ( ctx , " Ban ` {} `? " . format ( target_user ) , BAN_VOTE_TIME , MIN_BAN_VOTERS )
2019-06-27 22:53:26 -07:00
2019-08-31 20:28:21 -07:00
if vote_passed :
2019-06-27 22:53:26 -07:00
await ctx . guild . ban ( target_user )
2019-08-31 20:28:21 -07:00
await ctx . send ( " :crab: :crab: ` {} ` IS GONE :crab: :crab: " . format ( target_user . name ) )
2019-06-28 23:25:21 -07:00
banning_users . remove ( target_user )
2019-06-25 14:33:06 -07:00
bot . run ( open ( " token.txt " ) . read ( ) . strip ( ) )