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

View File

@ -5,3 +5,67 @@ def is_owner(**kwargs):
async def check(ctx):
return await ctx.bot.is_owner(ctx.author, **kwargs)
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
# Do we even need a Settings class this time? To be decided
class Settings:
def __init__(self):
args = {}
self.coowners = []
class CoreDB(JsonGuildDB):
"""
The central DB used by Red to store a variety
of settings, both global and guild specific
"""
def can_login(self):
"""Used on start to determine if Red is setup enough to login"""
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():
parser = argparse.ArgumentParser(description="Red - Discord Bot")

View File

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