async def ti_delete(self, ctx, user, id): member = ctx.message.mentions[0] sender = ctx.message.author # If time in channel has not been set if config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() else: async for message in self.bot.get_channel( config.get_timein_channel()).history( limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user( message, member.display_name) and (id in curr_message): lines = message.content.splitlines() # Delete whole message if len(lines) <= 5: await message.delete() await ctx.message.delete() return else: for line in lines: if id in line: new_message = curr_message.replace(line, "") new_message_clean = os.linesep.join( [s for s in new_message.splitlines() if s]) await message.edit(content=new_message_clean) await ctx.message.delete() return await sender.send('[Error] Cannot find time in ID.')
async def ti_cont(self, ctx): member = ctx.message.author # If time in channel has not been set if config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() # If member has not defined a timezone elif config.get_user_val(member, 'time_zone') is None: await member.send( '[Error] Please define your timezone: .set_timezone <zone_num>\n' 'Example: .set_timezone 1 \n \n' 'To find your timezone: .search_timezone <args>\n' 'Example: .search_timezone Pacific US') await ctx.message.delete() # If member is already timed in elif await self.is_timed_in(member): await member.send('[Error] You already have an' ' active time in.') await ctx.message.delete() # Member can time in else: task = await self.get_timein_task(member) time_raw = ctx.message.created_at time = await self.get_time(member, time_raw) await self.time_in(member, task, time) await ctx.message.delete()
async def ti_gethours(self, ctx, user): member = ctx.message.mentions[0] sender = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): if (config.get_payday() is None) or (config.get_user_val( member, 'pay_rate') is None): await sender.send( '[Error] Please define a pay day and a pay rate for the user.' ) else: time_raw = ctx.message.created_at time = await self.get_time(member, time_raw) time_sum = 0 async for message in self.bot.get_channel( config.get_timein_channel()).history( limit=self.MESSAGE_LIMIT): if await self.valid_calc(member, message, time): time_sum += await self.get_timein_hours(message) await sender.send( member.display_name + ' has timed in: ' + str(time_sum) + ' hours and has earned: $' + str(config.get_user_val(member, 'pay_rate') * time_sum) + ' this pay period.') await member.send( '[Announcement] A time in report is being generated. Please notify an admin if you are currently timed in or your time ins are incorrect.' ) await ctx.message.delete() else: await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def ti_search_timezones(self, ctx, *args): member = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): zones = pytz.all_timezones output = '' if len(args) <= 0: await member.send('[Error] Please insert keywords.') await ctx.message.delete() else: try: for zone in zones: if all(arg.lower() in zone.lower() for arg in args): if len(output) > 0: output += ', ' output += '[' + str( zones.index(zone)) + '] ' + zone await member.send(output) await ctx.message.delete() except: await member.send( '[Error] Can not find time zone matching keywords.') await ctx.message.delete() else: await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def ti_set_timezone(self, ctx, user, zone_num): member = ctx.message.mentions[0] sender = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): zones = pytz.all_timezones # Check if zone is int and is valid if zone_num.isdigit(): zone_num = int(zone_num) if zone_num >= 0 and zone_num <= len(zones): config.update_user(member, 'time_zone', zones[zone_num]) await sender.send('[Success] Updated time zone.') await ctx.message.delete() else: await sender.send('[Error] Not a valid zone number.') await ctx.message.delete() else: await sender.send('[Error] Please enter a zone number.') await ctx.message.delete() else: await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def ti_update(self, ctx, user, id, in_time, out_time, *description): member = ctx.message.mentions[0] sender = ctx.message.author in_time_raw = datetime.datetime.strptime(in_time, '%H:%M') out_time_raw = datetime.datetime.strptime(out_time, '%H:%M') task = ' '.join(description) # if there is no description if len(description) <= 0: await sender.send('[Error] Please include a timein description.') await ctx.message.delete() # If description is too long elif len(task) > 65: await member.send('[Error] Timein description is too long.') await ctx.message.delete() # If time in channel has not been set elif config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() # Member has invalid characters elif not await self.message_valid(task): await sender.send( '[Error] Invalid characters in time in description.') await ctx.message.delete() # Check if time range is valid elif not await self.valid_range(in_time_raw, out_time_raw): await sender.send( '[Error] Time in time must be before time out time.') await ctx.message.delete() else: async for message in self.bot.get_channel( config.get_timein_channel()).history( limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user( message, member.display_name) and (id in curr_message): lines = message.content.splitlines() for line in lines: if id in line: appended = curr_message.replace( line, ' [' + id + '] ' + task + ' {' + in_time_raw.strftime("%H:%M") + ' - ' + out_time_raw.strftime("%H:%M") + '}') await message.edit(content=appended) await ctx.message.delete() return await sender.send('[Error] Cannot find time in ID.') await ctx.message.delete()
async def timeout(self, ctx): member = ctx.message.author # If time in channel has not been set if config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() else: time_raw = ctx.message.created_at await ctx.message.delete() time = await self.get_time(member, time_raw) await self.time_out(member, time)
async def ti_set_pay(self, ctx, user, amount): sender = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): member = ctx.message.mentions[0] pay = float(amount) config.update_user(member, 'pay_rate', pay) await sender.send('[Success] Updated pay of ' + member.display_name + ' to: $' + str(pay) + ".") await ctx.message.delete() else: await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def timein_dic(self, start_date, end_date): output = {} timein_users = await self.timein_users() # Add all users to dic for member in timein_users: output[member.display_name] = {} for day in self.daterange(start_date, end_date): output[member.display_name][day.strftime("%B %d, %Y")] = 0 # Calculate time ins for day in self.daterange(start_date, end_date): async for message in self.bot.get_channel( config.get_timein_channel()).history( limit=self.MESSAGE_LIMIT): curr_message = message.content # If message contains date if (day.strftime("%B %d, %Y") in curr_message) and message.author.bot: # Check all users for each for user in timein_users: # Add total hours to specified user if user.display_name in curr_message: total = await self.get_timein_hours(message) output[user.display_name][day.strftime( "%B %d, %Y")] += total # Flatten list flattened = {} for member in timein_users: flattened[member.display_name] = [] for day in self.daterange(start_date, end_date): flattened[member.display_name].append( output[member.display_name][day.strftime("%B %d, %Y")]) return flattened
async def time_in(self, member, task, time): emote = config.get_user_val(member, 'emote') emote_id = await self.get_emote_id(emote) emote_display = '<:' + emote + ':' + str(emote_id) + '>' if emote_id is None: emote_display = ':' + emote + ':' last_timein = await self.check_timein(member, time) # New time in for the day if last_timein is None: ti_message = '----------------------- \n' ti_message += (emote_display + ' ' + member.display_name + ' ' + emote_display) ti_message += '\n----------------------- \n*' + time.strftime( "%B %d, %Y") + '*' identifier = await self.get_identifier(member) task_message = '\n [' + identifier + '] ' + task + ' {' + time.strftime( "%H:%M") + ' - ???}' await self.bot.get_channel(config.get_timein_channel() ).send(ti_message + task_message) # Add on to an existing time in else: identifier = await self.get_identifier(member) updated_timein = last_timein.content + '\n [' + identifier + '] ' + task + ' {' + time.strftime( "%H:%M") + ' - ???}' await last_timein.edit(content=updated_timein)
async def timeout_message(self, member, time): async for message in self.bot.get_channel( config.get_timein_channel()).history(limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user(message, member.display_name): curr_message = curr_message.replace('???', time) await message.edit(content=curr_message)
async def is_timed_in(self, member): async for message in self.bot.get_channel( config.get_timein_channel()).history(limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user(message, member.display_name): if '???}' in curr_message: return True return False
async def get_timein_date(self, member): async for message in self.bot.get_channel( config.get_timein_channel()).history(limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user(message, member.display_name): init_split = curr_message.split('*') date = init_split[1].split('*') return date[0]
async def check_timein(self, member, date): async for message in self.bot.get_channel( config.get_timein_channel()).history(limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user(message, member.display_name): if date.strftime("%B %d, %Y") in curr_message: return message return None
async def check_pay(self): for member in self.bot.get_channel( config.get_timein_channel()).members: if member.id != self.bot.user.id: if (config.get_user_val(member, 'pay_rate') is None) and ( member.id not in config.get_timein_exclusions()): return False return True
async def timein_users(self): timein_exclude = config.get_timein_exclusions() output = [] for member in self.bot.get_channel( config.get_timein_channel()).members: if member.id not in timein_exclude and member.id != self.bot.user.id: output.append(member) return output
async def get_timein_task(self, member): async for message in self.bot.get_channel( config.get_timein_channel()).history(limit=self.MESSAGE_LIMIT): curr_message = message.content if await self.valid_timein_user(message, member.display_name): line_split = curr_message.split('\n') line_split_len = len(line_split) id_split = line_split[line_split_len - 1].split('] ') time_split = id_split[1].split(' {') return time_split[0]
async def ti_message_limit(self, ctx, num): member = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): if num.isdigit(): if int(num) > 0: config.set_message_limit(int(num)) await member.send('[Success] Updated message limit.') else: await member.send('[Error] Please enter a valid number.') else: await member.send('[Error] Please enter a valid number.') await ctx.message.delete() else: await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def ti_set_emote(self, ctx, user, emote): member = ctx.message.mentions[0] sender = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): # Incorrect syntax if ':' in emote: await sender.send( '[Error] Please do not include colons (:) with this command.' ) else: config.update_user(member, 'emote', emote) await sender.send('[Success] Time in emote updated.') await ctx.message.delete() else: await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def timein(self, ctx, *description): member = ctx.message.author task = ' '.join(description) # if there is no description if len(description) <= 0: await member.send('[Error] Please include a timein description.') await ctx.message.delete() # If description is too long elif len(task) > 65: await member.send('[Error] Timein description is too long.') await ctx.message.delete() # If time in channel has not been set elif config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() # If member has not defined a timezone elif config.get_user_val(member, 'time_zone') is None: await member.send( '[Error] Please define your timezone: .set_timezone <zone_num>\n' 'Example: .set_timezone 1 \n \n' 'To find your timezone: .search_timezone <args>\n' 'Example: .search_timezone Pacific US') await ctx.message.delete() # If member is already timed in elif await self.is_timed_in(member): await member.send('[Error] You already have an' ' active time in.') await ctx.message.delete() # Member has invalid characters elif not await self.message_valid(task): await member.send( '[Error] Invalid characters in time in description.') await ctx.message.delete() # Member can time in else: time_raw = ctx.message.created_at time = await self.get_time(member, time_raw) await self.time_in(member, task, time) await ctx.message.delete()
async def ti_set_payday(self, ctx, day): member = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): if day.isdigit(): if 1 <= int(day) <= 32: config.set_pay_day(int(day)) await member.send('[Success] Updated pay date.') else: await member.send( '[Error] Please enter a valid day of the month.') else: await member.send( '[Error] Please enter a numeric day of the month.') await ctx.message.delete() else: await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def switch(self, ctx, *description): member = ctx.message.author task = ' '.join(description) # if there is no description if len(description) <= 0: await member.send('[Error] Please include a timein description.') await ctx.message.delete() # If description is too long elif len(task) > 65: await member.send('[Error] Timein description is too long.') await ctx.message.delete() # If time in channel has not been set elif config.get_timein_channel( ) is None or ctx.message.channel.id != config.get_timein_channel(): await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete() # If member is not already timed in elif not await self.is_timed_in(member): await member.send( '[Error] You cannot switch tasks if you are not currently timed in' ) await ctx.message.delete() # Member has invalid characters elif not await self.message_valid(task): await member.send( '[Error] Invalid characters in time in description.') await ctx.message.delete() # Member can switch tasks else: time_raw = ctx.message.created_at time = await self.get_time(member, time_raw) # Time out the user await self.time_out(member, time) # Time them back in with the new task await self.time_in(member, task, time) await ctx.message.delete()
async def ti_report(self, ctx): member = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): if not await self.check_pay(): await member.send( "[Error] Not all users have pay rates defined.") await ctx.message.delete() elif config.get_payday() is None: await member.send("[Error] No pay date has been defined.") await ctx.message.delete() else: await self.notify_all( 'A time in report is being generated. Please notify an admin if you are currently timed in or your time ins are incorrect.' ) await ctx.message.delete() output_file = await self.timein_report(ctx.message.created_at) await member.send(file=discord.File(output_file)) else: await member.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()
async def ti_manual(self, ctx, user, in_date, in_time, out_time, *description): member = ctx.message.mentions[0] sender = ctx.message.author if config.get_timein_channel( ) is not None and ctx.message.channel.id == config.get_timein_channel( ): date = datetime.datetime.strptime(in_date, '%m-%d-%Y') in_time_raw = datetime.datetime.strptime(in_time, '%H:%M') out_time_raw = datetime.datetime.strptime(out_time, '%H:%M') task = ' '.join(description) # if there is no description if len(description) <= 0: await sender.send( '[Error] Please include a timein description.') await ctx.message.delete() # If description is too long elif len(task) > 65: await member.send('[Error] Timein description is too long.') await ctx.message.delete() # Member has invalid characters elif not await self.message_valid(task): await sender.send( '[Error] Invalid characters in time in description.') await ctx.message.delete() # Check if time range is valid elif not await self.valid_range(in_time_raw, out_time_raw): await sender.send( '[Error] Time in time must be before time out time.') await ctx.message.delete() else: # See if time in already exists async for message in self.bot.get_channel( config.get_timein_channel()).history( limit=self.MESSAGE_LIMIT): curr_message = message.content # User has already timed in on this date if await self.valid_timein_user( message, member.display_name) and ( date.strftime("%B %d, %Y") in curr_message): identifier = await self.get_identifier(member) curr_message += '\n [' + identifier + '] ' + task + ' {' + in_time_raw.strftime( "%H:%M") + ' - ' + out_time_raw.strftime( "%H:%M") + '}' await message.edit(content=curr_message) await ctx.message.delete() return # User has not timed in on this date emote = config.get_user_val(member, 'emote') emote_id = await self.get_emote_id(emote) emote_display = '<:' + emote + ':' + str(emote_id) + '>' if emote_id is None: emote_display = ':' + emote + ':' ti_message = '----------------------- \n' ti_message += (emote_display + ' ' + member.display_name + ' ' + emote_display) ti_message += '\n----------------------- \n*' + date.strftime( "%B %d, %Y") + '*' identifier = await self.get_identifier(member) task_message = '\n [' + identifier + '] ' + task + ' {' + in_time_raw.strftime( "%H:%M") + ' - ' + out_time_raw.strftime("%H:%M") + '}' await self.bot.get_channel(config.get_timein_channel() ).send(ti_message + task_message) await ctx.message.delete() else: await sender.send( '[Error] Time in commands can only be run in the time in channel.' ) await ctx.message.delete()