Browse Source

Refactoring to make imports a lot easier and not have three versions of the blacklisted function. Lots of tiny formatting refactoring done too.

tags/v1.7.0
Roxie Gibson 6 years ago
parent
commit
baa7377b65
16 changed files with 145 additions and 161 deletions
  1. +22
    -0
      Roxbot/__init__.py
  2. +25
    -24
      Roxbot/cogs/admin.py
  3. +22
    -30
      Roxbot/cogs/customcommands.py
  4. +7
    -9
      Roxbot/cogs/fun.py
  5. +2
    -2
      Roxbot/cogs/joinleave.py
  6. +5
    -5
      Roxbot/cogs/nsfw.py
  7. +6
    -14
      Roxbot/cogs/reddit.py
  8. +7
    -11
      Roxbot/cogs/selfassign.py
  9. +2
    -1
      Roxbot/cogs/trivia.py
  10. +11
    -15
      Roxbot/cogs/twitch.py
  11. +9
    -10
      Roxbot/cogs/voice.py
  12. +0
    -10
      Roxbot/load_config.py
  13. +7
    -8
      Roxbot/logging.py
  14. +0
    -0
      Roxbot/settings/blacklist.txt
  15. +0
    -0
      Roxbot/settings/preferences_example.ini
  16. +20
    -22
      main.py

+ 22
- 0
Roxbot/__init__.py View File

from Roxbot import checks
from Roxbot.load_config import *
from Roxbot.logging import log
from Roxbot.settings import guild_settings


def blacklisted(user):
with open("Roxbot/settings/blacklist.txt", "r") as fp:
for line in fp.readlines():
if str(user.id)+"\n" == line:
return True
return False


__description__ = """RoxBot, A Discord Bot made by a filthy Mercy Main. Built with love (and discord.py) by Roxxers#7443.

[Github link](https://github.com/RainbowDinoaur/roxbot)
[Changelog](https://github.com/RainbowDinoaur/roxbot#v100)
[Found a bug or need to report an issue? Report it here](https://github.com/RainbowRoxxers/roxbot/issues/new)
[Say Thanks](https://saythanks.io/to/Roxxers)"""
__author__ = "Roxanne Gibson"
__version__ = "1.6.1"

+ 25
- 24
Roxbot/cogs/admin.py View File

from discord.ext import commands from discord.ext import commands
from discord.ext.commands import bot from discord.ext.commands import bot


from Roxbot import checks, load_config
from Roxbot.settings import guild_settings as gs
import Roxbot as roxbot
gs = roxbot.guild_settings




def _is_admin_or_mod(message):
if message.author.id == load_config.owner:
def _is_admin_or_mod(message): # TODO: Remove this function and find a better solution thank.
if message.author.id == roxbot.owner:
return True return True
else: else:
admin_roles = gs.get(message.channel.guild).perm_roles["admin"] admin_roles = gs.get(message.channel.guild).perm_roles["admin"]
else: else:
pass pass


@roxbot.checks.is_admin_or_mod()
@commands.guild_only() @commands.guild_only()
@checks.is_admin_or_mod()
@commands.bot_has_permissions(manage_messages=True) @commands.bot_has_permissions(manage_messages=True)
@bot.command() @bot.command()
async def slowmode(self, ctx, time):
async def slowmode(self, ctx, seconds):
"""Puts the current channel in slowmode. """Puts the current channel in slowmode.
Usage: Usage:
;slowmode [time/"off"] ;slowmode [time/"off"]
time = time of the cooldown between messages a user has.
seconds = number of seconds for the cooldown between messages a user has.
off = turns off slowmode for this channel""" off = turns off slowmode for this channel"""
if time == "off" and self.slow_mode: # Turn Slow Mode off
if seconds == "off" and self.slow_mode: # Turn Slow Mode off
self.slow_mode = False self.slow_mode = False
self.slow_mode_channels.pop(ctx.channel.id) self.slow_mode_channels.pop(ctx.channel.id)
self.users.pop(ctx.channel.id) self.users.pop(ctx.channel.id)
return await ctx.send("Slowmode off") return await ctx.send("Slowmode off")


elif time.isdigit() and not self.slow_mode: # Turn Slow Mode On
elif seconds.isdigit() and not self.slow_mode: # Turn Slow Mode On
self.users[ctx.channel.id] = {} self.users[ctx.channel.id] = {}
self.slow_mode_channels[ctx.channel.id] = int(time)
self.slow_mode_channels[ctx.channel.id] = int(seconds)
self.slow_mode = True self.slow_mode = True
return await ctx.send("Slowmode on :snail: ({} seconds)".format(time))
return await ctx.send("Slowmode on :snail: ({} seconds)".format(seconds))


elif time.isdigit and self.slow_mode: # Change value of Slow Mode timer
self.slow_mode_channels[ctx.channel.id] = int(time)
return await ctx.send("Slowmode set to :snail: ({} seconds)".format(time))
elif seconds.isdigit and self.slow_mode: # Change value of Slow Mode timer
self.slow_mode_channels[ctx.channel.id] = int(seconds)
return await ctx.send("Slowmode set to :snail: ({} seconds)".format(seconds))


else: else:
pass pass
messages = await ctx.channel.purge(limit=limit, check=predicate) messages = await ctx.channel.purge(limit=limit, check=predicate)
return await ctx.send("{} message(s) purged from chat.".format(len(messages))) return await ctx.send("{} message(s) purged from chat.".format(len(messages)))


@checks.is_admin_or_mod()
@roxbot.checks.is_admin_or_mod()
@commands.group(case_insensitive=True) @commands.group(case_insensitive=True)
async def warn(self, ctx): async def warn(self, ctx):
"""Group of commands handling warnings""" """Group of commands handling warnings"""
return await ctx.send('Missing Argument') return await ctx.send('Missing Argument')


@warn.command() @warn.command()
async def add(self, ctx, user: discord.User = None, *, warning = ""):
async def add(self, ctx, user: discord.User=None, *, warning=""):
"""Adds a warning to a user.""" """Adds a warning to a user."""
# Warning in the settings is a dictionary of user ids. The user ids are equal to a list of dictionaries. # Warning in the settings is a dictionary of user ids. The user ids are equal to a list of dictionaries.
settings = gs.get(ctx.guild) settings = gs.get(ctx.guild)
} }
user_id = str(user.id) user_id = str(user.id)


if not user_id in settings.warnings:
if user_id not in settings.warnings:
settings.warnings[user_id] = [] settings.warnings[user_id] = []


settings.warnings[user_id].append(warning_dict) settings.warnings[user_id].append(warning_dict)
"""Lists all or just the warnings for one user.""" """Lists all or just the warnings for one user."""
settings = gs.get(ctx.guild) settings = gs.get(ctx.guild)


if user == None:
if user is None:
output = "" output = ""
for member in settings.warnings: for member in settings.warnings:
# Remove users with no warning here instead of remove cause im lazy # Remove users with no warning here instead of remove cause im lazy
if not settings.warnings[user_id]: if not settings.warnings[user_id]:
settings.warnings.pop(user_id) settings.warnings.pop(user_id)
settings.update(settings.warnings, "warnings") settings.update(settings.warnings, "warnings")
if not user_id in settings.warnings:
if user_id not in settings.warnings:
return await ctx.send("This user doesn't have any warning on record.") return await ctx.send("This user doesn't have any warning on record.")


em = discord.Embed(title="Warnings for {}".format(str(user)), colour=0XDEADBF) em = discord.Embed(title="Warnings for {}".format(str(user)), colour=0XDEADBF)
warned_by = warning["warned-by"] warned_by = warning["warned-by"]
date = datetime.datetime.fromtimestamp(warning["date"]).strftime('%c') date = datetime.datetime.fromtimestamp(warning["date"]).strftime('%c')
warn_reason = warning["warning"] warn_reason = warning["warning"]
em.add_field(name="Warning %s"%x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warn_reason))
em.add_field(name="Warning %s" % x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warn_reason))
x += 1 x += 1
return await ctx.send(embed=em) return await ctx.send(embed=em)


@warn.command() @warn.command()
async def remove(self, ctx, user: discord.User = None, index = None):
async def remove(self, ctx, user: discord.User=None, index=None):
"""Removes one or all of the warnings for a user.""" """Removes one or all of the warnings for a user."""
user_id = str(user.id) user_id = str(user.id)
settings = gs.get(ctx.guild) settings = gs.get(ctx.guild)
@commands.has_permissions(kick_members=True) @commands.has_permissions(kick_members=True)
@commands.bot_has_permissions(kick_members=True) @commands.bot_has_permissions(kick_members=True)
@bot.command() @bot.command()
async def kick(self, ctx, member:discord.Member, *, reason = ""):
async def kick(self, ctx, member: discord.Member, *, reason=""):
"""Kicks mentioned user. Allows you to give a reason.""" """Kicks mentioned user. Allows you to give a reason."""
try: try:
await member.kick(reason=reason) await member.kick(reason=reason)
@commands.has_permissions(ban_members=True) @commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True) @commands.bot_has_permissions(ban_members=True)
@bot.command() @bot.command()
async def ban(self, ctx, member:discord.Member, *, reason = ""):
async def ban(self, ctx, member: discord.Member, *, reason=""):
"""Bans mentioned user. Allows you to give a reason.""" """Bans mentioned user. Allows you to give a reason."""
try: try:
await member.ban(reason=reason, delete_message_days=0) await member.ban(reason=reason, delete_message_days=0)
@commands.has_permissions(ban_members=True) @commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True) @commands.bot_has_permissions(ban_members=True)
@bot.command() @bot.command()
async def unban(self, ctx, member_id:int, *, reason = ""):
async def unban(self, ctx, member_id: int, *, reason=""):
"""Unbans user with given ID. Allows you to give a reason.""" """Unbans user with given ID. Allows you to give a reason."""
mem = None mem = None
for ban in await ctx.guild.bans(): for ban in await ctx.guild.bans():
except discord.Forbidden: except discord.Forbidden:
return await ctx.send("I can't kick the owner or users higher or equal to me.") return await ctx.send("I can't kick the owner or users higher or equal to me.")



def setup(bot_client): def setup(bot_client):
bot_client.add_cog(Admin(bot_client)) bot_client.add_cog(Admin(bot_client))

+ 22
- 30
Roxbot/cogs/customcommands.py View File

import discord import discord
from Roxbot import checks, load_config
from discord.ext.commands import group from discord.ext.commands import group
from Roxbot.settings import guild_settings



def blacklisted(user):
with open("Roxbot/blacklist.txt", "r") as fp:
for line in fp.readlines():
if str(user.id)+"\n" == line:
return True
return False
import Roxbot as roxbot




class CustomCommands(): class CustomCommands():
async def on_message(self, message): async def on_message(self, message):
if isinstance(message.channel, discord.DMChannel): if isinstance(message.channel, discord.DMChannel):
return return
settings = guild_settings.get(message.guild)
settings = roxbot.guild_settings.get(message.guild)
msg = message.content.lower() msg = message.content.lower()
channel = message.channel channel = message.channel


if blacklisted(message.author) or type(message.channel) != discord.TextChannel:
if roxbot.blacklisted(message.author) or type(message.channel) != discord.TextChannel:
return return
if message.author == self.bot.user: if message.author == self.bot.user:
return return
return await channel.send(settings.custom_commands["0"][command]) return await channel.send(settings.custom_commands["0"][command])


@group(pass_context=True, aliases=["cc"]) @group(pass_context=True, aliases=["cc"])
@checks.is_owner_or_admin()
@roxbot.checks.is_owner_or_admin()
async def custom(self, ctx): async def custom(self, ctx):
"A group of commands to manage custom commands for your server."
""""A group of commands to manage custom commands for your server."""
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
return await ctx.send('Missing Argument') return await ctx.send('Missing Argument')


@custom.command(pass_context=True) @custom.command(pass_context=True)
async def add(self, ctx, command, output, prefix_required = "0"):
"Adds a custom command to the list of custom commands."
settings = guild_settings.get(ctx.guild)
async def add(self, ctx, command, output, prefix_required="0"):
"""Adds a custom command to the list of custom commands."""
settings = roxbot.guild_settings.get(ctx.guild)
command = command.lower() command = command.lower()
output = output output = output
zero = settings.custom_commands["0"] zero = settings.custom_commands["0"]


@custom.command(pass_context=True) @custom.command(pass_context=True)
async def edit(self, ctx, command, edit): async def edit(self, ctx, command, edit):
"Edits an existing custom command."
settings = guild_settings.get(ctx.guild)
""""Edits an existing custom command."""
settings = roxbot.guild_settings.get(ctx.guild)
zero = settings.custom_commands["0"] zero = settings.custom_commands["0"]
one = settings.custom_commands["1"] one = settings.custom_commands["1"]




@custom.command(pass_context=True) @custom.command(pass_context=True)
async def remove(self, ctx, command): async def remove(self, ctx, command):
"Removes a custom command."
settings = guild_settings.get(ctx.guild)
""""Removes a custom command."""
settings = roxbot.guild_settings.get(ctx.guild)
command = command.lower() command = command.lower()
if command in settings.custom_commands["1"]: if command in settings.custom_commands["1"]:
settings.custom_commands["1"].pop(command) settings.custom_commands["1"].pop(command)
else: else:
return await ctx.send("Custom Command doesn't exist.") return await ctx.send("Custom Command doesn't exist.")



@custom.command(pass_context=True) @custom.command(pass_context=True)
async def list(self, ctx, debug="0"): async def list(self, ctx, debug="0"):
"Lists all custom commands for this server."
""""Lists all custom commands for this server."""
if debug != "0" and debug != "1": if debug != "0" and debug != "1":
debug = "0" debug = "0"
settings = guild_settings.get(ctx.guild)
l = settings.custom_commands
settings = roxbot.guild_settings.get(ctx.guild)
cc = settings.custom_commands
listzero = "" listzero = ""
listone = "" listone = ""


for command in l["0"]:
for command in cc["0"]:
if debug == "1": if debug == "1":
command += " - {}".format(l["0"][command])
command += " - {}".format(cc["0"][command])
listzero = listzero + "- " + command + "\n" listzero = listzero + "- " + command + "\n"
for command in l["1"]:
for command in cc["1"]:
if debug == "1": if debug == "1":
command += " - {}".format(l["1"][command])
command += " - {}".format(cc["1"][command])
listone = listone + "- " + command + "\n" listone = listone + "- " + command + "\n"
if not listone: if not listone:
listone = "There are no commands setup.\n" listone = "There are no commands setup.\n"


# TODO: Sort out a way to shorten this if it goes over 2000 characters. # TODO: Sort out a way to shorten this if it goes over 2000 characters.
em = discord.Embed(title="Here is the list of Custom Commands", color=load_config.embedcolour)
em = discord.Embed(title="Here is the list of Custom Commands", color=roxbot.embedcolour)
em.add_field(name="Commands that require Prefix:", value=listone, inline=False) em.add_field(name="Commands that require Prefix:", value=listone, inline=False)
em.add_field(name="Commands that don't:", value=listzero, inline=False) em.add_field(name="Commands that don't:", value=listzero, inline=False)
return await ctx.send(embed=em) return await ctx.send(embed=em)



def setup(bot_client): def setup(bot_client):
bot_client.add_cog(CustomCommands(bot_client))
bot_client.add_cog(CustomCommands(bot_client))

+ 7
- 9
Roxbot/cogs/fun.py View File

import requests import requests
from discord.ext.commands import bot from discord.ext.commands import bot


from Roxbot import checks
from Roxbot.settings import guild_settings
from Roxbot.logging import log
import Roxbot




class Fun: class Fun:
def __init__(self, bot_client): def __init__(self, bot_client):
self.bot = bot_client self.bot = bot_client


@bot.command() # Terra made this and it just work's but im too scared to clean it up so i hope it doesn't break
async def roll(self, ctx, expression = ""):
@bot.command() # Terra made this and it just work's but im too scared to clean it up so i hope it doesn't break
async def roll(self, ctx, expression=""):
""" """
Rolls a die using dice expression format. Rolls a die using dice expression format.
Usage: Usage:
if i < (times-1): response += '\n' if i < (times-1): response += '\n'
return await ctx.send(response) return await ctx.send(response)


@checks.isnt_anal()
@Roxbot.checks.isnt_anal()
@bot.command() @bot.command()
async def spank(self, ctx, *, user: discord.User = None): async def spank(self, ctx, *, user: discord.User = None):
""" """
return await ctx.send("You didn't mention someone for me to spank") return await ctx.send("You didn't mention someone for me to spank")
return await ctx.send(":peach: :wave: *{} spanks {}*".format(self.bot.user.name, user.name)) return await ctx.send(":peach: :wave: *{} spanks {}*".format(self.bot.user.name, user.name))


@checks.isnt_anal()
@Roxbot.checks.isnt_anal()
@bot.command(aliases=["succ"]) @bot.command(aliases=["succ"])
async def suck(self, ctx, *, user: discord.User = None): async def suck(self, ctx, *, user: discord.User = None):
""" """
converted = str(convert).translate(WIDE_MAP) converted = str(convert).translate(WIDE_MAP)
await ctx.send(converted) await ctx.send(converted)


logging = guild_settings.get(ctx.guild).logging
logging = Roxbot.guild_settings.get(ctx.guild).logging
log_channel = self.bot.get_channel(logging["channel"]) log_channel = self.bot.get_channel(logging["channel"])
await log(ctx.guild, log_channel, "aesthetics", User=ctx.author, Argument_Given=convert, Channel=ctx.channel, Channel_Mention=ctx.channel.mention)
await Roxbot.log(ctx.guild, log_channel, "aesthetics", User=ctx.author, Argument_Given=convert, Channel=ctx.channel, Channel_Mention=ctx.channel.mention)


@bot.command(aliases=["ft", "frog"]) @bot.command(aliases=["ft", "frog"])
async def frogtips(self, ctx): async def frogtips(self, ctx):

+ 2
- 2
Roxbot/cogs/joinleave.py View File

import discord import discord
from Roxbot.settings import guild_settings
from Roxbot import guild_settings




class JoinLeave(): class JoinLeave():




def setup(Bot): def setup(Bot):
Bot.add_cog(JoinLeave(Bot))
Bot.add_cog(JoinLeave(Bot))

+ 5
- 5
Roxbot/cogs/nsfw.py View File

import random import random
from Roxbot import checks
import requests import requests
from discord.ext.commands import bot from discord.ext.commands import bot
from Roxbot.settings import guild_settings as gs

from Roxbot import checks
from Roxbot import guild_settings as gs


class NFSW(): class NFSW():
def __init__(self, bot_client): def __init__(self, bot_client):
return blacklist return blacklist


def gelbooru_clone(self, ctx, base_url, tags): def gelbooru_clone(self, ctx, base_url, tags):
# Maybe a page randomiser
limit = 200 limit = 200
tags = tags + self.tag_blacklist(ctx) tags = tags + self.tag_blacklist(ctx)
url = base_url + '/index.php?page=dapi&s=post&q=index&json=1&tags=' + tags + '&limit=' + str(limit) url = base_url + '/index.php?page=dapi&s=post&q=index&json=1&tags=' + tags + '&limit=' + str(limit)
req = requests.get(url, headers={'User-agent': 'RoxBot Discord Bot'}) req = requests.get(url, headers={'User-agent': 'RoxBot Discord Bot'})
if str(req.content) == "b''": # This is to catch any errors if the tags don't return anything because I can't do my own error handling in commands.
if str(req.content) == "b''": # This is to catch any errors if the tags don't return anything because I can't do my own error handling in commands.
post = None post = None
return post return post
post = random.choice(req.json()) post = random.choice(req.json())
limit = 150 limit = 150
url = base_url + 'post/index.json?tags=' + tags + '&limit=' + str(limit) url = base_url + 'post/index.json?tags=' + tags + '&limit=' + str(limit)
req = requests.get(url, headers = {'User-agent': 'RoxBot Discord Bot'}) req = requests.get(url, headers = {'User-agent': 'RoxBot Discord Bot'})
if str(req.content) == "b'[]'": # This is to catch any errors if the tags don't return anything because I can't do my own error handling in commands.
if str(req.content) == "b'[]'": # This is to catch any errors if the tags don't return anything because I can't do my own error handling in commands.
return await ctx.send("Nothing was found. *psst, check the tags you gave me.*") return await ctx.send("Nothing was found. *psst, check the tags you gave me.*")
post = random.choice(req.json()) post = random.choice(req.json())
return await ctx.send(post["file_url"]) return await ctx.send(post["file_url"])

+ 6
- 14
Roxbot/cogs/reddit.py View File

from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from discord.ext.commands import bot from discord.ext.commands import bot


from Roxbot import checks
from Roxbot.logging import log
from Roxbot.settings import guild_settings

# Warning, this cog sucks so much but hopefully it works and doesn't break the bot too much.
# Just lazily edited old code and bodged it into this one.
# There is redundant code here that if removed would make it easier.

# Edit, cleaned up a lot more. But it still is a bit dodgy, when discord allows for the video object to be used in embeds, then we need to convert the cog to output embeds.
import Roxbot as roxbot
from Roxbot import guild_settings




def _imgur_removed(url): def _imgur_removed(url):
else: else:
return False return False



class Reddit(): class Reddit():
def __init__(self, bot_client): def __init__(self, bot_client):
self.bot = bot_client self.bot = bot_client
self.post_cache = {} self.post_cache = {}
for guild in self.bot.guilds: for guild in self.bot.guilds:
self.post_cache[guild.id] = [("","")]
self.post_cache[guild.id] = [("", "")]


@bot.command() @bot.command()
async def subreddit(self, ctx, subreddit): async def subreddit(self, ctx, subreddit):
title = "**{}** \nby /u/{} from /r/{}\n".format(unescape(choice["title"]), unescape(choice["author"]),subreddit) title = "**{}** \nby /u/{} from /r/{}\n".format(unescape(choice["title"]), unescape(choice["author"]),subreddit)
break break




# Check if post is NSFW, and if it is and this channel doesn't past the NSFW check, then return with the error message. # Check if post is NSFW, and if it is and this channel doesn't past the NSFW check, then return with the error message.
if choice["over_18"] and not checks.nsfw_predicate(ctx):
if choice["over_18"] and not roxbot.checks.nsfw_predicate(ctx):
return await ctx.send("This server/channel doesn't have my NSFW stuff enabled. This extends to posting NFSW content from Reddit.") return await ctx.send("This server/channel doesn't have my NSFW stuff enabled. This extends to posting NFSW content from Reddit.")
if not url: # If no image posts could be found with the for loop. if not url: # If no image posts could be found with the for loop.
return await ctx.send("I couldn't find any images from that subreddit.") return await ctx.send("I couldn't find any images from that subreddit.")
# Only log the command when it is this command being used. Not the inbuilt commands. # Only log the command when it is this command being used. Not the inbuilt commands.
logging = guild_settings.get(ctx.guild).logging logging = guild_settings.get(ctx.guild).logging
log_channel = self.bot.get_channel(logging["channel"]) log_channel = self.bot.get_channel(logging["channel"])
await log(ctx.guild, log_channel, "subreddit", User=ctx.author, Subreddit=subreddit, Returned="<{}>".format(url), Channel=ctx.channel, Channel_Mention=ctx.channel.mention)
await roxbot.log(ctx.guild, log_channel, "subreddit", User=ctx.author, Subreddit=subreddit, Returned="<{}>".format(url), Channel=ctx.channel, Channel_Mention=ctx.channel.mention)


# Not using a embed here because we can't use video in rich embeds but they work in embeds now :/ # Not using a embed here because we can't use video in rich embeds but they work in embeds now :/
return await ctx.send(title + text + url) return await ctx.send(title + text + url)

+ 7
- 11
Roxbot/cogs/selfassign.py View File

import discord import discord
from discord.ext import commands from discord.ext import commands


from Roxbot import load_config
from Roxbot.settings import guild_settings as gs
import Roxbot
from Roxbot import guild_settings as gs




class SelfAssign(): class SelfAssign():
def __init__(self, Bot): def __init__(self, Bot):
self.bot = Bot self.bot = Bot
self.embed_colour = load_config.embedcolour
self.embed_colour = Roxbot.embedcolour


@commands.command(pass_context=True) @commands.command(pass_context=True)
async def listroles(self, ctx): async def listroles(self, ctx):
""" """
settings = gs.get(ctx.guild) settings = gs.get(ctx.guild)
if not settings.self_assign["enabled"]: if not settings.self_assign["enabled"]:
embed = discord.Embed(colour=discord.Colour(self.embed_colour),
description="SelfAssignable roles are not enabled on this server")
embed = discord.Embed(colour=discord.Colour(self.embed_colour), description="SelfAssignable roles are not enabled on this server")
return await ctx.send(embed=embed) return await ctx.send(embed=embed)
roles = [] roles = []
for role in settings.self_assign["roles"]: for role in settings.self_assign["roles"]:
if role == serverrole.id: if role == serverrole.id:
roles.append("**"+serverrole.name+"**") roles.append("**"+serverrole.name+"**")
roles = '\n'.join(roles) roles = '\n'.join(roles)
embed = discord.Embed(colour=self.embed_colour,
description="The self-assignable roles for this server are: \n"+roles)
embed = discord.Embed(colour=self.embed_colour, description="The self-assignable roles for this server are: \n"+roles)
return await ctx.send(embed=embed) return await ctx.send(embed=embed)


@commands.command(pass_context=True) @commands.command(pass_context=True)
raise commands.MissingRequiredArgument(Parameter("Role", False)) raise commands.MissingRequiredArgument(Parameter("Role", False))


if not settings.self_assign["enabled"]: if not settings.self_assign["enabled"]:
embed = discord.Embed(colour=discord.Colour(self.embed_colour),
description="SelfAssignable roles are not enabled on this server")
embed = discord.Embed(colour=discord.Colour(self.embed_colour), description="SelfAssignable roles are not enabled on this server")
return await ctx.send(embed=embed) return await ctx.send(embed=embed)


member = ctx.author member = ctx.author
raise commands.MissingRequiredArgument(Parameter("role", False)) raise commands.MissingRequiredArgument(Parameter("role", False))


if not settings.self_assign["enabled"]: if not settings.self_assign["enabled"]:
embed = discord.Embed(colour=discord.Colour(self.embed_colour),
description="SelfAssignable roles are not enabled on this server")
embed = discord.Embed(colour=discord.Colour(self.embed_colour), description="SelfAssignable roles are not enabled on this server")
return await ctx.send(embed=embed) return await ctx.send(embed=embed)


member = ctx.author member = ctx.author

+ 2
- 1
Roxbot/cogs/trivia.py View File

# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-


from Roxbot import checks
import discord import discord
import asyncio import asyncio
import requests import requests
from collections import OrderedDict from collections import OrderedDict
from discord.ext import commands from discord.ext import commands


from Roxbot import checks



class Trivia: class Trivia:
""" """

+ 11
- 15
Roxbot/cogs/twitch.py View File

from discord import ActivityType from discord import ActivityType
from discord.ext import commands from discord.ext import commands


from Roxbot import checks
from Roxbot.settings import guild_settings
import Roxbot


def blacklisted(user):
with open("Roxbot/blacklist.txt", "r") as fp:
for line in fp.readlines():
if str(user.id)+"\n" == line:
return True
return False


class Twitch(): class Twitch():
""" """


async def on_member_update(self, member_b, member_a): async def on_member_update(self, member_b, member_a):
"""Twitch Shilling Part""" """Twitch Shilling Part"""
twitch = guild_settings.get(member_b.guild).twitch
if blacklisted(member_b) or not twitch["enabled"]:
twitch = Roxbot.guild_settings.get(member_b.guild).twitch
if Roxbot.blacklisted(member_b) or not twitch["enabled"]:
return return


if member_a.activitiy: if member_a.activitiy:
if not twitch["whitelist"]["enabled"] or member_a.id in twitch["whitelist"]["list"]: if not twitch["whitelist"]["enabled"] or member_a.id in twitch["whitelist"]["list"]:
channel = self.bot.get_channel(twitch["channel"]) channel = self.bot.get_channel(twitch["channel"])
return await channel.send(":video_game:** {} is live!** :video_game:\n{}\n{}".format( return await channel.send(":video_game:** {} is live!** :video_game:\n{}\n{}".format(
member_a.name, member_a.game.name, member_a.game.url))
member_a.name, member_a.game.name, member_a.game.url))


@commands.group() @commands.group()
@checks.is_admin_or_mod()
@Roxbot.checks.is_admin_or_mod()
async def whitelist(self, ctx): async def whitelist(self, ctx):
"""Command group that handles the twitch cog's whitelist.""" """Command group that handles the twitch cog's whitelist."""
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
"""Enables the twitch shilling whitelist. Repeat the command to disable. """Enables the twitch shilling whitelist. Repeat the command to disable.
Usage: Usage:
;whitelist enable""" ;whitelist enable"""
settings = guild_settings.get(ctx.guild)
settings = Roxbot.guild_settings.get(ctx.guild)
if not settings.twitch["whitelist"]["enabled"]: if not settings.twitch["whitelist"]["enabled"]:
settings.twitch["whitelist"]["enabled"] = 1 settings.twitch["whitelist"]["enabled"] = 1
settings.update(settings.twitch, "twitch") settings.update(settings.twitch, "twitch")
return await ctx.send("Whitelist for Twitch shilling has been disabled.") return await ctx.send("Whitelist for Twitch shilling has been disabled.")


@whitelist.command() @whitelist.command()
async def edit(self, ctx, option, mentions = None):
async def edit(self, ctx, option, mentions=None):
"""Adds or removes users to the whitelist. Exactly the same as the blacklist command in usage.""" """Adds or removes users to the whitelist. Exactly the same as the blacklist command in usage."""

# TODO: This is all horribly outdated useage and needs to be rewritten.

whitelist_count = 0 whitelist_count = 0
settings = guild_settings.get(ctx.guild)
settings = Roxbot.guild_settings.get(ctx.guild)


if not ctx.message.mentions and option != 'list': if not ctx.message.mentions and option != 'list':
return await ctx.send("You haven't mentioned anyone to whitelist.") return await ctx.send("You haven't mentioned anyone to whitelist.")

+ 9
- 10
Roxbot/cogs/voice.py View File

from math import ceil from math import ceil
from discord.ext import commands from discord.ext import commands


from Roxbot import checks
from Roxbot.load_config import owner
from Roxbot.settings import guild_settings
import Roxbot
from Roxbot import guild_settings




def _clear_cache(): def _clear_cache():
def predicate(ctx): def predicate(ctx):
gs = guild_settings.get(ctx.guild) gs = guild_settings.get(ctx.guild)
if gs.voice["need_perms"]: # Had to copy the admin or mod code cause it wouldn't work ;-; if gs.voice["need_perms"]: # Had to copy the admin or mod code cause it wouldn't work ;-;
if ctx.message.author.id == owner:
if ctx.message.author.id == Roxbot.owner:
return True return True
else: else:
admin_roles = gs.perm_roles["admin"] admin_roles = gs.perm_roles["admin"]
self.now_playing[guild.id] = None self.now_playing[guild.id] = None
self.queue_logic[guild.id] = None self.queue_logic[guild.id] = None


@checks.is_admin_or_mod()
@Roxbot.checks.is_admin_or_mod()
@commands.command() @commands.command()
async def join(self, ctx, *, channel: discord.VoiceChannel = None): async def join(self, ctx, *, channel: discord.VoiceChannel = None):
"""Joins the voice channel your in.""" """Joins the voice channel your in."""
guild = ctx.guild guild = ctx.guild


# Checks if invoker is in voice with the bot. Skips admins and mods and owner. # Checks if invoker is in voice with the bot. Skips admins and mods and owner.
if not checks._is_admin_or_mod(ctx) or from_queue:
if not Roxbot.checks._is_admin_or_mod(ctx) or from_queue:
if not ctx.author.voice: if not ctx.author.voice:
raise commands.CommandError("You're not in the same voice channel as Roxbot.") raise commands.CommandError("You're not in the same voice channel as Roxbot.")
if ctx.author.voice.channel != ctx.voice_client.channel: if ctx.author.voice.channel != ctx.voice_client.channel:
video = video["entries"][0] video = video["entries"][0]


# Duration limiter handling # Duration limiter handling
if video.get("duration", 1) > voice["max_length"] and not checks._is_admin_or_mod(ctx):
if video.get("duration", 1) > voice["max_length"] and not Roxbot.checks._is_admin_or_mod(ctx):
raise commands.CommandError("Cannot play video, duration is bigger than the max duration allowed.") raise commands.CommandError("Cannot play video, duration is bigger than the max duration allowed.")


# Actual playing stuff section. # Actual playing stuff section.
"""Skips or votes to skip the current video. Use option "--force" if your an admin and """ """Skips or votes to skip the current video. Use option "--force" if your an admin and """
voice = guild_settings.get(ctx.guild).voice voice = guild_settings.get(ctx.guild).voice
if ctx.voice_client.is_playing(): if ctx.voice_client.is_playing():
if voice["skip_voting"] and not (option == "--force" and checks._is_admin_or_mod(ctx)): # Admin force skipping
if voice["skip_voting"] and not (option == "--force" and Roxbot.checks._is_admin_or_mod(ctx)): # Admin force skipping
if ctx.author in self.skip_votes[ctx.guild.id]: if ctx.author in self.skip_votes[ctx.guild.id]:
return await ctx.send("You have already voted to skip the current track.") return await ctx.send("You have already voted to skip the current track.")
else: else:
embed = discord.Embed(title="Queue", description=output, colour=0xDEADBF) embed = discord.Embed(title="Queue", description=output, colour=0xDEADBF)
return await ctx.send(embed=embed) return await ctx.send(embed=embed)


@checks.is_admin_or_mod()
@Roxbot.checks.is_admin_or_mod()
@commands.command() @commands.command()
async def remove(self, ctx, index): async def remove(self, ctx, index):
"""Removes a item from the queue with the given index. Can also input all to delete all queued items.""" """Removes a item from the queue with the given index. Can also input all to delete all queued items."""
except IndexError: except IndexError:
raise commands.CommandError("Valid Index not given.") raise commands.CommandError("Valid Index not given.")


@checks.is_admin_or_mod()
@Roxbot.checks.is_admin_or_mod()
@commands.command(alaises=["disconnect"]) @commands.command(alaises=["disconnect"])
async def stop(self, ctx): async def stop(self, ctx):
"""Stops and disconnects the bot from voice.""" """Stops and disconnects the bot from voice."""

+ 0
- 10
Roxbot/load_config.py View File

token = settings["Roxbot"]["Token"] token = settings["Roxbot"]["Token"]
owner = int(settings["Roxbot"]["OwnerID"]) owner = int(settings["Roxbot"]["OwnerID"])
tat_token = settings["Roxbot"]["Tatsumaki_Token"] tat_token = settings["Roxbot"]["Tatsumaki_Token"]


__description__ = """RoxBot, A Discord Bot made by a filthy Mercy Main. Built with love (and discord.py) by Roxxers#7443.

[Github link](https://github.com/RainbowDinoaur/roxbot)
[Changelog](https://github.com/RainbowDinoaur/roxbot#v100)
[Found a bug or need to report an issue? Report it here](https://github.com/RainbowRoxxers/roxbot/issues/new)
[Say Thanks](https://saythanks.io/to/Roxxers)"""
__author__ = "Roxanne Gibson"
__version__ = "1.6.1"
embedcolour = 0xDEADBF embedcolour = 0xDEADBF


# IF YOU ARE TESTING OR NOT IN THE GSS DISCORD, REMOVE "cogs.gss" FROM THE LIST # IF YOU ARE TESTING OR NOT IN THE GSS DISCORD, REMOVE "cogs.gss" FROM THE LIST

+ 7
- 8
Roxbot/logging.py View File

import discord import discord
from Roxbot.settings import guild_settings
from Roxbot.load_config import embedcolour
import Roxbot




async def log(guild, channel, command_name, **kwargs): async def log(guild, channel, command_name, **kwargs):
logging = guild_settings.get(guild).logging
logging = Roxbot.guild_settings.get(guild).logging
if logging["enabled"]: if logging["enabled"]:
embed = discord.Embed(title="{} command logging".format(command_name), colour=embedcolour)
embed = discord.Embed(title="{} command logging".format(command_name), colour=Roxbot.embedcolour)
for key, value in kwargs.items(): for key, value in kwargs.items():
embed.add_field(name=key, value=value) embed.add_field(name=key, value=value)
return await channel.send(embed=embed) return await channel.send(embed=embed)
self.bot = bot_client self.bot = bot_client


async def on_member_join(self, member): async def on_member_join(self, member):
logging = guild_settings.get(member.guild).logging
logging = Roxbot.guild_settings.get(member.guild).logging
if logging["enabled"]: if logging["enabled"]:
channel = self.bot.get_channel(logging["channel"]) channel = self.bot.get_channel(logging["channel"])
embed = discord.Embed(title="{} joined the server".format(member), colour=embedcolour)
embed = discord.Embed(title="{} joined the server".format(member), colour=Roxbot.embedcolour)
embed.add_field(name="ID", value=member.id) embed.add_field(name="ID", value=member.id)
embed.add_field(name="Mention", value=member.mention) embed.add_field(name="Mention", value=member.mention)
embed.add_field(name="Date Account Created", value="{:%a %Y/%m/%d %H:%M:%S} UTC".format(member.created_at)) embed.add_field(name="Date Account Created", value="{:%a %Y/%m/%d %H:%M:%S} UTC".format(member.created_at))


async def on_member_remove(self, member): async def on_member_remove(self, member):
# TODO: Add some way of detecting whether a user left/was kicked or was banned. # TODO: Add some way of detecting whether a user left/was kicked or was banned.
logging = guild_settings.get(member.guild).logging
logging = Roxbot.guild_settings.get(member.guild).logging
if logging["enabled"]: if logging["enabled"]:
channel = self.bot.get_channel(logging["channel"]) channel = self.bot.get_channel(logging["channel"])
embed = discord.Embed(description="{} left the server".format(member), colour=embedcolour)
embed = discord.Embed(description="{} left the server".format(member), colour=Roxbot.embedcolour)
return await channel.send(embed=embed) return await channel.send(embed=embed)





Roxbot/blacklist.txt → Roxbot/settings/blacklist.txt View File


Roxbot/preferences_example.ini → Roxbot/settings/preferences_example.ini View File


+ 20
- 22
main.py View File

import datetime import datetime
import discord import discord
from discord.ext import commands from discord.ext import commands
from Roxbot import load_config
from Roxbot.settings import guild_settings as gs


import Roxbot
from Roxbot import guild_settings as gs


# Sets up Logging that discord.py does on its own # Sets up Logging that discord.py does on its own
logger = logging.getLogger('discord') logger = logging.getLogger('discord')
logger.addHandler(handler) logger.addHandler(handler)


bot = commands.Bot( bot = commands.Bot(
command_prefix=load_config.command_prefix,
description=load_config.__description__,
owner_id=load_config.owner,
activity=discord.Game(name="v{}".format(load_config.__version__), type=0),
command_prefix=Roxbot.command_prefix,
description=Roxbot.__description__,
owner_id=Roxbot.owner,
activity=discord.Game(name="v{}".format(Roxbot.__version__), type=0),
case_insensitive=True case_insensitive=True
) )


def blacklisted(user):
with open("Roxbot/blacklist.txt", "r") as fp:
for line in fp.readlines():
if str(user.id)+"\n" == line:
return True
return False


@bot.event @bot.event
async def on_ready(): async def on_ready():


# Load Extension Cogs # Load Extension Cogs
print("Cogs Loaded:") print("Cogs Loaded:")
for cog in load_config.cogs:
for cog in Roxbot.cogs:
bot.load_extension(cog) bot.load_extension(cog)
print(cog.split(".")[2]) print(cog.split(".")[2])
print("") print("")
# In the next two functions, I was gunna user bot.settings for something but I don't think it's possible. # In the next two functions, I was gunna user bot.settings for something but I don't think it's possible.
# So while I don't use it, the function still will do their jobs of adding and removing the settings. # So while I don't use it, the function still will do their jobs of adding and removing the settings.



@bot.event @bot.event
async def on_guild_join(guild): async def on_guild_join(guild):
gs.add_guild(guild) gs.add_guild(guild)



@bot.event @bot.event
async def on_guild_remove(guild): async def on_guild_remove(guild):
gs.remove_guild(guild) gs.remove_guild(guild)



@bot.event @bot.event
async def on_message(message): async def on_message(message):
""" """
:param message: :param message:
:return: :return:
""" """
if blacklisted(message.author):
if Roxbot.blacklisted(message.author):
return return
return await bot.process_commands(message) return await bot.process_commands(message)



@bot.command() @bot.command()
async def about(ctx): async def about(ctx):
""" """
Outputs info about RoxBot, showing uptime, how to report issues, what settings where set in prefs.ini and credits. Outputs info about RoxBot, showing uptime, how to report issues, what settings where set in prefs.ini and credits.
""" """
owner = bot.get_user(load_config.owner)
em = discord.Embed(title="About Roxbot", colour=load_config.embedcolour, description=load_config.__description__)
owner = bot.get_user(Roxbot.owner)
em = discord.Embed(title="About Roxbot", colour=Roxbot.embedcolour, description=Roxbot.__description__)
em.set_thumbnail(url=bot.user.avatar_url) em.set_thumbnail(url=bot.user.avatar_url)
em.add_field(name="Command Prefix", value=load_config.command_prefix)
em.add_field(name="Command Prefix", value=Roxbot.command_prefix)
em.add_field(name="Owner", value=str(owner)) em.add_field(name="Owner", value=str(owner))
em.add_field(name="Owner ID", value=load_config.owner)
em.add_field(name="Bot Version", value=load_config.__version__)
em.add_field(name="Author", value=load_config.__author__)
em.add_field(name="Owner ID", value=Roxbot.owner)
em.add_field(name="Bot Version", value=Roxbot.__version__)
em.add_field(name="Author", value=Roxbot.__author__)
em.add_field(name="Discord.py version", value=discord.__version__) em.add_field(name="Discord.py version", value=discord.__version__)
em.set_footer(text="RoxBot is licensed under the MIT License") em.set_footer(text="RoxBot is licensed under the MIT License")




if __name__ == "__main__": if __name__ == "__main__":
# Pre-Boot checks # Pre-Boot checks
if not os.path.isfile("Roxbot/preferences.ini"):
if not os.path.isfile("Roxbot/settings/preferences.ini"):
print( print(
"PREFERENCE FILE MISSING. Something has gone wrong. Please make sure there is a file called 'preferences.ini' in the settings folder") "PREFERENCE FILE MISSING. Something has gone wrong. Please make sure there is a file called 'preferences.ini' in the settings folder")
exit(0) exit(0)
fp.write("{}") fp.write("{}")


start_time = time.time() start_time = time.time()
bot.run(load_config.token)
bot.run(Roxbot.token)

Loading…
Cancel
Save