Beispiel #1
0
    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)
Beispiel #2
0
    async def _send_submission(self, channel: discord.Channel,
                               submission: reddit.models.Submission):
        """ Post a submission to a channel. """
        logger.info("Posting to #{}: {}".format(
            channel.name, self.log_submission(submission)))
        tags = []
        if submission.link_flair_text:
            tags.append(f'[{submission.link_flair_text}]')
        if submission.is_original_content:
            tags.append('[OC]')
        subreddit = '/r/{0}'.format(submission.subreddit.display_name)

        desc_parts = [''.join(tags)]
        if submission.is_self:
            desc_parts.append(f'(self.{submission.subreddit.display_name})')
        else:
            desc_parts.append(f'({submission.domain})')
        desc_parts.append('on')
        desc_parts.append(subreddit)

        es = EmbedSplitter(auto_truncate=True,
                           title=submission.title,
                           url='https://reddit.com' + submission.permalink,
                           timestamp=datetime.utcfromtimestamp(
                               submission.created_utc))
        es.set_footer(text=' '.join(desc_parts))
        es.set_author(name='/u/' + submission.author.name,
                      url='https://reddit.com/u/{}'.format(
                          submission.author.name))
        if submission.thumbnail.startswith(
                'http://') or submission.thumbnail.startswith('https://'):
            es.set_thumbnail(url=submission.thumbnail)
        await self.send_message(channel, embed=es)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
    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)