2019-06-27 22:53:26 -07:00
|
|
|
"""
|
|
|
|
Karl Marx 2
|
|
|
|
A bot by turtlebasket
|
|
|
|
"""
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
import json
|
2019-09-03 22:14:23 -07:00
|
|
|
from urllib.request import urlopen, Request
|
2019-09-04 12:48:49 -07:00
|
|
|
import random
|
2019-06-25 14:33:06 -07:00
|
|
|
import discord
|
|
|
|
from discord.ext import commands
|
2020-03-24 16:03:43 -07:00
|
|
|
from os import environ
|
2020-05-05 23:20:50 -07:00
|
|
|
import dbl
|
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
|
|
|
with open('config.json', 'r') as json_file:
|
|
|
|
config = json.load(json_file)
|
|
|
|
|
2020-05-05 23:20:50 -07:00
|
|
|
with open('tokens.json', 'r') as tokens_file:
|
|
|
|
tokens = json.load(tokens_file)
|
|
|
|
|
|
|
|
# Feeling cute, might refactor later
|
2019-06-28 23:25:21 -07:00
|
|
|
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-11-25 10:00:47 -08:00
|
|
|
STATUS_LOOP = config["STATUS_LOOP"]
|
|
|
|
|
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-11-25 10:00:47 -08:00
|
|
|
async def status_loop():
|
|
|
|
while True:
|
2020-05-05 23:14:17 -07:00
|
|
|
await bot.change_presence(activity=discord.Game(name="Serving {0} glorious servers".format(len(bot.guilds))))
|
2019-11-25 10:00:47 -08:00
|
|
|
await asyncio.sleep(STATUS_LOOP)
|
2019-11-29 12:24:49 -08:00
|
|
|
|
2020-05-05 23:14:17 -07:00
|
|
|
await bot.change_presence(activity=discord.Game(name=">>help"))
|
2019-11-29 21:33:51 -08:00
|
|
|
await asyncio.sleep(STATUS_LOOP)
|
|
|
|
|
2020-05-05 23:14:17 -07:00
|
|
|
await bot.change_presence(activity=discord.Game(name="Proletarian Uprising 2: Electric Boogaloo"))
|
2020-01-26 22:45:17 -08:00
|
|
|
await asyncio.sleep(STATUS_LOOP)
|
|
|
|
|
2020-05-05 23:20:50 -07:00
|
|
|
|
|
|
|
# top.gg API interaction handling (boilerplate);
|
|
|
|
class TopGG(commands.Cog):
|
|
|
|
"""Handles interactions with the top.gg API"""
|
|
|
|
|
|
|
|
def __init__(self, bot):
|
|
|
|
self.bot = bot
|
|
|
|
self.token = tokens["dbl_token"]
|
|
|
|
self.dblpy = dbl.DBLClient(self.bot, self.token, autopost=True) # refresh guild count every 30 mins
|
|
|
|
|
|
|
|
bot.add_cog(TopGG(bot))
|
|
|
|
|
2019-06-25 14:33:06 -07:00
|
|
|
@bot.event
|
|
|
|
async def on_ready():
|
2019-11-25 10:00:47 -08:00
|
|
|
# await bot.change_presence(activity=discord.Game(name='{} servers | >>help'.format(len(bot.guilds))))
|
|
|
|
bot.loop.create_task(status_loop())
|
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>",
|
2020-01-26 22:45:17 -08:00
|
|
|
value=
|
|
|
|
"""Vote to add a new emoji.
|
|
|
|
Vote time: {0} minutes
|
|
|
|
Minimum Voters: {1}
|
|
|
|
""".format(int(EMOTE_VOTE_TIME/60), MIN_EMOTE_VOTERS)
|
2019-08-31 20:28:21 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
embed.add_field(
|
|
|
|
name=">>mute <user>",
|
2020-01-26 22:45:17 -08:00
|
|
|
value=
|
|
|
|
"""Vote to mute user for {0} minutes.
|
|
|
|
Vote time: {1} minutes
|
|
|
|
Minimum Voters: {2}
|
|
|
|
""".format(int(MUTE_TIME/60), int(MUTE_VOTE_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>",
|
2020-01-26 22:45:17 -08:00
|
|
|
value=
|
|
|
|
"""Vote to kick user.
|
|
|
|
Vote Time: {0} minutes
|
|
|
|
Minimum Voters: {1}
|
|
|
|
""".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>",
|
2020-01-26 22:45:17 -08:00
|
|
|
value=
|
|
|
|
"""Vote to ban user.
|
2020-05-05 23:14:17 -07:00
|
|
|
Vote Time: {0} minutes
|
2020-01-26 22:45:17 -08:00
|
|
|
Minimum Voters: {1}
|
|
|
|
""".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(
|
2019-09-08 22:16:16 -07:00
|
|
|
name=">>shibe",
|
2020-01-26 22:45:17 -08:00
|
|
|
value="Random shibe :dog: :eyes:"
|
2019-08-31 20:28:21 -07:00
|
|
|
)
|
2019-09-03 22:14:23 -07:00
|
|
|
|
|
|
|
embed.add_field(
|
2019-09-08 22:16:16 -07:00
|
|
|
name=">>birb",
|
2020-01-26 22:45:17 -08:00
|
|
|
value="Random birb :bird: :hatching_chick:"
|
2019-09-03 22:14:23 -07:00
|
|
|
)
|
2019-06-28 23:25:21 -07:00
|
|
|
|
2019-09-08 22:16:16 -07:00
|
|
|
embed.add_field(
|
|
|
|
name=">>ping",
|
|
|
|
value="Get bot latency."
|
|
|
|
)
|
2020-03-25 12:33:20 -07:00
|
|
|
|
|
|
|
embed.add_field(
|
|
|
|
name="Need help or having an issue?",
|
|
|
|
value="Report an issue at: https://github.com/turtlebasket/comrade-bot/issues/new"
|
|
|
|
)
|
|
|
|
|
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-11-25 10:00:47 -08: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 vote_passed:
|
2019-11-07 18:52:53 -08:00
|
|
|
try:
|
|
|
|
file_bytes = await ctx.message.attachments[0].read()
|
|
|
|
await ctx.guild.create_custom_emoji(name=emote_name, image=file_bytes)
|
|
|
|
await ctx.send("`Emote {0} added!` :{0}:".format(emote_name))
|
|
|
|
except:
|
|
|
|
await ctx.send(":warning: `There was an error adding emote {}.`".format(emote_name))
|
|
|
|
|
2019-06-25 14:33:06 -07:00
|
|
|
|
2019-09-03 22:14:23 -07:00
|
|
|
@bot.command()
|
|
|
|
async def shibe(ctx):
|
|
|
|
# with urllib.request.urlopen("http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=true") as json_return:
|
|
|
|
with urlopen(Request(url="http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=true", headers={'User-Agent': 'Mozilla/5.0'})) as json_return:
|
|
|
|
shibe_contents = json_return.read()
|
2019-09-04 12:48:49 -07:00
|
|
|
msg="{0}, here is your random shibe:".format(ctx.message.author.name)
|
|
|
|
url=json.loads(shibe_contents)[0]
|
|
|
|
await ctx.send(embed=imgfun(msg, url))
|
2019-09-08 22:13:04 -07:00
|
|
|
|
|
|
|
@bot.command(aliases=['bird'])
|
|
|
|
async def birb(ctx):
|
|
|
|
with urlopen(Request(url="http://random.birb.pw/tweet.json", headers={'User-Agent': 'Mozilla/5.0'})) as json_return:
|
|
|
|
# get image filename
|
|
|
|
birb_contents = json_return.read()
|
|
|
|
msg="{0}, here is your random birb:".format(ctx.message.author.name)
|
|
|
|
# insert image filename into URL
|
|
|
|
url="http://random.birb.pw/img/{}".format(json.loads(birb_contents)["file"])
|
|
|
|
await ctx.send(embed=imgfun(msg, url))
|
2019-08-31 20:28:21 -07:00
|
|
|
|
|
|
|
@bot.command(aliases=['latency'])
|
|
|
|
async def ping(ctx):
|
2019-09-03 21:22:05 -07:00
|
|
|
await ctx.send("`Bot latency: {}s`".format(round(bot.latency, 2)))
|
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)
|
2020-03-24 17:07:09 -07:00
|
|
|
# add temp. role for mute, edit role position to take precedence over other roles
|
2019-06-27 22:53:26 -07:00
|
|
|
muted_role = await ctx.guild.create_role(name="Muted")
|
|
|
|
await muted_role.edit(position=ctx.guild.get_member(target_user.id).top_role.position+1)
|
2020-03-24 17:07:09 -07:00
|
|
|
|
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:
|
2020-03-24 17:07:09 -07:00
|
|
|
if type(channel) is discord.TextChannel and target_user in channel.members:
|
2019-06-28 23:25:21 -07:00
|
|
|
await channel.set_permissions(muted_role, read_messages=True, send_messages=False, add_reactions=False)
|
|
|
|
|
2020-03-24 17:07:09 -07:00
|
|
|
elif type(channel) is discord.VoiceChannel:
|
2019-06-28 23:25:21 -07:00
|
|
|
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)
|
|
|
|
|
2020-05-05 23:20:50 -07:00
|
|
|
bot.run(tokens["bot_token"])
|