async def defconchan(self, ctx, channel: discord.Channel = None): """Constrain defcon alerts to a specific channel. Omit the channel argument to clear the setting.""" me = ctx.message.server.me author = ctx.message.author server = ctx.message.server if channel is None: self.settings.setdefault(server.id, {}).update(channel=None) dataIO.save_json(self.settings_path, self.settings) await self.bot.say("DEFCON channel setting cleared.") return if channel.type != discord.ChannelType.text: await self.bot.say("Channel must be a text channel") return elif not channel.permissions_for(author).send_messages: await self.bot.say( "You're not allowed to send messages in that channel.") return elif not channel.permissions_for(me).send_messages: await self.bot.say( "I'm not allowed to send messaages in that channel.") return self.settings.setdefault(server.id, {}).update(channel=channel.id) dataIO.save_json(self.settings_path, self.settings) await self.bot.say("Defcon channel set to **{}**.".format(channel.name) )
async def embedwiz_channel(self, ctx, channel: discord.Channel, *, specification): """ Posts an embed in another channel according to the spec. See [p]help embedwiz for more information. """ member = channel.server and channel.server.get_member( ctx.message.author.id) override = self._check_override(member) if channel != ctx.message.channel and not member: await self.bot.say( error( "Channel is private or you aren't in the server that channel belongs to." )) return elif not channel.permissions_for(member).send_messages: msg = error("You don't have permissions to post there!") await self.bot.say(msg) return embed = await self._parse_embed(ctx, specification, force_author=not override) if embed: await self.bot.send_message(channel, embed=embed) if channel != ctx.message.channel: await self.bot.say("Embed sent to %s." % channel.mention)
async def set_log_channel(self, ctx, channel: discord.Channel=None): """Set's log channel for warn / mute / kick / ban commands Parameters: channel: The channel you want to set for the logs. Leaving this blank will remove the channel for logs.abs Example: [p]set_log_channel #logs-channel [p]set_log_channel""" bot = discord.utils.find(lambda m: m.id == self.bot.user.id, \ ctx.message.server.members) if bot: if channel: permissions = channel.permissions_for(bot) if permissions.send_messages: if ctx.message.server.id in self.servers_config["servers"]: self.servers_config["servers"][ctx.message.server.id]["log channel"] = channel #pylint: disable=line-too-long else: self.servers_config["servers"][ctx.message.server.id] = {"log channel": channel} #pylint: disable=line-too-long self.save_servers_config() await self.bot.say("Done. :ok_hand:") else: await self.bot.say("I'm not allowed to send messages there.\n" + \ "(Missing permissions)") else: if ctx.message.server.id in self.servers_config["servers"]: del self.servers_config["servers"][ctx.message.server.id]["log channel"] self.save_servers_config() await self.bot.say("Done! :ok_hand:")
def check_add_remove_roles(member: discord.Member, channel: discord.Channel) -> bool: """This method returns true if the currently logged in client can remove and add roles from the passed member in the passed channel.""" return channel.permissions_for( channel.server.me ).manage_roles and member.top_role.position < member.server.me.top_role.position
async def perms(self, ctx, user: discord.Member = None, channel: discord.Channel = None): """Fetch a specific user's permissions.""" if user is None: user = ctx.message.author if channel is None: channel = ctx.message.channel perms = iter(channel.permissions_for(user)) perms_we_have = "```diff\n" perms_we_dont = "" for x in perms: if "True" in str(x): perms_we_have += "+ {0}\n".format(str(x).split("'")[1]) else: perms_we_dont += "- {0}\n".format(str(x).split("'")[1]) try: embed = discord.Embed(title="_ _", description="{0}{1}```".format( perms_we_have, perms_we_dont), color=0xfac905) await self.bot.say("{0}{1}```".format(perms_we_have, perms_we_dont)) except Exception as e: await self.bot.whisper( f"The bot was prevented from sending in the channel because: `{e}`. " f"if `send_messages` is red, this is why. " f"please contact an admin to give me that perm. Let them also know that the bot does" f"not have it's minimum perms, which is bannable from TOS.")
async def _roles_add(self, ctx, message_id, channel: discord.Channel, emoji, *, role: discord.Role): """Add a role on a message `message_id` must be found in `channel` `emoji` can either be a Unicode emoji or a server emote `role` must be found in the channel's server""" server = channel.server message = await self.safe_get_message(channel, message_id) if message is None: response = self.MESSAGE_NOT_FOUND else: msg_conf = self.get_message_config(server.id, channel.id, message.id) emoji_match = self.EMOTE_REGEX.fullmatch(emoji) emoji_id = emoji if emoji_match is None else emoji_match.group(1) if emoji_id in msg_conf: response = self.ALREADY_BOUND elif server is None: response = self.NOT_IN_SERVER else: if role.server != channel.server: response = self.ROLE_NOT_FOUND elif channel.server.me.server_permissions.manage_roles is False: response = self.CANT_MANAGE_ROLES elif channel.permissions_for( channel.server.me).add_reactions is False: response = self.CANT_ADD_REACTIONS else: emoji = None for emoji_server in self.bot.servers: if emoji is None: emoji = discord.utils.get(emoji_server.emojis, id=emoji_id) try: await self.bot.add_reaction(message, emoji or emoji_id) except discord.HTTPException: # Failed to find the emoji response = self.EMOJI_NOT_FOUND else: try: await self.bot.add_roles(ctx.message.author, role) await self.bot.remove_roles( ctx.message.author, role) except (discord.Forbidden, discord.HTTPException): response = self.CANT_GIVE_ROLE await self.bot.remove_reaction( message, emoji or emoji_id, self.bot.user) else: self.add_to_cache(server.id, channel.id, message_id, emoji_id, role) msg_conf[emoji_id] = role.id self.save_data() response = self.ROLE_SUCCESSFULLY_BOUND.format( str(emoji or emoji_id), channel.mention) if self.bot.get_cog("ClientModification") is None: response += self.NO_CLIENT_MODIFICATION else: self.add_cache_message(message) await self.bot.send_message(ctx.message.channel, response)
async def chatchart(self, ctx, channel: discord.Channel = None): """ Generates a pie chart, representing the last 5000 messages in the specified channel. """ e = discord.Embed(description="Loading...", colour=0x00ccff) e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif") em = await self.bot.say(embed=e) if channel is None: channel = ctx.message.channel history = [] if not channel.permissions_for( ctx.message.author).read_messages == True: await self.bot.delete_message(em) return await self.bot.say( "You're not allowed to access that channel.") try: async for msg in self.bot.logs_from(channel, 5000): history.append(msg) except discord.errors.Forbidden: await self.bot.delete_message(em) return await self.bot.say("No permissions to read that channel.") msg_data = {'total count': 0, 'users': {}} for msg in history: if len(msg.author.name) >= 20: short_name = '{}...'.format(msg.author.name[:20]).replace( "$", "\$") else: short_name = msg.author.name.replace("$", "\$") whole_name = '{}#{}'.format(short_name, msg.author.discriminator) if msg.author.bot: pass elif whole_name in msg_data['users']: msg_data['users'][whole_name]['msgcount'] += 1 msg_data['total count'] += 1 else: msg_data['users'][whole_name] = {} msg_data['users'][whole_name]['msgcount'] = 1 msg_data['total count'] += 1 for usr in msg_data['users']: pd = float(msg_data['users'][usr]['msgcount']) / float( msg_data['total count']) msg_data['users'][usr]['percent'] = round(pd * 100, 1) top_ten = heapq.nlargest( 20, [(x, msg_data['users'][x][y]) for x in msg_data['users'] for y in msg_data['users'][x] if y == 'percent'], key=lambda x: x[1]) others = 100 - sum(x[1] for x in top_ten) img = self.create_chart(top_ten, others, channel) await self.bot.delete_message(em) await self.bot.send_file(ctx.message.channel, img, filename="chart.png")
def has_channel(self, member: discord.Member, channel: discord.Channel) -> bool: if not self.admin_module and self.global_module: return True if channel.permissions_for(member).administrator: if self.admin_module: return True return channel in self.channels
async def _embed_reactor(self, ctx: Context, channel: discord.Channel, *reactions): """Sets the reactions added to embeds in a channel If no reaction is given, resets the reactions for the channel reactions is a list of space-separated emojis (server or unicode) Custom server emojis must be visible to the bot Example to set 👍 👎 as reactions: [p]embed_reactor #my-channel 👍 👎 Example to remove the reactions: [p]embed_reactor #my-channel""" message = ctx.message invalid_emotes = [] if len(reactions) <= self.REACTION_CAP: for emote in reactions: if await self.is_valid_emote(emote, message) is False: invalid_emotes.append(emote) if len(reactions) > self.REACTION_CAP: response = self.TOO_MANY_REACTIONS elif len(reactions) == 0: self.config.pop(channel.id, None) self.save_data() self.preprocessed_config.pop(channel.id, None) response = self.REMOVED_CHANNEL_REACTOR.format(channel.mention) elif channel.server is None: response = self.MUST_BE_SERVER_CHANNEL elif not channel.permissions_for(channel.server.me).add_reactions: response = self.LACKING_PERMISSIONS elif len(invalid_emotes) > 0: if message.channel.server is not None and not channel.permissions_for( channel.server.me).add_reactions: response = self.LACKING_PERMISSIONS_TO_TEST else: response = self.INVALID_EMOTES.format( ", ".join(invalid_emotes)) else: self.config[channel.id] = reactions self.save_data() self.preprocessed_config[channel.id] = [ self.find_emote(emote) or emote for emote in reactions ] response = self.SET_CHANNEL_REACTOR.format(channel.mention, ", ".join(reactions)) await self.bot.send_message(message.channel, response)
def get_commands(self, member: discord.Member, channel: discord.Channel): result = [] for command in self.commands.values(): admin_required = self.admin_module or command.admin_required if not admin_required or channel.permissions_for( member).administrator: result.append(command) return result
async def planifie(channel_obj: discord.Channel = None): now = int(time.time()) thisDay = now - (now % 86400) seconds_left = 86400 - (now - thisDay) multiplicator = round(seconds_left / 86400, 5) if not channel_obj: logger.debug("Replanning") commons.bread = defaultdict(int) planification_ = {} if multiplicator == 0: multiplicator = 1 servers = prefs.JSONloadFromDisk("channels.json") for server_ in list(servers.keys()): server = bot.get_server(str(server_)) if not server: logger.debug("Non-existant server: " + str(server_)) servers.pop(server_) scores.delServerPlayers(sid=server_) elif not "channels" in servers[server.id]: await comm.logwithinfos(server.default_channel, log_str="Server not configured: " + server.id) try: await bot.send_message(server, "The bot is not configured properly, please check the config or contact Eyesofcreeper#4758 | https://discord.gg/2BksEkV") await comm.logwithinfos(server.default_channel, log_str="Unconfigured message sent...") except: await comm.logwithinfos(server.default_channel, log_str="Error sending the unconfigured message to the default channel on the server.") else: for channel_ in servers[server.id]["channels"]: channel = server.get_channel(str(channel_)) if channel: permissions = channel.permissions_for(server.me) if permissions.read_messages and permissions.send_messages: # logger.debug("Adding channel: {id} ({ducks_per_day} c/j)".format(**{ # "id" : channel.id, # "ducks_per_day": prefs.getPref(server, "ducks_per_day") # })) planification_[channel] = round(prefs.getPref(server, "ducks_per_day") * multiplicator) else: await comm.logwithinfos(channel, log_str="Error adding channel to planification: no read/write permissions!") else: pass commons.ducks_planned = planification_ # {"channel":[time objects]} prefs.JSONsaveToDisk(servers, "channels.json") else: commons.bread[channel_obj] = 0 permissions = channel_obj.permissions_for(channel_obj.server.me) if permissions.read_messages and permissions.send_messages: pass else: await comm.logwithinfos(channel_obj, log_str="Error adding channel to planification: no read/write permissions!") commons.ducks_planned[channel_obj] = round(prefs.getPref(channel_obj.server, "ducks_per_day") * multiplicator)
async def embed_channel(self, ctx, channel: discord.Channel, *, specification): """Posts an embed in another channel according to the spec. See [p]help embedwiz for more information. """ if not channel.permissions_for(ctx.message.author).send_messages: msg = error("You don't have permissions to post there!") await self.bot.say(msg) return embed = await self._parse_embed(ctx, specification) if embed: await self.bot.send_message(channel, embed=embed)
async def chan_perms(self, ctx, member: discord.Member, channel: discord.Channel = None): """Check user's permission for current or provided channel""" # From Dusty-Cogs for Red-DiscordBot: https://github.com/Lunar-Dust/Dusty-Cogs perms_names = { "add_reactions": "Add Reactions", "attach_files": "Attach Files", "change_nickname": "Change Nickname", "create_instant_invite": "Create Instant Invite", "embed_links": "Embed Links", "external_emojis": "Use External Emojis", "read_message_history": "Read Message History", "read_messages": "Read Messages", "send_messages": "Send Messages", "administrator": "Administrator", "ban_members": "Ban Members", "connect": "Connect", "deafen_members": "Deafen Members", "kick_members": "Kick Members", "manage_channels": "Manage Channels", "manage_emojis": "Manage Emojis", "manage_messages": "Manage Messages", "manage_nicknames": "Manage Nicknames", "manage_roles": "Manage Roles", "manage_server": "Manage Server", "manage_webhooks": "Manage Webhooks", "mention_everyone": "Mention Everyone", "move_members": "Move Members", "mute_members": "Mute Mebmers", "send_tts_messages": "Send TTS Messages", "speak": "Speak", "use_voice_activation": "Use Voice Activity", "view_audit_logs": "View Audit Log" } if channel is None: channel = ctx.message.channel perms = iter(channel.permissions_for(member)) has_perms = " ```diff\n" no_perms = "" for x in perms: if "True" in str(x): pattern = re.compile('|'.join(perms_names.keys())) result = pattern.sub(lambda y: perms_names[y.group()], "+\t{0}\n".format(str(x).split('\'')[1])) has_perms += result else: pattern = re.compile('|'.join(perms_names.keys())) result = pattern.sub(lambda y: perms_names[y.group()], ("-\t{0}\n".format(str(x).split('\'')[1]))) no_perms += result await self.bot.say(chat.inline(str(member.server_permissions.value)) + "{0}{1}```".format(has_perms, no_perms))
async def _leave_channel(self, ctx, hidden_channel: discord.Channel): """ 退室を行います。 隠れチャンネル#devを退室する例「!ch leave dev」 DMから利用不可。 """ message = ctx.message member = message.author permission = hidden_channel.permissions_for(member) visible = permission.read_messages overwrite = hidden_channel.overwrites_for(member) if visible and not overwrite.is_empty(): await self.bot.delete_channel_permissions(hidden_channel, member) await self.bot.say("{0.name}を退室しました。".format(hidden_channel), delete_after=10) else: raise commands.BadArgument
async def slowmode(self, ctx, channel: discord.Channel=None, time: int=None, messages: int=None, max_time: int=None): """Sends the current slowmode of a channel. Default: Current channel If `time` is specified, changes the slowmode time to the given one. If `messages` is specified, changes the slowmode messages to the given one. If `max_time` is specified, changes the slowmode maximum muted time to the given one. Sets the slowmode for a `channel` to `time` seconds, `messages` messages, and `max_time` seconds maximum. If the `time` is 0, `messages` is 0, and `max_time` is 0, it disables the slowmode in that channel.""" if channel is None: channel = ctx.message.channel if time is None and messages is None and max_time is None: # Show current slowmode slowmode = self.get_channel_slowmode(channel) if slowmode["time"] == 0 and slowmode["messages"] == 0 and slowmode["max_time"] == 0: await self.bot.say("**There is no slowmode in {}.**".format(channel.mention)) else: await self.bot.say(self.get_slowmode_msg(channel, slowmode)) else: # Update current slowmode new_slowmode = copy.deepcopy(self.DEFAULT_SLOWMODE) if time is not None: new_slowmode["time"] = time if messages is not None: new_slowmode["messages"] = messages if max_time is not None: new_slowmode["max_time"] = max_time if new_slowmode["time"] == 0 and new_slowmode["messages"] == 0 and new_slowmode["max_time"] == 0: del self.slowmodes[channel.id]["unstoppable_roles"] del self.slowmodes[channel.id]["overwrites"] del self.slowmodes[channel.id] await self.bot.say(":put_litter_in_its_place: Slowmode in {} deleted.".format(channel.mention)) else: if channel.id not in self.slowmodes: # Gather the overwrites member_overwrites = list(filter(lambda o: isinstance(o[0], discord.Member), channel.overwrites)) new_slowmode["overwrites"].update(map(lambda o: (o[0].id, o[1].send_messages), member_overwrites)) else: new_slowmode["overwrites"] = copy.deepcopy(self.slowmodes[channel.id]["overwrites"]) new_slowmode["unstoppable_roles"] = self.slowmodes[channel.id].get("unstoppable_roles", []) self.slowmodes[channel.id] = new_slowmode can_manage = channel.permissions_for(channel.server.me).manage_roles response = ":white_check_mark: Slowmode updated.\n" + self.get_slowmode_msg(channel, new_slowmode) await self.bot.say(response + ("" if can_manage else self.MISSING_MANAGE_PERMISSIONS)) self.save_data()
async def _slowmode_enable(self, ctx, *channel: discord.Channel): """Adds channels to the servers slowmode list.""" server = ctx.message.server serverchannels = [x.id for x in server.channels] channels = [r for r in channel if str(r.id) in serverchannels] schannels = self.settings[server.id].get("slowmode_channels", []) schannels = [ discord.utils.get(server.channels, id=sc) for sc in schannels ] schannels = [sc.id for sc in schannels if sc is not None] ctmp = {"worked": [], "present": [], "noperm": []} msg = "\n**Slowmode notices:**\n" #for schannels in serverchannels: # ctmp["listed"].append(schannels) for channel in channels: if channel.id in schannels: ctmp["present"].append(channel.name) elif channel.permissions_for(server.me).manage_messages == True: self.settings[server.id]["slowmode_channels"].append( channel.id) ctmp["worked"].append(channel.name) else: ctmp["noperm"].append(channel.name) self.save() if ctmp["worked"]: msg += "\n:white_check_mark: The following channel(s) are now in slowmode:\n\n```diff\n+ " + "\n+ ".join( ctmp["worked"]) + "```" if ctmp["present"]: msg += "\n:eight_spoked_asterisk: The following channel(s) are already in slowmode:\n\n```diff\n+ " + "\n+ ".join( ctmp["present"]) + "```" if ctmp["noperm"]: msg += "\n:anger:I do not have the perms to add the following channel(s) you gave me! These are not in slowmode!:anger:\n\n```diff\n- " + "\n- ".join( ctmp["noperm"]) + "```" await self.bot.say(msg)
async def addchan(self, ctx, *, channel: discord.Channel = None): """adds a channel to the rssrelay's channel list defaults to the current channel, can optionally be given a channel Will not announce to Direct Message""" if channel is None: channel = ctx.message.channel if channel.is_private: return await self.bot.say( "Ignoring Request: Invalid place to send announcements") server = channel.server member = server.get_member(ctx.message.author.id) if member is None: return await self.bot.say( "Ignoring request: You don't have permission to make " "announcements for this server (requires manage server)") if not member.server_permissions.manage_server: return await self.bot.say( "Ignoring request: You don't have permission to make " "announcements for this server (requires manage server)") if channel.permissions_for(server.me).send_messages is False: await self.bot.say("Warning: I cannot speak in that channel I " "will add it to the list, but announcements" " will not be sent if this is not fixed") if server.id not in self.settings: self.settings[server.id] = {'channel': channel.id} else: self.settings[server.id]['channel'] = channel.id self.save_settings() await self.bot.say( "Announcement channel for the associated server has been set")
async def embedwiz_channel(self, ctx, channel: discord.Channel, *, specification): """ Posts an embed in another channel according to the spec. See [p]help embedwiz for more information. """ member = channel.server and channel.server.get_member(ctx.message.author.id) override = self._check_override(member) if channel != ctx.message.channel and not member: await self.bot.say(error("Channel is private or you aren't in the server that channel belongs to.")) return elif not channel.permissions_for(member).send_messages: msg = error("You don't have permissions to post there!") await self.bot.say(msg) return embed = await self._parse_embed(ctx, specification, force_author=not override) if embed: await self.bot.send_message(channel, embed=embed) if channel != ctx.message.channel: await self.bot.say("Embed sent to %s." % channel.mention)
async def _join_channel(self, ctx, hidden_channel: discord.Channel): """ 入室を行います。 隠れチャンネル#devへ入室する例「!ch join dev」 DMから利用不可。 """ message = ctx.message member = message.author my_permission = hidden_channel.permissions_for(member) my_overwrite = hidden_channel.overwrites_for(member) visible = my_permission.read_messages if not visible and my_overwrite.is_empty(): # 隠れch("everyoneのみ"不可視指定) -> overwriteで可視化 if all([r.is_everyone for r in hidden_channel.changed_roles]): await self.bot.edit_channel_permissions( hidden_channel, member, VISIBLE_OVERWRITE) await self.bot.say("{0.name}に入室しました。".format(hidden_channel), delete_after=10) return # 役職限定ch(everyone不可視、特定の役職可視) -> 不正入力扱い else: raise commands.BadArgument #隠れチャンネルではない又は入室済み await self.bot.say("このチャンネルには入室済みです。", delete_after=10)
async def slowmode(self, ctx, channel: discord.Channel = None, time: int = None, messages: int = None, max_time: int = None): """Sends the current slowmode of a channel. Default: Current channel If `time`, `messages`, and `max_time` aren't given, displays the current slowmode of the channel If any of those is given, modifies the current slowmode of the channel. If they're all zeroes (0), removes the slowmode from the channel. `time` is a minimum amount of time the user should be muted for after sending a message `messages` is a minimum amount of messages in between the user's messages `max_time` is a maximum amount of time the user should be muted for For a concrete example on what those parameters mean, use the `[p]slowmode example` command.""" if channel is None: channel = ctx.message.channel if time is None and messages is None and max_time is None: # Show current slowmode slowmode = self.get_channel_slowmode(channel) if slowmode["time"] == 0 and slowmode[ "messages"] == 0 and slowmode["max_time"] == 0: await self.bot.say("**There is no slowmode in {}.**".format( channel.mention)) else: await self.bot.say(self.get_slowmode_msg(channel, slowmode)) elif (time is not None and time > sys.maxsize) or \ (messages is not None and messages > sys.maxsize) or \ (max_time is not None and max_time > sys.maxsize): await self.bot.say(self.TIME_TOO_BIG) elif time is not None and max_time is not None and max_time > 0 and time > max_time: await self.bot.say(self.TIME_BIGGER_THAN_MAX_TIME) else: # Update current slowmode new_slowmode = copy.deepcopy(self.DEFAULT_SLOWMODE) if time is not None: new_slowmode["time"] = time if messages is not None: new_slowmode["messages"] = messages if max_time is not None: new_slowmode["max_time"] = max_time if new_slowmode["time"] == 0 and new_slowmode[ "messages"] == 0 and new_slowmode["max_time"] == 0: del self.slowmodes[channel.id]["unstoppable_roles"] del self.slowmodes[channel.id]["overwrites"] del self.slowmodes[channel.id] await self.bot.say( ":put_litter_in_its_place: Slowmode in {} deleted.".format( channel.mention)) else: if channel.id not in self.slowmodes: # Gather the overwrites member_overwrites = ((o[0].id, o[1].send_messages) for o in channel.overwrites if isinstance(o[0], discord.Member) and o[1].send_messages is not False) new_slowmode["overwrites"].update(member_overwrites) else: new_slowmode["overwrites"] = copy.deepcopy( self.slowmodes[channel.id]["overwrites"]) new_slowmode["unstoppable_roles"] = self.slowmodes[ channel.id].get("unstoppable_roles", []) self.slowmodes[channel.id] = new_slowmode can_manage = channel.permissions_for( channel.server.me).manage_roles response = ":white_check_mark: Slowmode updated.\n" + self.get_slowmode_msg( channel, new_slowmode) await self.bot.say(response + ( "" if can_manage else self.MISSING_MANAGE_PERMISSIONS)) self.save_data()
def can_member_chat(member: Member, channel: Channel): """ Checks to see if the member can chat in the channel.""" return channel.permissions_for(member).send_messages