async def add_group(self, ctx, *args): """Adds a group or list of groups""" group_list = args if not group_list: await ctx.send(embed=error_embed('No group(s) given!')) else: # Update to string instead of list already_exists = [] added = [] for group in group_list: groupstr = str(group).lower() success = add_group(groupstr, ctx.author.id) if success: added.append(groupstr) add_group_alias_db(groupstr, groupstr, ctx.author.id) else: already_exists.append(groupstr) if already_exists and added: exists = ', '.join(already_exists) add = ', '.join(added) act = f"Added group(s): {add}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Added group(s): {add}!\nSkipped adding duplicates: {exists}!" await ctx.send(embed=success_embed(msg)) elif added and not already_exists: msg = f"Added group(s): {', '.join(added)}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Skipped adding duplicates: {', '.join(already_exists)}!" await ctx.send(embed=error_embed(msg))
async def follow_insta(self, ctx, user_name): """Follows an Instagram user in this channel. Example: `.follow_insta <username or link>`""" if 'instagram.com' in user_name: user_name = user_name.split('/')[-1] user = self.insta.get_user(user_name) try: if user['is_private']: await ctx.send(embed=error_embed('This user is private, and cannot be followed!')) return except Exception as e: print(e) user_id = user['user']['pk'] if not user_id: await ctx.send(embed=error_embed(f'No instagram user found called {escape_markdown(user_name)}!')) return add_insta_user_to_db(user_id) add_channel(ctx.channel.id) if not follow_insta_user_db(user_id, ctx.channel.id): await ctx.send(embed=error_embed(f'{escape_markdown(user_name)} is already followed in this channel!')) return name = user['user']['full_name'] link = f"https://www.instagram.com/{user['user']['username']}" embed = discord.Embed(title=f'Successfully followed {name}', description=f'This channel will now receive updates when {name} posts updates at {link}', color=INSTA_COLOUR) embed.set_thumbnail(url=user['user']['profile_pic_url']) await ctx.send(embed=embed)
async def follow_twitch(self, ctx, stream): """Follows a twitch stream in this channel! Live updates will be posted here. .follow_twitch <username or link>""" channel = ctx.channel.id if "twitch.tv" in stream: stream = stream.split("/")[-1].lower() else: stream = stream.lower() user = self.twitch.get_users(logins=stream) print(user) if not user: await ctx.send( embed=error_embed(f"Failed to find Twitch user {stream}!")) return for d in user["data"]: ayed = str(d["id"]) add_channel(channel) add_twitch_channel_to_db(ayed) followed = follow_twitch_channel_db(channel, ayed) if followed: display_name = d['display_name'] profile_image = d['profile_image_url'] link = f"https://www.twitch.tv/{d['login']}" msg = f'This channel will now receive updates on when {display_name} goes live at {link}' embed = discord.Embed( title=f'Successfully Followed {display_name}!', description=msg, color=discord.Color.purple()) embed.set_thumbnail(url=profile_image) await ctx.send(embed=embed) else: await ctx.send(embed=error_embed( f"Failed to follow {stream} in this channel!"))
async def _regex_channel(self, ctx, regex=None): """Force a specific type of text to be sent in a channel, message that do not match will be automatically deleted.""" if not regex: await ctx.send(embed=error_embed('No regex/text format provided!')) return if regex == 'gfy': pass elif regex == 'images': pass elif regex == 'videos': pass else: try: regex = rf'{regex}' reg = re.compile(regex) except Exception as e: print(e) await ctx.send(embed=error_embed( f'Failed to compile regex!: {regex}\n' f'There is likely an error with this expression.' 'Check out <https://regex101.com/> for help!')) return await ctx.send(embed=success_embed( f'Regex {regex} is now enforced in this channel!')) pass
async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandNotFound): async for message in ctx.history(limit=1): if message.author == self.disclient.user: print("sent out a custom command") else: prefix = get_prefix(self.disclient, ctx.message)[0] # once guild prefix is enabled need to change regex regexstr = r'(\..*){}|\{}\{}.*$'.format( '{2,}', prefix, prefix) print(regexstr) regex2 = re.compile(regexstr) # regex1 = re.compile(r'(\..*){2,}') match = re.search(regex2, message.content) if match: print('user wrote some ...') else: await ctx.send(embed=error_embed("Command not found!")) # raise error if isinstance(error, commands.MissingRequiredArgument): await ctx.send(embed=error_embed(f'Missing argument! {error}')) # always raise errors if isinstance(error, commands.CommandInvokeError): if ctx.command.name == 'timer': return else: await ctx.send(embed=error_embed('Something went wrong!')) if isinstance(error, commands.NoPrivateMessage): await ctx.send( embed=error_embed('This command does not work in DMs!')) return if isinstance(error, commands.CheckFailure): await ctx.send(embed=permission_denied_embed()) raise error
async def twitter_follow(self, ctx, user_name): """Follows a twitter user, new tweets will be posted in the channel the command was called! Example: .follow_twitter <username or link>""" if 'twitter.com' in user_name: user_name = user_name.split('/')[-1] channel_id = ctx.channel.id add_channel(channel_id) user = self.client.get_twitter_user(user_name) if user: add_twitter_to_db(user.id_str) else: await ctx.send(embed=error_embed( f'Twitter user `{escape_markdown(user_name)}` not found!')) added = add_twitter_channel_to_db(channel_id, user.id_str) if added: icon_url = user.profile_image_url display_name = user.name link = f'https://twitter.com/{user.screen_name}' msg = f'This channel will now receive updates when {display_name} tweets at {link}' embed = discord.Embed( title=f'Successfully followed {escape_markdown(display_name)}', description=escape_markdown(msg), color=discord.Color.blue()) embed.set_thumbnail(url=icon_url) await ctx.send(embed=embed) if user.id_str not in get_users_to_stream(): self.restart_stream() else: await ctx.send(embed=error_embed( f'Failed to follow twitter user `{escape_markdown(user_name)}`!' ))
async def set_command_prefix(self, ctx, prefix): prefix = prefix.strip() if len(prefix) > 3: await ctx.send(embed=error_embed( f'Invalid prefix: `{prefix}. Please use 3 characters maximum')) return set_prefix = set_guild_prefix_db(ctx.guild.id, prefix) if set_prefix: await ctx.send(embed=success_embed( f'Changed this servers prefix to `{prefix}`!')) else: await ctx.send(embed=error_embed( 'Failed to change the prefix in this server.'))
async def unfollow_insta(self, ctx, user_name): """Unfollows an Instagram user in this channel. Example: `.unfollow_insta <username or link>`""" if 'instagram.com' in user_name: user_name = user_name.split('/')[-1] user = self.insta.get_user(user_name) user_id = user['user']['pk'] if not user_id: await ctx.send(embed=error_embed(f'No instagram user found called {escape_markdown(user_name)}!')) return if unfollow_insta_user_db(user_id, ctx.channel.id): await ctx.send(embed=success_embed(f'Unfollowed {escape_markdown(user_name)}!')) else: await ctx.send(embed=error_embed(f'Failed to unfollow {escape_markdown(user_name)}!'))
async def add_tag_alias(self, ctx, tag, *aliases): """Adds an alias to a tag. A list of aliases can be passed through in one command, but only one tag. Please ensure you use the tag name, and not an alias for the first argument. Example: .add_tag_alias <tag> <alias> Example: .add_tag_alias <tag> <alias1> <alias2>""" tag = tag.lower() added_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() added = add_tag_alias_db(tag, alias, ctx.author.id) if added: added_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and added_aliases: exists = ', '.join(invalid_aliases) add = ', '.join(added_aliases) act = f"Added alias(es): {add} to {tag}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Added alias(es): {add} to {tag}!\nSkipped adding duplicates: {exists}!" await ctx.send(embed=success_embed(msg)) elif added_aliases and not invalid_aliases: msg = f"Added aliases(s): {', '.join(added_aliases)} to {tag}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Skipped adding duplicate alias(es): {', '.join(invalid_aliases)}!" await ctx.send(embed=error_embed(msg))
async def remove_perma_user(self, ctx, user_id): """Removes user from perma ban""" unperma = remove_perma_user_db(user_id) if unperma: await ctx.send(embed=success_embed("User un-perma'd.")) else: await ctx.send(embed=error_embed("Failed to un-perma user."))
async def twitches(self, ctx): """Returns a list of all twitch users followed in this server!""" guild = ctx.guild chans = get_all_twitch_followed_in_guild() chan_dict = {} for pair in chans: if pair[0] not in chan_dict: chan_dict.update({pair[0]: [pair[-1]]}) else: chan_dict[pair[0]].append(pair[-1]) msg = '' for channel in guild.channels: if channel.id in chan_dict: for twitch in chan_dict[channel.id]: twitch_str = str(twitch) twitch = self.twitch.get_users(user_ids=[twitch_str]) twitch = twitch['data'][0]['login'] spacing = 39 - len(channel.name + twitch) chan_str = f"`#{channel.name}{' ' * spacing}{twitch}`\n" msg = msg + chan_str if msg == '': await ctx.send( embed=error_embed('No Twitch streams followed in this server!') ) else: add_to_start = f"`Channel Name{' ' * 17}Twitch User`\n" msg = add_to_start + msg embed = discord.Embed( title=f'Twitch Streams Followed in {guild.name}!', description=msg, color=discord.Color.purple()) await ctx.send(embed=embed)
async def delete_link(self, ctx, group, idol, *links): """ Deletes link(s) from an idol. Example: .delete_link <group> <idol> <link> <link> <link> """ link_list = links group = group.lower() idol = idol.lower() # change list to string later failed = [] success = [] for link in link_list: if '-' in link: link = link.split('-')[0] removed = remove_link(group, idol, link) if removed: success.append(link) else: failed.append(link) if failed and not success: f = ', '.join(failed) await ctx.send(embed=error_embed(f'Failed to delete: {f}')) elif len(success) > 0 and failed: f = ', '.join(failed) s = '\n' + '\n'.join(success) act = f'Deleted link(s) from {group} {idol}: {s}' await moderation_auditing(self.disclient, ctx.author, act) await ctx.send(embed=success_embed( f'Removed {len(success)} links!\nFailed to delete: {f}')) else: s = '\n' + '\n'.join(success) act = f'Deleted link(s) from {group} {idol}: {s}' await moderation_auditing(self.disclient, ctx.author, act) await ctx.send( embed=success_embed(f'Removed {len(success)} links!'))
async def remove_tag(self, ctx, link, *tags): """ Removes tag(s) from a link previously added Example: <link> <tag> <tag> <tag> Any number of tags can be removed in one command. """ tags_list = tags # rework lists to strings once working removed = [] not_there = [] for tag in tags_list: tag = tag.lower() remove = remove_tag_from_link(link, tag) if remove: removed.append(tag) else: not_there.append(tag) if removed and not_there: r = ', '.join(removed) nt = ', '.join(not_there) act = f"Removed tag(s): {r} from {link}" await moderation_auditing(self.disclient, ctx.author, act) await ctx.send(embed=success_embed( f'Removed {r} tag(s) from link!\nLink did not have: {nt}')) elif removed: r = ', '.join(removed) act = f"Removed tag(s): {r} from the link:\n{link}" await moderation_auditing(self.disclient, ctx.author, act) await ctx.send( embed=success_embed(f'Removed {r} tag(s) from link!')) else: nt = ', '.join(not_there) await ctx.send( embed=error_embed(f'Link did not have tag(s): {nt}!'))
async def delete_idol_alias(self, ctx, group, idol, *aliases): """Removes an alias from an idol. A list of aliases can be passed through in one command, but only one idol. Please ensure you use the members name, and not an alias for the second argument. Example: .remove_idol_alias redvelvet joy j Example: .remove_idol_alias <group> <idol> <alias1> <alias2>""" group = group.lower() idol = idol.lower() removed_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() removed = remove_member_alias_db(group, idol, alias) if removed: removed_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and removed_aliases: exists = ', '.join(invalid_aliases) rem = ', '.join(removed_aliases) act = f"Removed alias(es): {rem} from {idol}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Removed alias(es): {rem} from {group}!\nFailed to removed: {exists}!" await ctx.send(embed=success_embed(msg)) elif removed_aliases and not invalid_aliases: msg = f"Removed aliases(s): {', '.join(removed_aliases)} from {idol}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"""Failed to remove alias(es): {', '.join(invalid_aliases)} from {idol}! \nPlease make sure you do not use an alias for the idol name.""" await ctx.send(embed=error_embed(msg))
async def add_idol_alias(self, ctx, group, idol, *aliases): """Adds an alias to an idol. A list of aliases can be passed through in one command, but only one idol. Please ensure you use the members name, and not an alias for the second argument. Example: .add_idol_alias redvelvet joy j Example: .add_idol_alias <group> <idol> <alias1> <alias2>""" group = group.lower() idol = idol.lower() added_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() added = add_member_alias_db(group, idol, alias, ctx.author.id) if added: added_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and added_aliases: exists = ', '.join(invalid_aliases) rem = ', '.join(added_aliases) act = f"Added alias(es): {rem} to {idol}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Added alias(es): {rem} to {group}!\nFailed to add: {exists}!" await ctx.send(embed=success_embed(msg)) elif added_aliases and not invalid_aliases: msg = f"Added aliases(s): {', '.join(added_aliases)} to {idol}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Failed to add alias(es): {', '.join(invalid_aliases)} to {idol}!" await ctx.send(embed=error_embed(msg))
async def delete_group_alias(self, ctx, group, *aliases): """Removes an alias from an existing group. A list of aliases can be passed through in one command, but only one group. Example: .remove_group_alias redvelvet rv Example: .remove_group_alias <group> <alias1> <alias2>""" group = group.lower() removed_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() removed = remove_group_alias_db(group, alias) if removed: removed_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and removed_aliases: exists = ', '.join(invalid_aliases) rem = ', '.join(removed_aliases) act = f"Removed alias(es): {rem} from {group}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Removed alias(es): {rem} from {group}!\nFailed to removed: {exists}!" await ctx.send(embed=success_embed(msg)) elif removed_aliases and not invalid_aliases: msg = f"Removed aliases(s): {', '.join(removed_aliases)} from {group}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Failed to remove alias(es): {', '.join(invalid_aliases)} from {group}!" await ctx.send(embed=error_embed(msg))
async def add_group_alias(self, ctx, group, *aliases): """Adds an alias to an existing group that can then be used to reference the group in other commands. A list of aliases can be passed through in one command, but only one group. Example: .add_group_alias redvelvet rv Example: .add_group_alias <group> <alias1> <alias2>""" group = group.lower() added_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() added = add_group_alias_db(group, alias, ctx.author.id) if added: added_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and added_aliases: exists = ', '.join(invalid_aliases) add = ', '.join(added_aliases) act = f"Added alias(es): {add} to {group}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Added alias(es): {add} to {group}!\nSkipped adding duplicates: {exists}!" await ctx.send(embed=success_embed(msg)) elif added_aliases and not invalid_aliases: msg = f"Added aliases(s): {', '.join(added_aliases)} to {group}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Skipped adding duplicate alias(es): {', '.join(invalid_aliases)}!" await ctx.send(embed=error_embed(msg))
async def instas(self, ctx): """Returns a list of all instagram users followed in this server!""" guild = ctx.guild chans = get_all_instas_followed_in_guild() chan_dict = {} for pair in chans: if pair[0] not in chan_dict: chan_dict.update({pair[0]: [pair[-1]]}) else: chan_dict[pair[0]].append(pair[-1]) msg = '' for channel in guild.channels: if channel.id in chan_dict: for insta in chan_dict[channel.id]: insta = self.insta.get_user_name(insta) spacing = 39 - len(channel.name + insta) chan_str = f"`#{channel.name}{' ' * spacing}{insta}`\n" msg = msg + chan_str if msg == '': await ctx.send(embed=error_embed('No instagram users followed in this server!')) else: add_to_start = f"`Channel Name{' ' * 14}Instagram User`\n" msg = add_to_start + msg embed = discord.Embed(title=f'Instagram Users Followed in {guild.name}!', description=msg, color=INSTA_COLOUR) await ctx.send(embed=embed)
async def delete_tag_alias(self, ctx, tag, *aliases): """Removes an alias from a tag. A list of aliases can be passed through in one command, but only one tag. Please ensure you use the tag name, and not an alias for the first argument. Example: .delete_tag_alias <tag> <alias> Example: .delete_tag_alias <tag> <alias1> <alias2>""" tag = tag.lower() removed_aliases = [] invalid_aliases = [] for alias in aliases: alias = alias.lower() removed = remove_tag_alias_db(tag, alias) if removed: removed_aliases.append(alias) else: invalid_aliases.append(alias) if invalid_aliases and removed_aliases: exists = ', '.join(invalid_aliases) rem = ', '.join(removed_aliases) act = f"Removed alias(es): {rem} from {tag}!" await moderation_auditing(self.disclient, ctx.author, act) msg = f"Removed alias(es): {rem} from {tag}!\nFailed to removed: {exists}!" await ctx.send(embed=success_embed(msg)) elif removed_aliases and not invalid_aliases: msg = f"Removed aliases(s): {', '.join(removed_aliases)} from {tag}!" await moderation_auditing(self.disclient, ctx.author, msg) await ctx.send(embed=success_embed(msg)) else: msg = f"Failed to remove alias(es): {', '.join(invalid_aliases)} from {tag}!" await ctx.send(embed=error_embed(msg))
async def perma_user(self, ctx, user_id): """Stops user from added anything to the bot""" perma = perma_user_db(user_id) if perma: await ctx.send(embed=success_embed("User successfully perma'd.")) else: await ctx.send(embed=error_embed("Failed to perma user."))
async def command_list(self, ctx): """Sends a list of all the custom commands.""" arrr = get_commands() if len(arrr) == 0: await ctx.send(embed=error_embed('No commands added... Yet!')) else: await ctx.send(f"`{format_list(arrr.keys())}`")
async def reddits(self, ctx): """Returns a list of followed subreddits in this server.""" guild = ctx.guild chans = get_all_reddit_channels_and_sub() chan_dict = {} for pair in chans: if pair[0] not in chan_dict: chan_dict.update({pair[0]: [pair[-1]]}) else: chan_dict[pair[0]].append(pair[-1]) msg = '' for channel in guild.channels: if channel.id in chan_dict: for reddit in chan_dict[channel.id]: spacing = 39 - len(channel.name + reddit) chan_str = f"`#{channel.name}{' ' * spacing}{reddit}`\n" msg = msg + chan_str if msg == '': await ctx.send( embed=error_embed('No subreddits followed in this server!')) else: add_to_start = f"`Channel Name{' ' * 19}Subreddit`\n" msg = add_to_start + msg embed = discord.Embed( title=f'Subreddits Followed in {guild.name}!', description=msg, color=discord.Color.blurple()) await ctx.send(embed=embed)
async def remove_moderator(self, ctx, member: discord.Member): """Add user to moderator list.""" removed = remove_moderator(member.id) if removed: await ctx.send( embed=success_embed(f'{member} is no longer a moderator!')) else: await ctx.send(embed=error_embed(f'{member} is not a moderator!'))
def handle_upload_finish(message, future: concurrent.futures.Future, author, disclient, filename): if not future.cancelled(): disclient.loop.create_task( finish_upload(message, filename, future.result(), author)) else: disclient.loop.create_task( message.edit(embed=error_embed('Failed to upload!')))
async def _unrestrict_user(self, ctx, member: discord.Member): """Unrestricts a user from using Joy's Fun category commands in this discord.""" removed = remove_restricted_user(ctx.guild.id, member.id) if removed: await ctx.send(embed=success_embed( f'{member} is no longer restricted in {ctx.guild.name}!')) else: await ctx.send(embed=error_embed( f'{member} is not restricted in {ctx.guild.name}!'))
async def remove_auditing(self, ctx): """Removes auditing from this channel!""" removed = remove_auditing_channel(ctx.channel.id) if removed: des = 'Removed this channel from the auditing list!' await ctx.send(embed=success_embed(des)) else: des = 'Channel not in the auditing list!' await ctx.send(embed=error_embed(des))
async def add_moderator(self, ctx, member: discord.Member): """Add user to moderator list.""" added = add_moderator(member.id) if added: await ctx.send(embed=success_embed(f'{member} is now a moderator!') ) else: await ctx.send( embed=error_embed(f'{member} is already a moderator!'))
async def _restrict_user(self, ctx, member: discord.Member): """Restricts a user from using Joy's Fun category commands in this discord. The user can continue to use the bot in DMs, other categories, and in other discords.""" added = add_restricted_user(ctx.guild.id, member.id) if added: await ctx.send(embed=success_embed( f'Restricted {member} in {ctx.guild.name}!')) else: await ctx.send(embed=error_embed( f'{member} is already restricted in {ctx.guild.name}!'))
async def twitter_unfollow(self, ctx, user_name): """Unfollows a twitter user in this channel. Example: .unfollow_twitter <username or link>""" if 'twitter.com' in user_name: user_name = user_name.split('/')[-1] channel_id = ctx.channel.id user = self.client.get_twitter_user(user_name) if not user.id_str: # TODO make better twitter embed with images of display pics etc await ctx.send(embed=error_embed( f'Twitter user `{escape_markdown(user_name)}` not found!')) removed = remove_twitter_user_from_db(channel_id, user.id_str) if removed: await ctx.send(embed=success_embed( f'Unfollowed twitter user `{escape_markdown(user_name)}`!')) else: await ctx.send(embed=error_embed( f'Failed to unfollow twitter user `{escape_markdown(user_name)}`!' ))
async def _link_channel(self, ctx, group, idol): """Links channel to a member to automatically add links when posted in here""" group = group.lower() idol = idol.lower() added = add_linked_channel_db(ctx.channel.id, group, idol) if added: await ctx.send(embed=success_embed( f"Linked channel to automatically grab links for {group}'s {idol}!" )) else: await ctx.send(embed=error_embed(f"Failed to add linked channel!"))