def from_table(self, table): """ Parses a ship's construction info from a table. :type table: lxml.html.HtmlElement """ const_nest = { 0: 'light', 1: 'heavy', 2: 'special', 3: 'limited', 4: 'exchange' } const_time = table[1][0].text_content().strip() try: self.time = convert_to_seconds(const_time) self.possible = True except LookupError: self.time = None self.possible = False for cell_index, cell in enumerate(table[3][:5]): cell_key = const_nest.get(cell_index) cell_text = cell.text_content().strip() if cell_text == '-': const_type_possible = False else: const_type_possible = True setattr(self, cell_key, const_type_possible)
async def decay(cmd: SigmaCommand, message: discord.Message, args: list): if message.author.permissions_in(message.channel).manage_guild: if message.channel_mentions and len(args): try: decay_time = convert_to_seconds(args[0]) if decay_time >= 10: decaying_channels = await cmd.db.get_guild_settings(message.guild.id, 'DecayingChannels') or [] decaying_timers = await cmd.db.get_guild_settings(message.guild.id, 'DecayingTimers') or {} target = message.channel_mentions[0] if target.id not in decaying_channels: decaying_channels.append(target.id) action = 'created' else: action = 'updated' decaying_timers.update({str(target.id): decay_time}) await cmd.db.set_guild_settings(message.guild.id, 'DecayingChannels', decaying_channels) await cmd.db.set_guild_settings(message.guild.id, 'DecayingTimers', decaying_timers) response = discord.Embed(color=0x66CC66, title=f'✅ Decay timer for #{target.name} {action}.') else: response = discord.Embed(color=0xBE1931, title='❗ Decay has a minimum of 10 seconds.') except (LookupError, ValueError): response = discord.Embed(color=0xBE1931, title='❗ Please use the format HH:MM:SS.') else: response = discord.Embed(color=0xBE1931, title='❗ Missing channel or time.') else: response = permission_denied('Manage Server') await message.channel.send(embed=response)
async def textmute(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if not pld.msg.author.permissions_in(pld.msg.channel).manage_messages: response = denied('Access Denied. Manage Messages needed.') else: if not pld.msg.mentions: response = error('No user targeted.') else: author = pld.msg.author target = pld.msg.mentions[0] if author.id == target.id: response = error('Can\'t mute yourself.') elif cmd.bot.user.id == target.id: response = error('I can\'t mute myself.') else: above_hier = hierarchy_permit(author, target) if not above_hier: response = denied('Can\'t mute someone equal or above you.') else: timed = pld.args[-1].startswith('--time=') try: now = arrow.utcnow().timestamp endstamp = now + convert_to_seconds(pld.args[-1].split('=')[-1]) if timed else None except (LookupError, ValueError): err_response = error('Please use the format HH:MM:SS.') await pld.msg.channel.send(embed=err_response) return mute_list = pld.settings.get('muted_users') if mute_list is None: mute_list = [] if target.id in mute_list: response = error(f'{target.display_name} is already text muted.') else: mute_list.append(target.id) await cmd.db.set_guild_settings(pld.msg.guild.id, 'muted_users', mute_list) response = ok(f'{target.display_name} has been text muted.') rarg = pld.args[1:-1] if timed else pld.args[1:] if pld.args[1:] else None reason = ' '.join(rarg) if rarg else None await make_incident(cmd.db, pld.msg.guild, pld.msg.author, target, reason) log_embed = generate_log_embed(pld.msg, target, reason) await log_event(cmd.bot, pld.settings, log_embed, 'log_mutes') guild_icon = str(pld.msg.guild.icon_url) if pld.msg.guild.icon_url else discord.Embed.Empty to_target_title = '🔇 You have been text muted.' to_target = discord.Embed(color=0x696969) to_target.add_field(name=to_target_title, value=f'Reason: {reason}') to_target.set_footer(text=f'On: {pld.msg.guild.name}', icon_url=guild_icon) try: await target.send(embed=to_target) except discord.Forbidden: pass if endstamp: doc_data = {'server_id': pld.msg.guild.id, 'user_id': target.id, 'time': endstamp} await cmd.db[cmd.db.db_nam].TextmuteClockworkDocs.insert_one(doc_data) await pld.msg.channel.send(embed=response)
async def remindme(cmd: SigmaCommand, message: discord.Message, args: list): if args: time_req = args[0] try: in_seconds = convert_to_seconds(time_req) upper_limit = 7776000 if in_seconds <= upper_limit: rem_count = await cmd.db[cmd.db.db_nam].Reminders.find({ 'UserID': message.author.id }).count() rem_limit = 15 if rem_count < rem_limit: if len(args) > 1: text_message = ' '.join(args[1:]) else: text_message = 'No reminder message set.' execution_stamp = arrow.utcnow().timestamp + in_seconds timestamp = arrow.get(execution_stamp).datetime if in_seconds < 60: time_diff = f'In {in_seconds} seconds' else: time_diff = arrow.get(execution_stamp + 5).humanize( arrow.utcnow()) reminder_id = secrets.token_hex(2) reminder_data = { 'ReminderID': reminder_id, 'UserID': message.author.id, 'CreationStamp': arrow.utcnow().timestamp, 'ExecutionStamp': execution_stamp, 'ChannelID': message.channel.id, 'ServerID': message.guild.id, 'TextMessage': text_message } await cmd.db[cmd.db.db_nam ]['Reminders'].insert_one(reminder_data) response = discord.Embed(color=0x66CC66, timestamp=timestamp) response.description = text_message response.set_author(name=f'Reminder {reminder_id} Created', icon_url=user_avatar(message.author)) response.set_footer(text=f'Executes: {time_diff.title()}') else: response = discord.Embed( color=0xBE1931, title='❗ You already have 15 reminders pending.') else: response = discord.Embed( color=0xBE1931, title='❗ Reminders have a limit of 90 days.') except (LookupError, ValueError): response = discord.Embed(color=0xBE1931, title='❗ Please use the format HH:MM:SS.') else: response = discord.Embed(color=0xBE1931, title='❗ Nothing inputted.') await message.channel.send(embed=response)
async def createinvite(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.msg.author.guild_permissions.create_instant_invite: target = pld.msg.channel_mentions[ 0] if pld.msg.channel_mentions else pld.msg.channel age, uses = 0, 0 for arg in pld.args: if arg.lower().startswith('d:'): try: age = convert_to_seconds(arg.partition(':')[-1]) except (LookupError, ValueError): age = None if arg.lower().startswith('u:'): try: uses = int(arg.split(':')[-1]) except ValueError: uses = None if age is not None: if not age > 86400: if uses is not None: if not uses > 100: try: invite = await target.create_invite(max_age=age, max_uses=uses) guild_icon = str( pld.msg.guild.icon_url ) if pld.msg.guild.icon_url else discord.Embed.Empty response = discord.Embed( color=await get_image_colors(guild_icon)) response.set_author( name=f'Invite for {target.name}.', icon_url=guild_icon) age = arrow.get(arrow.utcnow().timestamp + age).humanize() if age else None details = f"**Link:** {invite}\n**Expires:** {age or 'Never'}" details += f"\n**Uses:** {uses or 'Unlimited'}" response.description = details except discord.Forbidden: response = error('I was unable to make an invite.') else: response = error('Maximum invite uses is 100.') else: response = error('Max uses must be a number.') else: response = error('Maximum invite duration is 24 hours.') else: response = error('Please use the format HH:MM:SS.') else: response = denied('Access Denied. Create Instant Invites needed.') await pld.msg.channel.send(embed=response)
def test_convert_to_seconds(): targets = [['00:0:00000001', 1], ['11:10:99', 40299], ['51:99:10', 189550], ['711:74', 42734], ['15:88', 988], ['9:59', 599], ['51', 51], ['13', 13], ['98', 98], ['banana', None], ['1:1:1:1', None], ['-19:x:chinchilla', None]] for to_conv, conv_tar in targets: try: end = convert_to_seconds(to_conv) except LookupError: end = None assert end == conv_tar
async def delayreminder(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: if len(pld.args) == 2: rem_id = pld.args[0].lower() lookup_data = {'user_id': pld.msg.author.id, 'reminder_id': rem_id} reminder = await cmd.db[cmd.db.db_nam ].Reminders.find_one(lookup_data) if reminder: try: time_req = pld.args[1] upper_limit = 7776000 in_seconds = convert_to_seconds(time_req) execution_stamp = reminder.get( 'execution_stamp') + in_seconds expires_in = execution_stamp - arrow.utcnow().int_timestamp if expires_in <= upper_limit: timestamp = arrow.get(execution_stamp).datetime if execution_stamp < 60: time_diff = f'In {in_seconds} seconds' else: time_diff = arrow.get(execution_stamp + 5).humanize(arrow.utcnow()) reminder.update({'execution_stamp': execution_stamp}) await cmd.db[cmd.db.db_nam].Reminders.update_one( lookup_data, {'$set': reminder}) response = discord.Embed(color=0x66CC66, timestamp=timestamp) response.title = f'✅ Reminder {rem_id} has been delayed.' response.set_footer( text=f'Executes: {time_diff.title()}') else: response = GenericResponse( 'Reminders have a limit of 90 days.').error() except (LookupError, ValueError): response = GenericResponse( 'Please use the format HH:MM:SS.').error() else: response = GenericResponse( f'Reminder `{rem_id}` not found.').not_found() else: response = GenericResponse('Invalid number of arguments.').error() else: response = GenericResponse('Missing reminder ID and duration.').error() await pld.msg.channel.send(embed=response)
async def delayreminder(cmd: SigmaCommand, message: discord.Message, args: list): if args: if len(args) == 2: rem_id = args[0].lower() lookup_data = {'user_id': message.author.id, 'reminder_id': rem_id} reminder = await cmd.db[cmd.db.db_nam ].Reminders.find_one(lookup_data) if reminder: try: time_req = args[1] upper_limit = 7776000 in_seconds = convert_to_seconds(time_req) execution_stamp = reminder.get( 'execution_stamp') + in_seconds expires_in = execution_stamp - arrow.utcnow().timestamp if expires_in <= upper_limit: timestamp = arrow.get(execution_stamp).datetime if execution_stamp < 60: time_diff = f'In {in_seconds} seconds' else: time_diff = arrow.get(execution_stamp + 5).humanize(arrow.utcnow()) reminder.update({'execution_stamp': execution_stamp}) await cmd.db[cmd.db.db_nam].Reminders.update_one( lookup_data, {'$set': reminder}) response = discord.Embed(color=0x66CC66, timestamp=timestamp) response.title = f'✅ Reminder {rem_id} has been delayed.' response.set_footer( text=f'Executes: {time_diff.title()}') else: response = discord.Embed( color=0xBE1931, title='❗ Reminders have a limit of 90 days.') except (LookupError, ValueError): response = discord.Embed( color=0xBE1931, title='❗ Please use the format HH:MM:SS.') else: response = discord.Embed( color=0x696969, title=f'🔍 Reminder `{rem_id}` not found.') else: response = discord.Embed(color=0xBE1931, title='❗ Invalid number of arguments.') else: response = discord.Embed(color=0xBE1931, title='❗ Missing reminder ID and duration.') await message.channel.send(embed=response)
async def raffle(cmd: SigmaCommand, message: discord.Message, args: list): if len(args) >= 2: time_input = args[0] raffle_title = ' '.join(args[1:]) try: time_sec = convert_to_seconds(time_input) start_stamp = arrow.utcnow().float_timestamp end_stamp = start_stamp + time_sec end_dt = arrow.get(end_stamp).datetime if time_sec < 90: end_hum = f'in {time_sec} seconds' else: end_hum = arrow.get(end_stamp).humanize() rafid = secrets.token_hex(3) reaction_icon = secrets.choice(raffle_icons) icon_color = icon_colors.get(reaction_icon) resp_title = f'{message.author.display_name} started a raffle!' starter = discord.Embed(color=icon_color, timestamp=end_dt) starter.set_author(name=resp_title, icon_url=user_avatar(message.author)) starter.description = f'Reward: **{raffle_title}**' starter.description += f'\nReact with a {reaction_icon} to enter the raffle.' starter.set_footer(text=f'[{rafid}] Raffle ends {end_hum}.') starter_message = await message.channel.send(embed=starter) await starter_message.add_reaction(reaction_icon) raffle_data = { 'Author': message.author.id, 'Channel': message.channel.id, 'Title': raffle_title, 'Start': start_stamp, 'End': end_stamp, 'Icon': reaction_icon, 'Color': icon_color, 'Message': starter_message.id, 'Active': True, 'ID': rafid } await cmd.db[cmd.db.db_cfg.database ].Raffles.insert_one(raffle_data) response = None except (LookupError, ValueError): response = discord.Embed(color=0xBE1931, title='❗ Please use the format HH:MM:SS.') else: response = discord.Embed(color=0xBE1931, title='❗ No arguments inputted.') if response: await message.channel.send(embed=response)
async def textmute(cmd: SigmaCommand, message: discord.Message, args: list): if not message.author.permissions_in(message.channel).manage_messages: response = permission_denied('Manage Messages') else: if not message.mentions: response = discord.Embed(color=0xBE1931, title='❗ No user targeted.') else: author = message.author target = message.mentions[0] if author.id == target.id: response = discord.Embed(color=0xBE1931, title='❗ Can\'t mute yourself.') else: above_hier = hierarchy_permit(author, target) if not above_hier: response = discord.Embed(color=0xBE1931, title='⛔ Can\'t mute someone equal or above you.') else: timed = args[-1].startswith('--time=') endstamp = arrow.utcnow().timestamp + convert_to_seconds(args[-1].split('=')[-1]) if timed else None mute_list = await cmd.db.get_guild_settings(message.guild.id, 'MutedUsers') if mute_list is None: mute_list = [] if target.id in mute_list: resp_title = f'❗ {target.display_name} is already text muted.' response = discord.Embed(color=0xBE1931, title=resp_title) else: mute_list.append(target.id) await cmd.db.set_guild_settings(message.guild.id, 'MutedUsers', mute_list) response = discord.Embed(color=0x77B255, title=f'✅ {target.display_name} has been text muted.') rarg = args[1:-1] if timed else args[1:] if args[1:] else None reason = ' '.join(rarg) if rarg else None log_embed = generate_log_embed(message, target, reason) await log_event(cmd.bot, message.guild, cmd.db, log_embed, 'LogMutes') to_target_title = f'🔇 You have been text muted.' to_target = discord.Embed(color=0x696969) to_target.add_field(name=to_target_title, value=f'Reason: {reason}') to_target.set_footer(text=f'On: {message.guild.name}', icon_url=message.guild.icon_url) try: await target.send(embed=to_target) except discord.Forbidden: pass if endstamp: doc_data = {'ServerID': message.guild.id, 'UserID': target.id, 'Time': endstamp} await cmd.db[cmd.db.db_nam].TextmuteClockworkDocs.insert_one(doc_data) await message.channel.send(embed=response)
async def createinvite(cmd: SigmaCommand, message: discord.Message, args: list): if message.author.guild_permissions.create_instant_invite: target = message.channel_mentions[ 0] if message.channel_mentions else message.channel age, uses = 0, 0 for arg in args: if arg.lower().startswith('d:'): try: age = convert_to_seconds(arg.partition(':')[-1]) except (LookupError, ValueError): age = None if arg.lower().startswith('u:'): try: uses = int(arg.split(':')[-1]) except ValueError: uses = None if age is not None: if uses is not None: try: invite = await target.create_invite(max_age=age, max_uses=uses) response = discord.Embed( color=await get_image_colors(message.guild.icon_url)) response.set_author(name=f'Invite for {target.name}.', icon_url=message.guild.icon_url) age = arrow.get(arrow.utcnow().timestamp + age).humanize() if age else None details = f"**Link:** {invite}\n**Expires:** {age or 'Never'}\n**Uses:** {uses or 'Unlimited'}" response.description = details except discord.Forbidden: response = discord.Embed( color=0xBE1931, title='❗ I was unable to make an invite.') else: response = discord.Embed(color=0xBE1931, title='❗ Max uses must be a number.') else: response = discord.Embed(color=0xBE1931, title='❗ Please use the format HH:MM:SS.') else: response = permission_denied('Create Instant Invites') await message.channel.send(embed=response)
async def raffle(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if len(pld.args) >= 2: time_input = pld.args[0] try: time_sec = convert_to_seconds(time_input) start_stamp = arrow.utcnow().float_timestamp end_stamp = start_stamp + time_sec end_dt = arrow.get(end_stamp).datetime if time_sec < 90: end_hum = f'in {time_sec} seconds' else: end_hum = arrow.get(end_stamp).humanize() rafid = secrets.token_hex(3) reaction_name = reaction_icon = pld.settings.get('raffle_icon') icon_color = None if reaction_icon: gld = pld.msg.guild guild_icon = str( gld.icon_url) if gld.icon_url else discord.Embed.Empty custom_emote = reaction_icon.startswith( '<:') and reaction_icon.endswith('>') if custom_emote: emote_name = reaction_icon.split(':')[1] matching_emote = None for emote in pld.msg.guild.emojis: if emote.name == emote_name: matching_emote = emote if not matching_emote: reaction_icon = None await cmd.db.set_guild_settings( pld.msg.guild.id, 'raffle_icon', None) else: reaction_icon = matching_emote icon_color = await get_image_colors(matching_emote.url) else: icon_color = await get_image_colors(guild_icon) if not reaction_icon: reaction_name = reaction_icon = secrets.choice(raffle_icons) icon_color = icon_colors.get(reaction_icon) resp_title = f'{pld.msg.author.display_name} started a raffle!' target_ch = pld.msg.channel_mentions[ 0] if pld.msg.channel_mentions else pld.msg.channel external = pld.msg.channel.id != target_ch.id draw_count = 1 args = [a.lower() for a in pld.args] for arg in args: if arg.startswith('winners:'): pld.args.pop(args.index(arg)) draw_num = arg.split(':')[-1] if draw_num.isdigit(): draw_count = int(draw_num) break if external: allowed = pld.msg.author.permissions_in( target_ch).send_messages if allowed: for ai, arg in enumerate(pld.args): if arg == target_ch.mention: pld.args.pop(ai) else: allowed = True if allowed: raffle_title = ' '.join(pld.args[1:]) starter = discord.Embed(color=icon_color, timestamp=end_dt) starter.set_author(name=resp_title, icon_url=user_avatar(pld.msg.author)) starter.description = f'Prize: **{raffle_title}**' starter.description += f'\nReact with a {reaction_icon} to enter the raffle.' starter.set_footer(text=f'[{rafid}] Raffle ends {end_hum}.') starter_message = await target_ch.send(embed=starter) await starter_message.add_reaction(reaction_icon) raffle_data = { 'author': pld.msg.author.id, 'channel': target_ch.id, 'title': raffle_title, 'start': start_stamp, 'end': end_stamp, 'icon': reaction_name, 'color': icon_color, 'draw_count': draw_count, 'message': starter_message.id, 'active': True, 'id': rafid } await cmd.db[cmd.db.db_nam].Raffles.insert_one(raffle_data) response = None else: response = denied( f'You can\'t send messages to #{target_ch.name}.') except (LookupError, ValueError): response = error('Please use the format HH:MM:SS.') else: response = error('Nothing inputted.') if response: await pld.msg.channel.send(embed=response)
async def autopunishlevels(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.msg.author.guild_permissions.manage_guild: if not pld.args: settings = pld.settings.get('auto_punish_levels') or {} if settings: level_info = [] for level, details in settings.items(): action = details.get('action') duration = details.get('duration') lvl_word = 'Warning' if int(level) == 1 else 'Warnings' info = f'**{level} {lvl_word}:** {action.title()}' if duration: info += f' ({parse_time(duration)})' level_info.append(info) response = discord.Embed(color=0x3B88C3, title='🔄 Auto-Punishment Levels') response.description = '\n'.join(level_info) else: response = GenericResponse('No Auto-Punishments set.').error() else: if ':' in pld.args[0]: duration = None if len(pld.args) > 1: try: duration = convert_to_seconds(pld.args[-1]) except (LookupError, ValueError): err_response = GenericResponse( 'Please use the format HH:MM:SS.').error() await pld.msg.channel.send(embed=err_response) return level, _, action = pld.args[0].partition(':') if level.isdigit() and action.lower() in actions: settings = pld.settings.get('auto_punish_levels') or {} if action.lower() == 'remove': if str(level) in settings: settings.pop(str(level)) response = GenericResponse( f'Level {level} punishment removed.').ok() else: if duration and action.lower() in ['softban', 'kick']: err_response = GenericResponse( f'{action.title()} cannot be timed.').error() await pld.msg.channel.send(embed=err_response) return settings.update({ str(level): { 'action': action.lower(), 'duration': duration } }) ok_text = f'Level {level} set to {action.lower()}' if duration: ok_text += f' ({parse_time(duration)})' response = GenericResponse(ok_text).ok() await cmd.db.set_guild_settings(pld.msg.guild.id, 'auto_punish_levels', settings) else: ender = 'level' if not level.isdigit() else 'punishment' response = GenericResponse(f'Invalid {ender}.').error() else: response = GenericResponse( 'Separate level and punishment with a colon.').error() else: response = GenericResponse( 'Access Denied. Manage Server needed.').denied() await pld.msg.channel.send(embed=response)
async def ban(cmd: SigmaCommand, message: discord.Message, args: list): if message.author.permissions_in(message.channel).ban_members: if message.mentions: target = message.mentions[0] timed = args[-1].startswith('--time=') try: now = arrow.utcnow().timestamp endstamp = now + convert_to_seconds( args[-1].split('=')[-1]) if timed else None except (LookupError, ValueError): err_response = discord.Embed( color=0xBE1931, title='❗ Please use the format HH:MM:SS.') await message.channel.send(embed=err_response) return if len(args) >= 2: try: if endstamp: clean_days = int(args[-2]) else: clean_days = int(args[-1]) except ValueError: clean_days = 0 else: clean_days = 0 clean_days = clean_days if clean_days in [0, 1, 7] else 0 if cmd.bot.user.id != target.id: if message.author.id != target.id: above_hier = hierarchy_permit(message.author, target) is_admin = message.author.permissions_in( message.channel).administrator if above_hier or is_admin: above_me = hierarchy_permit(message.guild.me, target) if above_me: rarg = args[1:-1] if timed else args[1:] if args[ 1:] else None reason = ' '.join(rarg) if rarg else None response = discord.Embed( color=0x696969, title=f'🔨 The user has been banned.') response_title = f'{target.name}#{target.discriminator}' response.set_author(name=response_title, icon_url=user_avatar(target)) to_target = discord.Embed(color=0x696969) to_target.add_field(name='🔨 You have been banned.', value=f'Reason: {reason}') to_target.set_footer( text=f'From: {message.guild.name}.', icon_url=message.guild.icon_url) try: await target.send(embed=to_target) except discord.Forbidden: pass audit_reason = f'By {message.author.name}: {reason}' await target.ban(reason=audit_reason, delete_message_days=clean_days) log_embed = generate_log_embed( message, target, reason) await log_event(cmd.bot, message.guild, cmd.db, log_embed, 'log_bans') if endstamp: doc_data = { 'server_id': message.guild.id, 'user_id': target.id, 'time': endstamp } await cmd.db[ cmd.db.db_nam ].BanClockworkDocs.insert_one(doc_data) else: response = discord.Embed( color=0xBE1931, title='⛔ Target is above my highest role.') else: response = discord.Embed( color=0xBE1931, title='⛔ Can\'t ban someone equal or above you.') else: response = discord.Embed( color=0xBE1931, title='❗ You can\'t ban yourself.') else: response = discord.Embed(color=0xBE1931, title='❗ I can\'t ban myself.') else: response = discord.Embed(color=0xBE1931, title='❗ No user targeted.') else: response = permission_denied('Ban permissions') await message.channel.send(embed=response)
async def remindme(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: time_req = pld.args[0] try: in_seconds = convert_to_seconds(time_req) upper_limit = 7776000 if in_seconds <= upper_limit: rem_count = await cmd.db[cmd.db.db_nam ].Reminders.count_documents( {'user_id': pld.msg.author.id}) rem_limit = 15 if rem_count < rem_limit: is_dm = False if len(pld.args) > 1: if pld.args[-1].lower() == '--direct': is_dm = True text_message = ' '.join(pld.args[1:-1]) text_message = 'No reminder message set.' if not text_message else text_message else: text_message = ' '.join(pld.args[1:]) else: text_message = 'No reminder message set.' execution_stamp = arrow.utcnow().int_timestamp + in_seconds timestamp = arrow.get(execution_stamp).datetime if in_seconds < 60: time_diff = f'In {in_seconds} seconds' else: time_diff = arrow.get(execution_stamp + 5).humanize( arrow.utcnow()) reminder_id = secrets.token_hex(2) reminder_data = { 'reminder_id': reminder_id, 'user_id': pld.msg.author.id, 'creation_stamp': arrow.utcnow().int_timestamp, 'execution_stamp': execution_stamp, 'channel_id': pld.msg.channel.id, 'server_id': pld.msg.guild.id, 'text_message': text_message, 'direct_message': is_dm } await cmd.db[cmd.db.db_nam ].Reminders.insert_one(reminder_data) response = discord.Embed(color=0x66CC66, timestamp=timestamp) response.description = text_message response.set_author(name=f'Reminder {reminder_id} Created', icon_url=user_avatar(pld.msg.author)) response.set_footer(text=f'Executes: {time_diff.title()}') else: response = GenericResponse( 'You already have 15 reminders pending.').error() else: response = GenericResponse( 'Reminders have a limit of 90 days.').error() except (LookupError, ValueError): response = GenericResponse( 'Please use the format HH:MM:SS.').error() else: response = GenericResponse('Nothing inputted.').error() await pld.msg.channel.send(embed=response)
async def hardmute(cmd: SigmaCommand, message: discord.Message, args: list): if message.author.permissions_in(message.channel).manage_channels: if message.mentions: target = message.mentions[0] hierarchy_me = hierarchy_permit(message.guild.me, target) if hierarchy_me: hierarchy_auth = hierarchy_permit(message.author, target) if hierarchy_auth: ongoing = discord.Embed(color=0x696969, title='⛓ Editing permissions...') ongoing_msg = await message.channel.send(embed=ongoing) timed = args[-1].startswith('--time=') try: now = arrow.utcnow().timestamp endstamp = now + convert_to_seconds( args[-1].split('=')[-1]) if timed else None except (LookupError, ValueError): err_response = discord.Embed( color=0xBE1931, title='❗ Please use the format HH:MM:SS.') await message.channel.send(embed=err_response) return for channel in message.guild.channels: if isinstance(channel, discord.TextChannel) or isinstance( channel, discord.CategoryChannel): try: await channel.set_permissions( target, send_messages=False, add_reactions=False) except discord.Forbidden: pass await ongoing_msg.delete() rarg = args[ 1:-1] if timed else args[1:] if args[1:] else None reason = ' '.join(rarg) if rarg else None log_embed = generate_log_embed(message, target, reason) await log_event(cmd.bot, message.guild, cmd.db, log_embed, 'log_mutes') title = f'✅ {target.display_name} has been hard-muted.' response = discord.Embed(color=0x77B255, title=title) to_target_title = f'🔇 You have been hard-muted.' to_target = discord.Embed(color=0x696969) to_target.add_field(name=to_target_title, value=f'Reason: {reason}') to_target.set_footer(text=f'On: {message.guild.name}', icon_url=message.guild.icon_url) try: await target.send(embed=to_target) except discord.Forbidden: pass if endstamp: doc_data = { 'server_id': message.guild.id, 'user_id': target.id, 'time': endstamp } await cmd.db[ cmd.db.db_nam ].HardmuteClockworkDocs.insert_one(doc_data) else: response = discord.Embed( color=0xBE1931, title='❗ That user is equal or above you.') else: response = discord.Embed( color=0xBE1931, title='❗ I can\'t mute a user equal or above me.') else: response = discord.Embed(color=0xBE1931, title='❗ No user targeted.') else: response = permission_denied('Manage Channels') await message.channel.send(embed=response)
async def ban(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.msg.author.permissions_in(pld.msg.channel).ban_members: target = get_broad_target(pld) if target: timed = pld.args[-1].startswith('--time=') try: now = arrow.utcnow().timestamp endstamp = now + convert_to_seconds( pld.args[-1].split('=')[-1]) if timed else None except (LookupError, ValueError): err_response = error('Please use the format HH:MM:SS.') await pld.msg.channel.send(embed=err_response) return if len(pld.args) >= 2: try: if endstamp: clean_days = int(pld.args[-2]) else: clean_days = int(pld.args[-1]) except ValueError: clean_days = 0 else: clean_days = 0 clean_days = clean_days if clean_days in [0, 1, 7] else 0 if cmd.bot.user.id != target.id: if pld.msg.author.id != target.id: above_hier = hierarchy_permit(pld.msg.author, target) is_admin = pld.msg.author.permissions_in( pld.msg.channel).administrator if above_hier or is_admin: above_me = hierarchy_permit(pld.msg.guild.me, target) if above_me: rarg = pld.args[1:-1] if timed else pld.args[ 1:] if pld.args[1:] else None reason = ' '.join(rarg) if rarg else None response = discord.Embed( color=0x696969, title='🔨 The user has been banned.') response_title = f'{target.name}#{target.discriminator}' response.set_author(name=response_title, icon_url=user_avatar(target)) guild_icon = str( pld.msg.guild.icon_url ) if pld.msg.guild.icon_url else discord.Embed.Empty to_target = discord.Embed(color=0x696969) to_target.add_field( name='🔨 You have been banned.', value=f'Reason: {reason}') to_target.set_footer( text=f'From: {pld.msg.guild.name}.', icon_url=guild_icon) try: await target.send(embed=to_target) except discord.Forbidden: pass audit_reason = f'By {pld.msg.author.name}#{pld.msg.author.discriminator}: {reason}' await target.ban(reason=audit_reason, delete_message_days=clean_days) log_embed = generate_log_embed( pld.msg, target, reason) await log_event(cmd.bot, pld.settings, log_embed, 'log_bans') if endstamp: doc_data = { 'server_id': pld.msg.guild.id, 'user_id': target.id, 'time': endstamp } await cmd.db[ cmd.db.db_nam ].BanClockworkDocs.insert_one(doc_data) else: response = denied( 'Target is above my highest role.') else: response = denied( 'Can\'t ban someone equal or above you.') else: response = error('You can\'t ban yourself.') else: response = error('I can\'t ban myself.') else: response = error('No user targeted.') else: response = denied('Access Denied. Ban permissions needed.') await pld.msg.channel.send(embed=response)
async def hardmute(cmd, pld): """ :param cmd: The command object referenced in the command. :type cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.msg.author.permissions_in(pld.msg.channel).manage_channels: target = get_broad_target(pld) if target: hierarchy_me = hierarchy_permit(pld.msg.guild.me, target) if hierarchy_me: hierarchy_auth = hierarchy_permit(pld.msg.author, target) if hierarchy_auth: ongoing = discord.Embed(color=0x696969, title='⛓ Editing permissions...') ongoing_msg = await pld.msg.channel.send(embed=ongoing) timed = pld.args[-1].startswith('--time=') try: now = arrow.utcnow().int_timestamp endstamp = now + convert_to_seconds(pld.args[-1].split('=')[-1]) if timed else None except (LookupError, ValueError): err_response = GenericResponse('Please use the format HH:MM:SS.').error() await pld.msg.channel.send(embed=err_response) return for channel in pld.msg.guild.channels: if isinstance(channel, discord.TextChannel) or isinstance(channel, discord.CategoryChannel): try: await channel.set_permissions(target, send_messages=False, add_reactions=False) except (discord.Forbidden, discord.NotFound): pass try: await ongoing_msg.delete() except discord.NotFound: pass rarg = pld.args[1:-1] if timed else pld.args[1:] if pld.args[1:] else None reason = ' '.join(rarg) if rarg else None await make_incident(cmd.db, pld.msg.guild, pld.msg.author, target, reason) log_embed = generate_log_embed(pld.msg, target, reason) await log_event(cmd.bot, pld.settings, log_embed, 'log_mutes') response = GenericResponse(f'{target.display_name} has been hard-muted.').ok() guild_icon = str(pld.msg.guild.icon_url) if pld.msg.guild.icon_url else discord.Embed.Empty to_target_title = '🔇 You have been hard-muted.' to_target = discord.Embed(color=0x696969) to_target.add_field(name=to_target_title, value=f'Reason: {reason}') to_target.set_footer(text=f'On: {pld.msg.guild.name}', icon_url=guild_icon) try: await target.send(embed=to_target) except (discord.Forbidden, discord.HTTPException): pass if endstamp: doc_data = {'server_id': pld.msg.guild.id, 'user_id': target.id, 'time': endstamp} await cmd.db[cmd.db.db_nam].HardmuteClockworkDocs.insert_one(doc_data) else: response = GenericResponse('That user is equal or above you.').error() else: response = GenericResponse('I can\'t mute a user equal or above me.').error() else: response = GenericResponse('No user targeted.').error() else: response = GenericResponse('Access Denied. Manage Channels needed.').denied() await pld.msg.channel.send(embed=response)
async def wftrials(_cmd, pld): """ :param _cmd: The command object referenced in the command. :type _cmd: sigma.core.mechanics.command.SigmaCommand :param pld: The payload with execution data and details. :type pld: sigma.core.mechanics.payload.CommandPayload """ if pld.args: username = '******'.join(pld.args) trials_url = f'https://api.trials.wf/api/player/pc/{username}/completed' async with aiohttp.ClientSession() as session: async with session.get(trials_url) as data: trial_data = await data.read() trial_data = json.loads(trial_data) if len(trial_data) == 0: response = GenericResponse( f'User {username} Not Found.').not_found() else: # noinspection PyBroadException try: username_proper = get_usercaps(username, trial_data) raidlist_url = f'https://trials.wf/player/?user={username_proper}' # LoR lor_deaths = 0 lor_kills = 0 lor_time_total = 0 lor_time_short = 0 lor_count = 0 lor_won = 0 lor_failed = 0 # LoR NM lornm_deaths = 0 lornm_kills = 0 lornm_time_total = 0 lornm_time_short = 0 lornm_count = 0 lornm_won = 0 lornm_failed = 0 # JV jv_deaths = 0 jv_kills = 0 jv_time_total = 0 jv_time_short = 0 jv_count = 0 jv_won = 0 jv_failed = 0 # Calculate Data for trial in trial_data: if trial['type'] == 'lor': lor_deaths += trial['deaths'] lor_kills += trial['kills'] lor_time_total += convert_to_seconds(trial['time']) if lor_time_short == 0: lor_time_short = convert_to_seconds(trial['time']) else: if lor_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': lor_time_short = convert_to_seconds( trial['time']) lor_count += 1 if trial['objective'] == 'VICTORY': lor_won += 1 elif trial['objective'] == 'FAILED': lor_failed += 1 elif trial['type'] == 'lornm': lornm_deaths += trial['deaths'] lornm_kills += trial['kills'] lornm_time_total += convert_to_seconds(trial['time']) lornm_count += 1 if trial['objective'] == 'VICTORY': lornm_won += 1 elif trial['objective'] == 'FAILED': lornm_failed += 1 if lornm_time_short == 0: lornm_time_short = convert_to_seconds( trial['time']) else: if lornm_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': lornm_time_short = convert_to_seconds( trial['time']) elif trial['type'] == 'jv': jv_deaths += trial['deaths'] jv_kills += trial['kills'] jv_time_total += convert_to_seconds(trial['time']) jv_count += 1 if trial['objective'] == 'VICTORY': jv_won += 1 elif trial['objective'] == 'FAILED': jv_failed += 1 if jv_time_short == 0: jv_time_short = convert_to_seconds(trial['time']) else: if jv_time_short > convert_to_seconds( trial['time']): if trial['objective'] == 'VICTORY': jv_time_short = convert_to_seconds( trial['time']) # Total total_deaths = lor_deaths + lornm_deaths + jv_deaths total_kills = lor_kills + lornm_kills + jv_kills total_time_total = lor_time_total + lornm_time_total + jv_time_total total_time_short = 0 short_times = [lor_time_short, lornm_time_short, jv_time_short] for short_time in short_times: if total_time_short == 0: total_time_short = short_time else: if total_time_short > short_time: total_time_short = short_time total_count = lor_count + lornm_count + jv_count total_won = lor_won + lornm_won + jv_won total_failed = lor_failed + lornm_failed + jv_failed # Make Descriptions try: lor_desc = f'Total: {lor_count}' lor_desc += f'\nWin/Lose: {lor_won}/{lor_failed}' lor_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lor_time_total))}' lor_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(lor_time_total // lor_count)))}' lor_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lor_time_short))}' lor_desc += f'\nKills: {lor_kills}' lor_desc += f'\nAverage Kills: {lor_kills // lor_count}' lor_desc += f'\nDeaths: {lor_deaths}' lor_desc += f'\nAverage Deaths: {lor_deaths // lor_count}' except ZeroDivisionError: lor_desc = 'Invalid Data' try: lornm_desc = f'Total: {lornm_count}' lornm_desc += f'\nWin/Lose: {lornm_won}/{lornm_failed}' lornm_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lornm_time_total))}' lornm_avg_sec = lornm_time_total // lornm_count lornm_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=lornm_avg_sec))}' lornm_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lornm_time_short))}' lornm_desc += f'\nKills: {lornm_kills}' lornm_desc += f'\nAverage Kills: {lornm_kills // lornm_count}' lornm_desc += f'\nDeaths: {lornm_deaths}' lornm_desc += f'\nAverage Deaths: {lornm_deaths // lornm_count}' except ZeroDivisionError: lornm_desc = 'Invalid Data' try: jv_desc = f'Total: {jv_count}' jv_desc += f'\nWin/Lose: {jv_won}/{jv_failed}' jv_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=jv_time_total))}' jv_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(jv_time_total // jv_count)))}' jv_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=jv_time_short))}' jv_desc += f'\nKills: {jv_kills}' jv_desc += f'\nAverage Kills: {jv_kills // jv_count}' jv_desc += f'\nDeaths: {jv_deaths}' jv_desc += f'\nAverage Deaths: {jv_deaths // jv_count}' except ZeroDivisionError: jv_desc = 'Invalid Data' try: total_desc = f'Total: {total_count}' total_desc += f'\nWin/Lose: {total_won}/{total_failed}' total_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=total_time_total))}' total_desc += '\nAverage Time: ' total_desc += f'{str(datetime.timedelta(seconds=(total_time_total // total_count)))}' total_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=total_time_short))}' total_desc += f'\nKills: {total_kills}' total_desc += f'\nAverage Kills: {total_kills // total_count}' total_desc += f'\nDeaths: {total_deaths}' total_desc += f'\nAverage Deaths: {total_deaths // total_count}' except ZeroDivisionError: total_desc = 'Invalid Data' response = discord.Embed(color=0xa12626) response.set_thumbnail(url='https://i.imgur.com/pf89nIk.png') response.set_author(name=username_proper, icon_url='https://i.imgur.com/n0EESkn.png', url=raidlist_url) response.add_field(name='Law of Retribution', value=lor_desc) response.add_field(name='Nightmare LoR', value=lornm_desc) response.add_field(name='Jordas Verdict', value=jv_desc) response.add_field(name='Total Trials', value=total_desc) except Exception: response = GenericResponse( f'Stats for {username} were found but contained errors.' ).warn() await pld.msg.channel.send(embed=response)