async def reminders(self, ctx, *, member=None): """List up to 10 pending reminders - pass a user to see their reminders.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False 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.message.channel.send(msg) return if not member: member = ctx.message.author myReminders = self.settings.getUserStat(member, member.guild, "Reminders") if member == ctx.message.author: msg = 'You don\'t currently have any reminders set. You can add some with the `{}remindme "[message]" [time]` command.'.format( ctx.prefix) else: msg = '*{}* doesn\'t currently have any reminders set. They can add some with the `{}remindme "[message]" [time]` command.'.format( DisplayName.name(member), ctx.prefix) if not len(myReminders): # No reminders await ctx.channel.send(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 ctx.channel.send(msg)
async def withcontext(self, ctx): """Spout out some contextual brilliance.""" msg = await self.getTitle( 'https://www.reddit.com/r/evenwithcontext/top.json?sort=top&t=week&limit=100' ) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def removeadmin(self, ctx, *, role : str = None): """Removes a role from the admin list (admin only).""" usage = 'Usage: `{}removeadmin [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: await ctx.message.channel.send(usage) return # Name placeholder roleName = role if type(role) is str: if role.lower() == "everyone" or role.lower() == "@everyone": role = ctx.guild.default_role else: role = DisplayName.roleForName(role, ctx.guild) # If we're here - then the role is a real one promoArray = self.settings.getServerStat(ctx.message.guild, "AdminArray") for aRole in promoArray: # Check for Name if aRole['Name'].lower() == roleName.lower(): # We found it - let's remove it promoArray.remove(aRole) self.settings.setServerStat(ctx.message.guild, "AdminArray", promoArray) msg = '**{}** removed successfully.'.format(aRole['Name']) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return # Get the role that corresponds to the id if role and (str(aRole['ID']) == str(role.id)): # We found it - let's remove it promoArray.remove(aRole) self.settings.setServerStat(ctx.message.guild, "AdminArray", promoArray) msg = '**{}** removed successfully.'.format(role.name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return # If we made it this far - then we didn't find it msg = '**{}** not found in list.'.format(role.name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg)
async def lpt(self, ctx): """Become a pro - AT LIFE.""" msg = await self.getTitle( 'https://www.reddit.com/r/LifeProTips/top.json?sort=top&t=week&limit=100' ) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def thinkdeep(self, ctx): """Spout out some intellectual brilliance.""" msg = await self.getTitle( 'https://www.reddit.com/r/showerthoughts/top.json?sort=top&t=week&limit=100' ) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def renhw(self, ctx, *, build = None): """Renames a build from your build list.""" if not build: await ctx.channel.send("Usage: `{}renhw [build name or index]`".format(ctx.prefix)) return hwChannel = None if ctx.guild: # Not a pm hwChannel = self.settings.getServerStat(ctx.guild, "HardwareChannel") if not (not hwChannel or hwChannel == ""): # We need the channel id if not str(hwChannel) == str(ctx.channel.id): msg = 'This isn\'t the channel for that...' for chan in ctx.guild.channels: if str(chan.id) == str(hwChannel): msg = 'This isn\'t the channel for that. Take the hardware talk to the **{}** channel.'.format(chan.name) await ctx.channel.send(msg) return else: hwChannel = self.bot.get_channel(hwChannel) if not hwChannel: # Nothing set - pm hwChannel = ctx.author # Make sure we're not already in a parts transaction if self.settings.getGlobalUserStat(ctx.author, 'HWActive'): await ctx.send("You're already in a hardware session! You can leave with `{}cancelhw`".format(ctx.prefix)) return buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) mainBuild = None # Get build by name first - then by index for b in buildList: if b['Name'].lower() == build.lower(): # Found it mainBuild = b if not mainBuild: try: build = int(build)-1 if build >= 0 and build < len(buildList): mainBuild = buildList[build] except: pass if not mainBuild: msg = "I couldn't find that build or index." await ctx.channel.send(msg) return # Set our HWActive flag self.settings.setGlobalUserStat(ctx.author, 'HWActive', True) # Post the dm reaction if hwChannel == ctx.author and ctx.channel != ctx.author.dm_channel: await ctx.message.add_reaction("📬") # Here, we have a build bname = mainBuild['Name'] if self.checkSuppress(ctx): bname = Nullify.clean(bname) msg = 'Alright, *{}*, what do you want to rename "{}" to?'.format(DisplayName.name(ctx.author), bname) while True: buildName = await self.prompt(ctx, msg, hwChannel, DisplayName.name(ctx.author)) if not buildName: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return buildExists = False for build in buildList: if build['Name'].lower() == buildName.content.lower(): mesg = 'It looks like you already have a build by that name, *{}*. Try again.'.format(DisplayName.name(ctx.author)) await hwChannel.send(mesg) buildExists = True break if not buildExists: mainBuild['Name'] = buildName.content # Flush settings to all servers self.settings.setGlobalUserStat(ctx.author, "Hardware", buildList) break bname2 = buildName.content if self.checkSuppress(ctx): bname2 = Nullify.clean(bname2) msg = '*{}*, {} was renamed to {} successfully!'.format(DisplayName.name(ctx.author), bname, bname2) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) await hwChannel.send(msg)
async def rawhw(self, ctx, *, user : str = None, build = None): """Lists the raw markdown for either the user's default build - or the passed build.""" if not user: user = ctx.author.name # Let's check for username and build name parts = user.split() memFromName = None buildParts = None for j in range(len(parts)): # Reverse search direction i = len(parts)-1-j # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i]) buildStr = ' '.join(parts[i:]) memFromName = DisplayName.memberForName(nameStr, ctx.guild) if memFromName: buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] for build in buildList: if build['Name'].lower() == buildStr.lower(): # Ha! Found it! buildParts = build break if buildParts: # We're in business break else: memFromName = None if not memFromName: # Try again with indexes for j in range(len(parts)): # Reverse search direction i = len(parts)-1-j # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i]) buildStr = ' '.join(parts[i:]) memFromName = DisplayName.memberForName(nameStr, ctx.guild) if memFromName: buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) try: buildStr = int(buildStr)-1 if buildStr >= 0 and buildStr < len(buildList): buildParts = buildList[buildStr] except Exception: memFromName = None buildParts = None if buildParts: # We're in business break else: memFromName = None if not memFromName: # One last shot - check if it's a build for us buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) for build in buildList: if build['Name'].lower() == user.lower(): memFromName = ctx.author buildParts = build break if not memFromName: # Okay - *this* time is the last - check for index try: user_as_build = int(user)-1 if user_as_build >= 0 and user_as_build < len(buildList): buildParts = buildList[user_as_build] memFromName = ctx.author except Exception: pass if not memFromName: # Last check for a user passed as the only param memFromName = DisplayName.memberForName(user, ctx.guild) if not memFromName: # We couldn't find them :( msg = "I couldn't find that user/build combo..." await ctx.channel.send(msg) return if buildParts == None: # Check if that user has no builds buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] if not len(buildList): # No parts! msg = '*{}* has no builds on file! They can add some with the `{}newhw` command.'.format(DisplayName.name(memFromName), ctx.prefix) await ctx.channel.send(msg) return # Must be the default build for build in buildList: if build['Main']: buildParts = build break if not buildParts: # Well... uh... no defaults msg = "I couldn't find that user/build combo..." await ctx.channel.send(msg) return # At this point - we *should* have a user and a build # Escape all \ with \\ p = buildParts['Hardware'].replace('\\', '\\\\') p = p.replace('*', '\\*') p = p.replace('`', '\\`') p = p.replace('_', '\\_') msg = "__**{}'s {} (Raw Markdown):**__\n\n{}".format(DisplayName.name(memFromName), buildParts['Name'], p) if self.checkSuppress(ctx): msg = Nullify.clean(msg) await ctx.channel.send(msg)
async def removeprofile(self, ctx, *, name: str = None): """Remove a profile from your 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 # Why did I do this? There shouldn't be role requirements for your own profiles... '''# Check for role requirements requiredRole = self.settings.getServerStat(server, "RequiredXPRole") if requiredRole == "": #admin only isAdmin = author.permissions_in(channel).administrator if not isAdmin: await channel.send('You do not have sufficient privileges to access this command.') return else: #role requirement hasPerms = False for role in author.roles: if str(role.id) == str(requiredRole): hasPerms = True if not hasPerms: await channel.send('You do not have sufficient privileges to access this command.') return''' if name == None: msg = 'Usage: `{}removeprofile "[profile name]"`'.format( ctx.prefix) await channel.send(msg) return linkList = self.settings.getUserStat(author, server, "Profiles") if not linkList or linkList == []: msg = '*{}* has no profiles set! They can add some with the `{}addprofile "[profile name]" [url]` command!'.format( DisplayName.name(author), ctx.prefix) await channel.send(msg) return for alink in linkList: if alink['Name'].lower() == name.lower(): linkList.remove(alink) self.settings.setUserStat(author, server, "Profiles", linkList) msg = '*{}* removed from *{}\'s* profile list!'.format( alink['Name'], DisplayName.name(author)) # Check for suppress if suppress: msg = Nullify.clean(msg) await channel.send(msg) return msg = '*{}* not found in *{}\'s* profile list!'.format( name, DisplayName.name(author)) # Check for suppress if suppress: msg = Nullify.clean(msg) await 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.guild, "SuppressMentions"): 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), len(channelList), "channel" if len(channelList) is 1 else "channels", checkRead ) else: msg = '*{}* is **muted** in {} {}.'.format( DisplayName.name(member), len(channelList), "channel" if len(channelList) is 1 else "channels" ) else: msg = '{} is **unmuted**.'.format( DisplayName.name(member) ) await ctx.channel.send(msg)
async def rawprofile(self, ctx, *, member: str = None, name: str = None): """Retrieve a profile's raw markdown 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: `{}rawprofile [member] [profile name]`'.format( ctx.prefix) await channel.send(msg) return # 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. msg = '*{}\'s {} Profile:*\n\n{}'.format( DisplayName.name(memFromName), alink['Name'], alink['URL'].replace( '\\', '\\\\').replace('*', '\\*').replace( '`', '\\`').replace('_', '\\_')) # Check for suppress if suppress: msg = Nullify.clean(msg) await channel.send(msg) return # 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. msg = '*{}\'s {} Profile:*\n\n{}'.format( DisplayName.name(author), alink['Name'], alink['URL'].replace('\\', '\\\\').replace( '*', '\\*').replace('`', '\\`').replace('_', '\\_')) # Check for suppress if suppress: msg = Nullify.clean(msg) await channel.send(msg) return # If we got this far - we didn't find them or somehow they added a name msg = 'Sorry, I couldn\'t find that user/profile.' await channel.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 getMarkdown(url, style=None, escape=False): # Ensure we're using a list if url.lower().endswith("pcpartpicker.com/list/"): # Not *just* the list... we want actual parts return None url = url.replace("#view=", "") if '/b/' in url.lower(): # We have a build - let's try to convert to list try: response = await DL.async_text(url, {"user-agent": "Mozilla"}) except Exception: return None try: newLink = response.split('">View full price breakdown<')[0].split( '"')[-1] except Exception as e: newLink = None if newLink == None: return None url = "https://pcpartpicker.com" + str(newLink) # url = url.replace('/b/', '/list/') if not style: style = 'normal' try: response = await DL.async_text(url, {"user-agent": "Mozilla"}) except Exception: return None # Let's walk the lines of the file and gather based on cues names = [] types = [] current_name = current_type = None primed = name_primed = type_primed = False for i in response.split("\n"): if i.strip() == "": # skip empty lines continue if "tr__product" in i: # Clear and prime current_name = current_type = None primed = True continue if not primed: continue if "</tr>" in i: # Closing bracket for our stuff - dump name and type if we have them if current_name and current_type: names.append( unescape(current_name, { "'": "'", """: '"', "​": "" })) types.append( unescape(current_type, { "'": "'", """: '"', "​": "" })) primed = name_primed = type_primed = False type_primed = 0 current_name = current_type = None continue # Should be primed here - and checking for name and type if name_primed: name_primed = False # Assume we should be pulling the name here try: if i.strip().startswith("<"): # Try to format it current_name = i.split('">')[1].split("</a>")[0] else: current_name = i.strip() except Exception as e: pass continue if type_primed: # If it's a custom part - we need to look for <p>[whatever]</p> # or for the absense of <a href= if i.strip().startswith("<p>"): type_primed = False current_type = i.split("<p>")[1].split("</p>")[0] elif not i.strip().startswith("<a href="): type_primed = False current_type = i.strip() continue if "td__component" in i: # Got the type try: current_type = i.split("</a></td>")[-2].split('">')[-1] type_primed = False except: # bad type - prime it though type_primed = True continue if "td__name" in i: # Primed for name name_primed = True continue if not len(types): return None if not len(types) == len(names): # Only way this would happen that I've seen so far, is with custom entries return None partout = '' if style.lower() == 'md': partout = mdStyle(types, names, escape) elif style.lower() == 'mdblock': partout = mdBlockStyle(types, names, escape) elif style.lower() == 'bold': partout = boldStyle(types, names, escape) elif style.lower() == 'bolditalic': partout = boldItalicStyle(types, names, escape) elif style.lower() == 'normal': partout = normalStyle(types, names, escape) else: # No style present return None return Nullify.clean(partout)
async def xpblock(self, ctx, *, user_or_role: str = None): """Adds a new user or role to the xp block list (bot-admin only).""" usage = 'Usage: `{}xpblock [user_or_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 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 user_or_role == None: await ctx.message.channel.send(usage) return roleName = user_or_role is_user = True if type(user_or_role) is str: # Check user first user_or_role = DisplayName.memberForName(roleName, ctx.guild) if not user_or_role: is_user = False # Check role if roleName.lower() == "everyone" or roleName.lower( ) == "@everyone": user_or_role = ctx.guild.default_role else: user_or_role = DisplayName.roleForName(roleName, ctx.guild) if not user_or_role: msg = 'I couldn\'t find *{}*...'.format(roleName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return if is_user: # Check if they're admin or bot admin isAdmin = user_or_role.permissions_in( ctx.message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat( ctx.message.guild, "AdminArray") for role in user_or_role.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(role.id): isAdmin = True if isAdmin: msg = "You can't block other admins with this command." await ctx.send(msg) return ur_name = DisplayName.name(user_or_role) else: # Check if the role is admin or bot admin isAdmin = user_or_role.permissions.administrator if not isAdmin: checkAdmin = self.settings.getServerStat( ctx.message.guild, "AdminArray") for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(user_or_role.id): isAdmin = True if isAdmin: msg = "You can't block other admins with this command." await ctx.send(msg) return ur_name = user_or_role.name # Now we see if we already have that role in our list promoArray = self.settings.getServerStat(ctx.message.guild, "XpBlockArray") for aRole in promoArray: # Get the role that corresponds to the id if str(aRole) == str(user_or_role.id): # We found it - throw an error message and return msg = '**{}** is already in the list.'.format(ur_name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return # If we made it this far - then we can add it promoArray.append(user_or_role.id) self.settings.setServerStat(ctx.message.guild, "XpBlockArray", promoArray) msg = '**{}** added to list.'.format(ur_name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return
async def xpunblock(self, ctx, *, user_or_role: str = None): """Removes a user or role from the xp block list (bot-admin only).""" usage = 'Usage: `{}xpunblock [user_or_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 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 user_or_role == None: await ctx.message.channel.send(usage) return roleName = user_or_role is_user = True if type(user_or_role) is str: # Check user first user_or_role = DisplayName.memberForName(roleName, ctx.guild) if not user_or_role: is_user = False # Check role if roleName.lower() == "everyone" or roleName.lower( ) == "@everyone": user_or_role = ctx.guild.default_role else: user_or_role = DisplayName.roleForName(roleName, ctx.guild) if not user_or_role: msg = 'I couldn\'t find *{}*...'.format(roleName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return if is_user: ur_name = DisplayName.name(user_or_role) else: ur_name = user_or_role.name # If we're here - then the role is a real one promoArray = self.settings.getServerStat(ctx.message.guild, "XpBlockArray") for aRole in promoArray: # Check for Name if str(aRole) == str(user_or_role.id): # We found it - let's remove it promoArray.remove(aRole) self.settings.setServerStat(ctx.message.guild, "XpBlockArray", promoArray) msg = '**{}** removed successfully.'.format(ur_name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg) return # If we made it this far - then we didn't find it msg = '**{}** not found in list.'.format(ur_name) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.message.channel.send(msg)
async def confirm(self, ctx, message, dest = None, m = None, author = None): # Get author name authorName = None if author: if type(author) is str: authorName = author else: try: authorName = DisplayName.name(author) except Exception: pass else: if message: try: author = message.author except Exception: pass try: authorName = DisplayName.name(message.author) except Exception: pass if not dest: dest = message.channel if not m: if authorName: msg = '*{}*, I got:'.format(authorName) else: msg = "I got:" if type(message) is str: msg2 = message else: msg2 = '{}'.format(message.content) msg3 = 'Is that correct? (y/n/stop)' if self.checkSuppress(ctx): msg = Nullify.clean(msg) msg2 = Nullify.clean(msg2) msg3 = Nullify.clean(msg3) await dest.send(msg) await dest.send(msg2) await dest.send(msg3) else: msg = m if self.checkSuppress(ctx): msg = Nullify.clean(msg) await dest.send(msg) while True: def littleCheck(m): return ctx.author.id == m.author.id and self.confirmCheck(m, dest) and len(m.content) try: talk = await self.bot.wait_for('message', check=littleCheck, timeout=300) except Exception: talk = None # Hardware ended if not self.stillHardwaring(ctx.author): return None if not talk: if authorName: msg = "*{}*, I'm out of time...".format(authorName) else: msg = "I'm out of time..." await dest.send(msg) return None else: # We got something if talk.content.lower().startswith('y'): return True elif talk.content.lower().startswith('stop'): if authorName: msg = "No problem, *{}!* See you later!".format(authorName) else: msg = "No problem! See you later!" await dest.send(msg) return None else: return False
async def rolecall(self, ctx, *, role = None): """Lists the number of users in a current role.""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.message.guild, "SuppressMentions"): suppress = True else: suppress = False author = ctx.message.author server = ctx.message.guild channel = ctx.message.channel if role == None: msg = 'Usage: `{}rolecall [role]`'.format(ctx.prefix) await channel.send(msg) return if type(role) is str: roleName = role role = DisplayName.roleForName(roleName, ctx.message.guild) if not role: msg = 'I couldn\'t find *{}*...'.format(roleName) # Check for suppress if suppress: msg = Nullify.clean(msg) await ctx.channel.send(msg) return # Create blank embed role_embed = discord.Embed(color=role.color) # Get server's icon url if one exists - otherwise grab the default blank Discord avatar avURL = server.icon_url if not len(avURL): avURL = discord.User.default_avatar_url # Add the server icon # role_embed.set_author(name='{}'.format(role.name), icon_url=avURL) role_embed.set_author(name='{}'.format(role.name)) # We have a role memberCount = 0 memberOnline = 0 for member in server.members: roles = member.roles if role in roles: # We found it memberCount += 1 if not member.status == discord.Status.offline: memberOnline += 1 '''if memberCount == 1: msg = 'There is currently *1 user* with the **{}** role.'.format(role.name) role_embed.add_field(name="Members", value='1 user', inline=True) else: msg = 'There are currently *{} users* with the **{}** role.'.format(memberCount, role.name) role_embed.add_field(name="Members", value='{}'.format(memberCount), inline=True)''' role_embed.add_field(name="Members", value='{:,} of {:,} online.'.format(memberOnline, memberCount), inline=True) # await channel.send(msg) await channel.send(embed=role_embed)
async def edithw(self, ctx, *, build = None): """Edits a build from your build list.""" if not build: await ctx.channel.send("Usage: `{}edithw [build name or index]`".format(ctx.prefix)) return hwChannel = None if ctx.guild: # Not a pm hwChannel = self.settings.getServerStat(ctx.guild, "HardwareChannel") if not (not hwChannel or hwChannel == ""): # We need the channel id if not str(hwChannel) == str(ctx.channel.id): msg = 'This isn\'t the channel for that...' for chan in ctx.guild.channels: if str(chan.id) == str(hwChannel): msg = 'This isn\'t the channel for that. Take the hardware talk to the **{}** channel.'.format(chan.name) await ctx.channel.send(msg) return else: hwChannel = self.bot.get_channel(hwChannel) if not hwChannel: # Nothing set - pm hwChannel = ctx.author # Make sure we're not already in a parts transaction if self.settings.getGlobalUserStat(ctx.author, 'HWActive'): await ctx.send("You're already in a hardware session! You can leave with `{}cancelhw`".format(ctx.prefix)) return buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) mainBuild = None # Get build by name first - then by index for b in buildList: if b['Name'].lower() == build.lower(): # Found it mainBuild = b if not mainBuild: try: build = int(build)-1 if build >= 0 and build < len(buildList): mainBuild = buildList[build] except: pass if not mainBuild: msg = "I couldn't find that build or index." await ctx.channel.send(msg) return # Set our HWActive flag self.settings.setGlobalUserStat(ctx.author, 'HWActive', True) # Here, we have a build bname = mainBuild['Name'] bparts = mainBuild['Hardware'] if self.checkSuppress(ctx): bname = Nullify.clean(bname) bparts = Nullify.clean(bparts) msg = '"{}"\'s current parts:'.format(bname) await hwChannel.send(msg) if hwChannel == ctx.author and ctx.channel != ctx.author.dm_channel: await ctx.message.add_reaction("📬") await hwChannel.send(bparts) msg = 'Alright, *{}*, what parts does "{}" have now? (Please include *all* parts for this build - you can add new lines with *shift + enter*)\n'.format(DisplayName.name(ctx.author), bname) msg += 'You can also pass pcpartpicker links to have them formatted automagically - I can also format them using different styles.\n' msg += 'For example: ' msg += '```https://pcpartpicker.com/list/123456 mdblock``` would format with the markdown block style.\n' msg += 'Markdown styles available are *normal, md, mdblock, bold, bolditalic*' while True: parts = await self.prompt(ctx, msg, hwChannel, DisplayName.name(ctx.author)) if not parts: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return if 'pcpartpicker.com' in parts.content.lower(): # Possibly a pc partpicker link? msg = 'It looks like you sent a pc part picker link - did you want me to try and format that? (y/n/stop)' test = await self.confirm(ctx, parts, hwChannel, msg) if test == None: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return elif test == True: partList = parts.content.split() if len(partList) == 1: partList.append(None) output = None try: output = await PCPP.getMarkdown(partList[0], partList[1], False) except: pass if not output: msg = 'Something went wrong! Make sure you use a valid pcpartpicker link.' await hwChannel.send(msg) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return if len(output) > 2000: msg = "That's an *impressive* list of parts - but the max length allowed for messages in Discord is 2000 characters, and you're at *{}*.".format(len(output)) msg += '\nMaybe see if you can prune up that list a bit and try again?' await hwChannel.send(msg) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return # Make sure conf = await self.confirm(ctx, output, hwChannel, None, ctx.author) if conf == None: # Timed out self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return elif conf == False: # Didn't get our answer msg = 'Alright, *{}*, what parts does "{}" have now? (Please include *all* parts for this build - you can add new lines with *shift + enter*)'.format(DisplayName.name(ctx.author), bname) continue m = '{} set to:\n{}'.format(bname, output) await hwChannel.send(m) mainBuild['Hardware'] = output self.settings.setGlobalUserStat(ctx.author, "Hardware", buildList) break mainBuild['Hardware'] = parts.content break msg = '*{}*, {} was edited successfully!'.format(DisplayName.name(ctx.author), bname) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) await hwChannel.send(msg)
async def tr(self, ctx, *, translate=None): """Translate some stuff!""" # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(ctx.guild, "SuppressMentions"): suppress = True else: suppress = False usage = "Usage: `{}tr [words] [from code (optional)] [to code]`".format( ctx.prefix) if translate == None: await ctx.send(usage) return word_list = translate.split(" ") if len(word_list) < 2: await ctx.send(usage) return lang = word_list[len(word_list) - 1] from_lang = word_list[len(word_list) - 2] if len(word_list) >= 3 else "auto" # Get the from language from_lang_back = [ x for x in self.languages if x["code"].lower() == from_lang.lower() ] from_lang_code = from_lang_back[0]["code"] if len( from_lang_back) else "auto" from_lang_name = from_lang_back[0]["name"] if len( from_lang_back) else "Auto" # Get the to language lang_back = [ x for x in self.languages if x["code"].lower() == lang.lower() ] lang_code = lang_back[0]["code"] if len(lang_back) else None lang_name = lang_back[0]["name"] if len(lang_back) else None # Translate all but our language codes if len(word_list) > 2 and word_list[ len(word_list) - 2].lower() == from_lang_code.lower(): trans = " ".join(word_list[:-2]) else: trans = " ".join(word_list[:-1]) if not lang_code: await Message.EmbedText( title="Something went wrong...", description="I couldn't find that language!", color=ctx.author).send(ctx) return result = mtranslate.translate(trans, lang_code, from_lang_code) if not result: await Message.EmbedText( title="Something went wrong...", description="I wasn't able to translate that!", color=ctx.author).send(ctx) return if result == trans: # We got back what we put in... await Message.EmbedText( title="Something went wrong...", description= "The text returned from Google was the same as the text put in. Either the translation failed - or you were translating from/to the same language (en -> en)", color=ctx.author).send(ctx) return # Check for suppress if suppress: result = Nullify.clean(result) await Message.EmbedText( title="{}, your translation is:".format( DisplayName.name(ctx.author)), force_pm=True, color=ctx.author, description=result, footer="{} --> {} - Powered by Google Translate".format( from_lang_name, lang_name)).send(ctx)
async def gethw(self, ctx, *, user = None, search = None): """Searches the user's hardware for a specific search term.""" if not user: usage = "Usage: `{}gethw [user] [search term]`".format(ctx.prefix) await ctx.channel.send(usage) return # Let's check for username and search term parts = user.split() memFromName = None buildParts = None for j in range(len(parts)): # Reverse search direction i = len(parts)-1-j memFromName = None buildParts = None # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i]) buildStr = ' '.join(parts[i:]) memFromName = DisplayName.memberForName(nameStr, ctx.guild) if memFromName: # Got a member - let's check the remainder length, and search! if len(buildStr) < 3: usage = "Search term must be at least 3 characters." await ctx.channel.send(usage) return buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) foundStr = '' foundCt = 0 for build in buildList: bParts = build['Hardware'] for line in bParts.splitlines(): if buildStr.lower() in line.lower(): foundCt += 1 foundStr += '{}. **{}**\n {}\n'.format(foundCt, build['Name'], line.replace("`", "")) if len(foundStr): # We're in business foundStr = "__**\"{}\" Results:**__\n\n".format(buildStr, DisplayName.name(memFromName)) + foundStr break else: # foundStr = 'Nothing found for "{}" in *{}\'s* builds.'.format(buildStr, DisplayName.name(memFromName)) # Nothing found... memFromName = None buildStr = None if memFromName and len(foundStr): # We're in business if self.checkSuppress(ctx): foundStr = Nullify.clean(foundStr) await Message.Message(message=foundStr).send(ctx) return # If we're here - then we didn't find a member - set it to the author, and run another quick search buildStr = user if len(buildStr) < 3: usage = "Search term must be at least 3 characters." await ctx.channel.send(usage) return buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) foundStr = '' foundCt = 0 for build in buildList: bParts = build['Hardware'] for line in bParts.splitlines(): if buildStr.lower() in line.lower(): foundCt += 1 foundStr += '{}. **{}**\n {}\n'.format(foundCt, build['Name'], line.replace("`", "")) if len(foundStr): # We're in business foundStr = "__**\"{}\" Results:**__\n\n".format(buildStr) + foundStr else: foundStr = 'Nothing found for "{}".'.format(buildStr) # Nothing found... if self.checkSuppress(ctx): foundStr = Nullify.clean(foundStr) await Message.Message(message=foundStr).send(ctx)
async def vk(self, ctx, user = None, *, server = None): """Places your vote to have the passed user kicked.""" # Should be a dict like this: # { "ID" : 123456789, "Kicks" : [ { "ID" : 123456789, "Added" : 123456789 } ] } if user == None: await ctx.send('Usage: `{}vk "[user]" [server]`'.format(ctx.prefix)) return if server == None: guild = ctx.guild else: found = False for guild in self.bot.guilds: if not server.lower() in [guild.name.lower(), str(guild.id)]: continue found = True break if not found: guild = ctx.guild user = user + " " + server if not guild and not server: await ctx.send("Specify what server the user that you are vote kicking is in.") return elif not guild and server: await ctx.send("I couldn't find that server.") return if ctx.author not in guild.members: await ctx.send("You're not a member of that server!") return server_msg = " in **{}**".format(guild.name) if guild != ctx.guild else "" check_user = DisplayName.memberForName(user, guild) if not check_user: await ctx.send("I couldn't find *{}*{}...".format(Nullify.clean(user), server_msg)) return mute_votes = self.settings.getServerStat(guild, "VotesToMute") ment_votes = self.settings.getServerStat(guild, "VotesToMention") mute_time = self.settings.getServerStat(guild, "VotesMuteTime") ment_chan = self.settings.getServerStat(guild, "VoteKickChannel") vote_ment = self.settings.getServerStat(guild, "VoteKickMention") vote_anon = self.settings.getServerStat(guild, "VoteKickAnon") if vote_anon and not isinstance(ctx.channel, discord.DMChannel): await ctx.message.delete() # 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): await ctx.send('This function is not setup{} yet.'.format(server_msg)) return # Check if we're trying to kick ourselves if check_user.id == ctx.author.id: await ctx.send("You should probably find a way to be okay with yourself. Kicking yourself will get you nowhere.") return # Check if we're trying to kick an admin isAdmin = check_user.permissions_in(ctx.message.channel).administrator if not isAdmin: checkAdmin = self.settings.getServerStat(guild, "AdminArray") for role in check_user.roles: for aRole in checkAdmin: # Get the role that corresponds to the id if str(aRole['ID']) == str(role.id): isAdmin = True if isAdmin: await ctx.channel.send('You cannot vote to kick the admins. Please work out any issues you may have with them in a civil manner.') return vote_list = self.settings.getServerStat(guild, "VoteKickArray") for member in vote_list: if member["ID"] == check_user.id: # They're in the list - let's see if you've already voted for them for vote in member["Kicks"]: if vote["ID"] == ctx.author.id: await ctx.send("You've already voted to kick that member. You cannot vote against them again while your vote is still active.") return # We haven't voted for them yet - add our vote member["Kicks"].append({ "ID" : ctx.author.id, "Added" : time.time() }) # Update the array self.settings.setServerStat(guild, "VoteKickArray", vote_list) await ctx.send("Vote kick added for *{}!*".format(DisplayName.name(check_user))) await self._check_votes(ctx, check_user) return # Never found the member vote_list.append({ "ID" : check_user.id, "Muted" : False, "Mentioned" : False, "Kicks" : [ { "ID" : ctx.author.id, "Added" : time.time() } ] }) # Set the list self.settings.setServerStat(guild, "VoteKickArray", vote_list) await ctx.send("Vote kick added for *{}*{}!".format(DisplayName.name(check_user), server_msg)) await self._check_votes(ctx, check_user)
async def newhw(self, ctx): """Initiate a new-hardware conversation with the bot.""" buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] hwChannel = None if ctx.guild: # Not a pm hwChannel = self.settings.getServerStat(ctx.guild, "HardwareChannel") if not (not hwChannel or hwChannel == ""): # We need the channel id if not str(hwChannel) == str(ctx.channel.id): msg = 'This isn\'t the channel for that...' for chan in ctx.guild.channels: if str(chan.id) == str(hwChannel): msg = 'This isn\'t the channel for that. Take the hardware talk to the **{}** channel.'.format(chan.name) await ctx.channel.send(msg) return else: hwChannel = self.bot.get_channel(hwChannel) if not hwChannel: # Nothing set - pm hwChannel = ctx.author # Make sure we're not already in a parts transaction if self.settings.getGlobalUserStat(ctx.author, 'HWActive'): await ctx.send("You're already in a hardware session! You can leave with `{}cancelhw`".format(ctx.prefix)) return # Set our HWActive flag self.settings.setGlobalUserStat(ctx.author, 'HWActive', True) msg = 'Alright, *{}*, let\'s add a new build.\n\n'.format(DisplayName.name(ctx.author)) if len(buildList) == 1: msg += 'You currently have *1 build* on file.\n\n' else: msg += 'You currently have *{} builds* on file.\n\nLet\'s get started!'.format(len(buildList)) try: await hwChannel.send(msg) except: # Can't send to the destination self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) if hwChannel == ctx.author: # Must not accept pms await ctx.send("It looks like you don't accept pms. Please enable them and try again.") return if hwChannel == ctx.author and ctx.channel != ctx.author.dm_channel: await ctx.message.add_reaction("📬") msg = '*{}*, tell me what you\'d like to call this build (type stop to cancel):'.format(DisplayName.name(ctx.author)) # Get the build name newBuild = { 'Main': True } while True: buildName = await self.prompt(ctx, msg, hwChannel, DisplayName.name(ctx.author)) if not buildName: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return buildExists = False for build in buildList: if build['Name'].lower() == buildName.content.lower(): mesg = 'It looks like you already have a build by that name, *{}*. Try again.'.format(DisplayName.name(ctx.author)) await hwChannel.send(mesg) buildExists = True break if not buildExists: newBuild['Name'] = buildName.content break bname = buildName.content if self.checkSuppress(ctx): bname = Nullify.clean(bname) msg = 'Alright, *{}*, what parts does "{}" have? (Please include *all* parts for this build - you can add new lines with *shift + enter*)\n'.format(DisplayName.name(ctx.author), bname) msg += 'You can also pass pcpartpicker links to have them formatted automagically - I can also format them using different styles.\n' msg += 'For example: ' msg += '```https://pcpartpicker.com/list/123456 mdblock``` would format with the markdown block style.\n' msg += 'Markdown styles available are *normal, md, mdblock, bold, bolditalic*' while True: parts = await self.prompt(ctx, msg, hwChannel, DisplayName.name(ctx.author)) if not parts: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return if 'pcpartpicker.com' in parts.content.lower(): # Possibly a pc partpicker link? msg = 'It looks like you sent a pc part picker link - did you want me to try and format that? (y/n/stop)' test = await self.confirm(ctx, parts, hwChannel, msg) if test == None: self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return elif test == True: partList = parts.content.split() if len(partList) == 1: partList.append(None) output = None try: output = await PCPP.getMarkdown(partList[0], partList[1], False) except: pass #output = PCPP.getMarkdown(parts.content) if not output: msg = 'Something went wrong! Make sure you use a valid pcpartpicker link.' await hwChannel.send(msg) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return if len(output) > 2000: msg = "That's an *impressive* list of parts - but the max length allowed for messages in Discord is 2000 characters, and you're at *{}*.".format(len(output)) msg += '\nMaybe see if you can prune up that list a bit and try again?' await hwChannel.send(msg) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return # Make sure conf = await self.confirm(ctx, output, hwChannel, None, ctx.author) if conf == None: # Timed out self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) return elif conf == False: # Didn't get our answer msg = 'Alright, *{}*, what parts does "{}" have? (Please include *all* parts for this build - you can add new lines with *shift + enter*)'.format(DisplayName.name(ctx.author), bname) continue m = '{} set to:\n{}'.format(bname, output) await hwChannel.send(m) newBuild['Hardware'] = output break newBuild['Hardware'] = parts.content break # Check if we already have a main build for build in buildList: if build['Main']: newBuild['Main'] = False buildList.append(newBuild) self.settings.setGlobalUserStat(ctx.author, "Hardware", buildList) msg = '*{}*, {} was created successfully!'.format(DisplayName.name(ctx.author), bname) self.settings.setGlobalUserStat(ctx.author, 'HWActive', False) await hwChannel.send(msg)
async def eat(self, ctx, *, member: str = None): """Eat like a boss.""" authorName = DisplayName.name(ctx.message.author) # Check if we're eating nothing if member == None: nothingList = [ 'you sit quietly and eat *nothing*...', 'you\'re *sure* there was something to eat, so you just chew on nothingness...', 'there comes a time when you need to realize that you\'re just chewing nothing for the sake of chewing. That time is now.' ] randnum = random.randint(0, len(nothingList) - 1) msg = '*{}*, {}'.format(authorName, nothingList[randnum]) msg = Nullify.clean(msg) await ctx.channel.send(msg) return # Check if we're eating a member memberCheck = DisplayName.memberForName(member, ctx.message.guild) if memberCheck: # We're eating a member - let's do a bot-check if memberCheck.id == self.bot.user.id: # It's me! memberList = [ 'you try to eat *me* - but unfortunately, I saw it coming - your jaw hangs open as I deftly sidestep.', 'your mouth hangs open for a brief second before you realize that *I\'m* eating *you*.', 'I\'m a bot. You can\'t eat me.', 'your jaw clamps down on... wait... on nothing, because I\'m *digital!*.', 'what kind of bot would I be if I let you eat me?' ] elif memberCheck.id == ctx.message.author.id: # We're eating... ourselves? memberList = [ 'you clamp down on your own forearm - not surprisingly, it hurts.', 'you place a finger into your mouth, but *just can\'t* force yourself to bite down.', 'you happily munch away, but can now only wave with your left hand.', 'wait - you\'re not a sandwich!', 'you might not be the smartest...' ] else: memName = DisplayName.name(memberCheck) memberList = [ 'you unhinge your jaw and consume *{}* in one bite.'. format(memName), 'you try to eat *{}*, but you just can\'t quite do it - you spit them out, the taste of failure hanging in your mouth...' .format(memName), 'you take a quick bite out of *{}*. They probably didn\'t even notice.' .format(memName), 'you sink your teeth into *{}\'s* shoulder - they turn to face you, eyes wide as you try your best to scurry away and hide.' .format(memName), 'your jaw clamps down on *{}* - a satisfying *crunch* emanates as you finish your newest meal.' .format(memName) ] randnum = random.randint(0, len(memberList) - 1) msg = '*{}*, {}'.format(authorName, memberList[randnum]) msg = Nullify.clean(msg) await ctx.channel.send(msg) return # Assume we're eating something else itemList = [ 'you take a big chunk out of *{}*. *Delicious.*'.format(member), 'your teeth sink into *{}* - it tastes satisfying.'.format(member), 'you rip hungrily into *{}*, tearing it to bits!'.format(member), 'you just can\'t bring yourself to eat *{}* - so you just hold it for awhile...' .format(member), 'you attempt to bite into *{}*, but you\'re clumsier than you remember - and fail...' .format(member), ] randnum = random.randint(0, len(itemList) - 1) msg = '*{}*, {}'.format(authorName, itemList[randnum]) msg = Nullify.clean(msg) await ctx.channel.send(msg) return
async def shittylpt(self, ctx): """Your advise is bad, and you should feel bad.""" msg = await self.getTitle( 'https://www.reddit.com/r/ShittyLifeProTips/top.json?sort=top&t=week&limit=100' ) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def prompt(self, hw_id, ctx, message, dest = None, author = None): # Get author name authorName = None if author: if type(author) is str: authorName = author else: try: authorName = DisplayName.name(author) except Exception: pass else: if message: try: author = message.author except Exception: pass try: authorName = DisplayName.name(message.author) except Exception: pass if not dest: dest = ctx.channel if self.checkSuppress(ctx): msg = Nullify.clean(message) await dest.send(message) while True: def littleCheck(m): return ctx.author.id == m.author.id and self.channelCheck(m, dest) and len(m.content) try: talk = await self.bot.wait_for('message', check=littleCheck, timeout=300) except Exception: talk = None # See if we're still in the right context if not hw_id == self.hwactive.get(str(ctx.author.id),None): return None # Hardware ended if not self.stillHardwaring(ctx.author): return None if not talk: msg = "*{}*, I'm out of time...".format(authorName) await dest.send(msg) return None else: # Check for a stop if talk.content.lower() == 'stop': msg = "No problem, *{}!* See you later!".format(authorName, ctx.prefix) await dest.send(msg) return None # Make sure conf = await self.confirm(hw_id, ctx, talk, dest, "", author) if conf == True: # We're sure - return the value return talk elif conf == False: # Not sure - ask again return await self.prompt(hw_id, ctx, message, dest, author) else: # Timed out return None
async def brainfart(self, ctx): """Spout out some uh... intellectual brilliance...""" msg = await self.getTitle( 'https://www.reddit.com/r/Showerthoughts/controversial.json?sort=controversial&t=week&limit=100' ) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def renhw(self, ctx, *, build = None): """Renames a build from your build list.""" hwChannel = None if ctx.guild: # Not a pm hwChannel = self.settings.getServerStat(ctx.guild, "HardwareChannel") if not (not hwChannel or hwChannel == ""): # We need the channel id if not str(hwChannel) == str(ctx.channel.id): msg = 'This isn\'t the channel for that...' for chan in ctx.guild.channels: if str(chan.id) == str(hwChannel): msg = 'This isn\'t the channel for that. Take the hardware talk to the **{}** channel.'.format(chan.name) await ctx.channel.send(msg) return else: hwChannel = self.bot.get_channel(hwChannel) if not hwChannel: # Nothing set - pm hwChannel = ctx.author # Make sure we're not already in a parts transaction if str(ctx.author.id) in self.hwactive: await ctx.send("You're already in a hardware session! You can leave with `{}cancelhw`".format(ctx.prefix)) return buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] if not len(buildList): # No parts! msg = 'You have no builds on file! You can add some with the `{}newhw` command.'.format(ctx.prefix) await ctx.channel.send(msg) return buildList = sorted(buildList, key=lambda x:x['Name'].lower()) mainBuild = None # Get build by name first - then by number if build is not None: for b in buildList: if b['Name'].lower() == build.lower(): # Found it mainBuild = b break if not mainBuild: try: build = int(build)-1 if build >= 0 and build < len(buildList): mainBuild = buildList[build] except: pass else: # No build passed - get the main if it exists for b in buildList: if b['Main']: mainBuild = b break if not mainBuild: msg = "I couldn't find that build or number." await ctx.channel.send(msg) return # Set our HWActive flag hw_id = self.gen_id() self.hwactive[str(ctx.author.id)] = hw_id # Post the dm reaction if hwChannel == ctx.author and ctx.channel != ctx.author.dm_channel: await ctx.message.add_reaction("📬") # Here, we have a build bname = mainBuild['Name'] if self.checkSuppress(ctx): bname = Nullify.clean(bname) msg = 'Alright, *{}*, what do you want to rename "{}" to?'.format(DisplayName.name(ctx.author), bname) while True: try: buildName = await self.prompt(hw_id, ctx, msg, hwChannel, DisplayName.name(ctx.author)) except: # Can't send to the destination self._stop_hw(ctx.author) if hwChannel == ctx.author: # Must not accept pms await ctx.send("It looks like you don't accept pms. Please enable them and try again.") return if not buildName: self._stop_hw(ctx.author) return buildExists = False for build in buildList: if build['Name'].lower() == buildName.content.lower(): mesg = 'It looks like you already have a build by that name, *{}*. Try again.'.format(DisplayName.name(ctx.author)) await hwChannel.send(mesg) buildExists = True break if not buildExists: mainBuild['Name'] = buildName.content # Flush settings to all servers self.settings.setGlobalUserStat(ctx.author, "Hardware", buildList) break bname2 = buildName.content if self.checkSuppress(ctx): bname2 = Nullify.clean(bname2) msg = '*{}*, {} was renamed to {} successfully!'.format(DisplayName.name(ctx.author), bname, bname2) self._stop_hw(ctx.author) await hwChannel.send(msg)
async def answer(self, ctx): """Spout out some interstellar answering... ?""" answer = self.settings.getServerStat(ctx.guild, "LastAnswer") msg = "You need to ask a `{}question` first!".format( ctx.prefix) if not answer else "{}".format(answer) await ctx.send(Nullify.escape_all(msg, markdown=False))
async def hw(self, ctx, *, user : str = None, build = None): """Lists the hardware for either the user's default build - or the passed build.""" if not user: user = "******".format(ctx.author.mention) # Let's check for username and build name parts = user.split() memFromName = None buildParts = None for j in range(len(parts)): # Reverse search direction i = len(parts)-1-j # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i]) buildStr = ' '.join(parts[i:]) memFromName = DisplayName.memberForName(nameStr, ctx.guild) if memFromName: buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] for build in buildList: if build['Name'].lower() == buildStr.lower(): # Ha! Found it! buildParts = build break if buildParts: # We're in business break else: memFromName = None if not memFromName: # Try again with numbers for j in range(len(parts)): # Reverse search direction i = len(parts)-1-j # Name = 0 up to i joined by space nameStr = ' '.join(parts[0:i]) buildStr = ' '.join(parts[i:]) memFromName = DisplayName.memberForName(nameStr, ctx.guild) if memFromName: buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) try: buildStr = int(buildStr)-1 if buildStr >= 0 and buildStr < len(buildList): buildParts = buildList[buildStr] except Exception: memFromName = None buildParts = None if buildParts: # We're in business break else: memFromName = None if not memFromName: # One last shot - check if it's a build for us buildList = self.settings.getGlobalUserStat(ctx.author, "Hardware") if buildList == None: buildList = [] buildList = sorted(buildList, key=lambda x:x['Name'].lower()) for build in buildList: if build['Name'].lower() == user.lower(): memFromName = ctx.author buildParts = build break if not memFromName: # Okay - *this* time is the last - check for number try: user_as_build = int(user)-1 if user_as_build >= 0 and user_as_build < len(buildList): buildParts = buildList[user_as_build] memFromName = ctx.author except Exception: pass if not memFromName: # Last check for a user passed as the only param memFromName = DisplayName.memberForName(user, ctx.guild) if not memFromName: # We couldn't find them :( msg = "I couldn't find that user/build combo..." await ctx.channel.send(msg) return if buildParts == None: # Check if that user has no builds buildList = self.settings.getGlobalUserStat(memFromName, "Hardware") if buildList == None: buildList = [] if not len(buildList): # No parts! msg = ':facepalm: *{}* has no builds on file! Please stop being lazy and fillout your hardware information. You can add some with the `{}newhw` command.'.format(DisplayName.name(memFromName), ctx.prefix) await ctx.channel.send(msg) return # Must be the default build for build in buildList: if build['Main']: buildParts = build break if not buildParts: # Well... uh... no defaults msg = "I couldn't find that user/build combo..." await ctx.channel.send(msg) return # At this point - we *should* have a user and a build msg_head = "__**{}'s {}:**__\n\n".format(DisplayName.name(memFromName), buildParts['Name']) msg = msg_head + buildParts['Hardware'] if len(msg) > 2000: # is there somwhere the discord char count is defined, to avoid hardcoding? msg = buildParts['Hardware'] # if the header pushes us over the limit, omit it and send just the string if self.checkSuppress(ctx): msg = Nullify.clean(msg) await ctx.channel.send(msg)
def suppressed(self, guild, msg): # Check if we're suppressing @here and @everyone mentions if self.settings.getServerStat(guild, "SuppressMentions"): return Nullify.clean(msg) else: return msg
async def madlibs(self, ctx): """Let's play MadLibs!""" 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 # Check if we have a MadLibs channel - and if so, restrict to that channelID = self.settings.getServerStat(server, "MadLibsChannel") if not (not channelID or channelID == ""): # We need the channel id if not str(channelID) == str(channel.id): msg = 'This isn\'t the channel for that...' for chan in server.channels: if str(chan.id) == str(channelID): msg = 'This isn\'t the channel for that. Take the MadLibs to the **{}** channel.'.format( chan.name) await channel.send(msg) return # Check if our folder exists if not os.path.isdir("./Cogs/MadLibs"): msg = 'I\'m not configured for MadLibs yet...' await channel.send(msg) return # Folder exists - let's see if it has any files choices = [] # Empty array for file in os.listdir("./Cogs/MadLibs"): if file.endswith(".txt"): choices.append(file) if len(choices) == 0: # No madlibs... msg = 'I\'m not configured for MadLibs yet...' await channel.send(msg) return # Check if we're already in a game if self.playing_madlibs.get(str(server.id), False): msg = 'I\'m already playing MadLibs - use `{}{} [your word]` to submit answers.'.format( ctx.prefix, self.prefix) await channel.send(msg) return self.playing_madlibs[str(server.id)] = True # Get a random madlib from those available randnum = random.randint(0, (len(choices) - 1)) randLib = choices[randnum] # Let's load our text and get to work with open("./Cogs/MadLibs/{}".format(randLib), 'r') as myfile: data = myfile.read() # Set up an empty arry words = [] # Match matches = re.finditer(self.regex, data) # Iterate matches for match in matches: words.append(match.group(0)) # Create empty substitution array subs = [] # Iterate words and ask for input i = 0 while i < len(words): # Ask for the next word vowels = "aeiou" word = words[i][2:-2] if word[:1].lower() in vowels: msg = "I need an **{}** (word *{}/{}*). `{}{} [your word]`".format( words[i][2:-2], str(i + 1), str(len(words)), ctx.prefix, self.prefix) else: msg = "I need a **{}** (word *{}/{}*). `{}{} [your word]`".format( words[i][2:-2], str(i + 1), str(len(words)), ctx.prefix, self.prefix) await channel.send(msg) # Setup the check def check(msg): return msg.content.startswith("{}{}".format( ctx.prefix, self.prefix)) and msg.channel == channel # Wait for a response try: talk = await self.bot.wait_for('message', check=check, timeout=60) except Exception: talk = None if not talk: # We timed out - leave the loop msg = "*{}*, I'm done waiting... we'll play another time.".format( DisplayName.name(author)) await channel.send(msg) self.playing_madlibs.pop(str(server.id), None) return # Check if the message is to leave if talk.content.lower().startswith('{}{}'.format( ctx.prefix, self.leavePrefix.lower())): if talk.author is author: msg = "Alright, *{}*. We'll play another time.".format( DisplayName.name(author)) await channel.send(msg) self.playing_madlibs.pop(str(server.id), None) return else: # Not the originator msg = "Only the originator (*{}*) can leave the MadLibs.".format( DisplayName.name(author)) await channel.send(msg) continue # We got a relevant message word = talk.content # Let's remove the $ml prefix (with or without space) if word.startswith('{}{} '.format(ctx.prefix.lower(), self.prefix.lower())): word = word[len(ctx.prefix) + len(self.prefix) + 1:] if word.startswith('{}{}'.format(ctx.prefix.lower(), self.prefix.lower())): word = word[len(ctx.prefix) + len(self.prefix):] # Check capitalization if words[i][:3].isupper(): # Capitalized word = string.capwords(word) # Add to our list subs.append(word) # Increment our index i += 1 # Let's replace for asub in subs: # Only replace the first occurence data = re.sub(self.regex, "**{}**".format(asub), data, 1) self.playing_madlibs.pop(str(server.id), None) # Check for suppress if suppress: data = Nullify.clean(data) # Message the output await channel.send(data)