[Core] Implemented missing checks, extended DB

The DB has been extended and now covers the functionality of the old Settings class of the previous version
This commit is contained in:
Twentysix 2017-04-30 00:28:56 +02:00
parent 9fc4e54ece
commit ba9d4b7f0f
4 changed files with 149 additions and 14 deletions

View File

@ -1,6 +1,6 @@
from discord.ext import commands from discord.ext import commands
from collections import Counter from collections import Counter
from core.utils.helpers import JsonGuildDB from core.settings import CoreDB
from enum import Enum from enum import Enum
import os import os
@ -8,7 +8,7 @@ import os
class Red(commands.Bot): class Red(commands.Bot):
def __init__(self, cli_flags, **kwargs): def __init__(self, cli_flags, **kwargs):
self._shutdown_mode = ExitCodes.CRITICAL self._shutdown_mode = ExitCodes.CRITICAL
self.db = JsonGuildDB("core/data/settings.json", self.db = CoreDB("core/data/settings.json",
autosave=True, autosave=True,
create_dirs=True) create_dirs=True)

View File

@ -5,3 +5,67 @@ def is_owner(**kwargs):
async def check(ctx): async def check(ctx):
return await ctx.bot.is_owner(ctx.author, **kwargs) return await ctx.bot.is_owner(ctx.author, **kwargs)
return commands.check(check) return commands.check(check)
async def check_permissions(ctx, perms):
if await ctx.bot.is_owner(ctx.author):
return True
elif not perms:
return False
resolved = ctx.channel.permissions_for(ctx.author)
return all(getattr(resolved, name, None) == value for name, value in perms.items())
def mod_or_permissions(**perms):
async def predicate(ctx):
has_perms_or_is_owner = await check_permissions(ctx, perms)
if ctx.guild is None:
return has_perms_or_is_owner
author = ctx.author
mod_role = ctx.bot.db.get_mod_role(ctx.guild)
admin_role = ctx.bot.db.get_admin_role(ctx.guild)
is_staff = mod_role in author.roles or admin_role in author.roles
is_guild_owner = author == ctx.guild.owner
return is_staff or has_perms_or_is_owner or is_guild_owner
return commands.check(predicate)
def admin_or_permissions(**perms):
async def predicate(ctx):
has_perms_or_is_owner = await check_permissions(ctx, perms)
if ctx.guild is None:
return has_perms_or_is_owner
author = ctx.author
is_guild_owner = author == ctx.guild.owner
admin_role = ctx.bot.db.get_admin_role(ctx.guild)
return admin_role in author.roles or has_perms_or_is_owner or is_guild_owner
return commands.check(predicate)
def guildowner_or_permissions(**perms):
async def predicate(ctx):
has_perms_or_is_owner = await check_permissions(ctx, perms)
if ctx.guild is None:
return has_perms_or_is_owner
is_guild_owner = ctx.author == ctx.guild.owner
return is_guild_owner or has_perms_or_is_owner
return commands.check(predicate)
def guildowner():
return guildowner_or_permissions()
def admin():
return admin_or_permissions()
def mod():
return mod_or_permissions()

View File

@ -1,17 +1,88 @@
from core.utils.helpers import JsonGuildDB
import discord
import argparse import argparse
# Do we even need a Settings class this time? To be decided
class CoreDB(JsonGuildDB):
class Settings: """
def __init__(self): The central DB used by Red to store a variety
args = {} of settings, both global and guild specific
self.coowners = [] """
def can_login(self): def can_login(self):
"""Used on start to determine if Red is setup enough to login""" """Used on start to determine if Red is setup enough to login"""
raise NotImplementedError raise NotImplementedError
def get_admin_role(self, guild):
"""Returns the guild's admin role
Returns None if not set or if the role
couldn't be retrieved"""
_id = self.get_all(guild, {}).get("admin_role", None)
return discord.utils.get(guild.roles, id=_id)
def get_mod_role(self, guild):
"""Returns the guild's mod role
Returns None if not set or if the role
couldn't be retrieved"""
_id = self.get_all(guild, {}).get("mod_role", None)
return discord.utils.get(guild.roles, id=_id)
async def set_admin_role(self, role):
"""Sets the admin role for the guild"""
if not isinstance(role, discord.Role):
raise TypeError("A valid Discord role must be passed.")
await self.set(role.guild, "admin_role", role.id)
async def set_mod_role(self, role):
"""Sets the mod role for the guild"""
if not isinstance(role, discord.Role):
raise TypeError("A valid Discord role must be passed.")
await self.set(role.guild, "mod_role", role.id)
def get_global_whitelist(self):
"""Returns the global whitelist"""
return self.get_global("whitelist", [])
def get_global_blacklist(self):
"""Returns the global whitelist"""
return self.get_global("blacklist", [])
async def set_global_whitelist(self, whitelist):
"""Sets the global whitelist"""
if not isinstance(list, whitelist):
raise TypeError("A list of IDs must be passed.")
await self.set_global("whitelist", whitelist)
async def set_global_blacklist(self, blacklist):
"""Sets the global blacklist"""
if not isinstance(list, blacklist):
raise TypeError("A list of IDs must be passed.")
await self.set_global("blacklist", blacklist)
def get_guild_whitelist(self, guild):
"""Returns the guild's whitelist"""
return self.get(guild, "whitelist", [])
def get_guild_blacklist(self, guild):
"""Returns the guild's blacklist"""
return self.get(guild, "blacklist", [])
async def set_guild_whitelist(self, guild, whitelist):
"""Sets the guild's whitelist"""
if not isinstance(guild, discord.Guild) or not isinstance(whitelist, list):
raise TypeError("A valid Discord guild and a list of IDs "
"must be passed.")
await self.set(guild, "whitelist", whitelist)
async def set_guild_blacklist(self, guild, blacklist):
"""Sets the guild's blacklist"""
if not isinstance(guild, discord.Guild) or not isinstance(blacklist, list):
raise TypeError("A valid Discord guild and a list of IDs "
"must be passed.")
await self.set(guild, "blacklist", blacklist)
def parse_cli_flags(): def parse_cli_flags():
parser = argparse.ArgumentParser(description="Red - Discord Bot") parser = argparse.ArgumentParser(description="Red - Discord Bot")

View File

@ -152,7 +152,7 @@ class JsonGuildDB(JsonDB):
await self.save() await self.save()
return value return value
def get_all(self, guild, default): def get_all(self, guild, default=None):
"""Returns all entries of a guild""" """Returns all entries of a guild"""
if not isinstance(guild, discord.Guild): if not isinstance(guild, discord.Guild):
raise TypeError('Can only get guild data') raise TypeError('Can only get guild data')
@ -182,7 +182,7 @@ class JsonGuildDB(JsonDB):
"""Removes a global value""" """Removes a global value"""
if GLOBAL_KEY not in self._data: if GLOBAL_KEY not in self._data:
self._data[GLOBAL_KEY] = {} self._data[GLOBAL_KEY] = {}
del self._data[key] del self._data[GLOBAL_KEY][key]
await self.save() await self.save()
async def pop_global(self, key, default=None): async def pop_global(self, key, default=None):