Source code for discordRebot.members

from typing import (
    Pattern,
    Tuple,
    Sequence,
    Set,
    Mapping,
    Hashable,
    Union,
    Optional,
)
import discord

__all__ = [
    "Roles",
    "RolesMetaClass",
    "Permissions",
    "PermissionsMetaClass",
    "Members",
    "MembersSet",
]


[docs]class RolesMetaClass(type): """For roles without guild_id. ``Roles[x] <==> Roles(None)[x]`` this is useful for authorize some specific roles irrespective of server Example:: # To authorize Admin roles in all servers # roles = ('Admin',) and guild_id = None Fn.auth = Roles['Admin'] """ def __getitem__(cls, roles: Union[Tuple[Union[str, int]], Union[str, int]]): if type(roles) is not tuple: roles = (roles,) if slice in map(type, roles): raise TypeError("'slice' object is not allowded") return Roles(None, roles)
[docs]class Roles(metaclass=RolesMetaClass): """To group members with their roles in a server. This can't be used to Authorize in DM channel. Example:: server1 = Roles(1234567890) # guild_id of server1 Fn.auth = {server1['Admin','Mod'], Roles[0987654321]} # authorizes: # members with both 'Admin' and 'Mod' roles in server1 # members with role.id 0987654321 """ def __init__( self, guild_id: Optional[int] = None, roles: Optional[Tuple[Union[str, int]]] = None ): self.guild_id = guild_id self.roles = ("@everyone",) if roles is None else roles def __getitem__(self, roles: Union[Tuple[Union[str, int]], Union[str, int]]): if type(roles) is not tuple: roles = (roles,) if slice in map(type, roles): raise TypeError("'slice' object is not allowded") return Roles(self.guild_id, roles) def __repr__(self): return "<Roles guild_id={0} roles={1}>".format(self.guild_id, self.roles) def __str__(self): return str((self.guild_id, *self.roles))
[docs]class PermissionsMetaClass(type): """For permissions without guild_id. ``Permissions[x] <==> Permissions(None)[x]`` this is useful for check some permissions irrespective of server Example:: # To authorize members with Administrator permission in all servers # discord.permissions.Permissions(administrator=True) and guild_id = None Fn.auth = Permissions['administrator'] """ def __getitem__(cls, permissions: Union[Tuple[Union[str, int]], Union[str, int]]): if type(permissions) is not tuple: permissions = (permissions,) if slice in map(type, permissions): raise TypeError("'slice' object is not allowded") kwargs = dict() for key in permissions: if type(key) is int: kwargs["permissions"] = key elif key.startswith("!"): kwargs[key[1:]] = False else: kwargs[key] = True return Permissions(None, **kwargs)
[docs]class Permissions(discord.permissions.Permissions, metaclass=PermissionsMetaClass): """To group members with their permissions in a server. This can't be used to Authorize in DM channel. Example:: server1 = Permissions(1234567890) # guild_id of server1 Fn.auth = {server1['manage_guild', 'manage_roles'], Permissions(0987654321, administrator=True)} # authorizes: # members with both ManageServer and ManageRoles permissions in server1 # members with Administrator permission in server with guild_id 0987654321 """ def __init__(self, guild_id: Optional[int] = None, permissions: int = 0, **kwargs: bool): self.guild_id = guild_id super().__init__(permissions=permissions, **kwargs) def __getitem__(self, permissions: Union[Tuple[Union[str, int]], Union[str, int]]): if type(permissions) is not tuple: permissions = (permissions,) if slice in map(type, permissions): raise TypeError("'slice' object is not allowded") kwargs = dict() for key in permissions: if type(key) is int: kwargs["permissions"] = key elif key.startswith("!"): kwargs[key[1:]] = False else: kwargs[key] = True return Permissions(self.guild_id, **kwargs) def __repr__(self): return "<Permissions guild_id={0} value={1}>".format(self.guild_id, self.value) def __str__(self): return str((self.guild_id, self.value))
MemberIdentity = Union[int, str, Pattern, Roles, Permissions] MemberGroups = Union[Sequence[Set[MemberIdentity]], Mapping[Hashable, Set[MemberIdentity]]]
[docs]class Members: """To group members for authorization Example:: level = Members([{'root#0000','admin#1000'}, {'user1#1001'}]) def privileged_cmd(msg, *args): #code# privileged_cmd.auth = level[0] """ def __init__(self, groups: MemberGroups): """ Args: groups : Sequence or Mapping of Set of MemberIdentity """ self.groups = groups # subscript def __getitem__(self, arg: Hashable): """MemberGroups => MemberGroup """ return MembersSet(self, ("__getitem__", arg)) # Union def __or__(self, arg: Union["Members", "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self, ("__or__", arg)) # Intersection def __and__(self, arg: Union["Members", "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self, ("__and__", arg)) # Difference def __sub__(self, arg: Union["Members", "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self, ("__sub__", arg)) # Symmetric difference def __xor__(self, arg: Union["Members", "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self, ("__xor__", arg)) @property def members(self) -> Set[MemberIdentity]: """To return all the members """ return MembersSet(self).members def __repr__(self): return "MemberGroups(" + repr(self.groups) + ")" def __str__(self): return str(self.groups)
[docs]class MembersSet: """Set of members subscripted from Members. It is alos possible to do set operations. Example:: group = Members({'Admin': {'admin1#0001', 'admin2#0002'}, 'users': {'user1#1001', 1234567890}}) def privileged_cmd(msg, *args): #code# privileged_cmd.auth = group['Admin']|{'root#0000'} def cmd(msg, *args): #code# cmd.auth = group # <==> group['Admin']|group['users'] """ def __init__(self, Groups: Members, *MethodCalls): """ Args: MemberGroups : Members instance for groups MethodCalls : previous method calls """ self.Groups = Groups self.chain = list(MethodCalls) # Union def __or__(self, arg: Union[Members, "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self.Groups, *self.chain, ("__or__", arg)) # Intersection def __and__(self, arg: Union[Members, "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self.Groups, *self.chain, ("__and__", arg)) # Difference def __sub__(self, arg: Union[Members, "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self.Groups, *self.chain, ("__sub__", arg)) # Symmetric difference def __xor__(self, arg: Union[Members, "MembersSet", Set[MemberIdentity]]): if type(arg) is set: arg = set(arg) return MembersSet(self.Groups, *self.chain, ("__xor__", arg)) @property def members(self) -> Set[MemberIdentity]: """members set with all operations done. All the operations done to :obj:`Members` is only executed at the time of ``getattr(MembersObj, "members")`` So, no need to update auth of each callbacks after updating the group. Example:: group = Members([{'root#0000'}]) Admin = group[0]|{'admin1#0001'} print(Admin.members) #{'root#0000', 'admin1#0001'} group.Groups[0] = {'admin2#0002'} print(Admin.members) #{'admin1#0001', 'admin2#0002'} """ if len(self.chain) == 0: membersSet = set() if isinstance(self.Groups.groups, Sequence): for members_ in self.Groups.groups: membersSet |= members_ elif isinstance(self.Groups.groups, Mapping): for members_ in self.Groups.groups.values(): membersSet |= members_ return membersSet method = self.chain[0][0] arg = self.chain[0][1] if method == "__getitem__": membersSet_ = getattr(self.Groups.groups, method)(arg) if type(membersSet_) is not set: # for slicing membersSet = set() for members_ in membersSet_: membersSet |= set(members_) else: membersSet = set(membersSet_) else: membersSet = self.Groups.members if type(arg) is MembersSet or type(arg) is Members: arg = arg.members membersSet = getattr(membersSet, method)(arg) if len(self.chain) == 1: return membersSet for call in self.chain[1:]: method = call[0] arg = call[1] if type(arg) is MembersSet or type(arg) is Members: arg = arg.members membersSet = getattr(membersSet, method)(arg) return membersSet def __repr__(self): return "Members(" + repr(self.members) + ")" def __str__(self): return str(self.members)