async def _item_info(self,ctx,name,l_role="RequiredLinkRole",l_list="Links",l_name="Link",l_key="URL"): if name == None: msg = 'Usage: `{}info{} "[{} name]"`'.format(ctx.prefix,l_name.lower(),l_name.lower()) return await ctx.send(msg) itemList = self.settings.getServerStat(ctx.guild, l_list) if not itemList or itemList == []: msg = 'No [[name]]s in list! You can add some with the `{}add[[name]] "[[[name]] name]" [[[key]]]` command!'.format(ctx.prefix).replace("[[name]]",l_name.lower()).replace("[[key]]",l_key.lower()) return await ctx.send(msg) item = next((x for x in itemList if x["Name"].lower() == name.lower()),None) if not item: return await ctx.send('{} not found in {} list!'.format(Nullify.escape_all(name),l_name.lower())) current_time = int(time.time()) msg = "**{}:**\n".format(Nullify.escape_all(item["Name"])) # Get the info created_by = DisplayName.memberForID(item.get("CreatedID",0),ctx.guild) created_by = DisplayName.name(created_by) if created_by else item.get("CreatedBy","`UNKNOWN`") msg += "Created by: {}\n".format(created_by) created = item.get("Created",None) if created: msg += "Created: {} ago\n".format(ReadableTime.getReadableTimeBetween(created, current_time, True)) if item.get("Updated",None): updated_by = DisplayName.memberForID(item.get("UpdatedID",0),ctx.guild) updated_by = DisplayName.name(updated_by) if updated_by else item.get("UpdatedBy","`UNKNOWN`") msg += "Updated by: {}\n".format(updated_by) updated = item.get("Updated",None) if created: msg += "Updated: {} ago\n".format(ReadableTime.getReadableTimeBetween(updated, current_time, True)) return await ctx.send(msg)
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. # Check if our server supports it table = self.settings.getServerStat(message.guild, "TableFlipMute") if not table: return { 'Ignore' : False, 'Delete' : False} # Check for admin status isAdmin = message.author.permissions_in(message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat(message.guild, "AdminArray") for role in message.author.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(role.id): isAdmin = True # Check if the message contains the flip chars conts = message.content face = table = False table_list = [ '┻', '╙', '╨', '╜', 'ǝʃqɐʇ', '┺' ] front_list = [ '(' ] back_list = [ ')', ')' ] if any(ext in conts for ext in front_list) and any(ext in conts for ext in back_list): face = True if any(ext in conts for ext in table_list): table = True if face and table: # Contains all characters # Table flip - add time currentTime = int(time.time()) cooldownFinal = currentTime+60 alreadyMuted = self.settings.getUserStat(message.author, message.guild, "Muted") if not isAdmin: # Check if we're muted already previousCooldown = self.settings.getUserStat(message.author, message.guild, "Cooldown") if not previousCooldown: if alreadyMuted: # We're perma-muted - ignore return { 'Ignore' : False, 'Delete' : False} previousCooldown = 0 if int(previousCooldown) > currentTime: # Already cooling down - add to it. cooldownFinal = previousCooldown+60 coolText = ReadableTime.getReadableTimeBetween(currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, I understand that you\'re frustrated, but we still don\'t flip tables here. Why don\'t you cool down for *{}* instead.'.format(DisplayName.name(message.author), coolText) else: # Not cooling down - start it coolText = ReadableTime.getReadableTimeBetween(currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, we don\'t flip tables here. You should cool down for *{}*'.format(DisplayName.name(message.author), coolText) # Do the actual muting await self.mute.mute(message.author, message.guild, cooldownFinal) await message.channel.send(res) return { 'Ignore' : True, 'Delete' : True } return { 'Ignore' : False, 'Delete' : False}
async def vkexpiretime(self, ctx, *, the_time=None): """Sets the amount of time before a vote expires. 0 or less will make them permanent.""" isAdmin = ctx.message.author.permissions_in( ctx.message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat(ctx.message.guild, "AdminArray") for role in ctx.message.author.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(role.id): isAdmin = True # Only allow admins to change server stats if not isAdmin: await ctx.channel.send( 'You do not have sufficient privileges to access this command.' ) return if the_time == None: # Output the current setting current = self.settings.getServerStat(ctx.guild, "VotesResetTime") if current < 1: await ctx.send("Votes never expire.") else: await ctx.send("Votes will expire after {}.".format( ReadableTime.getReadableTimeBetween(0, current))) return seconds = None try: # Get current time - and end time currentTime = int(time.time()) cal = parsedatetime.Calendar() time_struct, parse_status = cal.parse(the_time) start = datetime(*time_struct[:6]) end = time.mktime(start.timetuple()) # Get the time from now to end time seconds = end - currentTime except Exception: pass if seconds == None: await ctx.send( "Hmmm - I couldn't figure out what time frame you wanted...") return if seconds < 0: seconds = 0 if seconds == 0: self.settings.setServerStat(ctx.guild, "VotesResetTime", 0) await ctx.send("Votes will never expire.") else: self.settings.setServerStat(ctx.guild, "VotesResetTime", seconds) await ctx.send("Votes will expire after {}.".format( ReadableTime.getReadableTimeBetween(0, seconds)))
async def approvejoin(self, ctx, server_id=None): """Temporarily allows the bot to join the passed server id or join url (owner-only).""" # Only allow owner isOwner = self.settings.isOwner(ctx.author) if isOwner == None: return await ctx.send('I have not been claimed, *yet*.') elif isOwner == False: return await ctx.send( 'You are not the *true* owner of me. Only the rightful owner can use this command.' ) if server_id == None: return await ctx.send("Usage: `{}approvejoin server_id`".format( ctx.prefix)) try: server_id = int(server_id) except: try: invite = await self.bot.fetch_invite(server_id) server_id = invite.guild.id except: return await ctx.send("Invalid server id passed.") guild_list = [x.id for x in self.bot.guilds] # Check if we're already on that server, or if it's already been approved if server_id in guild_list: return await ctx.send("I'm already in that server.") temp = next((x for x in self.temp_allowed if x[0] == server_id), None) if temp: # Let's remove the approval to allow it to re-add with a new time try: self.temp_allowed.remove(temp) except: pass # Allow the guild temp_allow = (server_id, time.time() + self.approval_time) self.temp_allowed.append(temp_allow) # Remove if it's been requested request = next( (x for x in self.current_requests if x[1].id == invite.guild.id), None) if request: await request[3].send( "{}, your request for me to join {} has been approved for the next {}. You can invite me with this link:\n<{}>" .format( request[0].mention, Nullify.clean(request[1].name), ReadableTime.getReadableTimeBetween(0, self.approval_time), discord.utils.oauth_url( self.bot.user.id, permissions=discord.Permissions(permissions=8), guild=request[1]))) try: self.current_requests.remove(request) except: pass self.bot.loop.create_task(self.remove_allow(temp_allow)) await ctx.send("I've been approved to join {} for the next {}.".format( server_id, ReadableTime.getReadableTimeBetween(0, self.approval_time)))
async def vkinfo(self, ctx): """Lists the vote-kick info.""" mute_votes = self.settings.getServerStat(ctx.guild, "VotesToMute") ment_votes = self.settings.getServerStat(ctx.guild, "VotesToMention") mute_time = self.settings.getServerStat(ctx.guild, "VotesMuteTime") ment_chan = self.settings.getServerStat(ctx.guild, "VoteKickChannel") vote_ment = self.settings.getServerStat(ctx.guild, "VoteKickMention") vote_rest = self.settings.getServerStat(ctx.guild, "VotesResetTime") vote_list = self.settings.getServerStat(ctx.guild, "VoteKickArray") vote_anon = self.settings.getServerStat(ctx.guild, "VoteKickAnon") msg = "__**Current Vote-Kick Settings For {}:**__\n```\n".format( Nullify.clean(ctx.guild.name)) msg += " Votes To Mute: {}\n".format(int(mute_votes)) msg += " Muted For: {}\n".format( ReadableTime.getReadableTimeBetween(0, mute_time)) msg += "Votes to Mention: {}\n".format(int(ment_votes)) if vote_ment: role_check = DisplayName.roleForName(vote_ment, ctx.guild) if not role_check: user_check = DisplayName.memberForName(vote_ment, ctx.guild) if not user_check: msg += " Mention: None\n" else: msg += " Mention: {}\n".format(user_check) else: msg += " Mention: {} (role)\n".format(role_check) else: msg += " Mention: None\n" m_channel = self.bot.get_channel(ment_chan) if m_channel: msg += " Mention in: #{}\n".format(m_channel.name) else: msg += " Mention in: None\n" if vote_rest == 0: msg += " Vote reset: Permanent\n" elif vote_rest == 1: msg += " Vote reset: After 1 second\n" else: msg += " Vote reset: After {}\n".format( ReadableTime.getReadableTimeBetween(0, vote_rest)) votes = 0 for user in vote_list: votes += len(user["Kicks"]) msg += " Anonymous votes: {}\n".format(vote_anon) msg += " Active votes: {}\n```".format(votes) # Check if mention and mute are disabled if (ment_votes == 0 or ment_chan == None or ment_chan == None) and (mute_votes == 0 or mute_time == 0): msg += "\nSystem **not** configured fully." await ctx.send(msg)
async def requestjoin(self, ctx, invite_url=None): """Forwards the invite url to the bot's owners for review.""" if self.settings.getGlobalStat("AllowServerJoin", True): return await ctx.invoke(self.invite) # Get the list of owners - and account for any that have left owners = self.settings.getOwners() if not len(owners): return await ctx.send("I have not been claimed, *yet*.") if not invite_url: return await ctx.send( "Usage: `{}requestjoin discord.gg_invite_url`".format( ctx.prefix)) try: invite = await self.bot.fetch_invite(invite_url) except: return await ctx.send("That invite url was not valid or expired.") if invite.guild in self.bot.guilds: return await ctx.send("I'm already in that server.") temp = next( (x for x in self.current_requests if x[1].id == invite.guild.id), None) if temp: return await ctx.send( "I've already been requested for that server. Request rolls off in {}, or when approved." .format( ReadableTime.getReadableTimeBetween(time.time(), temp[2]))) temp = next((x for x in self.temp_allowed if x[0] == invite.guild.id), None) if temp: await ctx.invoke(self.invite, invite_url) return await ctx.send("Valid for {}.".format( ReadableTime.getReadableTimeBetween(time.time(), temp[1]))) # Build a request to dm to up to the first 10 owners msg = "{} ({} - {}#{} - {})\nhas requested the bot for: {} ({})\nvia the following invite: {}".format( DisplayName.name(ctx.author), ctx.author.mention, Nullify.clean(ctx.author.name), ctx.author.discriminator, ctx.author.id, Nullify.clean(invite.guild.name), invite.guild.id, invite) owners = owners if len(owners) < 11 else owners[:10] for owner in owners: target = self.bot.get_user(int(owner)) if not target: continue await target.send(msg) request = (ctx.author, invite.guild, time.time() + self.request_time, ctx) self.current_requests.append(request) self.bot.loop.create_task(self.remove_request(request)) await ctx.send( "I've forwarded the request to my owner{}. The request is valid for {}." .format("" if len(owners) == 1 else "s", ReadableTime.getReadableTimeBetween(0, self.request_time)))
async def getautotemp(self, ctx): """Gets the temp role applied to each new user that joins.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False isAdmin = ctx.message.author.permissions_in( ctx.message.channel).administrator # Only allow admins to change server stats if not isAdmin: await ctx.message.channel.send( 'You do not have sufficient privileges to access this command.' ) return temp_id = self.settings.getServerStat(ctx.guild, "TempRole") if temp_id == None: # No temp setup await ctx.send("There is no default temp role.") return temp_role = DisplayName.roleForName(temp_id, ctx.guild) if temp_role == None: # Not a role anymore await ctx.send( "The default temp role ({}) no longer exists.".format(temp_id)) return role_time = self.settings.getServerStat(ctx.guild, "TempRoleTime") msg = "**{}** is the default temp role - will be active for *{}*.".format( Nullify.escape_all(temp_role.name), ReadableTime.getReadableTimeBetween(0, role_time * 60)) await ctx.send(msg)
async def temptime(self, ctx, *, minutes = None): """Sets the number of minutes for the temp role - must be greater than 0 (admin-only).""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False isAdmin = ctx.message.author.permissions_in(ctx.message.channel).administrator # Only allow admins to change server stats if not isAdmin: await ctx.message.channel.send('You do not have sufficient privileges to access this command.') return try: minutes = int(minutes) except: await ctx.send("That's not a valid integer!") return if minutes < 1: await ctx.send("Time must be greater than 0!") return self.settings.setServerStat(ctx.guild, "TempRoleTime", minutes) msg = "Temp role will last *{}*.".format(ReadableTime.getReadableTimeBetween(0, minutes*60)) await ctx.send(msg)
async def uptime(self, ctx): """Lists the bot's uptime.""" currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( self.startTime, currentTime) msg = 'I\'ve been up for *{}*.'.format(timeString) await ctx.channel.send(msg)
async def lastonline(self, ctx, *, member = None): """Lists the last time a user was online if known.""" if not member: msg = 'Usage: `{}lastonline "[member]"`'.format(ctx.prefix) return await ctx.send(msg) if type(member) is str: memberName = member member = DisplayName.memberForName(memberName, ctx.guild) if not member: msg = 'I couldn\'t find *{}*...'.format(Nullify.escape_all(memberName)) return await ctx.send(msg) name = DisplayName.name(member) # We have a member here if not member.status == discord.Status.offline: msg = '*{}* is here right now.'.format(name) else: lastOnline = self.settings.getUserStat(member, ctx.guild, "LastOnline") if lastOnline == "Unknown": self.settings.setUserStat(member, ctx.guild, "LastOnline", None) lastOnline = None if lastOnline: currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween(int(lastOnline), currentTime, True) msg = 'The last time I saw *{}* was *{} ago*.'.format(name, timeString) else: msg = 'I don\'t know when *{}* was last online. Sorry.'.format(name) await ctx.send(msg)
async def profileinfo(self, ctx, *, member = None, name = None): """Displays info about a profile from the passed user's profile list.""" if not member: msg = 'Usage: `{}profileinfo [member] [profile name]`'.format(ctx.prefix) return await ctx.send(msg) item = self._get_profile(ctx,member) if item == None: return await ctx.send("Sorry, I couldn't find that user/profile.") member,item = item # We have a profile current_time = int(time.time()) msg = '**{}:**\n'.format(item['Name']) msg += "Created: {} ago\n".format(ReadableTime.getReadableTimeBetween(item.get("Created",None), current_time, True)) if item.get("Created",None) else "Created: `UNKNOWN`\n" if item.get("Updated",None): msg += "Updated: {} ago\n".format(ReadableTime.getReadableTimeBetween(item["Updated"], current_time, True)) return await ctx.send(Utils.suppressed(ctx,msg))
async def linkinfo(self, ctx, name : str = None): """Displays info about a link from the link list.""" channel = ctx.message.channel author = ctx.message.author server = ctx.message.server if not name: msg = 'Usage: `$linkinfo "[link name]"`' await self.bot.send_message(channel, msg) return linkList = self.settings.getServerStat(server, "Links") if not linkList or linkList == []: msg = 'No links in list! You can add some with the `$addlink "[link name]" [url]` command!' await self.bot.send_message(channel, msg) return for alink in linkList: if alink['Name'].lower() == name.lower(): currentTime = int(time.time()) msg = '**{}:**'.format(alink['Name']) try: msg = '{}\nCreated By: *{}*'.format(msg, alink['CreatedBy']) except KeyError as e: msg = '{}\nCreated By: `UNKNOWN`'.format(msg) try: createdTime = int(alink['Created']) timeString = ReadableTime.getReadableTimeBetween(createdTime, currentTime) msg = '{}\nCreated : *{}* ago'.format(msg, timeString) except KeyError as e: pass try: msg = '{}\nUpdated By: *{}*'.format(msg, alink['UpdatedBy']) except KeyError as e: pass try: createdTime = alink['Updated'] createdTime = int(createdTime) timeString = ReadableTime.getReadableTimeBetween(createdTime, currentTime) msg = '{}\nUpdated : *{}* ago'.format(msg, timeString) except: pass await self.bot.send_message(channel, msg) return await self.bot.send_message(channel, 'Link "*{}*" not found!'.format(name))
async def reminders(self, ctx): """List up to 10 pending reminders.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.server, "SuppressMentions").lower() == "yes": suppress = True else: suppress = False member = ctx.message.author myReminders = self.settings.getUserStat(member, member.server, "Reminders") msg = 'You don\'t currently have any reminders set. You can add some with the `{}remindme "[message]" [time]` command.'.format( ctx.prefix) if not len(myReminders): # No reminders await self.bot.send_message(ctx.message.channel, msg) return mySorted = sorted(myReminders, key=lambda x: int(x['End'])) currentTime = int(time.time()) total = 10 # Max number to list remain = 0 if len(mySorted) < 10: # Less than 10 - set the total total = len(mySorted) else: # More than 10 - let's find out how many remain after remain = len(mySorted) - 10 if len(mySorted): # We have at least 1 item msg = '***{}\'s*** **Remaining Reminders:**\n'.format( DisplayName.name(member)) for i in range(0, total): endTime = int(mySorted[i]['End']) # Get our readable time readableTime = ReadableTime.getReadableTimeBetween( currentTime, endTime) msg = '{}\n{}. {} - in *{}*'.format(msg, i + 1, mySorted[i]['Message'], readableTime) if remain == 1: msg = '{}\n\nYou have *{}* additional reminder.'.format( msg, remain) elif remain > 1: msg = '{}\n\nYou have *{}* additional reminders.'.format( msg, remain) # Check for suppress if suppress: msg = Nullify.clean(msg) await self.bot.send_message(ctx.message.channel, msg)
async def ismuted(self, ctx, *, member = None): """Says whether a member is muted in chat.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions").lower() == "yes": suppress = True else: suppress = False if member == None: msg = 'Usage: `{}ismuted [member]`'.format(ctx.prefix) await ctx.channel.send(msg) return if type(member) is str: memberName = member member = DisplayName.memberForName(memberName, ctx.message.guild) if not member: msg = 'I couldn\'t find *{}*...'.format(memberName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.channel.send(msg) return mutedIn = 0 channelList = [] for channel in ctx.guild.channels: if not type(channel) is discord.TextChannel: continue overs = channel.overwrites_for(member) if overs.send_messages == False: # member can't send messages here perms = member.permissions_in(channel) if perms.read_messages: mutedIn +=1 channelList.append(channel.name) if len(channelList): # Get time remaining if needed #cd = self.settings.getUserStat(member, ctx.message.server, "Cooldown") muteList = self.settings.getServerStat(ctx.guild, "MuteList") cd = None for entry in muteList: if str(entry['ID']) == str(member.id): # Found them! cd = entry['Cooldown'] if not cd == None: ct = int(time.time()) checkRead = ReadableTime.getReadableTimeBetween(ct, cd) msg = '*{}* is **muted** in *{}*\n*{}* remain'.format(DisplayName.name(member), ', '.join(channelList), checkRead) else: msg = '*{}* is **muted** in *{}*.'.format(DisplayName.name(member), ', '.join(channelList)) else: msg = '{} is **unmuted**.'.format(DisplayName.name(member)) await ctx.channel.send(msg)
async def hostinfo(self, ctx): """List info about the bot's host environment.""" message = await ctx.channel.send('Gathering info...') # cpuCores = psutil.cpu_count(logical=False) # cpuThred = psutil.cpu_count() cpuThred = os.cpu_count() cpuUsage = psutil.cpu_percent(interval=1) memStats = psutil.virtual_memory() memPerc = memStats.percent memUsed = memStats.used memTotal = memStats.total memUsedGB = "{0:.1f}".format(((memUsed / 1024) / 1024) / 1024) memTotalGB = "{0:.1f}".format(((memTotal / 1024) / 1024) / 1024) currentOS = platform.platform() system = platform.system() release = platform.release() version = platform.version() processor = platform.processor() botMember = DisplayName.memberForID(self.bot.user.id, ctx.message.guild) botName = DisplayName.name(botMember) currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( self.startTime, currentTime) pythonMajor = sys.version_info.major pythonMinor = sys.version_info.minor pythonMicro = sys.version_info.micro pythonRelease = sys.version_info.releaselevel pyBit = struct.calcsize("P") * 8 process = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'], shell=False, stdout=subprocess.PIPE) git_head_hash = process.communicate()[0].strip() threadString = 'thread' if not cpuThred == 1: threadString += 's' msg = '***{}\'s*** **Home:**\n'.format(botName) msg += '```\n' msg += 'OS : {}\n'.format(currentOS) msg += 'Hostname : {}\n'.format(platform.node()) msg += 'Language : Python {}.{}.{} {} ({} bit)\n'.format( pythonMajor, pythonMinor, pythonMicro, pythonRelease, pyBit) msg += 'Commit : {}\n\n'.format(git_head_hash.decode("utf-8")) msg += ProgressBar.center( '{}% of {} {}'.format(cpuUsage, cpuThred, threadString), 'CPU') + '\n' msg += ProgressBar.makeBar(int(round(cpuUsage))) + "\n\n" msg += ProgressBar.center( '{} ({}%) of {}GB used'.format(memUsedGB, memPerc, memTotalGB), 'RAM') + '\n' msg += ProgressBar.makeBar(int(round(memPerc))) + "\n\n" msg += '{} uptime```'.format(timeString) await message.edit(content=msg)
async def uptime(self, ctx): """Melihat uptime bot.""" currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( self.startTime, currentTime) msg = 'Aku telah online selama\n*{}*.'.format(timeString) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}".format(ctx.author)) await ctx.channel.send(embed=em)
async def _check_votes(self, ctx, member=None): # A helper function that checks if a user needs to be punished for a vote level guild = ctx.guild vote_list = self.settings.getServerStat(guild, "VoteKickArray") vote_mute = self.settings.getServerStat(guild, "VotesToMute") mute_time = self.settings.getServerStat(guild, "VotesMuteTime") vote_mention = self.settings.getServerStat(guild, "VotesToMention") mention_id = self.settings.getServerStat(guild, "VoteKickMention") m_target = DisplayName.roleForName(mention_id, guild) if not m_target: m_target = DisplayName.memberForName(mention_id, guild) channel_id = self.settings.getServerStat(guild, "VoteKickChannel") m_channel = self.bot.get_channel(channel_id) for user in vote_list: if member != None and member.id != user["ID"]: # skip this user continue # Check the user # Check mutes if vote_mute > 0 and len( user["Kicks"]) >= vote_mute and user["Muted"] == False: if mute_time == 0: # Disabled continue cd = self.settings.getUserStat(member, guild, "Cooldown") isMute = self.settings.getUserStat(member, guild, "Muted", False) if cd == None: if isMute: # We're now muted permanently continue # Check our cooldowns elif cd >= (time.time() + mute_time): # Cooldown is higher as is - ignore continue # We need to mute await self.muter.mute(member, ctx.message.guild, time.time() + mute_time) user["Muted"] = True await ctx.send("*{}* has been muted for {}.".format( DisplayName.name(member), ReadableTime.getReadableTimeBetween(0, mute_time))) # Check for mention if vote_mention > 0 and len( user["Kicks"] ) >= vote_mention and user["Mentioned"] == False: if not m_channel or not m_target: continue kick_words = "1 user" if not len(user["Kicks"]) == 1: kick_words = "{} users".format(len(user["Kicks"])) user["Mentioned"] = True await m_channel.send( "{} - *{}* has had {} vote to kick them.".format( m_target.mention, member.mention, kick_words))
async def on_mute(self, member, guild, cooldown, muted_by): if not self.shouldLog('user.mute', guild): return # A memeber was muted pfpurl = member.avatar_url if len(member.avatar_url) else member.default_avatar_url msg = "🔇 {}#{} ({}) was muted.".format(member.name, member.discriminator, member.id) message = "Muted by {}.\nMuted {}.".format( "Auto-Muted" if not muted_by else "{}#{} ({})".format(muted_by.name, muted_by.discriminator, muted_by.id), "for "+ReadableTime.getReadableTimeBetween(time.time(), cooldown) if cooldown else "until further notice" ) await self._logEvent(guild, message, title=msg, color=discord.Color.red(),thumbnail=pfpurl)
async def remindme(self, ctx, message: str = None, *, endtime: str = None): """Set a reminder. If the message contains spaces, it must be wrapped in quotes.""" if not endtime or not message: msg = 'Usage: `{}remindme "[message]" [endtime]`'.format( ctx.prefix) await ctx.channel.send(msg) return # Get current time - and end time currentTime = int(time.time()) cal = parsedatetime.Calendar() time_struct, parse_status = cal.parse(endtime) start = datetime(*time_struct[:6]) end = time.mktime(start.timetuple()) # Get the time from now to end time timeFromNow = end - currentTime if timeFromNow < 1: # Less than a second - set it to 1 second end = currentTime + 1 timeFromNow = 1 if timeFromNow < 1: # Less than a second - set it to 1 second end = currentTime + 1 timeFromNow = 1 # Get our readable time readableTime = ReadableTime.getReadableTimeBetween( int(currentTime), int(end)) # Add reminder reminders = self.settings.getUserStat(ctx.message.author, ctx.message.guild, "Reminders") reminder = { 'End': end, 'Message': message, 'Server': self.suppressed(ctx.guild, ctx.guild.name) } reminders.append(reminder) self.settings.setUserStat(ctx.message.author, ctx.message.guild, "Reminders", reminders) # Start timer for reminder self.loop_list.append( self.bot.loop.create_task( self.checkRemind(ctx.message.author, reminder))) # Confirm the reminder msg = 'Okay *{}*, I\'ll remind you in *{}*.'.format( DisplayName.name(ctx.message.author), readableTime) await ctx.channel.send(msg)
async def ismuted(self, ctx, *, member = None): """Says whether a member is muted in chat.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.server, "SuppressMentions").lower() == "yes": suppress = True else: suppress = False if member == None: msg = 'Usage: `{}ismuted [member]`'.format(ctx.prefix) await self.bot.send_message(ctx.message.channel, msg) return if type(member) is str: memberName = member member = DisplayName.memberForName(memberName, ctx.message.server) if not member: msg = 'I couldn\'t find *{}*...'.format(memberName) # Check for suppress if suppress: msg = Nullify.clean(msg) await self.bot.send_message(ctx.message.channel, msg) return isMute = self.settings.getUserStat(member, ctx.message.server, "Muted") checkTime = self.settings.getUserStat(member, ctx.message.server, "Cooldown") if checkTime: checkTime = int(checkTime) currentTime = int(time.time()) checkRead = None # Check if they've outlasted their time if checkTime and (currentTime >= checkTime): # We have passed the check time ignore = False delete = False self.settings.setUserStat(member, ctx.message.server, "Cooldown", None) self.settings.setUserStat(member, ctx.message.server, "Muted", "No") isMute = self.settings.getUserStat(member, ctx.message.server, "Muted") elif checkTime: checkRead = ReadableTime.getReadableTimeBetween(currentTime, checkTime) if isMute.lower() == "yes": if checkRead: msg = '*{}* is *Muted* - *{}* remain.'.format(DisplayName.name(member), checkRead) else: msg = '*{}* is *Muted*.'.format(DisplayName.name(member)) else: msg = '{} is *Unmuted*.'.format(DisplayName.name(member)) await self.bot.send_message(ctx.message.channel, msg)
async def lastonline(self, ctx, *, member=None): """Lists the last time a user was online if known.""" author = ctx.message.author server = ctx.message.guild channel = ctx.message.channel # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions").lower() == "yes": suppress = True else: suppress = False if not member: msg = 'Usage: `{}lastonline "[member]"`'.format(ctx.prefix) await channel.send(msg) return if type(member) is str: memberName = member member = DisplayName.memberForName(memberName, ctx.message.guild) if not member: msg = 'I couldn\'t find *{}*...'.format(memberName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.channel.send(msg) return name = DisplayName.name(member) # We have a member here if not str(member.status).lower() == "offline": msg = '*{}* is here right now.'.format(name) else: lastOnline = self.settings.getUserStat(member, server, "LastOnline") if lastOnline == "Unknown": self.settings.setUserStat(member, server, "LastOnline", None) lastOnline = None if lastOnline: currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( int(lastOnline), currentTime) msg = 'The last time I saw *{}* was *{} ago*.'.format( name, timeString) else: msg = 'I don\'t know when *{}* was last online. Sorry.'.format( name) await ctx.channel.send(msg)
async def remindme(self, ctx, message: str = None, *, endtime: str = None): """Set a reminder.""" if not endtime or not message: msg = 'Usage: `{}remindme "[message]" [endtime]`'.format( ctx.prefix) await self.bot.send_message(ctx.message.channel, msg) return # Get current time - and end time currentTime = int(time.time()) cal = parsedatetime.Calendar() time_struct, parse_status = cal.parse(endtime) start = datetime(*time_struct[:6]) end = time.mktime(start.timetuple()) # Get the time from now to end time timeFromNow = end - currentTime # Get our readable time readableTime = ReadableTime.getReadableTimeBetween( int(currentTime), int(end)) # Add reminder reminders = self.settings.getUserStat(ctx.message.author, ctx.message.server, "Reminders") reminder = { 'End': end, 'Message': message, 'Server': ctx.message.server.name } reminders.append(reminder) self.settings.setUserStat(ctx.message.author, ctx.message.server, "Reminders", reminders) # Start timer for reminder self.bot.loop.create_task( self.checkRemind(ctx.message.author, reminder)) # Confirm the reminder msg = 'Okay *{}*, I\'ll remind you in *{}*.'.format( DisplayName.name(ctx.message.author), readableTime) await self.bot.send_message(ctx.message.channel, msg)
async def hostinfo(self, ctx): """List info about the bot's host environment.""" # cpuCores = psutil.cpu_count(logical=False) # cpuThred = psutil.cpu_count() cpuThred = os.cpu_count() cpuUsage = psutil.cpu_percent(interval=1) memStats = psutil.virtual_memory() memPerc = memStats.percent memUsed = memStats.used memTotal = memStats.total memUsedGB = "{0:.1f}".format(((memUsed / 1024) / 1024) / 1024) memTotalGB = "{0:.1f}".format(((memTotal / 1024) / 1024) / 1024) currentOS = platform.platform() system = platform.system() release = platform.release() version = platform.version() processor = platform.processor() botMember = DisplayName.memberForID(self.bot.user.id, ctx.message.server) botName = DisplayName.name(botMember) currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( self.startTime, currentTime) pythonMajor = sys.version_info.major pythonMinor = sys.version_info.minor pythonMicro = sys.version_info.micro pythonRelease = sys.version_info.releaselevel msg = '***{}\'s*** **Home:**\n'.format(botName) msg += '```{}\n'.format(currentOS) msg += 'Python {}.{}.{} {}\n'.format(pythonMajor, pythonMinor, pythonMicro, pythonRelease) msg += '{}% of {} ({} thread[s])\n'.format(cpuUsage, processor, cpuThred) msg += ProgressBar.makeBar(int(round(cpuUsage))) + "\n" msg += '{} ({}%) of {}GB RAM used\n'.format(memUsedGB, memPerc, memTotalGB) msg += ProgressBar.makeBar(int(round(memPerc))) + "\n" msg += 'Hostname: {}\n'.format(platform.node()) msg += '{} uptime```'.format(timeString) await self.bot.send_message(ctx.message.channel, msg)
async def autotemp(self, ctx, *, role=None): """Sets the temp role to apply to each new user that joins.""" usage = 'Usage: `{}addtemprole [role]`'.format(ctx.prefix) # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False isAdmin = ctx.message.author.permissions_in( ctx.message.channel).administrator # Only allow admins to change server stats if not isAdmin: await ctx.message.channel.send( 'You do not have sufficient privileges to access this command.' ) return if role == None: self.settings.setServerStat(ctx.guild, "TempRole", None) await ctx.send("Default temp role *removed*.") return roleName = role role = DisplayName.roleForName(roleName, ctx.guild) if not role: msg = 'I couldn\'t find *{}*...'.format(roleName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.send(msg) return self.settings.setServerStat(ctx.guild, "TempRole", role.id) role_time = self.settings.getServerStat(ctx.guild, "TempRoleTime") msg = "**{}** is now the default temp role - will be active for *{}*.".format( role.name, ReadableTime.getReadableTimeBetween(0, role_time * 60)) if suppress: msg = Nullify.clean(msg) await ctx.send(msg)
async def profileinfo(self, ctx, *, member: str = None, name: str = None): """Displays info about a profile from the passed user's profile list.""" channel = ctx.message.channel author = ctx.message.author server = ctx.message.guild # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False if not member: msg = 'Usage: `{}profileinfo [member] [profile name]`'.format( ctx.prefix) await channel.send(msg) return profile = None # name is likely to be empty unless quotes are used if name == None: # Either a name wasn't set - or it's the last section if type(member) is str: # It' a string - the hope continues # Let's search for a name at the beginning - and a profile at the end parts = member.split() for j in range(len(parts)): # Reverse search direction i = len(parts) - 1 - j memFromName = None foundProf = False # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i + 1]) # Profile = end of name -> end of parts joined by space profileStr = ' '.join(parts[i + 1:]) memFromName = DisplayName.memberForName( nameStr, ctx.message.guild) if memFromName: # We got a member - let's check for a profile linkList = self.settings.getUserStat( memFromName, server, "Profiles") if not linkList or linkList == []: pass for alink in linkList: if alink['Name'].lower() == profileStr.lower(): # Found the link - return it. profile = alink break if not profile: # Check if there is no member specified linkList = self.settings.getUserStat(author, server, "Profiles") if not linkList or linkList == []: pass for alink in linkList: if alink['Name'].lower() == member.lower(): # Found the link - return it. profile = alink if not profile: # At this point - we've exhausted our search msg = 'Sorry, I couldn\'t find that user/profile.' await channel.send(msg) return # We have a profile currentTime = int(time.time()) msg = '**{}:**'.format(profile['Name']) try: createdTime = int(profile['Created']) timeString = ReadableTime.getReadableTimeBetween( createdTime, currentTime, True) msg = '{}\nCreated : *{}* ago'.format(msg, timeString) except KeyError as e: msg = '{}\nCreated : `UNKNOWN`'.format(msg) try: createdTime = profile['Updated'] createdTime = int(createdTime) timeString = ReadableTime.getReadableTimeBetween( createdTime, currentTime, True) msg = '{}\nUpdated : *{}* ago'.format(msg, timeString) except: pass # Check for suppress if suppress: msg = Nullify.clean(msg) await channel.send(msg) return
async def hostinfo(self, ctx): """Informasi host bot.""" message = await ctx.channel.send('Gathering info...') # cpuCores = psutil.cpu_count(logical=False) # cpuThred = psutil.cpu_count() cpuThred = os.cpu_count() cpuUsage = psutil.cpu_percent(interval=1) memStats = psutil.virtual_memory() memPerc = memStats.percent memUsed = memStats.used memTotal = memStats.total memUsedGB = "{0:.1f}".format(((memUsed / 1024) / 1024) / 1024) memTotalGB = "{0:.1f}".format(((memTotal / 1024) / 1024) / 1024) currentOS = platform.platform() system = platform.system() release = platform.release() version = platform.version() processor = platform.processor() botMember = DisplayName.memberForID(self.bot.user.id, ctx.message.guild) botName = DisplayName.name(botMember) currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( self.startTime, currentTime) pythonMajor = sys.version_info.major pythonMinor = sys.version_info.minor pythonMicro = sys.version_info.micro pythonRelease = sys.version_info.releaselevel pyBit = struct.calcsize("P") * 8 process = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'], shell=False, stdout=subprocess.PIPE) git_head_hash = process.communicate()[0].strip() threadString = 'thread' if not cpuThred == 1: threadString += 's' msg = '```\n' msg += 'OS : {}\n'.format(currentOS) msg += 'Hostname : {}\n'.format(platform.node()) msg += 'Language : Python {}.{}.{} {} ({} bit)\n\n'.format( pythonMajor, pythonMinor, pythonMicro, pythonRelease, pyBit) msg += 'Commit : {}\n\n'.format(git_head_hash.decode("utf-8")) CPU = ProgressBar.center( '{}% of {} {}'.format(cpuUsage, cpuThred, threadString), 'CPU') + '\n' #CPU += ProgressBar.makeBar(int(round(cpuUsage))) RAM = ProgressBar.center( '{} ({}%) of {}GB used'.format(memUsedGB, memPerc, memTotalGB), 'RAM') + '\n\n' #RAM += ProgressBar.makeBar(int(round(memPerc))) msg += '{} uptime```'.format(timeString) em = discord.Embed( color=0XFF8C00, description="**Owner**\n```\n[ACX] NvStar#9110\n```\n" "**Version**\n```\n3.282.0\n```\n" "**Informasi standar**\n```\nOS : Ubuntu 18.04 x86 LTS\nHostname: {}\nLanguage: Python {}.{}.{}.{} ({}bit)\nCPU : {}% of {} {}\nRAM : {} ({}%) of {}GB used\n```\n" "**Uptime**\n```\n{}\n```".format(platform.node(), pythonMajor, pythonMinor, pythonMicro, pythonRelease, pyBit, cpuUsage, cpuThred, threadString, memUsedGB, memPerc, memTotalGB, timeString)) em.set_author( name="Informasi host", icon_url= "https://cdn.discordapp.com/attachments/518118753226063887/725569194304733435/photo.jpg" ) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) await message.edit(embed=em)
async def lastonline(self, ctx, *, member=None): """**INDONESIA** Melihat member terakhir online. **ENGLISH** Lists the last time a user was online. Contoh \ Example: acx lastonline @ACX•NvStar acx lastonline ACX•NvStar#9110 acx lastonline ACX•NvStar """ cekAuthor = ctx.author checkLang = self.settings.getUserStat(cekAuthor, ctx.guild, "Language") #kalo belum ada language if checkLang == None: await self.language_not_set(ctx) if not member: if checkLang == "ID": em = discord.Embed( color=0XFF8C00, description="Melihat informasi member terakhir online\n\n" "**Panduan**\n" "*`{}lastonline [member]`*\n\n" "*Catatan:*" "*`member` dapat berupa mention, nama, atau nickname.*\n" "*ketik `{}help lastonline` untuk informasi lebih lanjut.*" .format(ctx.prefix, ctx.prefix)) em.set_footer( text= "Saat mengetik command, tanda [] tidak usah digunakan\n{}#{}" .format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) return await ctx.send(embed=em) if checkLang == "EN": msg = "Lists the last time a user was online.\n\n" msg += "**Usage**\n" msg += "*`{}lastonline [member]`*\n\n".format(ctx.prefix) msg += "*Note : you can type `member` as mention someone, nickname, or username.*" em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer( text= "When typing commands, you don't need to use the [] sign\n{}#{}" .format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) return await ctx.send(embed=em) if type(member) is str: memberName = member member = DisplayName.memberForName(memberName, ctx.guild) if not member: if checkLang == "ID": msg = '┐( ̄ヘ ̄;)┌\nAku tidak dapat menemukan *{}*...'.format( memberName) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format( ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) return await ctx.send(embed=em) #return await ctx.send(Utils.suppressed(ctx,msg)) if checkLang == "EN": msg = '┐( ̄ヘ ̄;)┌\nI can\'t find *{}*...'.format(memberName) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format( ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) return await ctx.send(embed=em) name = DisplayName.name(member) # lanjut kebawah ini kalo sudah pilih bahasa if not member.status == discord.Status.offline: if checkLang == "ID": msg = '*{}* sedang online.'.format(member.mention) if checkLang == "EN": msg = '*{}* is online.'.format(member.mention) else: lastOnline = self.settings.getUserStat(member, ctx.guild, "LastOnline") if lastOnline == "Unknown": self.settings.setUserStat(member, ctx.guild, "LastOnline", None) lastOnline = None if lastOnline: if checkLang == "ID": currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetween( int(lastOnline), currentTime, True) msg = 'Terakhir aku lihat {} online\n*{} yang lalu*.'.format( member.mention, timeString) if checkLang == "EN": currentTime = int(time.time()) timeString = ReadableTime.getReadableTimeBetweenEng( int(lastOnline), currentTime, True) msg = 'The last time I saw *{}* was\n*{} ago*'.format( member.mention, timeString) else: if checkLang == "ID": msg = '┐( ̄ヘ ̄;)┌\nAku tidak tau kapan *{}* terakhir online.'.format( member.mention) if checkLang == "EN": msg = '┐( ̄ヘ ̄;)┌\nI don\'t know when *{}* was last online.'.format( member.mention) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) await ctx.send(embed=em)
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. ignore = False delete = False res = None # Check if user is muted isMute = self.settings.getUserStat(message.author, message.guild, "Muted") # Check for admin status isAdmin = message.author.permissions_in(message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat(message.guild, "AdminArray") for role in message.author.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(role.id): isAdmin = True if isMute: ignore = True delete = True checkTime = self.settings.getUserStat(message.author, message.guild, "Cooldown") if checkTime: checkTime = int(checkTime) currentTime = int(time.time()) # Build our PM if checkTime: # We have a cooldown checkRead = ReadableTime.getReadableTimeBetween(currentTime, checkTime) res = 'You are currently **Muted**. You need to wait *{}* before sending messages in *{}*.'.format(checkRead, self.suppressed(message.guild, message.guild.name)) else: # No cooldown - muted indefinitely res = 'You are still **Muted** in *{}* and cannot send messages until you are **Unmuted**.'.format(self.suppressed(message.guild, message.guild.name)) if checkTime and currentTime >= checkTime: # We have passed the check time ignore = False delete = False res = None self.settings.setUserStat(message.author, message.guild, "Cooldown", None) self.settings.setUserStat(message.author, message.guild, "Muted", False) ignoreList = self.settings.getServerStat(message.guild, "IgnoredUsers") if ignoreList: for user in ignoreList: if not isAdmin and str(message.author.id) == str(user["ID"]): # Found our user - ignored ignore = True adminLock = self.settings.getServerStat(message.guild, "AdminLock") if not isAdmin and adminLock: ignore = True if isAdmin: ignore = False delete = False # Get Owner and OwnerLock ownerLock = self.settings.getGlobalStat("OwnerLock",False) owner = self.settings.isOwner(message.author) # Check if owner exists - and we're in OwnerLock if (not owner) and ownerLock: # Not the owner - ignore ignore = True if not isAdmin and res: # We have a response - PM it await message.author.send(res) return { 'Ignore' : ignore, 'Delete' : delete}
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. # Check for admin status isAdmin = message.author.permissions_in(message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat(message.server, "AdminArray") for role in message.author.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if aRole['ID'] == role.id: isAdmin = True # Check if the message contains the flip chars # if message.content.startswith('(') and message.content.endswith('┻'): conts = message.content face = table = False if '(' in conts: if ')' in conts or ')' in conts: face = True if '┻' in conts or '┻' in conts or '╙' in conts or '╨' in conts or '╜' in conts or 'ǝʃqɐʇ' in conts: table = True if face and table: # Contains all characters # Table flip - add time currentTime = int(time.time()) cooldownFinal = currentTime + 60 alreadyMuted = self.settings.getUserStat(message.author, message.server, "Muted") if not isAdmin: # Check if we're muted already previousCooldown = self.settings.getUserStat( message.author, message.server, "Cooldown") if not previousCooldown: if alreadyMuted.lower() == "yes": # We're perma-muted - ignore return {'Ignore': False, 'Delete': False} previousCooldown = 0 if int(previousCooldown) > currentTime: # Already cooling down - add to it. cooldownFinal = previousCooldown + 60 coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, I understand that you\'re frustrated, but we still don\'t flip tables here. Why don\'t you cool down for *{}* instead.'.format( DisplayName.name(message.author), coolText) else: # Not cooling down - start it coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, we don\'t flip tables here. You should cool down for *{}*'.format( DisplayName.name(message.author), coolText) self.settings.setUserStat(message.author, message.server, "Cooldown", cooldownFinal) self.settings.setUserStat(message.author, message.server, "Muted", "Yes") await self.bot.send_message(message.channel, res) return {'Ignore': True, 'Delete': True} return {'Ignore': False, 'Delete': False}
def format_invite(self, invite, sent=False): # Gather prelim info guild = invite.guild channel = None if guild == None else invite.channel url = invite.url if invite.url else "https://discord.gg/{}".format( invite.code) expires_after = None if invite.max_age == None else "Never" if invite.max_age == 0 else "In " + ReadableTime.getReadableTimeBetween( 0, invite.max_age) max_uses = None if invite.max_uses == None else "Unlimited" if invite.max_uses == 0 else "{:,}".format( invite.max_uses) uses = None if invite.uses == None else "{:,}".format(invite.uses) created_by = None if invite.inviter == None else "{}#{} ({})".format( invite.inviter.name, invite.inviter.discriminator, invite.inviter.id) created_at = None if invite.created_at == None else invite.created_at.strftime( "%b %d %Y - %I:%M %p") + " UTC" temp = None if invite.temporary == None else invite.temporary # Build the description desc = "Invite URL: {}".format(url) if sent == True: if guild != None: desc += "\nName: {}".format(guild.name) if invite.approximate_member_count != None: desc += "\nUsers: {}\{}".format( invite.approximate_presence_count, invite.approximate_member_count) if created_by != None: desc += "\nCreated By: {}".format(created_by) if created_at != None: desc += "\nCreated At: {}".format(created_at) if channel != None: desc += "\nFor Channel: #{} ({})".format( channel.name, channel.id) if expires_after != None: desc += "\nExpires: {}".format(expires_after) if temp != None: desc += "\nTemporary: {}".format(temp) if uses != None: desc += "\nUses: {}".format(uses) if max_uses != None: desc += "\nMax Uses: {}".format(max_uses) return desc