From d565849a352f700ddf21980da4fbdd877fb20833 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Fri, 26 Feb 2016 23:47:30 -0500 Subject: [PATCH 01/11] started on multi server roles configuration --- .gitignore | 2 + cogs/alias.py | 122 ++++++++++++++++++++++++++++++++++ cogs/mod.py | 53 ++++++++++++++- cogs/utils/chat_formatting.py | 17 +++++ cogs/utils/checks.py | 38 +++++++++-- red.py | 23 ++++--- 6 files changed, 241 insertions(+), 14 deletions(-) create mode 100644 cogs/alias.py create mode 100644 cogs/utils/chat_formatting.py diff --git a/.gitignore b/.gitignore index f4ca4c697..c39171c95 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ __pycache__ data !data/trivia/* !data/audio/playlists/* +*.exe +*.dll \ No newline at end of file diff --git a/cogs/alias.py b/cogs/alias.py new file mode 100644 index 000000000..209e22189 --- /dev/null +++ b/cogs/alias.py @@ -0,0 +1,122 @@ +import discord +from discord.ext import commands +from .utils import checks +from .utils.chat_formatting import * +from .utils.dataIO import fileIO +from .utils import checks +from __main__ import send_cmd_help +import os + +class Alias: + def __init__(self,bot): + self.bot = bot + self.aliases = fileIO("data/alias/aliases.json","load") + + @commands.group(pass_context=True) + @checks.mod_or_permissions(manage_server=True) + async def alias(self,ctx): + """Manage per-server aliases for commands""" + if ctx.invoked_subcommand is None: + await send_cmd_help(ctx) + + @alias.command(name="add",pass_context=True) + async def _add_alias(self,ctx,command : str,*,to_execute): + """Add an alias for a command + + Example: !alias add test penis @TwentySix""" + server = ctx.message.server + if self.get_prefix(to_execute) == False: + to_execute = self.bot.command_prefix[0] + to_execute + if server.id not in self.aliases: + self.aliases[server.id] = {} + #curr_aliases = self.aliases[server.id] + if command not in self.bot.commands: + self.aliases[server.id][command] = to_execute + fileIO("data/alias/aliases.json","save",self.aliases) + await self.bot.say("Alias '{}' added.".format(command)) + else: + await self.bot.say("Cannot add '{}' because it's a real bot command.".format(command)) + + @alias.command(name="help",pass_context=True) + async def _help_alias(self,ctx,command): + """Tries to execute help for the base command of the alias""" + server = ctx.message.server + if server.id in self.aliases: + server_aliases = self.aliases[server.id] + if command in server_aliases: + help_cmd = server_aliases[command].split(" ")[0] + new_content = self.bot.command_prefix[0] + new_content += "help " + new_content += help_cmd[len(self.get_prefix(help_cmd)):] + message = ctx.message + message.content = new_content + await self.bot.process_commands(message) + else: + await self.bot.say("That alias doesn't exist.") + + @alias.command(name="show",pass_context=True) + async def _show_alias(self,ctx,command): + """Shows what command the alias executes.""" + server = ctx.message.server + if server.id in self.aliases: + server_aliases = self.aliases[server.id] + if command in server_aliases: + await self.bot.say(box(server_aliases[command])) + else: + await self.bot.say("That alias doesn't exist.") + + @alias.command(name="del",pass_context=True) + async def _del_alias(self,ctx,command : str): + """Deletes an alias""" + server = ctx.message.server + if server.id in self.aliases: + self.aliases[server.id].pop(command,None) + fileIO("data/alias/aliases.json","save",self.aliases) + await self.bot.say("Alias '{}' deleted.".format(command)) + + async def check_aliases(self,message): + if message.author.id == self.bot.user.id or len(message.content) < 2 or message.channel.is_private: + return + + msg = message.content + server = message.server + prefix = self.get_prefix(msg) + + if prefix and server.id in self.aliases: + aliaslist = self.aliases[server.id] + alias = msg[len(prefix):].split(" ")[0] + args = msg[len(self.first_word(message.content)):] + if alias in aliaslist.keys(): + content = aliaslist[alias] + args + new_message = message + new_message.content = content + await self.bot.process_commands(new_message) + + def first_word(self,msg): + return msg.split(" ")[0] + + def get_prefix(self, msg): + for p in self.bot.command_prefix: + if msg.startswith(p): + return p + return False + +def check_folder(): + if not os.path.exists("data/alias"): + print("Creating data/alias folder...") + os.makedirs("data/alias") + +def check_file(): + aliases = {} + + f = "data/alias/aliases.json" + if not fileIO(f, "check"): + print("Creating default alias's aliases.json...") + fileIO(f, "save", aliases) + +def setup(bot): + check_folder() + check_file() + n = Alias(bot) + bot.add_listener(n.check_aliases, "on_message") + bot.add_cog(n) \ No newline at end of file diff --git a/cogs/mod.py b/cogs/mod.py index dd9685991..c9c84f84a 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -2,9 +2,10 @@ import discord from discord.ext import commands from .utils import checks from .utils.dataIO import fileIO -from __main__ import send_cmd_help +from __main__ import send_cmd_help, settings import os import logging +import json class Mod: """Moderation tools.""" @@ -16,6 +17,56 @@ class Mod: self.ignore_list = fileIO("data/mod/ignorelist.json", "load") self.filter = fileIO("data/mod/filter.json", "load") + # HEY, YOU THERE, READ THIS + # In order to save modified BOT settings you MUST: + # 1) use self.bot_settings to GET the current settings + # THEN + # 2) Use checks.save_bot_settings(modified_bot_settings) + # 3) Don't blame me (Will), blame the other guy (not 26) + @property + def bot_settings(self): + settings = {} + with open("data/red/settings.json", "r") as f: + settings = json.loads(f.read()) + if settings == {}: + raise RuntimeError("Settings not found.") + return settings + + @commands.group(pass_context=True) + @checks.admin_or_permissions(manage_server=True) + async def modset(self,ctx): + """Manages server administration settings.""" + if ctx.invoked_subcommand is None: + send_cmd_help(ctx) + + @modset.command(name="adminrole",pass_context=True) + async def _modset_adminrole(self,ctx,role_name : str): + """Sets the admin role for this server, case insensitive.""" + sid = ctx.message.server.id + settings = self.bot_settings + if sid in settings: + settings[sid]["ADMIN_ROLE"] = role_name + else: + settings[sid] = {"ADMIN_ROLE":role_name,"MOD_ROLE":""} + settings[sid]["MOD_ROLE"] = settings["default"]["MOD_ROLE"] + await self.bot.say("Remember to set modrole too.") + await self.bot.say("Admin role set to '{}'".format(role_name)) + checks.save_bot_settings(settings) + + @modset.command(name="modrole",pass_context=True) + async def _modset_modrole(self,ctx,role_name : str): + """Sets the mod role for this server, case insensitive.""" + sid = ctx.message.server.id + settings = self.bot_settings + if sid in settings: + settings[sid]["MOD_ROLE"] = role_name + else: + settings[sid] = {"MOD_ROLE":role_name,"ADMIN_ROLE":""} + settings[sid]["ADMIN_ROLE"] = settings["default"]["ADMIN_ROLE"] + await self.bot.say("Remember to set adminrole too.") + await self.bot.say("Mod role set to '{}'".format(role_name)) + checks.save_bot_settings(settings) + @commands.command(no_pm=True, pass_context=True) @checks.admin_or_permissions(kick_members=True) async def kick(self, ctx, user : discord.Member): diff --git a/cogs/utils/chat_formatting.py b/cogs/utils/chat_formatting.py new file mode 100644 index 000000000..79631b77f --- /dev/null +++ b/cogs/utils/chat_formatting.py @@ -0,0 +1,17 @@ +def bold(text): + return "**"+str(text)+"**" + +def italics(text): + return "*"+str(text)+"*" + +def strikethrough(text): + return "~~"+str(text)+"~~" + +def underline(text): + return "__"+str(text)+"__" + +def box(text): + return "```"+str(text)+"```" + +def inline(text): + return "`"+str(text)+"`" \ No newline at end of file diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index d480579ce..e62282e73 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -13,8 +13,9 @@ import json try: with open("data/red/settings.json", "r") as f: settings = json.loads(f.read()) -except: - settings = {"OWNER" : False, "ADMIN_ROLE" : False, "MOD_ROLE" : False} +except Exception as e: + print(e) + settings = {"OWNER" : False, "default":{"ADMIN_ROLE" : False, "MOD_ROLE" : False}} def is_owner_check(ctx): return ctx.message.author.id == settings["OWNER"] @@ -32,6 +33,17 @@ def is_owner(): # the permissions required for them. # Of course, the owner will always be able to execute commands. +def save_bot_settings(bot_settings=settings): + with open("data/red/settings.json", "w") as f: + f.write(json.dumps(bot_settings,sort_keys=True,indent=4,separators=(',',':'))) + +def update_old_settings(): + mod = settings["MOD_ROLE"] + admin = settings["ADMIN_ROLE"] + del settings["MOD_ROLE"] + del settings["ADMIN_ROLE"] + settings["default"] = {"MOD_ROLE":mod,"ADMIN_ROLE":admin} + def check_permissions(ctx, perms): if is_owner_check(ctx): return True @@ -55,12 +67,30 @@ def role_or_permissions(ctx, check, **perms): def mod_or_permissions(**perms): def predicate(ctx): - return role_or_permissions(ctx, lambda r: r.name in (settings["MOD_ROLE"], settings["ADMIN_ROLE"]), **perms) + if "default" not in settings: + update_old_settings() + if admin_or_permissions(**perms): + return True + sid = ctx.message.server.id + if sid not in settings: + mod_role = settings["default"]["MOD_ROLE"].lower() + admin_role = settings["default"]["ADMIN_ROLE"].lower() + else: + mod_role = settings[sid]["MOD_ROLE"].lower() + admin_role = settings[sid]["ADMIN_ROLE"].lower() + return role_or_permissions(ctx, lambda r: r.name.lower() in (mod_role,admin_role), **perms) return commands.check(predicate) def admin_or_permissions(**perms): def predicate(ctx): - return role_or_permissions(ctx, lambda r: r.name == settings["ADMIN_ROLE"], **perms) + if "default" not in settings: + update_old_settings() + sid = ctx.message.server.id + if sid not in settings: + admin_role = settings["default"]["ADMIN_ROLE"] + else: + admin_role = settings[sid]["ADMIN_ROLE"] + return role_or_permissions(ctx, lambda r: r.name.lower() == admin_role.lower(), **perms) return commands.check(predicate) diff --git a/red.py b/red.py index 84b0f696f..197ce68a2 100644 --- a/red.py +++ b/red.py @@ -195,7 +195,7 @@ async def prefix(*prefixes): data = load_settings() data["PREFIXES"] = list(prefixes) with open("data/red/settings.json", "w") as f: - f.write(json.dumps(data)) + f.write(json.dumps(data)) if len(prefixes) > 1: await bot.say("Prefixes set") else: @@ -280,9 +280,13 @@ def user_allowed(message): if checks.settings["OWNER"] == author.id: return True if not message.channel.is_private: - if discord.utils.get(author.roles, name=checks.settings["ADMIN_ROLE"]) is not None: - return True - if discord.utils.get(author.roles, name=checks.settings["MOD_ROLE"]) is not None: + sid = message.server.id + if sid in checks.settings: + names = (checks.settings[sid]["ADMIN_ROLE"],checks.settings[sid]["MOD_ROLE"]) + else: + names = (checks.settings["default"]["ADMIN_ROLE"],checks.settings["default"]["MOD_ROLE"]) + + if None not in map(lambda name: discord.utils.get(author.roles,name=name),names): return True if author.id in mod.blacklist_list: @@ -345,7 +349,7 @@ def check_folders(): def check_configs(): settings_path = "data/red/settings.json" - settings = {"EMAIL" : "EmailHere", "PASSWORD" : "PasswordHere", "OWNER" : "id_here", "PREFIXES" : [], "ADMIN_ROLE" : "Transistor", "MOD_ROLE" : "Process"} + settings = {"EMAIL" : "EmailHere", "PASSWORD" : "PasswordHere", "OWNER" : "id_here", "PREFIXES" : [], "default":{"ADMIN_ROLE" : "Transistor", "MOD_ROLE" : "Process"}} if not os.path.isfile(settings_path): print("Red - First run configuration") @@ -379,13 +383,13 @@ def check_configs(): print("\nInput the admin role's name. Anyone with this role will be able to use the bot's admin commands") print("Leave blank for default name (Transistor)") - settings["ADMIN_ROLE"] = input("\nAdmin role> ") - if settings["ADMIN_ROLE"] == "": settings["ADMIN_ROLE"] = "Transistor" + settings["default"]["ADMIN_ROLE"] = input("\nAdmin role> ") + if settings["default"]["ADMIN_ROLE"] == "": settings["default"]["ADMIN_ROLE"] = "Transistor" print("\nInput the moderator role's name. Anyone with this role will be able to use the bot's mod commands") print("Leave blank for default name (Process)") - settings["MOD_ROLE"] = input("\nAdmin role> ") - if settings["MOD_ROLE"] == "": settings["MOD_ROLE"] = "Process" + settings["default"]["MOD_ROLE"] = input("\nAdmin role> ") + if settings["default"]["MOD_ROLE"] == "": settings["default"]["MOD_ROLE"] = "Process" with open(settings_path, "w") as f: f.write(json.dumps(settings)) @@ -478,6 +482,7 @@ def main(): set_logger() settings = load_settings() checks.settings["OWNER"] = settings["OWNER"] + checks.save_bot_settings(checks.settings) load_cogs() bot.command_prefix = settings["PREFIXES"] yield from bot.login(settings["EMAIL"], settings["PASSWORD"]) From 563d7bb3957fc64b433481643aa168edd6ae1645 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 04:02:32 -0500 Subject: [PATCH 02/11] initial working update --- cogs/alias.py | 1 - cogs/audio.py | 19 ++++++- cogs/economy.py | 2 +- cogs/mod.py | 48 ++++++---------- cogs/utils/checks.py | 48 +++------------- cogs/utils/dataIO.py | 2 +- cogs/utils/settings.py | 125 +++++++++++++++++++++++++++++++++++++++++ red.py | 93 ++++++++++++------------------ 8 files changed, 205 insertions(+), 133 deletions(-) create mode 100644 cogs/utils/settings.py diff --git a/cogs/alias.py b/cogs/alias.py index 209e22189..7d2889415 100644 --- a/cogs/alias.py +++ b/cogs/alias.py @@ -1,6 +1,5 @@ import discord from discord.ext import commands -from .utils import checks from .utils.chat_formatting import * from .utils.dataIO import fileIO from .utils import checks diff --git a/cogs/audio.py b/cogs/audio.py index c374c6f06..8e203721a 100644 --- a/cogs/audio.py +++ b/cogs/audio.py @@ -2,7 +2,6 @@ import discord from discord.ext import commands import asyncio import threading -import youtube_dl import os from random import choice as rndchoice from random import shuffle @@ -15,8 +14,16 @@ import aiohttp import json import time -if not discord.opus.is_loaded(): - discord.opus.load_opus('libopus-0.dll') +try: + import youtube_dl +except: + youtube_dl = None + +try: + if not discord.opus.is_loaded(): + discord.opus.load_opus('libopus-0.dll') +except: + opus = None youtube_dl_options = { 'format': 'bestaudio/best', @@ -775,6 +782,12 @@ def check_files(): def setup(bot): check_folders() check_files() + if youtube_dl is None: + raise RuntimeError("You need to run `pip3 install youtube_dl`") + return + if opus is None: + raise RuntimeError("You need to get the *.exe's and opus.dll from 26's github.") + return loop = asyncio.get_event_loop() n = Audio(bot) loop.create_task(n.queue_manager()) diff --git a/cogs/economy.py b/cogs/economy.py index b731e2eca..4a3d67e5d 100644 --- a/cogs/economy.py +++ b/cogs/economy.py @@ -1,9 +1,9 @@ import discord from discord.ext import commands from .utils.dataIO import fileIO -from .utils import checks from random import randint from copy import deepcopy +from .utils import checks from __main__ import send_cmd_help import os import time diff --git a/cogs/mod.py b/cogs/mod.py index c9c84f84a..2ebda50fc 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -1,7 +1,7 @@ import discord from discord.ext import commands -from .utils import checks from .utils.dataIO import fileIO +from .utils import checks from __main__ import send_cmd_help, settings import os import logging @@ -23,49 +23,31 @@ class Mod: # THEN # 2) Use checks.save_bot_settings(modified_bot_settings) # 3) Don't blame me (Will), blame the other guy (not 26) - @property - def bot_settings(self): - settings = {} - with open("data/red/settings.json", "r") as f: - settings = json.loads(f.read()) - if settings == {}: - raise RuntimeError("Settings not found.") - return settings @commands.group(pass_context=True) @checks.admin_or_permissions(manage_server=True) async def modset(self,ctx): """Manages server administration settings.""" if ctx.invoked_subcommand is None: - send_cmd_help(ctx) + await send_cmd_help(ctx) - @modset.command(name="adminrole",pass_context=True) + @modset.command(name="adminrole",pass_context=True,no_pm=True) async def _modset_adminrole(self,ctx,role_name : str): """Sets the admin role for this server, case insensitive.""" - sid = ctx.message.server.id - settings = self.bot_settings - if sid in settings: - settings[sid]["ADMIN_ROLE"] = role_name - else: - settings[sid] = {"ADMIN_ROLE":role_name,"MOD_ROLE":""} - settings[sid]["MOD_ROLE"] = settings["default"]["MOD_ROLE"] + server = ctx.message.server + if server.id not in settings.servers: await self.bot.say("Remember to set modrole too.") + settings.set_server_admin(server,role_name) await self.bot.say("Admin role set to '{}'".format(role_name)) - checks.save_bot_settings(settings) - @modset.command(name="modrole",pass_context=True) + @modset.command(name="modrole",pass_context=True,no_pm=True) async def _modset_modrole(self,ctx,role_name : str): """Sets the mod role for this server, case insensitive.""" - sid = ctx.message.server.id - settings = self.bot_settings - if sid in settings: - settings[sid]["MOD_ROLE"] = role_name - else: - settings[sid] = {"MOD_ROLE":role_name,"ADMIN_ROLE":""} - settings[sid]["ADMIN_ROLE"] = settings["default"]["ADMIN_ROLE"] + server = ctx.message.server + if server.id not in settings.servers: await self.bot.say("Remember to set adminrole too.") + settings.set_server_mod(server,role_name) await self.bot.say("Mod role set to '{}'".format(role_name)) - checks.save_bot_settings(settings) @commands.command(no_pm=True, pass_context=True) @checks.admin_or_permissions(kick_members=True) @@ -449,11 +431,15 @@ class Mod: def immune_from_filter(self, message): user = message.author - if user.id == checks.settings["OWNER"]: + server = message.server + admin_role = settings.get_server_admin(server) + mod_role = settings.get_server_mod(server) + + if user.id == settings.owner: return True - elif discord.utils.get(user.roles, name=checks.settings["ADMIN_ROLE"]): + elif discord.utils.get(user.roles, name=admin_role): return True - elif discord.utils.get(user.roles, name=checks.settings["MOD_ROLE"]): + elif discord.utils.get(user.roles, name=mod_role): return True else: return False diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index e62282e73..2f534c714 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -1,7 +1,8 @@ from discord.ext import commands import discord.utils -import os.path -import json +from cogs.utils.settings import Settings +from cogs.utils.dataIO import fileIO +from __main__ import settings # # This is a modified version of checks.py, originally made by Rapptz @@ -10,15 +11,8 @@ import json # https://github.com/Rapptz/RoboDanny/tree/async # -try: - with open("data/red/settings.json", "r") as f: - settings = json.loads(f.read()) -except Exception as e: - print(e) - settings = {"OWNER" : False, "default":{"ADMIN_ROLE" : False, "MOD_ROLE" : False}} - def is_owner_check(ctx): - return ctx.message.author.id == settings["OWNER"] + return ctx.message.author.id == settings.owner def is_owner(): return commands.check(is_owner_check) @@ -33,17 +27,6 @@ def is_owner(): # the permissions required for them. # Of course, the owner will always be able to execute commands. -def save_bot_settings(bot_settings=settings): - with open("data/red/settings.json", "w") as f: - f.write(json.dumps(bot_settings,sort_keys=True,indent=4,separators=(',',':'))) - -def update_old_settings(): - mod = settings["MOD_ROLE"] - admin = settings["ADMIN_ROLE"] - del settings["MOD_ROLE"] - del settings["ADMIN_ROLE"] - settings["default"] = {"MOD_ROLE":mod,"ADMIN_ROLE":admin} - def check_permissions(ctx, perms): if is_owner_check(ctx): return True @@ -67,30 +50,17 @@ def role_or_permissions(ctx, check, **perms): def mod_or_permissions(**perms): def predicate(ctx): - if "default" not in settings: - update_old_settings() - if admin_or_permissions(**perms): - return True - sid = ctx.message.server.id - if sid not in settings: - mod_role = settings["default"]["MOD_ROLE"].lower() - admin_role = settings["default"]["ADMIN_ROLE"].lower() - else: - mod_role = settings[sid]["MOD_ROLE"].lower() - admin_role = settings[sid]["ADMIN_ROLE"].lower() + server = ctx.message.server + mod_role = settings.get_server_mod(server) + admin_role = settings.get_server_admin(server) return role_or_permissions(ctx, lambda r: r.name.lower() in (mod_role,admin_role), **perms) return commands.check(predicate) def admin_or_permissions(**perms): def predicate(ctx): - if "default" not in settings: - update_old_settings() - sid = ctx.message.server.id - if sid not in settings: - admin_role = settings["default"]["ADMIN_ROLE"] - else: - admin_role = settings[sid]["ADMIN_ROLE"] + server = ctx.message.server + admin_role = settings.get_server_admin(server) return role_or_permissions(ctx, lambda r: r.name.lower() == admin_role.lower(), **perms) return commands.check(predicate) diff --git a/cogs/utils/dataIO.py b/cogs/utils/dataIO.py index f84312607..e2d1ece05 100644 --- a/cogs/utils/dataIO.py +++ b/cogs/utils/dataIO.py @@ -3,7 +3,7 @@ import json def fileIO(filename, IO, data=None): if IO == "save" and data != None: with open(filename, encoding='utf-8', mode="w") as f: - f.write(json.dumps(data)) + f.write(json.dumps(data,indent=4,sort_keys=True,separators=(',',' : '))) elif IO == "load" and data == None: with open(filename, encoding='utf-8', mode="r") as f: return json.loads(f.read()) diff --git a/cogs/utils/settings.py b/cogs/utils/settings.py new file mode 100644 index 000000000..cd513d51f --- /dev/null +++ b/cogs/utils/settings.py @@ -0,0 +1,125 @@ +from .dataIO import fileIO +import discord + +default_path = "data/red/settings.json" + +class Settings: + def __init__(self,path=default_path): + self.path = path + self.default_settings = {"EMAIL" : "EmailHere", "PASSWORD" : "PasswordHere", "OWNER" : "id_here", "PREFIXES" : [], "default":{"ADMIN_ROLE" : "Transistor", "MOD_ROLE" : "Process"}} + if not fileIO(self.path,"check"): + self.bot_settings = self.default_settings + self.save_settings() + else: + self.bot_settings = fileIO(self.path,"load") + if "default" not in self.bot_settings: + self.update_old_settings() + + def save_settings(self): + fileIO(self.path,"save",self.bot_settings) + + def update_old_settings(self): + mod = self.bot_settings["MOD_ROLE"] + admin = self.bot_settings["ADMIN_ROLE"] + del self.bot_settings["MOD_ROLE"] + del self.bot_settings["ADMIN_ROLE"] + self.bot_settings["default"] = {"MOD_ROLE":mod,"ADMIN_ROLE":admin} + self.save_settings() + + @property + def owner(self): + return self.bot_settings["OWNER"] + + @owner.setter + def owner(self,value): + self.bot_settings["OWNER"] = value + self.save_settings() + + @property + def email(self): + return self.bot_settings["EMAIL"] + + @property + def password(self): + return self.bot_settings["PASSWORD"] + + @property + def prefixes(self): + return self.bot_settings["PREFIXES"] + + @prefixes.setter + def prefixes(self,value): + self.bot_settings["PREFIXES"] = value + self.save_settings() + + @property + def default_admin(self): + if "default" not in self.bot_settings: + self.update_old_settings() + return self.bot_settings["default"].get("ADMIN_ROLE","") + + @default_admin.setter + def default_admin(self,value): + if "default" not in self.bot_settings: + self.update_old_settings() + self.bot_settings["default"]["ADMIN_ROLE"] = value + self.save_settings() + + @property + def default_mod(self): + if "default" not in self.bot_settings: + self.update_old_settings() + return self.bot_settings["default"].get("MOD_ROLE","") + + @default_mod.setter + def default_mod(self,value): + if "default" not in self.bot_settings: + self.update_old_settings() + self.bot_settings["default"]["MOD_ROLE"] = value + self.save_settings() + + @property + def servers(self): + ret = {} + server_ids = list(filter(lambda x: str(x).isdigit(),self.bot_settings)) + for server in server_ids: + ret.update({server:self.bot_settings[server]}) + return ret + + def get_server_admin(self,server): + assert isinstance(server,discord.Server) + if server is None: + return + if server.id not in self.bot_settings: + return self.default_admin + return self.bot_settings[server.id].get("ADMIN_ROLE","") + + def set_server_admin(self,server,value): + assert isinstance(server,discord.Server) + if server is None: + return + if server.id not in self.bot_settings: + self.add_server(server.id) + self.bot_settings[server.id]["ADMIN_ROLE"] = value + self.save_settings() + + def get_server_mod(self,server): + assert isinstance(server,discord.Server) + if server is None: + return + if server.id not in self.bot_settings: + return self.default_mod + return self.bot_settings[server.id].get("MOD_ROLE","") + + def set_server_mod(self,server,value): + assert isinstance(server,discord.Server) + if server is None: + return + if server.id not in self.bot_settings: + self.add_server(server.id) + self.bot_settings[server.id]["MOD_ROLE"] = value + self.save_settings() + + def add_server(self,sid): + self.bot_settings[sid] = self.bot_settings["default"].copy() + self.save_settings() diff --git a/red.py b/red.py index 197ce68a2..12c64eb5d 100644 --- a/red.py +++ b/red.py @@ -1,6 +1,6 @@ from discord.ext import commands import discord -from cogs.utils import checks +from cogs.utils.settings import Settings from random import choice as rndchoice import threading import datetime, re @@ -31,6 +31,10 @@ formatter = commands.HelpFormatter(show_check_failure=False) bot = commands.Bot(command_prefix=["_"], formatter=formatter, description=description, pm_help=None) +settings = Settings() + +from cogs.utils import checks + lock = False @bot.event @@ -150,7 +154,7 @@ async def debug(ctx, *, code : str): result = python.format(result) if not ctx.message.channel.is_private: - censor = (settings["EMAIL"], settings["PASSWORD"]) + censor = (settings.email, settings.password) r = "[EXPUNGED]" for w in censor: result = result.replace(w, r) @@ -169,8 +173,7 @@ async def owner(ctx): """Sets owner""" global lock msg = ctx.message - data = load_settings() - if data["OWNER"] != "id_here": + if settings.owner != "id_here": await bot.say("Owner ID has already been set.") return if lock: @@ -192,10 +195,7 @@ async def prefix(*prefixes): await bot.say("Example: setprefix [ ! ^ .") return bot.command_prefix = list(prefixes) - data = load_settings() - data["PREFIXES"] = list(prefixes) - with open("data/red/settings.json", "w") as f: - f.write(json.dumps(data)) + settings.prefixes = list(prefixes) if len(prefixes) > 1: await bot.say("Prefixes set") else: @@ -207,7 +207,7 @@ async def name(ctx, *name : str): """Sets Red's name""" if name == (): await send_cmd_help(ctx) - await bot.edit_profile(settings["PASSWORD"], username=" ".join(name)) + await bot.edit_profile(settings.password, username=" ".join(name)) await bot.say("Done.") @_set.command(pass_context=True) @@ -227,7 +227,7 @@ async def avatar(url : str): try: async with aiohttp.get(url) as r: data = await r.read() - await bot.edit_profile(settings["PASSWORD"], avatar=data) + await bot.edit_profile(settings.password, avatar=data) await bot.say("Done.") except: await bot.say("Error.") @@ -277,15 +277,11 @@ def user_allowed(message): mod = bot.get_cog('Mod') if mod is not None: - if checks.settings["OWNER"] == author.id: + if settings.owner == author.id: return True if not message.channel.is_private: - sid = message.server.id - if sid in checks.settings: - names = (checks.settings[sid]["ADMIN_ROLE"],checks.settings[sid]["MOD_ROLE"]) - else: - names = (checks.settings["default"]["ADMIN_ROLE"],checks.settings["default"]["MOD_ROLE"]) - + server = message.server + names = (settings.get_server_admin(server),settings.get_server_mod(server)) if None not in map(lambda name: discord.utils.get(author.roles,name=name),names): return True @@ -314,24 +310,13 @@ def wait_for_answer(author): while choice.lower() != "yes" and choice == "None": choice = input("> ") if choice == "yes": - data = load_settings() - data["OWNER"] = author.id - with open("data/red/settings.json", "w") as f: - f.write(json.dumps(data)) - checks.owner = data["OWNER"] - print(author.name + " has been set as owner. A restart is required.") + settings.owner = author.id + print(author.name + " has been set as owner. A restart is required, maybe?") lock = False else: print("setowner request has been ignored.") lock = False -def load_settings(): - try: - with open('data/red/settings.json', "r") as f: - return json.load(f) - except: - raise("Couldn't load credentials.") - def list_cogs(): cogs = glob.glob("cogs/*.py") clean = [] @@ -348,51 +333,46 @@ def check_folders(): os.makedirs(folder) def check_configs(): - settings_path = "data/red/settings.json" - settings = {"EMAIL" : "EmailHere", "PASSWORD" : "PasswordHere", "OWNER" : "id_here", "PREFIXES" : [], "default":{"ADMIN_ROLE" : "Transistor", "MOD_ROLE" : "Process"}} - if not os.path.isfile(settings_path): - + if settings.bot_settings == settings.default_settings: print("Red - First run configuration") print("If you don't have one, create a NEW ACCOUNT for Red. Do *not* use yours. (https://discordapp.com)") - settings["EMAIL"] = input("\nEmail> ") - settings["PASSWORD"] = input("\nPassword> ") + settings.email = input("\nEmail> ") + settings.password = input("\nPassword> ") - if not settings["EMAIL"] or not settings["PASSWORD"]: + if not settings.email or not settings.password: input("Email and password cannot be empty. Restart Red and repeat the configuration process.") exit(1) - if "@" not in settings["EMAIL"]: + if "@" not in settings.email: input("You didn't enter a valid email. Restart Red and repeat the configuration process.") exit(1) print("\nChoose a prefix (or multiple ones, one at once) for the commands. Type exit when you're done. Example prefix: !") - settings["PREFIXES"] = [] + settings.prefixes = [] new_prefix = "" - while new_prefix.lower() != "exit" or settings["PREFIXES"] == []: + while new_prefix.lower() != "exit" or settings.prefixes == []: new_prefix = input("Prefix> ") if new_prefix.lower() != "exit" and new_prefix != "": - settings["PREFIXES"].append(new_prefix) + settings.prefixes = settings.prefixes.append(new_prefix) + #Remember we're using property's here, oh well... print("\nInput *your own* ID. You can type \@Yourname in chat to see it (copy only the numbers).") print("If you want, you can also do it later with [prefix]set owner. Leave empty in that case.") - settings["OWNER"] = input("\nID> ") - if settings["OWNER"] == "": settings["OWNER"] = "id_here" - if not settings["OWNER"].isdigit() and settings["OWNER"] != "id_here": + settings.owner = input("\nID> ") + if settings.owner == "": settings["OWNER"] = "id_here" + if not settings.owner.isdigit() and settings["OWNER"] != "id_here": print("\nERROR: What you entered is not a valid ID. Set yourself as owner later with [prefix]set owner") - settings["OWNER"] = "id_here" + settings.owner = "id_here" print("\nInput the admin role's name. Anyone with this role will be able to use the bot's admin commands") print("Leave blank for default name (Transistor)") - settings["default"]["ADMIN_ROLE"] = input("\nAdmin role> ") - if settings["default"]["ADMIN_ROLE"] == "": settings["default"]["ADMIN_ROLE"] = "Transistor" + settings.default_admin = input("\nAdmin role> ") + if settings.default_admin == "": settings.default_admin = "Transistor" print("\nInput the moderator role's name. Anyone with this role will be able to use the bot's mod commands") print("Leave blank for default name (Process)") - settings["default"]["MOD_ROLE"] = input("\nAdmin role> ") - if settings["default"]["MOD_ROLE"] == "": settings["default"]["MOD_ROLE"] = "Process" - - with open(settings_path, "w") as f: - f.write(json.dumps(settings)) + settings.default_mod = input("\nModerator role> ") + if settings.default_mod == "": settings.default_mod = "Process" cogs_s_path = "data/red/cogs.json" cogs = {} @@ -477,15 +457,14 @@ def load_cogs(): def main(): global settings + global checks + check_folders() check_configs() set_logger() - settings = load_settings() - checks.settings["OWNER"] = settings["OWNER"] - checks.save_bot_settings(checks.settings) load_cogs() - bot.command_prefix = settings["PREFIXES"] - yield from bot.login(settings["EMAIL"], settings["PASSWORD"]) + bot.command_prefix = settings.prefixes + yield from bot.login(settings.email, settings.password) yield from bot.connect() if __name__ == '__main__': From bbcf52a3a51e6524d5f4414d7c8d58c049ea0512 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 04:05:47 -0500 Subject: [PATCH 03/11] remove deprecated comment --- cogs/mod.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 2ebda50fc..4c71d34bd 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -17,13 +17,6 @@ class Mod: self.ignore_list = fileIO("data/mod/ignorelist.json", "load") self.filter = fileIO("data/mod/filter.json", "load") - # HEY, YOU THERE, READ THIS - # In order to save modified BOT settings you MUST: - # 1) use self.bot_settings to GET the current settings - # THEN - # 2) Use checks.save_bot_settings(modified_bot_settings) - # 3) Don't blame me (Will), blame the other guy (not 26) - @commands.group(pass_context=True) @checks.admin_or_permissions(manage_server=True) async def modset(self,ctx): From fc073343e4c40565fa26ff8379b3a333c0a58902 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 04:17:01 -0500 Subject: [PATCH 04/11] add get_server for admin/mod settings for modset help --- cogs/general.py | 5 +++++ cogs/mod.py | 7 ++++++- cogs/utils/settings.py | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cogs/general.py b/cogs/general.py index 852e31dab..a3de88c93 100644 --- a/cogs/general.py +++ b/cogs/general.py @@ -21,6 +21,11 @@ class General: "Don't count on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful"] self.poll_sessions = [] + @commands.command() + async def ping(self): + """Pong.""" + self.bot.say("Pong.") + @commands.command() async def choose(self, *choices): """Chooses between multiple choices. diff --git a/cogs/mod.py b/cogs/mod.py index 4c71d34bd..ba8e4e6cc 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -17,12 +17,17 @@ class Mod: self.ignore_list = fileIO("data/mod/ignorelist.json", "load") self.filter = fileIO("data/mod/filter.json", "load") - @commands.group(pass_context=True) + @commands.group(pass_context=True,no_pm=True) @checks.admin_or_permissions(manage_server=True) async def modset(self,ctx): """Manages server administration settings.""" if ctx.invoked_subcommand is None: await send_cmd_help(ctx) + msg = "```" + for k, v in settings.get_server(ctx.message.server).items(): + msg += str(k) + ": " + str(v) + "\n" + msg += "```" + await self.bot.say(msg) @modset.command(name="adminrole",pass_context=True,no_pm=True) async def _modset_adminrole(self,ctx,role_name : str): diff --git a/cogs/utils/settings.py b/cogs/utils/settings.py index cd513d51f..55ee46b8d 100644 --- a/cogs/utils/settings.py +++ b/cogs/utils/settings.py @@ -49,6 +49,7 @@ class Settings: @prefixes.setter def prefixes(self,value): + assert isinstance(value,list) self.bot_settings["PREFIXES"] = value self.save_settings() @@ -86,6 +87,10 @@ class Settings: ret.update({server:self.bot_settings[server]}) return ret + def get_server(self,server): + assert isinstance(server,discord.Server) + return self.bot_settings.get(server.id,self.bot_settings["default"].copy()) + def get_server_admin(self,server): assert isinstance(server,discord.Server) if server is None: From 07afde2d959fdaab4d3dd64ddfe1e31bfb7ee5ed Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 16:42:09 -0500 Subject: [PATCH 05/11] cc case insensitive --- cogs/customcom.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cogs/customcom.py b/cogs/customcom.py index 7abe7c881..42629387d 100644 --- a/cogs/customcom.py +++ b/cogs/customcom.py @@ -24,8 +24,9 @@ class CustomCommands: await send_cmd_help(ctx) return server = ctx.message.server - to_replace = ctx.prefix + "addcom " + command + " " - text = ctx.message.content.replace(to_replace, "") + to_replace = ctx.message.content.find(text[0]) + text = ctx.message.content[to_replace:] + command = command.lower() if not server.id in self.c_commands: self.c_commands[server.id] = {} cmdlist = self.c_commands[server.id] @@ -49,8 +50,9 @@ class CustomCommands: await send_cmd_help(ctx) return server = ctx.message.server - to_replace = ctx.prefix + "editcom " + command + " " - text = ctx.message.content.replace(to_replace, "") + to_replace = ctx.message.content.find(text[0]) + text = ctx.message.content[to_replace:] + command = command.lower() if server.id in self.c_commands: cmdlist = self.c_commands[server.id] if command in cmdlist: @@ -71,6 +73,7 @@ class CustomCommands: Example: !delcom yourcommand""" server = ctx.message.server + command = command.lower() if server.id in self.c_commands: cmdlist = self.c_commands[server.id] if command in cmdlist: From 36c9650551a7f2a2f53846819c30e516d495b61c Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 17:04:23 -0500 Subject: [PATCH 06/11] copy both dicts, not just default --- cogs/utils/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/utils/settings.py b/cogs/utils/settings.py index 55ee46b8d..ecd4d8dfb 100644 --- a/cogs/utils/settings.py +++ b/cogs/utils/settings.py @@ -89,7 +89,7 @@ class Settings: def get_server(self,server): assert isinstance(server,discord.Server) - return self.bot_settings.get(server.id,self.bot_settings["default"].copy()) + return self.bot_settings.get(server.id,self.bot_settings["default"]).copy() def get_server_admin(self,server): assert isinstance(server,discord.Server) From 43413a4e26d9cba36e6a83461cf2a81432a42bf5 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 21:15:49 -0500 Subject: [PATCH 07/11] add else case for opus check --- cogs/audio.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cogs/audio.py b/cogs/audio.py index 8e203721a..4502406fc 100644 --- a/cogs/audio.py +++ b/cogs/audio.py @@ -24,6 +24,8 @@ try: discord.opus.load_opus('libopus-0.dll') except: opus = None +else: + opus = True youtube_dl_options = { 'format': 'bestaudio/best', From 96e04bdf98e793e80f9ce8c5b5551474058253a7 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sat, 27 Feb 2016 21:28:25 -0500 Subject: [PATCH 08/11] fixed variable name in ban --- cogs/mod.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index ba8e4e6cc..fd44dcbdf 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -63,17 +63,17 @@ class Mod: @commands.command(no_pm=True, pass_context=True) @checks.admin_or_permissions(ban_members=True) - async def ban(self, ctx, user : discord.Member, purge_msg : int=0): + async def ban(self, ctx, user : discord.Member, days : int=0): """Bans user and deletes last X days worth of messages. Minimum 0 days, maximum 7. Defaults to 0.""" author = ctx.message.author - if purge_msg < 0 or purge_msg > 7: + if days < 0 or days > 7: await self.bot.say("Invalid days. Must be between 0 and 7.") return try: await self.bot.ban(user, days) - logger.info("{}({}) banned {}({}), deleting {} days worth of messages".format(author.name, author.id, user.name, user.id, str(purge_msg))) + logger.info("{}({}) banned {}({}), deleting {} days worth of messages".format(author.name, author.id, user.name, user.id, str(days))) await self.bot.say("Done. It was about time.") except discord.errors.Forbidden: await self.bot.say("I'm not allowed to do that.") From 4eed137aaac93ea2ebb0b22a702054d715dac53d Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sun, 28 Feb 2016 01:29:53 -0500 Subject: [PATCH 09/11] fix case sensitivity on mod checks --- cogs/utils/checks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index 2f534c714..961ccd717 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -51,8 +51,8 @@ def role_or_permissions(ctx, check, **perms): def mod_or_permissions(**perms): def predicate(ctx): server = ctx.message.server - mod_role = settings.get_server_mod(server) - admin_role = settings.get_server_admin(server) + mod_role = settings.get_server_mod(server).lower() + admin_role = settings.get_server_admin(server).lower() return role_or_permissions(ctx, lambda r: r.name.lower() in (mod_role,admin_role), **perms) return commands.check(predicate) From 1d9888a4567190427b3a3bc6855dae11757207b3 Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sun, 28 Feb 2016 16:20:47 -0500 Subject: [PATCH 10/11] fix PR-found issues with red"s settings and audio --- cogs/audio.py | 27 +++++++++++++++------------ cogs/utils/settings.py | 19 +++++++++++++++++++ red.py | 7 ++++--- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cogs/audio.py b/cogs/audio.py index 4502406fc..0ed425271 100644 --- a/cogs/audio.py +++ b/cogs/audio.py @@ -8,6 +8,7 @@ from random import shuffle from .utils.dataIO import fileIO from .utils import checks from __main__ import send_cmd_help +from __main__ import settings as bot_settings import glob import re import aiohttp @@ -69,7 +70,7 @@ class Audio: msg = ctx.message if await self.check_voice(msg.author, msg): if self.is_playlist_valid([link]): # reusing a function - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): self.queue = [] self.current = -1 self.playlist = [] @@ -128,7 +129,7 @@ class Audio: """ msg = ctx.message if self.music_player.is_playing(): - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): self.music_player.paused = False self.music_player.stop() else: @@ -177,7 +178,7 @@ class Audio: files.extend(glob.glob("data/audio/localtracks/" + name + "/*.mp3")) if glob.glob("data/audio/localtracks/" + name + "/*.flac"): files.extend(glob.glob("data/audio/localtracks/" + name + "/*.flac")) - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): if await self.check_voice(msg.author, ctx.message): self.queue = [] self.current = -1 @@ -197,7 +198,7 @@ class Audio: """ msg = ctx.message if self.music_player.is_playing(): - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): self.current = -1 self.playlist = [self.downloader["URL"]] await self.bot.say("I will play this song on repeat.") @@ -210,7 +211,7 @@ class Audio: """ msg = ctx.message if self.music_player.is_playing(): - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): if self.playlist: shuffle(self.playlist) await self.bot.say("The order of this playlist has been mixed") @@ -223,7 +224,7 @@ class Audio: """ msg = ctx.message if self.music_player.is_playing() and self.playlist: - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): self.current -= 2 if self.current == -1: self.current = len(self.playlist) -3 @@ -240,7 +241,7 @@ class Audio: """ msg = ctx.message if self.music_player.is_playing(): - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): await self.close_audio() else: await self.bot.say("You can't stop music when there are other people in the channel! Vote to skip instead.") @@ -282,14 +283,16 @@ class Audio: else: await self.bot.say("That link is now allowed.") - async def is_alone_or_admin(self, author): #Direct control. fix everything + async def is_alone_or_admin(self, message): #Direct control. fix everything + author = message.author + server = message.server if not self.settings["QUEUE_MODE"]: return True - elif author.id == checks.settings["OWNER"]: + elif author.id == bot_settings.owner: return True - elif discord.utils.get(author.roles, name=checks.settings["ADMIN_ROLE"]) is not None: + elif discord.utils.get(author.roles, name=bot_settings.get_server_admin(server)) is not None: return True - elif discord.utils.get(author.roles, name=checks.settings["MOD_ROLE"]) is not None: + elif discord.utils.get(author.roles, name=bot_settings.get_server_mod(server)) is not None: return True elif len(author.voice_channel.voice_members) in (1, 2): return True @@ -308,7 +311,7 @@ class Audio: self.queue = [] await self.play_video(rndchoice(self.sing)) else: - if await self.is_alone_or_admin(msg.author): + if await self.is_alone_or_admin(msg): self.queue = [] await self.play_video(rndchoice(self.sing)) else: diff --git a/cogs/utils/settings.py b/cogs/utils/settings.py index ecd4d8dfb..06cbdbfed 100644 --- a/cogs/utils/settings.py +++ b/cogs/utils/settings.py @@ -1,11 +1,13 @@ from .dataIO import fileIO import discord +import os default_path = "data/red/settings.json" class Settings: def __init__(self,path=default_path): self.path = path + self.check_folders() self.default_settings = {"EMAIL" : "EmailHere", "PASSWORD" : "PasswordHere", "OWNER" : "id_here", "PREFIXES" : [], "default":{"ADMIN_ROLE" : "Transistor", "MOD_ROLE" : "Process"}} if not fileIO(self.path,"check"): self.bot_settings = self.default_settings @@ -15,6 +17,13 @@ class Settings: if "default" not in self.bot_settings: self.update_old_settings() + def check_folders(self): + folders = ("data", os.path.dirname(self.path), "cogs", "cogs/utils") + for folder in folders: + if not os.path.exists(folder): + print("Creating " + folder + " folder...") + os.makedirs(folder) + def save_settings(self): fileIO(self.path,"save",self.bot_settings) @@ -39,10 +48,20 @@ class Settings: def email(self): return self.bot_settings["EMAIL"] + @email.setter + def email(self,value): + self.bot_settings["EMAIL"] = value + self.save_settings() + @property def password(self): return self.bot_settings["PASSWORD"] + @password.setter + def password(self,value): + self.bot_settings["PASSWORD"] = value + self.save_settings() + @property def prefixes(self): return self.bot_settings["PREFIXES"] diff --git a/red.py b/red.py index 12c64eb5d..2b50dc209 100644 --- a/red.py +++ b/red.py @@ -348,13 +348,14 @@ def check_configs(): exit(1) print("\nChoose a prefix (or multiple ones, one at once) for the commands. Type exit when you're done. Example prefix: !") - settings.prefixes = [] + prefixes = [] new_prefix = "" - while new_prefix.lower() != "exit" or settings.prefixes == []: + while new_prefix.lower() != "exit" or prefixes == []: new_prefix = input("Prefix> ") if new_prefix.lower() != "exit" and new_prefix != "": - settings.prefixes = settings.prefixes.append(new_prefix) + prefixes.append(new_prefix) #Remember we're using property's here, oh well... + settings.prefixes = prefixes print("\nInput *your own* ID. You can type \@Yourname in chat to see it (copy only the numbers).") print("If you want, you can also do it later with [prefix]set owner. Leave empty in that case.") From e794fb1c9a3496b3c51ec39f3bd0febefa89cfca Mon Sep 17 00:00:00 2001 From: Will Tekulve Date: Sun, 28 Feb 2016 20:24:26 -0500 Subject: [PATCH 11/11] add serverowner check and make modset owner only --- cogs/mod.py | 2 +- cogs/utils/checks.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cogs/mod.py b/cogs/mod.py index fd44dcbdf..b1c7a6691 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -18,7 +18,7 @@ class Mod: self.filter = fileIO("data/mod/filter.json", "load") @commands.group(pass_context=True,no_pm=True) - @checks.admin_or_permissions(manage_server=True) + @checks.serverowner_or_permissions(manage_server=True) async def modset(self,ctx): """Manages server administration settings.""" if ctx.invoked_subcommand is None: diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index 961ccd717..3e8c59828 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -64,3 +64,14 @@ def admin_or_permissions(**perms): return role_or_permissions(ctx, lambda r: r.name.lower() == admin_role.lower(), **perms) return commands.check(predicate) + +def serverowner_or_permissions(**perms): + def predicate(ctx): + server = ctx.message.server + owner = server.owner + + if ctx.message.author.id == owner.id: + return True + + return check_permissions(ctx,perms) + return commands.check(predicate)