def load(self, guild: discord.Guild): """ Load the settings from our settings-file. """ try: with open(SAVEFILE) as fh: as_dict = json.loads(fh.read()) self.prefix = as_dict.get("prefix", "archer ") self.roles_msg = as_dict.get("roles_msg", None) self.roles_channel = as_dict.get("roles_channel", None) if as_dict.get("mod_role", None): self.mod_role = guild.get_role(as_dict["mod_role"]) else: self.mod_role = None self.distraction_probability = as_dict.get( "distraction_probability", 100) self.roles = { emoji: guild.get_role(role) for emoji, role in as_dict.get("roles", {}).items() } except: # it probably just doesn't exist yet pass self.loaded = True
async def list_topics(guild: Guild) -> List[Role]: roles: List[Role] = [] for btp_role in await run_in_thread(db.all, BTPRole): if (role := guild.get_role(btp_role.role_id)) is None: await run_in_thread(db.delete, btp_role) else: roles.append(role)
def get_permissions(self, member: discord.Member or discord.User, guild: discord.Guild): with open('run/config/permissions.yml', 'r') as file: permissions = yaml.safe_load(file) r = requests.get(f'{self.base_url}servers/?discord_id={str(guild.id)}', headers=self.get_headers()) if not r.ok: return False, f'API error: {r.reason}' admin_role, modo_role = None, None if len(r.json()) == 1: data = r.json()[0] admin_role = guild.get_role(data['discord_admin_role_id']) modo_role = guild.get_role(data['discord_modo_role_id']) if member.id in permissions['dev']: return True, 3 if admin_role in member.roles: return True, 2 if modo_role in member.roles: return True, 1 return True, 0
async def assignGuild(self, guild: discord.Guild) -> str: print(f'The guild "{guild}" is being assigned to {self.name}.') print(f'There are {len(self.players)} players in this tournament!\n') self.guild = guild self.guildID = guild.id self.hostGuildName = guild.name self.pairingsChannel = guild.get_channel(self.pairingsChannelID) infoChannel = None if isinstance(self.infoMessageChannelID, int): infoChannel = self.guild.get_channel(self.infoMessageChannelID) if (not infoChannel is None) and isinstance(self.infoMessageID, int): self.infoMessage = await infoChannel.fetch_message( self.infoMessageID) if self.pairingsChannel is None: self.pairingsChannel = discord.utils.get(guild.channels, name="match-pairings") if self.roleID != "": self.role = guild.get_role(self.roleID) for player in self.players: ID = self.players[player].discordID if ID != "": self.players[player].addDiscordUser(self.guild.get_member(ID)) for mtch in self.matches: if mtch.roleID != "": mtch.addMatchRole(guild.get_role(mtch.roleID)) if mtch.VC_ID != "": mtch.addMatchVC(guild.get_channel(mtch.VC_ID))
async def list_topics(guild: Guild) -> List[Role]: roles: List[Role] = [] async for btp_role in await db.stream(select(BTPRole)): if (role := guild.get_role(btp_role.role_id)) is None: await db.delete(btp_role) else: roles.append(role)
async def add_max_warn_mute(self, context: commands.Context, cache: ModerationGlobalData, timer: TimerManager, config: ModerationGuildSettings, guild: discord.Guild, member: discord.Member): if config.mute_enabled: if config.mute_role and (mute_role := guild.get_role( config.mute_role)): await self.add_mute(context, cache, timer, config, guild, member, mute_role, False) if config.warn_max_mode == WARN_MAX_MODE_KEEP: pass await context.send("Max warns hit, mute given.") elif config.warn_max_mode == WARN_MAX_MODE_RESET: timer.rm_timer(TIMER_WARN_UUID.format(guild.id, member.id)) self.warns[member.id].clear() await context.send( "Max warns hit, removing warns and mute given.") else: logger.warning( f"Warn max mode is unhandled value \"{config.warn_max_mode}\", defaulting to keep!" ) await context.send( f"Warn max mode is unhandled value \"{config.warn_max_mode}\", defaulting to keep!" ) await context.send("Max warns hit, mute given.") pass else: logger.debug( "Tried to mute, but mute_role missing or invalid.") await context.send( "Max warns hit, tried to mute but the mute role is either invalid or not specified, " "please configure it.")
async def is_bot_user(self, guild: discord.Guild, command_user: discord.Member) -> bool: """そのサーバーのBOT_user役職を持っているか判定する関数 Args: guild (discord.Guild): サーバーのギルドオブジェクト command_user (discord.Member): コマンド使用者のメンバーオブジェクト Returns: bool: 入ってたらTrue、入ってなかったらFalse Memo: 管理者は使用者の権限も持つことにする """ guild_DB = await self.setting_mng.get_guild(guild.id) if guild_DB is None: return False bot_user_role = guild.get_role(guild_DB.bot_user_id) bot_manager_role = guild.get_role(guild_DB.bot_manager_id) if any([ role in command_user.roles for role in [bot_manager_role, bot_user_role] ]): return True else: return False
async def set_mute_role( self, guild: discord.Guild, role: discord.Role, ) -> tuple: before = None try: before = await self.config.guild(guild).get_raw( self.rule_name, "role_to_add", ) except KeyError: # role not set yet probably pass await self.config.guild(guild).set_raw( self.rule_name, "role_to_add", value=role.id, ) before_role = None if before: before_role = guild.get_role(before) after_role = guild.get_role(await self.config.guild(guild).get_raw( self.rule_name, "role_to_add")) return before_role, after_role
def resolve_as_roles(guild: discord.Guild, user_input: str) -> Sequence[discord.Role]: if match := (_id_regex.match(user_input) or _role_mention_regex.match(user_input)): # We assume that nobody will make a role with a name that is an ID # If someone reports this as a bug, # kindly tell them to change the name of the impacted role. if role := guild.get_role(int(match.group(1))): return (role,)
def __init__(self, guild: discord.Guild, conn: sql.connection, sql_fetcher: SqlFetcher): self.guild = guild self.unassigned_role = guild.get_role(utils.get_id("UNASSIGNED_ROLE")) self.student_role = guild.get_role(utils.get_id("STUDENT_ROLE")) self.welcome_channel = guild.get_channel( utils.get_id("OFF_TOPIC_CHANNEL")) self.conn = conn self.sql_fetcher = sql_fetcher
async def add_roles(guild: Guild, members: t.List[Member]) -> None: """Assign team leader and jammer roles.""" # Assign team leader role await members[0].add_roles(guild.get_role(Roles.team_leaders)) # Assign rest of roles jammer_role = guild.get_role(Roles.jammers) for member in members: await member.add_roles(jammer_role)
def join_role_stats(role_ids: list[int], guild: Guild, name: Optional[str] = None) -> dict[str, int]: """Return a dictionary with the number of `members` of each role given, and the `name` for this joined group.""" members = 0 for role_id in role_ids: if (role := guild.get_role(role_id)) is not None: members += len(role.members) else: raise NonExistentRoleError(role_id)
def get_shop_items(self, guild: discord.Guild): """ Get a dict of shop items. """ # See if there's a specified guild new_data = copy.deepcopy(self.ORIGINAL_SHOP_ITEMS) if guild is None: return new_data guild_settings = self.bot.guild_settings[guild.id] # Update original prices from cache for i, o in new_data.items(): o['amount'] = guild_settings.get(o['price_key'], o['amount']) # Add the buyable roles buyable_roles = guild_settings.setdefault('buyable_roles', dict()) ordered_roles = sorted(buyable_roles.keys()) index = 0 for role_id in ordered_roles: role = guild.get_role(role_id) if role is None: continue new_data[f"{index}\N{COMBINING ENCLOSING KEYCAP}"] = { "emoji": None, "name": "Buyable Role - " + role.name, "amount": buyable_roles[role_id], "description": f"Purchase the {role.mention} role.", "aliases": [], "price_key": None, "quantity": 1, } index += 1 buyable_temporary_roles = guild_settings.setdefault( 'buyable_temporary_roles', dict()) ordered_roles = sorted(buyable_temporary_roles.keys()) for role_id in ordered_roles: role = guild.get_role(role_id) if role is None: continue new_data[f"{index}\N{COMBINING ENCLOSING KEYCAP}"] = { "emoji": None, "name": "Buyable Temporary Role - " + role.name, "amount": buyable_temporary_roles[role_id]['price'], "description": f"Purchase the {role.mention} role for {utils.TimeValue(buyable_temporary_roles[role_id]['duration']).clean}.", "aliases": [], "price_key": None, "quantity": 1, } index += 1 # Return data return new_data
async def set_admin_role_logic( self, guild: discord.Guild, author: discord.Member, new_role_id: Optional[str]) -> discord.Embed: if not author.guild_permissions.administrator: raise commands.MissingPermissions(["administrator" ]) # type: ignore db_guild = await self.bot.guild_cache.get(guild.id) original_role_id = db_guild.management_role original_role = (guild.get_role(original_role_id) if original_role_id is not None else None) if new_role_id is None: await self.bot.guild_cache.update_management_role(guild.id, None) embed = discord.Embed( title="Config updated!", timestamp=datetime.now(timezone.utc), colour=discord.Colour(15653155), ) if original_role is None: embed.description = "Management role has not changed! It remains None" else: embed.description = ( f"Management role updated from {original_role.mention} to None" ) return embed else: if new_role_id[:3] == "<@&": new_role_id = new_role_id[3:-1] if isinstance(new_role_id, str): try: new_role_id = int(new_role_id) # type: ignore except ValueError: raise errors.InputContentIncorrect( "I could not find that role! Please try again") assert isinstance(new_role_id, int) new_role = guild.get_role(new_role_id) if new_role is None: raise errors.InputContentIncorrect( "I could not find that role! Please try again") await self.bot.guild_cache.update_management_role( guild.id, new_role_id) embed = discord.Embed( title="Config updated!", timestamp=datetime.now(timezone.utc), colour=discord.Colour(15653155), ) if original_role is None: embed.description = f"Management role updated to {new_role.mention}" else: embed.description = f"Management role updated from {original_role.mention} to {new_role.mention}" return embed
async def fetch_guild_rules(self, guild: discord.Guild, member: discord.Member): permcog = self.bot.get_cog("Permissions") # Basically a copy and paste of perms._yaml_get_guild, except doesn't save to a yaml file and instead returns JSON data, and tinkers with the data guild_rules = {} for category in ("COG", "COMMAND"): guild_rules.setdefault(category, {}) rules_dict = await permcog.config.custom(category).all() for cmd_name, cmd_rules in rules_dict.items(): model_rules = cmd_rules.get(str(guild.id)) if model_rules is not None: for target, rule in model_rules.items(): if cmd_name not in guild_rules[category]: guild_rules[category][cmd_name] = [] if target != "default": if rule is None: continue target = int(target) obj = None name = "" objtype = "" if (obj := guild.get_channel(target)): objtype = "Channel" name = obj.name elif (obj := guild.get_role(target)): objtype = "Role" name = obj.name elif (obj := guild.get_member(target)): objtype = "User" name = f"{obj.display_name}#{obj.discriminator}" else: continue saving = { "type": objtype, "name": name, "id": str(target), "permission": "allowed" if rule else "denied", } else: if rule is None: continue saving = { "type": "Default", "permission": "allowed" if rule else "denied", } guild_rules[category][cmd_name].append(saving)
async def activeFunction(send, guild: discord.Guild): error_code = '' conn = psycopg2.connect(**conn_parse) cursor = conn.cursor() try: cursor.execute( f"SELECT msg, emoji, role, type='ind' FROM ind WHERE guild={guild.id}" ) for row in cursor.fetchall(): #print( [ str( x ) for x in guild.emojis ] ) print(row) try: emoji = list(filter(lambda x: str(x) == row[1], guild.emojis))[0] except IndexError: emoji = DefaultEmoji(row[1]) if (role := guild.get_role(row[2])) is None: error_code += '\n' + str(row) + ' => this role is unavailable' continue if isinstance(emoji, DefaultEmoji) and '<' in str(emoji): error_code += '\n' + str(row) + ' => this emoji is unavailable' print(f"{str(emoji) =} , {type(emoji) =}") continue if guild.id not in list(reactSetInd.keys()): reactSetInd[guild.id] = { row[0]: { row[1]: (emoji, role, row[3] == 1) } } elif row[0] not in list(reactSetInd[guild.id].keys()): reactSetInd[guild.id][row[0]] = { row[1]: (emoji, role, row[3] == 1) } else: reactSetInd[guild.id][row[0]][row[1]] = (emoji, role, row[3] == 1) await send( f"loaded ! {('below sq was broke and not be loaded' + error_code ) if error_code != '' else ''}" ) conn.close() print(reactSetInd) except TypeError: print( f"SELECT msg, emoji, role, type='ind' FROM ind WHERE guild={guild.id}" )
def has_any_role(guild: discord.Guild, given_roles: Iterable, member: discord.Member) -> bool: for role in given_roles: for user_role in member.roles: if guild.get_role(role) == user_role: return True return False
def _rbr_message_content(guild: Guild, guild_data: GuildData) -> Embed: title = guild_data.title combinations = guild_data.combinations if combinations: content = "" for combination in combinations: emoji = combination.emoji try: emoji = ImprovedList(guild.emojis).get_item( emoji, key=lambda e: e.id ) except ValueError: pass role = guild.get_role(combination.role) if not role: # Role does not exist case continue content += f"{emoji} - {role.name}" + "\n" else: content = "No combination registered yet" return Embed( title=title, description=content )
def add_proposal(message: discord.Message, guild: discord.Guild) -> None: """Aggiunge la proposta al file proposals.json salvando timestamp e numero di membri attivi in quel momento. :param message: messaggio mandato nel canale proposte da aggiungere :param guild: il server discord """ proposals: Dict[str, Dict[str, Any]] = {} try: with open('proposals.json', 'r') as file: proposals = json.load(file) except FileNotFoundError: print('file non trovato, lo creo ora') with open('proposals.json', 'w+') as file: proposals = {} active_count = 2 # moderatori non hanno ruolo attivo members = guild.members active_role = guild.get_role(Config.get_config().active_role_id) for member in members: if not member.bot: if active_role in member.roles: active_count += 1 proposal = { 'timestamp': datetime.date(message.created_at).__str__(), 'total_voters': active_count, 'threshold': calculate_threshold(active_count), 'passed': False, 'yes': 0, 'no': 0, 'content': message.content } # save as string for coherency with the loading proposals[str(message.id)] = proposal shared_functions.update_json_file(proposals, 'proposals.json')
async def make_binding_message(bind_data: dict, guild: discord.Guild, group_id: str, description: bool): """ :param bind_data: :type bind_data: :param guild: :type guild: :param group_id: :type group_id: :param description: :type description: :return: :rtype: """ emote_block_lines = [] for icon_key in bind_data.keys(): role = guild.get_role(bind_data.get(icon_key)) binding_line = f'{icon_key} - {role.name}' emote_block_lines.append(binding_line) emote_block = ' '.join(emote_block_lines) toggler_description = 'Press the emote icon under this message corresponding to the role that you want to toggle.' guild_icon = str(guild.icon_url) if guild.icon_url else discord.Embed.Empty toggler = discord.Embed(color=await get_image_colors(guild_icon)) toggler.set_author(name=f'Group {group_id} Emote Role Toggles', icon_url=guild_icon) if description: toggler.description = toggler_description toggler.add_field(name='Emote Legend', value=emote_block) return toggler
def get_staff_channel_count(self, guild: Guild) -> int: """ Get the number of channels that are staff-only. We need to know two things about a channel: - Does the @everyone role have explicit read deny permissions? - Do staff roles have explicit read allow permissions? If the answer to both of these questions is yes, it's a staff channel. """ channel_ids = set() for channel in guild.channels: if channel.type is ChannelType.category: continue everyone_can_read = self.role_can_read(channel, guild.default_role) for role in constants.STAFF_ROLES: role_can_read = self.role_can_read(channel, guild.get_role(role)) if role_can_read and not everyone_can_read: channel_ids.add(channel.id) break return len(channel_ids)
async def bot_welcome(self, member: discord.Member, guild: discord.Guild): bot_welcome = await self.config.guild(guild).BOTS_MSG() bot_role = await self.config.guild(guild).BOTS_ROLE() msg = bot_welcome or rand_choice(await self.config.guild(guild).GREETING()) channel = await self.get_welcome_channel(member, guild) is_embed = await self.config.guild(guild).EMBED() if bot_role: try: role = cast(discord.abc.Snowflake, guild.get_role(bot_role)) await member.add_roles(role, reason=_("Automatic Bot Role")) except Exception: log.error( _("welcome.py: unable to add a role. ") + f"{bot_role} {member}", exc_info=True, ) else: log.debug( _("welcome.py: added ") + str(role) + _(" role to ") + _("bot, ") + str(member) ) if bot_welcome: # finally, welcome them if not channel: return if is_embed and channel.permissions_for(guild.me).embed_links: em = await self.make_embed(member, guild, msg, False) if await self.config.guild(guild).EMBED_DATA.mention(): await channel.send(member.mention, embed=em) else: await channel.send(embed=em) else: await channel.send( filter_mass_mentions( await self.convert_parms(member, guild, bot_welcome, False) ) )
def _find_role(guild: discord.Guild, argument: str) -> Optional[discord.Role]: match = _ID_RE.match(argument) or _ROLE_MENTION_RE.match(argument) if match: result = guild.get_role(int(match.group(1))) else: result = discord.utils.get(guild.roles, name=argument) return result
async def bump_message(self, guild: discord.Guild): data = await self.config.guild(guild).all() channel = guild.get_channel(data["channel"]) allowed_mentions = discord.AllowedMentions(roles=True) if not channel or not channel.permissions_for(guild.me).send_messages: await self.config.guild(guild).channel.clear() elif data["role"]: role = guild.get_role(data["role"]) if role: message = f"{role.mention}: {data['message']}" cog = self.bot.get_cog("ForceMention") if cog: await cog.forcemention(channel, role, message) else: await channel.send(message, allowed_mentions=allowed_mentions) else: await self.config.guild(guild).role.clear() elif channel: message = data["message"] try: await channel.send(message, allowed_mentions=allowed_mentions) except discord.errors.Forbidden: await self.config.guild(guild).channel.clear() else: await self.config.guild(guild).channel.clear() await self.config.guild(guild).nextBump.clear()
async def get_guild_role(guild: discord.Guild, role_identifier: str) -> Optional[discord.Role]: """ Get guild's role by its name or id. Parameters ---------------- guild: :class:`discord.Guild` Guild where to search the role from. role_identifier: :class:`str` Either role name or id. Returns ------- Optional[:class:`discord.Role`] Role if one is found, otherwise `None`. """ match = id_match(role_identifier, r"<@&([0-9]+)>$") if match: role = guild.get_role(int(match.group(1))) else: role = discord.utils.find(lambda rl: rl.name == role_identifier, guild.roles) return role
def clean_string(self, string: str, guild: discord.Guild) -> str: if guild is None: return string else: parts = [''] for char in string: if char in '<>': parts.append(char) else: parts[-1] += char new = [] for piece in parts: new_piece = piece if len(piece) > 3 and piece[1] == '@' and all(x in '0123456789' for x in piece[3:]): if piece[2] in '0123456789!': uid = int(''.join(x for x in piece if x in '0123456789')) user = guild.get_member(uid) new_piece = '`@{}`'.format(user) elif piece[2] == '&': rid = int(''.join(x for x in piece if x in '0123456789')) role = guild.get_role(rid) new_piece = '`@@{}`'.format(role) new.append(new_piece) return ''.join(new)
async def _make_reactions_state( guild: Guild, guild_data: GuildData, reactions: List[Reaction] ) -> Dict[Member, Set[Role]]: combinations = guild_data.combinations # Dict[Role, Set[Member]] state_by_role = dict() for reaction in reactions: emoji = reaction.emoji try: combination = ImprovedList(combinations).get_item( v=emoji.id if hasattr(emoji, "id") else str(emoji), key=lambda c: c.emoji ) except ValueError: # emoji not registered in combinations list continue else: role = guild.get_role(combination.role) if role: # role might have been deleted, so excluding None case # Set[Member] members = set() async for user in reaction.users(): # excluding non-Members and self-reaction cases if isinstance(user, Member) and user != guild.me: members.add(user) state_by_role[role] = members return revert_dict(state_by_role)
async def set_language_channel_permissions(self, guild: discord.Guild, room_id: int, vc): """ Sets channel permissions when given the room_id and the voice channel :param guild: Discord server instance. :param room_id: ID of the language room. :param vc: Voice Channel to be modified. """ channel_permission = await self.get_language_channel_permission( room_id, object_form=True) await vc.edit(sync_permissions=True) await vc.edit(sync_permissions=False) for permission in channel_permission: m_perm_name = permission.permission_name m_room_id = permission.room_id m_perm_value = permission.permission_value m_role_id = permission.role_id m_member = guild.get_role(m_role_id) if m_perm_name == "speaker": asyncio.create_task(vc.set_permissions(target=m_member, view_channel=True, connect=True, speak=True), name=f"set_{m_room_id}_permission") else: asyncio.create_task( vc.set_permissions(**{ "target": m_member, m_perm_name: m_perm_value }))
async def add_invite_roles(self, guild: discord.Guild, member: discord.Member): invite_roles = await self.config.guild(guild).roles() member_roles = member.roles invites = await self.config.member(member).invites() for r, amount in invite_roles.items(): role = guild.get_role(int(r)) if not role: all_invite_roles = await self.config.guild(guild).roles() all_invite_roles.pop(r) await self.config.guild(guild).roles.set(all_invite_roles) continue if amount > invites: if role in member.roles: try: await member.remove_roles(role) except discord.errors.Forbidden: continue else: if role not in member.roles: try: await member.add_roles(role) except discord.errors.Forbidden: pass
async def bump_remind(self, guild: discord.Guild): guild = self.bot.get_guild(guild.id) if not guild: return data = await self.config.guild(guild).all() channel = guild.get_channel(data["channel"]) if not channel: await self.config.guild(guild).channel.clear() return my_perms = channel.permissions_for(guild.me) if not my_perms.send_messages: await self.config.guild(guild).channel.clear() return if data["lock"] and my_perms.manage_roles: await self.autolock_channel(guild, channel, my_perms, lock=False) message = data["message"] allowed_mentions = self.bot.allowed_mentions if data["role"]: role = guild.get_role(data["role"]) if role: message = f"{role.mention}: {message}" allowed_mentions = discord.AllowedMentions(roles=[role]) kwargs = self.process_tagscript(message) try: await channel.send(allowed_mentions=allowed_mentions, **kwargs) except discord.Forbidden: await self.config.guild(guild).channel.clear() await self.config.guild(guild).nextBump.clear()