async def milestone_report(self, ctx: commands.Context): """!kazhelp description: Give a report of each user's current milestone roles compared to their last check-in. """ report = self.c.generate_milestone_report() es = EmbedSplitter(title="Milestone Updates Required", colour=solarized.yellow, timestamp=datetime.utcnow(), repeat_header=True, auto_truncate=True) es.set_footer(text="Generated: ") for role, ms_info_list in report.items(): if role is not None: changed_milestone_list = [ m for m in ms_info_list if m.milestone_changed ] es.add_field( name=role.name, value=self._ms_report_list_users(changed_milestone_list) or 'None', inline=False) else: es.add_field(name="No Check-Ins", value=self._ms_report_list_users(ms_info_list) or 'None') await self.send_message(ctx.message.channel, embed=es)
async def list(self, ctx: commands.Context): """!kazhelp brief: List all configured sticky messages. description: | List all configured sticky messages. """ sorted_data = sorted(self.cog_state.messages.values(), key=lambda v: v.channel.name) if sorted_data: es = EmbedSplitter(title="Channel Sticky Messages") else: es = EmbedSplitter(title="Channel Sticky Messages", description="None.") for data in sorted_data: try: jump_url = ' *([link]({}))*'.format( get_jump_url(await data.get_posted_message(self.bot))) except (AttributeError, discord.NotFound): jump_url = '' delay_string = ' (delay: {})'.format(format_timedelta( data.delay)) if data.delay else '' es.add_field(name="#{}{}".format(data.channel.name, delay_string), value="{}{}".format( natural_truncate(data.message, 512), jump_url), inline=False) await self.send_message(ctx.message.channel, embed=es)
async def show_record_page(self, dest: discord.Object, *, user: Optional[User], group: Sequence[User] = None, records: Pagination, title: str): if group is None: group = [] es = EmbedSplitter(color=self.COLOR_MAP[None], title=title) es.set_footer(text='Page {page:d}/{total:d} (Total {len:d} records)'. format(page=records.page + 1, total=records.total_pages, len=len(records))) # user information if user: user_fields = self._get_user_fields(user, group) for field_name, field_value in user_fields.items(): es.add_field_no_break(name=field_name, value=field_value, inline=True) # separator sep_name = 'Records Listing' sep_value = self.EMBED_SEPARATOR es.add_field_no_break(name=sep_name, value=sep_value, inline=False) # records page for record in records: # type: Union[Record, JoinRecord] # special case: join records without a normal record if isinstance(record, DummyRecord): es.add_field(name="First seen", value=record.display_append + self.EMBED_SEPARATOR, inline=False) continue # normal record record_fields, contents = self._get_record_fields(record, show_user=True) for field_name, field_value in record_fields.items(): es.add_field_no_break(name=field_name, value=field_value, inline=True) for field_name, field_value in contents.items(): # for JoinRecords display_append = getattr(record, 'display_append', '') if display_append: field_value += '\n' + display_append + self.EMBED_SEPARATOR es.add_field(name=field_name, value=field_value, inline=False) await self.send_message(dest, embed=es)
async def send_check_in_list(self, dest: discord.Channel, check_ins: Pagination, member: discord.Member): es = EmbedSplitter(auto_truncate=True, title="Check-in list", description=member.mention, colour=self.EMBED_COLOR) es.set_footer(text="Page {:d}/{:d}".format(check_ins.page + 1, check_ins.total_pages)) for check_in in check_ins: # type: model.CheckIn f_name = format_datetime(check_in.timestamp) f_message = '{}\n*{:d} {}* – {}\n\\_\\_\\_'.format( member.mention, check_in.word_count, self.PROJECT_UNIT_MAP[check_in.project_type], check_in.message) es.add_field(name=f_name, value=f_message, inline=False) for em in es.finalize(): await self.bot.send_message(dest, embed=em)
async def send_quotes_list(self, dest: discord.Channel, quotes: Pagination, user: model.User): title = "Quotes by {}".format(user.name) footer_text = "Page {:d}/{:d}".format(quotes.page + 1, quotes.total_pages) es = EmbedSplitter(title=title, color=self.EMBED_COLOR, auto_truncate=True) es.set_footer(text=footer_text) start_index, end_index = quotes.get_page_indices() for i, quote in enumerate(quotes.get_page_records()): # Format strings for this quote f_name = "#{:d}".format(start_index + i + 1) f_message = self.format_quote(quote, show_saved=False) + '\n\\_\\_\\_' es.add_field(name=f_name, value=f_message, inline=False) await self.send_message(dest, embed=es)
async def show_badges(self, dest: discord.Channel, badges: Pagination, member: discord.Member): es = EmbedSplitter(auto_truncate=True, title="Badges", description="{} - {:d} badges".format( member.mention, len(badges)), colour=self.EMBED_COLOUR) es.set_footer(text="Page {:d}/{:d} (total {:d} badges)".format( badges.page + 1, badges.total_pages, len(badges))) for b in badges: # type: model.Badge es.add_field_no_break(name=format_datetime(b.timestamp), value=self._get_badge(b.badge)) es.add_field_no_break(name="From", value=user_mention(b.from_user.discord_id)) es.add_field(name="For", value=b.reason + '\n' + r'\_' * 16, inline=False) for em in es.finalize(): await self.bot.send_message(dest, embed=em)
async def mixed_splitter(self, ctx: commands.Context): lines = [] for i in range(50): lines.append( '{:d}. The quick brown fox jumped over the lazy dog.'.format( i)) full_text = '\n'.join(lines) es = EmbedSplitter(auto_truncate=True, title="The Title", description="A Short Title") for i in range(10): es.add_field_no_break(name=str(i) + " A", value="A") es.add_field_no_break(name=str(i) + " B", value="B") es.add_field(name=str(i) + " C", value="CCC " * 256 + 'DDD ' * 32, inline=False) await self.send_message(ctx.message.channel, full_text, embed=es, split='line')
async def embedsplitter(self, ctx): es = EmbedSplitter(auto_truncate=True, title="asdfjkl ", description="short and stout ") es.set_author(name='ABCMan1 ', url='https://google.com') for i in range(10): es.add_field_no_break(name=str(i) + " A", value="A") es.add_field_no_break(name=str(i) + " B", value="B") es.add_field(name=str(i) + " C", value="CCCC", inline=False) for i in range(10): es.add_field_no_break(name=str(i) + " A", value="A") es.add_field_no_break(name=str(i) + " B", value="B") es.add_field(name=str(i) + " C", value="CCC " * 256 + 'DDD ' * 32, inline=False) embeds = es.finalize() self.bot.say(str(len(embeds))) for em in embeds: await self.bot.say(embed=em)
async def check_in_delta(self, ctx: commands.Context, *, datespec: NaturalDateConverter = None): """!kazhelp description: "Get a report of wordcount changes in a given check-in week, compared to previous check-in." parameters: - name: datespec type: datespec optional: true default: 'last week ("7 days ago")' description: A date in any unambiguous format (2018-03-14, March 14 2018, 14 March 2018, today, 1 month ago, etc.). The report will be for the check-in week that includes this date. examples: - command: .checkin delta description: Get a report for last week. - command: .checkin delta 2018-04-18 description: Get a report for the week that includes 18 April 2018. """ if not datespec: datespec = datetime.utcnow() - timedelta(days=7) start, end = self.c.get_check_in_week(datespec) week_str = "the week from {} to {}".format(format_datetime(start), format_datetime(end)) try: report, ci_map = self.c.generate_check_in_deltas(datespec) except orm.exc.NoResultFound: await self.bot.say("No check-ins for {}.".format(week_str)) return # sort descending by diff value s_users = list(report.keys()) s_users.sort(key=lambda u: report[u] if report.get(u, None) else float('-inf'), reverse=True) # Prepare display delta_strings = [] for u in s_users: if report[u] is not None: unit = self.PROJECT_UNIT_MAP[ci_map[u].project_type] if ci_map.get(u, None) \ else 'words' delta_strings.append( "{0} ({1:+d} {3} - *total {2:d} {3}*)".format( u.mention, report[u], ci_map[u].word_count if ci_map.get(u, None) else 0, unit)) else: delta_strings.append("{0} (no check-in)".format(u.mention)) delta_list_str = '\n'.join(delta_strings) # Prepare the overall embed es = EmbedSplitter(title="User Progress Report", colour=solarized.cyan, description="Report for " + week_str + '\n\n', timestamp=datetime.utcnow(), repeat_header=True, auto_truncate=True) es.set_footer(text="Generated: ") es.add_field(name="_", value=delta_list_str, inline=False) await self.send_message(ctx.message.channel, embed=es)
async def check_in_report(self, ctx: commands.Context, *, datespec: NaturalDateConverter = None): """!kazhelp description: "Get a report of who has or has not checked in in a given week." parameters: - name: datespec type: datespec optional: true default: 'last week ("7 days ago")' description: A date in any unambiguous format (2018-03-14, March 14 2018, 14 March 2018, today, 1 month ago, etc.). The report will be for the check-in week that includes this date. examples: - command: .checkin report description: Get a report for last week. - command: .checkin report 2018-04-18 description: Get a report for the week that includes 18 April 2018. """ if not datespec: datespec = datetime.utcnow() - timedelta(days=7) start, end = self.c.get_check_in_week(datespec) week_str = "the week from {} to {}".format(format_datetime(start), format_datetime(end)) try: ci, nci = self.c.generate_check_in_report( datespec) # checked in, not checked in except orm.exc.NoResultFound: await self.bot.say("No check-ins for {}.".format(week_str)) return # # determine sorting order of each list # # checked in: by name ci_users = list(ci.keys()) ci_users.sort( key=lambda u: u.nick.lower() if u.nick else u.name.lower()) # not checked in: by last checkin date pre-reporting week nci_users = list(nci.keys()) epoch = datetime(1970, 1, 1) nci_users.sort(key=lambda u: nci[u].timestamp if nci.get(u, None) else epoch, reverse=True) # # Prepare display # # format strings for display ci_list_str = '\n'.join("{0} ({1} - *{2:d} {3}*)".format( u.mention, format_datetime(ci[u].timestamp), ci[u].word_count, self.PROJECT_UNIT_MAP[ci[u].project_type]) for u in ci_users) nci_list_str = '\n'.join("{0} (last: {1})".format( u.mention, format_date(nci[u].timestamp) if nci.get(u, None) else 'Never') for u in nci_users) # Prepare the overall embed es = EmbedSplitter(title="Check-In Report", colour=solarized.green, description="Report for " + week_str, timestamp=datetime.utcnow(), repeat_header=True, auto_truncate=True) es.set_footer(text="Generated: ") if len(ci_list_str) < Limits.EMBED_FIELD_VALUE: es.add_field(name="Checked in", value=ci_list_str or 'Nobody', inline=False) else: es.add_field(name="Checked in", value="{:d} users (list too long)".format( len(ci_users)), inline=False) es.add_field(name="Did NOT check in", value=nci_list_str, inline=False) await self.send_message(ctx.message.channel, embed=es)