@@ -9,10 +9,11 @@ | |||
### Regular Updates | |||
#### New Features | |||
- Roxbot will remove all redundant settings (removed roles from self assign, etc.). | |||
- Cogs have a message if they fail to load. This is better than the entire program breaking. | |||
- Roxbot Facts! | |||
#### Minor Changes | |||
- Roxbot will remove all redundant settings (removed roles from self assign, etc.). | |||
- Cogs have a message if they fail to load instead of breaking entire bot. | |||
- NSFW commands should have even less chance of dupes. | |||
- All time formatting is now standardised. | |||
- Error messages dont time out anymore. | |||
@@ -27,6 +28,7 @@ | |||
- Roxbot can now fully function in DMs. Before, she would break. DM's have less commands. | |||
- `;subreddit`'s "subscriptable" error has been fixed. | |||
- is_anal value can be changed again and check now works. | |||
- Common commands that would go over 2000 characters have been paginated to avoid this error. | |||
## v1.8.0 | |||
#### New Features |
@@ -144,6 +144,10 @@ class Admin: | |||
if user_id not in settings.warnings: | |||
settings.warnings[user_id] = [] | |||
warn_limit = 10 | |||
if len(settings.warnings[user_id]) > warn_limit: | |||
raise commands.CommandError("You can only warn a user {} times!".format(warn_limit)) | |||
settings.warnings[user_id].append(warning_dict) | |||
settings.update(settings.warnings, "warnings") | |||
@@ -160,7 +164,7 @@ class Admin: | |||
settings = gs.get(ctx.guild) | |||
if user is None: | |||
output = "" | |||
paginator = commands.Paginator() | |||
for member in settings.warnings: | |||
# Remove users with no warning here instead of remove cause im lazy | |||
if not settings.warnings[member]: | |||
@@ -168,38 +172,38 @@ class Admin: | |||
else: | |||
member_obj = discord.utils.get(ctx.guild.members, id=int(member)) | |||
if member_obj: | |||
output += "{}: {} Warning(s)\n".format(str(member_obj), len( | |||
settings.warnings[member])) | |||
paginator.add_line("{}: {} Warning(s)".format(str(member_obj), len(settings.warnings[member]))) | |||
else: | |||
output += "{}: {} Warning(s)\n".format(member, len( | |||
settings.warnings[member])) | |||
if not output: | |||
paginator.add_line("{}: {} Warning(s)".format(member, len(settings.warnings[member]))) | |||
if len(paginator.pages) <= 0: | |||
return await ctx.send("No warnings on record.") | |||
return await ctx.send(output) | |||
for page in paginator.pages: | |||
await ctx.send(page) | |||
else: | |||
user_id = str(user.id) | |||
user_id = str(user.id) | |||
if not settings.warnings.get(user_id): | |||
return await ctx.send("This user doesn't have any warning on record.") | |||
if not settings.warnings.get(user_id): | |||
return await ctx.send("This user doesn't have any warning on record.") | |||
if not settings.warnings[user_id]: | |||
settings.warnings.pop(user_id) | |||
settings.update(settings.warnings, "warnings") | |||
em = discord.Embed(title="Warnings for {}".format(str(user)), colour=roxbot.EmbedColours.pink) | |||
em.set_thumbnail(url=user.avatar_url) | |||
x = 1 | |||
userlist = settings.warnings[user_id] | |||
for warning in userlist: | |||
try: | |||
warned_by = str(await self.bot.get_user_info(warning["warned-by"])) | |||
except discord.ext.commands.CommandInvokeError: | |||
warned_by = warning["warned-by"] | |||
date = roxbot.datetime_formatting.format(datetime.datetime.fromtimestamp(warning["date"])) | |||
warn_reason = warning["warning"] | |||
em.add_field(name="Warning %s" % x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warn_reason)) | |||
x += 1 | |||
return await ctx.send(embed=em) | |||
if not settings.warnings[user_id]: | |||
settings.warnings.pop(user_id) | |||
settings.update(settings.warnings, "warnings") | |||
em = discord.Embed(title="Warnings for {}".format(str(user)), colour=roxbot.EmbedColours.pink) | |||
em.set_thumbnail(url=user.avatar_url) | |||
x = 1 | |||
userlist = settings.warnings[user_id] | |||
for warning in userlist: | |||
try: | |||
warned_by = str(await self.bot.get_user_info(warning["warned-by"])) | |||
except discord.ext.commands.CommandInvokeError: | |||
warned_by = warning["warned-by"] | |||
date = roxbot.datetime_formatting.format(datetime.datetime.fromtimestamp(warning["date"])) | |||
warn_reason = warning["warning"] | |||
em.add_field(name="Warning %s" % x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warn_reason)) | |||
x += 1 | |||
return await ctx.send(embed=em) | |||
@warn.command() | |||
async def remove(self, ctx, user: roxbot.converters.User=None, index=None): |
@@ -243,31 +243,35 @@ class CustomCommands: | |||
debug = "0" | |||
settings = roxbot.guild_settings.get(ctx.guild) | |||
cc = settings.custom_commands | |||
list_no_prefix = "" | |||
list_prefix = "" | |||
no_prefix_commands = cc["0"] | |||
prefix_commands = {**cc["1"], **cc["2"]} | |||
for command in no_prefix_commands: | |||
if debug == "1": | |||
command += " - {}".format(cc["0"][command]) | |||
list_no_prefix = list_no_prefix + "- " + command + "\n" | |||
for command in prefix_commands: | |||
if debug == "1": | |||
command += " - {}".format(cc["1"][command]) | |||
list_prefix = list_prefix + "- " + command + "\n" | |||
if not list_prefix: | |||
list_prefix = "There are no commands setup.\n" | |||
if not list_no_prefix: | |||
list_no_prefix = "There are no commands setup.\n" | |||
# TODO: Sort out a way to shorten this if it goes over 2000 characters. Also clean up command to make sense | |||
em = discord.Embed(title="Here is the list of Custom Commands", color=roxbot.EmbedColours.pink) | |||
em.add_field(name="Commands that require Prefix:", value=list_prefix, inline=False) | |||
em.add_field(name="Commands that don't:", value=list_no_prefix, inline=False) | |||
return await ctx.send(embed=em) | |||
paginator = commands.Paginator() | |||
paginator.add_line("Here is the list of Custom Commands...") | |||
paginator.add_line() | |||
paginator.add_line("Commands that require Prefix:") | |||
if not prefix_commands: | |||
paginator.add_line("There are no commands setup.") | |||
else: | |||
for command in prefix_commands: | |||
if debug == "1": | |||
command += " = '{}'".format(prefix_commands[command]) | |||
paginator.add_line("- " + command) | |||
paginator.add_line() | |||
paginator.add_line("Commands that don't require prefix:") | |||
if not no_prefix_commands: | |||
paginator.add_line("There are no commands setup.") | |||
else: | |||
for command in no_prefix_commands: | |||
if debug == "1": | |||
command += " = '{}'".format(no_prefix_commands[command]) | |||
paginator.add_line("- " + command) | |||
output = paginator.pages | |||
for page in output: | |||
await ctx.send(page) | |||
def setup(bot_client): |
@@ -53,17 +53,20 @@ class SelfAssign(): | |||
{command_prefix}listroles | |||
""" | |||
settings = gs.get(ctx.guild) | |||
paginator = commands.Paginator(prefix="`", suffix="`") | |||
if not settings.self_assign["enabled"]: | |||
embed = discord.Embed(colour=roxbot.EmbedColours.pink, description="SelfAssignable roles are not enabled on this server") | |||
return await ctx.send(embed=embed) | |||
roles = [] | |||
paginator.add_line("The self-assignable roles for this server are: \n") | |||
for role in settings.self_assign["roles"]: | |||
for serverrole in ctx.guild.roles: | |||
if role == serverrole.id: | |||
roles.append("**"+serverrole.name+"**") | |||
roles = '\n'.join(roles) | |||
embed = discord.Embed(colour=roxbot.EmbedColours.pink, description="The self-assignable roles for this server are: \n"+roles) | |||
return await ctx.send(embed=embed) | |||
paginator.add_line("- {}".format(serverrole.name)) | |||
for page in paginator.pages: | |||
await ctx.send(page) | |||
@commands.guild_only() | |||
@commands.command(pass_context=True) |
@@ -413,15 +413,25 @@ class Voice: | |||
@commands.command() | |||
async def queue(self, ctx): | |||
"""Displays what videos are queued up and waiting to be played.""" | |||
output = "" | |||
paginator = commands.Paginator(prefix="", suffix="") | |||
index = 1 | |||
for video in self.playlist[ctx.guild.id]: | |||
output += "{}) '{}' queued by {}\n".format(index, video["title"], video["queued_by"]) | |||
index += 1 | |||
if output == "": | |||
output = "Nothing is up next. Maybe you should add something!" | |||
embed = discord.Embed(title="Queue", description=output, colour=roxbot.EmbedColours.pink) | |||
return await ctx.send(embed=embed) | |||
if len(self.playlist[ctx.guild.id]) == 0: | |||
return await ctx.send("Nothing is up next. Maybe you should add something!") | |||
else: | |||
for video in self.playlist[ctx.guild.id]: | |||
paginator.add_line("{}) '{}' queued by {}\n".format(index, video["title"], video["queued_by"])) | |||
index += 1 | |||
if len(paginator.pages) <= 1: | |||
embed = discord.Embed(title="Queue", description=paginator.pages[0], colour=roxbot.EmbedColours.pink) | |||
return await ctx.send(embed=embed) | |||
else: | |||
pages = [] | |||
pages.append(discord.Embed(title="Queue", description=paginator.pages.pop(0), colour=roxbot.EmbedColours.pink)) | |||
for page in paginator.pages: | |||
pages.append(discord.Embed(description=page, colour=roxbot.EmbedColours.pink)) | |||
for page in pages: | |||
await ctx.send(embed=page) | |||
@commands.guild_only() | |||
@roxbot.checks.is_admin_or_mod() |
@@ -57,13 +57,16 @@ class Settings: | |||
setting[x] = "True" | |||
elif convert[x] == "channel": | |||
if isinstance(setting[x], list): | |||
new_channels = [] | |||
for channel in setting[x]: | |||
try: | |||
new_channels.append(self.bot.get_channel(channel).mention) | |||
except AttributeError: | |||
new_channels.append(channel) | |||
setting[x] = new_channels | |||
if len(setting[x]) >= 60: | |||
setting[x] = "There is too many channels to display." | |||
else: | |||
new_channels = [] | |||
for channel in setting[x]: | |||
try: | |||
new_channels.append(self.bot.get_channel(channel).mention) | |||
except AttributeError: | |||
new_channels.append(channel) | |||
setting[x] = new_channels | |||
else: | |||
try: | |||
setting[x] = self.bot.get_channel(setting[x]).mention | |||
@@ -71,13 +74,16 @@ class Settings: | |||
pass | |||
elif convert[x] == "role": | |||
if isinstance(setting[x], list): | |||
new_roles = [] | |||
for role_id in setting[x]: | |||
try: | |||
new_roles.append(discord.utils.get(ctx.guild.roles, id=role_id).name) | |||
except AttributeError: | |||
new_roles.append(role_id) | |||
setting[x] = new_roles | |||
if len(setting[x]) >= 60: | |||
setting[x] = "There is too many roles to display." | |||
else: | |||
new_roles = [] | |||
for role_id in setting[x]: | |||
try: | |||
new_roles.append(discord.utils.get(ctx.guild.roles, id=role_id).name) | |||
except AttributeError: | |||
new_roles.append(role_id) | |||
setting[x] = new_roles | |||
else: | |||
try: | |||
setting[x] = discord.utils.get(ctx.guild.roles, id=setting[x]).name | |||
@@ -85,21 +91,26 @@ class Settings: | |||
pass | |||
elif convert[x] == "user": | |||
if isinstance(setting[x], list): | |||
new_users = [] | |||
for user_id in setting[x]: | |||
user = self.bot.get_user(user_id) | |||
if user is None: | |||
new_users.append(str(user_id)) | |||
else: | |||
new_users.append(str(user)) | |||
setting[x] = new_users | |||
if len(setting[x]) >= 60: | |||
setting[x] = "There is too many users to display." | |||
else: | |||
new_users = [] | |||
for user_id in setting[x]: | |||
user = self.bot.get_user(user_id) | |||
if user is None: | |||
new_users.append(str(user_id)) | |||
else: | |||
new_users.append(str(user)) | |||
setting[x] = new_users | |||
else: | |||
user = self.bot.get_user(setting[x]) | |||
if user is None: | |||
setting[x] = str(setting[x]) | |||
else: | |||
setting[x] = str(user) | |||
elif convert[x] == "hide": | |||
setting[x] = "This is hidden. Please use other commands to get this data." | |||
for x in setting.items(): | |||
if x[0] != "convert": | |||
settingcontent += str(x).strip("()") + "\n" | |||
@@ -112,22 +123,24 @@ class Settings: | |||
# TODO: Use paginator to make the output here not break all the time. | |||
config = guild_settings.get(ctx.guild) | |||
settings = dict(config.settings.copy()) # Make a copy of settings so we don't change the actual settings. | |||
em = discord.Embed(colour=EmbedColours.pink) | |||
em.set_author(name="{} settings for {}.".format(self.bot.user.name, ctx.message.guild.name), icon_url=self.bot.user.avatar_url) | |||
paginator = commands.Paginator(prefix="```md") | |||
paginator.add_line("{} settings for {}.\n".format(self.bot.user.name, ctx.message.guild.name)) | |||
if option in settings: | |||
raw = bool(ctx.invoked_with == "printsettingsraw") | |||
settingcontent = self.parse_setting(ctx, settings[option], raw=raw) | |||
em.add_field(name=option, value=settingcontent, inline=False) | |||
return await ctx.send(embed=em) | |||
paginator.add_line("**{}**".format(option)) | |||
paginator.add_line(settingcontent) | |||
for page in paginator.pages: | |||
await ctx.send(page) | |||
else: | |||
for setting in settings: | |||
if setting != "custom_commands" and setting != "warnings": | |||
raw = bool(ctx.invoked_with == "printsettingsraw") | |||
settingcontent = self.parse_setting(ctx, settings[setting], raw=raw) | |||
em.add_field(name=setting, value=settingcontent, inline=False) | |||
elif setting == "custom_commands": | |||
em.add_field(name="custom_commands", value="For Custom Commands, use the custom list command.", inline=False) | |||
return await ctx.send(embed=em) | |||
paginator.add_line("**{}**".format(setting)) | |||
paginator.add_line(settingcontent) | |||
for page in paginator.pages: | |||
await ctx.send(page) | |||
@commands.group(case_insensitive=True) | |||
@checks.is_admin_or_mod() |